IE8 throws long running script error while using Google HeatMap overlay - google-maps

I am trying to render a heatmap using google maps api v3 which works on all browsers but not in IE. IE 9 takes long time to render but IE8 starts throwing "Stop running this script" alert saying the script is taking too long.
I have placed a simple example below with just 5 clusters and IE8 still throws long running script error. Could you please help me with this issue. Thanks!
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&sensor=false">
</script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function () {
var data = [
{ "lat": "45.284397", "lon": "-126.724372", "count": 10 },
{ "lat": "45.284156", "lon": "-126.724853", "count": 5 },
{ "lat": "45.284450", "lon": "-126.725532", "count": 20 },
{ "lat": "45.284839", "lon": "-126.725875", "count": 34 },
{ "lat": "45.285442", "lon": "-126.726181", "count": 46 }
];
var usaCenter = new google.maps.LatLng(54.6, -119.2);
var heatMap = new google.maps.Map(document.getElementById('heatMap'), {
zoom: 4,
center: usaCenter,
mapTypeControlOptions: {
mapTypeIds: ["Traffic", google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID, google.maps.MapTypeId.TERRAIN]
},
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var heatMapData = [];
var bounds = new google.maps.LatLngBounds;
$.each(data, function (index, point) {
var latLng = new google.maps.LatLng(point["lat"], point["lon"]);
var heatPoint = {
location: latLng,
weight: point["count"]
};
heatMapData.push(heatPoint);
bounds.extend(latLng);
});
var heatmapOverLay = new google.maps.visualization.HeatmapLayer({
data: heatMapData,
opacity: 0.7
});
heatmapOverLay.setMap(heatMap);
});
</script>
<div id="heatMap" style="width:1600px;height:1600px"></div>

IE8 makes this warning based on the number of statements and not based on the time the scripts are taking to run. This warning in my opinion is inaccurate.
By default threshold limit for the time-out dialog box is 5,000,000 statements.
Microsoft released a patch to correct this: http://support.microsoft.com/kb/175500
Please note that microsoft also indicates that which is the registry entry to increase this to any level if necessary:
Using a Registry Editor such as Regedt32.exe, open this key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Styles
Note If the Styles key is not present, create a new key that is called Styles.
Create a new DWORD value called "MaxScriptStatements" under this key, and set the value to the desired number of script statements.
If you are not sure about which value you need to set this to, you can set it to a DWORD value of 0xFFFFFFFF to avoid the dialog box.

Related

Multiple Map Markers

I'm trying to set a different marker icon size on click. The trouble I'm having is all icons with an infowindow change to the first icon item in the array. The Infowindow and data within is correct.
I've been scratching my head on this one, any ideas why the vars would be different on click? They are set using the same file path, just using different scaled sizes.
Is there a better approach to how this is currently being done?
var markers = new Array();
var mapMultiple;
function initMap() {
// Get focus point
var mapLat = parseFloat(mapVar.lat);
var mapLng = parseFloat(mapVar.lng);
var myLatLng = {lat: mapLat, lng: mapLng};
// Get locations
var locationsMultipleMarkers = mapVar.locationsMultipleMarkers;
// Map Defaults
var mapMultiple = new google.maps.Map(document.getElementById('map-multiple'), {
zoom: 9,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Markers and info popup
var markerMultipleMarkers, i;
for (i = 0; i < locationsMultipleMarkers.length; i++) {
var iconMultiple = locationsMultipleMarkers[i]['icon'];
if(!iconMultiple) {
iconMultiple = mapVar.path + '/assets/svg/marker-default.svg';
}
// Icon ready state
var iconMultipleMarkers = {
url: iconMultiple,
scaledSize: new google.maps.Size(60, 60)
};
// Icon active state
var iconMultipleMarkersActive = {
url: iconMultiple,
scaledSize: new google.maps.Size(120, 120)
};
// Markers and info popup
var infowindowMultipleMarkers = new google.maps.InfoWindow();
var markerMultipleMarkers, i;
markerMultipleMarkers = new google.maps.Marker({
position: new google.maps.LatLng(locationsMultipleMarkers[i]['lat'], locationsMultipleMarkers[i]['lng']),
map: mapMultiple,
animation: google.maps.Animation.DROP,
icon: iconMultipleMarkers
});
markers.push(markerMultipleMarkers);
google.maps.event.addListener(markerMultipleMarkers, 'click', (function(markerMultipleMarkers, i) {
return function() {
if(locationsMultipleMarkers[i]['marker_info']) {
for (var j = 0; j < markers.length; j++) {
markers[j].setIcon(iconMultipleMarkers);
}
this.setIcon(iconMultipleMarkersActive);
infowindowMultipleMarkers.setContent(locationsMultipleMarkers[i]['marker_info']);
infowindowMultipleMarkers.open(mapMultiple, markerMultipleMarkers);
}
}
})(markerMultipleMarkers, i));
}
}
Based upon your code, with some ( ok, lots of ) modifications and a degree of creative license, I put together a demo of how you can essentially toggle each marker you have loaded onto the map between two states - differing here simply by the scaledSize property only as far as I can tell from your code. Personally I found it a little confusing when there were several variables with similar long names - just sort of adds too much clutter to my mind.
Assuming that the source data is probably being derived from a database query and output as JSON I generated some dummy data based upon the various properties of the mapVar variable.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Google Maps: </title>
<style>
#map{
width:800px;
height:600px;
float:none;
margin:auto;
}
</style>
<script>
const mapVar={
path:'/path/to/images/markers',
sizes:{ // sizes used to build `Icons`
ready:32, // default -> 60
active:60 // default -> 120
},
lat:56.522556, // default latitude ~ details unknown
lng:-2.969856, // default longitude ~ details unknown
locations:[ // example data
{
"name": "Glaxo - 2 x 132m turbines",
"lat": "56.70431711148748",
"lng": "-2.4660869436035",
"marker_info": "Glaxo - 2 x 132m turbines, 2 Blade Turbine, 5 Meridian St, Montrose, Angus DD10 8DS, UK",
"icon": "/images/css/2_blade_turbine.png"
},
{
"name": "Carsegownie - 1 x78m turbine",
"lat": "56.67951330362271",
"lng": "-2.8062983350524746",
"marker_info": "Carsegownie - 1 x78m turbine, Anemometer, B9134, Forfar, Angus DD8, UK",
"icon": "/images/css/mappoint-anemometer.png"
},
{
"name": "Frawney - Over Finlarg - 5x100m turbines",
"lat": "56.56806620951482",
"lng": "-2.9501720266113125",
"marker_info": "Frawney - Over Finlarg - 5x100m turbines, Antenna, Kerton Farm, Forfar, Angus DD8, UK",
"icon": "/images/css/mappoint-antenna.png"
},
{
"name": "Dodd Hill - 5 x 125m turbines",
"lat": "56.54251020079966",
"lng": "-2.9051538305053555",
"marker_info": "Dodd Hill - 5 x 125m turbines, Simple, 4 Backmuir Rd, Duntrune, Tealing, Dundee, Angus DD4 0PT, UK.",
"icon": "/images/css/mappoint-blue.png"
},
{
"name": "Ark Hill - 8 x 81m turbines",
"lat": "56.57065514278748",
"lng": "-3.0511732892761074",
"marker_info": "Ark Hill - 8 x 81m turbines, New location, 3 Dryburn Cottages, Glenogilvy, Forfar, Angus DD8 1UP, UK",
"icon": "/images/css/mappoint-green.png"
},
{
"name": "Nathro 17 x 135m turbines",
"lat": "56.793249595719956",
"lng": "-2.8623101711273193",
"marker_info": "Nathro 17 x 135m turbines, House, 1 Goynd Steading, Glenogil, Forfar, Angus DD8 3SW, UK.",
"icon": "/images/css/mappoint_house.png"
},
{
"name": "Govals - 6 x 87m turbines",
"lat": "56.582320876071854",
"lng": "-2.9509015874633633",
"marker_info": "Govals - 6 x 87m turbines, McDonalds, B9127, Forfar, Angus DD8, UK.",
"icon": "/images/css/mappoint_mcdonalds.png"
},
{
"name": "The Carrach - 9 x 84m turbines",
"lat": "56.6938437674986",
"lng": "-3.131382067657455",
"marker_info": "The Carrach - 9 x 84m turbines, vawt, B951, Kirriemuir, Angus DD8, UK",
"icon": "/images/css/vawt.png"
}
]
};
class marker{
/*
simple class to add new marker and assign callbacks.
Override default options by giving different args at
runtime.
*/
constructor( map, latlng, args={}, callbacks=false ){
this.map=map;
this.latlng=latlng;
this.args=args;
this.callbacks=callbacks;
return this.create();
};
create(){
let options=Object.assign({
clickable:true,
draggable:false,
position:this.latlng,
map:this.map
},this.args );
let mkr=new google.maps.Marker( options );
if( this.callbacks && Object.keys( this.callbacks ).length > 0 ){
Object.keys( this.callbacks ).forEach( event => {
google.maps.event.addListener( mkr, event, this.callbacks[ event ] );
})
}
return mkr;
};
};
function initMap(){
let markers=[];
let latlng = new google.maps.LatLng( mapVar.lat, mapVar.lng );
let locations=mapVar.locations;
let map = new google.maps.Map( document.getElementById('map'), {
zoom: 9,
center: latlng,
mapTypeId:google.maps.MapTypeId.ROADMAP
});
locations.forEach( obj=>{
let icon=obj.icon || mapVar.path + '/assets/svg/marker-default.svg';
// A default Icon to be used when creating the map
let _default={
url:icon,
scaledSize:new google.maps.Size( mapVar.sizes.ready, mapVar.sizes.ready )
};
// The alternative state Icon to be displayed when marker is clicked.
let _active={
url:icon,
scaledSize:new google.maps.Size( mapVar.sizes.active, mapVar.sizes.active )
};
/*
custom properties to assign to the marker using the marker class above.
The `content` is used to build the infowindow - from mapVar data.
The `index` is used to determine which marker to select from the array.
The `infowindow` becomes a property of the marker... many markers might cause issues!
*/
let args={
index:0,
infowindow:new google.maps.InfoWindow(),
content:obj.marker_info,
icon:_default
};
// toggle between these Icons
let Icons=[ _default, _active ];
// assign whatever callbacks are needed to be used with the new marker.
let callbacks={
click:function(e){
this.index = 1 - this.index;
this.setIcon( Icons[ this.index ] );
// open the infowindow
with( this.infowindow ){
setContent( this.content );
setPosition( e.latLng );
open( map, this );
}
// if the infowindow is open, close it
if( !this.index )this.infowindow.close()
}
};
markers.push( new marker( map, new google.maps.LatLng( obj.lat, obj.lng ), args, callbacks ) );
});
};
</script>
</head>
<body>
<div id='map'></div>
<script async defer src='//maps.googleapis.com/maps/api/js?key=<APIKEY>&callback=initMap'></script>
</body>
</html>
The icons could be completely different rather than just a different size if needed.
Working example

Google Maps Weather Layer on top of other

I have a google map with two layers:
1 - Fusion Layer
2 - Weather Layer
The problem is, where fusion appears, the weather layer isn't visible anymore. So basically, I want like a css z-index property, to display the weather at the top
My code till now:
$(function() {
window.table_id = "abc";
window.map = new google.maps.Map(document.getElementById("map-canvas"), {
center: new google.maps.LatLng(31.056091682584327, -96.01576748461912),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.initializeWeather();
return google.initializeFusion();
});
google.initializeFusion = function() {
google.maps.visualRefresh = true;
return window.fusionLayer = new google.maps.FusionTablesLayer({
map: window.map,
heatmap: {
enabled: false
},
query: {
select: "col2",
from: "abc",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
};
google.initializeWeather = function() {
var cloudLayer, weatherLayer;
weatherLayer = new google.maps.weather.WeatherLayer({
map: window.map,
temperatureUnits: google.maps.weather.TemperatureUnit.FAHRENHEIT
});
cloudLayer = new google.maps.weather.CloudLayer();
return cloudLayer.setMap(window.map);
};
Thanks for your time!
Have you tried adding the weather layer after the Fusion Tables layer?
It's a headache that we get to deal with when using more than 1 styled fusiontables layer. What works 1 day may not work the next, and it seems to be on Google's end.
You can try to initialize one before the other, or clear both and bring one back (background) and then the other (foreground) but that seems to have its own issues.
It's an issue that the Fusion Tables and Maps staff at Google need to figure out, and unfortunately I've not seen a decent workaround to this point.

Google Maps toggle button

I have been struggling with this all day. I have made new buttons to actually go on my map that match the Google Maps buttons sit on the map better. I have been trying to get them to work with the current buttons above the map so I can remove those but I can't seem to get them to work. What am I missing.
Here is a link to the page so you can see. The buttons above the map work and I am going to remove them. The buttons on the map don't work which I am trying to get to work.
DEMO LINK
Here is the code. The var radarButton and var satButton is the new ones. The ones below that is to the current buttons.
jQuery(document).ready(function($) {
var mapTypeId = wundermap.getMapTypeId("hyb");
var googlemap = new google.maps.Map($("#map")[0], {
center: new google.maps.LatLng(32.782878, -96.609862),
panControl: false,
zoom: 6,
mapTypeId: mapTypeId,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL,
position: google.maps.ControlPosition.RIGHT_TOP
},
});
var radarOptions = {
gmap: googlemap,
name: 'Radar',
position: google.maps.ControlPosition.TOP_RIGHT,
action: function(){
if (wundermap.map.overlayMapTypes.length==0) {
wundermap.map.overlayMapTypes.push(null); // create empty overlay entry
wundermap.map.overlayMapTypes.setAt("1",Radar);
}
else {
wundermap.map.overlayMapTypes.clear();
}
}
}
var radarButton = new buttonControl(radarOptions);
var satOptions = {
gmap: googlemap,
name: 'Satellite',
position: google.maps.ControlPosition.TOP_RIGHT,
action: function(){
if (wundermap.map.overlayMapTypes.length==0) {
wundermap.map.overlayMapTypes.push(null); // create empty overlay entry
wundermap.map.overlayMapTypes.setAt("1",Satellite);
}
else {
wundermap.map.overlayMapTypes.clear();
}
}
}
var satButton = new buttonControl(satOptions);
wundermap.setOptions({
map: googlemap,
refreshPeriod: 60000,
units: "english",
debug: 0,
source: "wxmap",
StreetsOverlay: true,
layers: [
{
layer: "Radar",
active: "on",
opacity: 70,
type: "N0R",
type2: "",
animation: {
num: 6,
max: 10,
delay: 25
},
stormtracks: "off",
smooth: "on",
subdomain: "radblast-aws"
},
{
layer: "Satellite",
defaultUI: 0,
opacity: "85",
source: "",
active: "off",
animation: {
num: 1,
max: 8,
delay: 25
}
},
],
});
wundermap.initialize();
});
Here is the link to the code for the actual layer. The code is to long to post but the overlay is called Radar.
RADAR CODE
The place to start is the JavaScript console. The error messages there tell you what the problems are.
First, when the page is loaded you have an error on line 286 of wxgr3radar.php:
<body onload="initialize()">
Where is your initialize() function defined? I don't see it in your code.
Then, when I click the Satellite button it stops on line 41 of imap.js because map.overlayMapTypes is undefined:
if (map.overlayMapTypes.length==0) {
Here you're expecting map to be a Maps API object, but map is not what you think it is. Look at it in the debugger. It's a DOM element, not a Maps API map. Your Maps API map is in a variable called googlemap, which you create in line 3 of imap.js.

Google Maps showing wrong current location

I am using google maps in my sencha touch application. And I am using current location as true. But some time I am getting my current location different some time.
Below is the code I have used to show map.
this.map = new Ext.Map({
mapOptions : {
zoom: 12,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
useCurrentLocation: true,
});

Google Maps Fusion Table layer doesn't apply conditional styles based on the text column

I'd like to apply different marker styles depends on the column with three different string values. Query works fine, it uses FT styles if no styles defined in the script, but if there is conditional logic implemented - map gets the layer with "Data still maybe loading" label and no error produced.
The code is:
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
var map,layer;
google.load('maps', '3', { other_params: 'sensor=false' });
google.setOnLoadCallback(function(){
var cp = new google.maps.LatLng(42.87, 74.57);
map = new google.maps.Map(document.getElementById('map'), {
center: cp,
zoom: 7,
mapTypeId: 'roadmap'
});
layer = new google.maps.FusionTablesLayer({
query: { select: 'Locations (oblast, rayon, village)', from: '2825956' },
// if the styles definition below exists map doesn't get any data layer applied
styles: [
{ markerOptions: { iconName: 'wht_blank'} },
{ where: "'Thematic area' = 'Environment and Sustainable development'", markerOptions: { iconName: 'grn_blank' }},
{ where: "'Thematic area' = 'Democratic Governance Programme'", markerOptions: { iconName: 'blu_blank' }},
{ where: "'Thematic area' = 'Poverty Reduction'", markerOptions: { iconName: 'red_blank' }}
]
});
layer.setMap(map);
});
</script>
Cool to see that you're using FT styling. It's a great feature.
There's only one problem with your code. The column you're looking for in your table is actually called Locations.
Change your query to this:
query: { select: 'Locations', from: '2825956' },
and everything works.