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
Related
Using samples from Customizing the Map I created two custom styled map types. Now my map has four tabs.
I would like to display green markers on the green map (tab), and red markers on the red map (tab). I haven't seen a similar question, is this even possible with this approach or do I need to look into something else?
EDIT: during preview I could see red and green maps (tabs) but after posting they are not showing in the snippet. There should be four options for the map:
Map Satellite red green
Not sure why it looks different after posting.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(51, 4),
zoom:8,
mapTypeControlOptions: {
mapTypeIds: ["roadmap", "satellite", "red", "green"],
},
});
var red = new google.maps.StyledMapType(
[
{
"featureType": "administrative",
"stylers": [
{
"visibility": "on"
}
]
}
],
{ name: "red" }
);
map.mapTypes.set("red", red);
map.setMapTypeId("red");
var green = new google.maps.StyledMapType(
[
{
"featureType": "administrative",
"stylers": [
{
"visibility": "on"
}
]
}
],
{ name: "green" }
);
map.mapTypes.set("green", green);
map.setMapTypeId("green");
var markers = [];
// make random red, yellow, blue markers
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(), 4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/green.png',
label: '${i}',
map: map
});
markers.push(marker);
}
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(),4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/yellow.png',
label: '${i}',
map: map
});
markers.push(marker);
}
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(),4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/red.png',
label: '${i}',
map: map
});
markers.push(marker);
}
// match cluster icon to markers
var calc = function(markers, numStyles) {
for (var i = 0; i < markers.length; i++) {
if (markers[i].getIcon().indexOf("red.png") > -1) {
return {text: markers.length, index: 3}; // index of red
}else if (markers[i].getIcon().indexOf("yellow.png") > -1) {
return {text: markers.length, index: 2}; // index of yellow
}else if (markers[i].getIcon().indexOf("green.png") > -1) {
return {text: markers.length, index: 1};// index of blue
}
}
}
// define cluster icons
var mcOptions = {gridSize: 50, maxZoom: 15, styles: [{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m1.png",
width: 50
},
{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m2.png",
width: 50
},
{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m3.png",
width: 50
}]
};
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
markerCluster.setCalculator(calc);
}
#map {
height: 80%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<script defer src="https://maps.googleapis.com/maps/api/js?v=3.42&key=YOUR_API_KEY&callback=initMap"></script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
<div id="map"></div>
From the question one thing that was not overly clear is whether or not the colour of the cluster icon should be the same as the colour of the icons. The default, numerically indexed, available colours do not include green yet your code does specifically reference this colour - as an icon green is perfectly fine however. Because of this the following might only be "close" to the initial requirement as there is no Green.
If you were hosting the various cluster images on your own server it is trivial to create a new icon in green!
With that in mind perhaps the following will be of use -
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Google Maps: Clustered Markers with Custom "Map Stylers"</title>
<style>
#map{
width:800px;
height:600px;
float:none;
margin:auto;
}
.label{
padding:0.25rem;
border:2px solid gray;
border-radius:0.5rem;
background:whitesmoke;
text-align:center;
}
.blue{}
.yellow{color:black!important;background:yellow}
.red{}
.pink{color:black!important;background:pink;}
.purple{}
</style>
<script src='//developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js'></script>
<script>
const additional_stylers=true;
// pseudo random number generator
const mt_rand=function(a,b){
return Math.floor( Math.random() * ( b - a + 1 ) + a );
};
/*
These correspond to the colours of the icons available within
the default icons found number 1-5:
https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m[N].png
There is no Green...
*/
const colours={
'Blue':{
color:'#0000ff',
compliment:'#ff8000'
},
'Yellow':{
color:'#fbf6d1',
compliment:'#f1d1fb'
},
'Red':{
color:'#f1d7d7',
compliment:'#d89595'
},
'Pink':{
color:'#f08194',
compliment:'#f09381'
},
'Purple':{
color:'#9365f7',
compliment:'#a387de'
}
};
function initMap(){
/*
set the map with basic options
- append the new MapTypeIds
*/
let latlng=new google.maps.LatLng( 51, 4 );
let options = {
zoom:8,
center:latlng,
mapTypeId:google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions:{
mapTypeIds:[ 'roadmap' ].concat( Object.keys( colours ) ),
}
};
const map = new google.maps.Map( document.getElementById('map'), options );
// set up the colours for themes and icons/markers
let rgb={};
/*
for each colour, add a new map styler and
create some markers - these are not yet
added to the map.
*/
Object.keys(colours).forEach( ( colour,index ) => {
/* set the custom style rules */
let rules=[
{ featureType:'administrative', elementType:'all',stylers:[ { visibility:'on' } ] }
];
if( additional_stylers ){
rules.push({ featureType:'road', elementType:'geometry', stylers:[ { color:colours[colour].compliment } ] });
rules.push({ featureType:'water', elementType:'geometry.fill', stylers:[ { color:colours[colour].color } ] });
/* other rules... */
};
rgb[colour]={
'markers':[],
'style':new google.maps.StyledMapType( rules, { name:colour } )
};
map.mapTypes.set( colour, rgb[colour].style );
/*
generate a varying number of markers for each
cluster colour || or just 20 as per original...
*/
for( let i=0; i < ( 20 * ( index + 1 + mt_rand(1,10) ) ); i++ ){
let mkr=new google.maps.Marker({
position: new google.maps.LatLng( 51.11 - Math.random(), 4.11 - Math.random() ),
colour:colour,
title:i.toString(),
icon:{
url:'//maps.google.com/mapfiles/ms/micons/'+colour.toLowerCase()+'.png',
labelOrigin:new google.maps.Point(16,-15)
},
label:{
text:i.toString(),
fontFamily:'monospace',
fontSize:'1rem',
fontWeight:'bold',
color:colour,
className:[ 'label', colour.toLowerCase() ].join(' ')
}
});
// store the new marker
rgb[colour].markers.push( mkr );
}
});
const calculator=function( markers, numStyles ) {
return {
text:[ markers[0].colour, markers.length ].join( String.fromCharCode(32) ),
index:Object.keys(colours).indexOf( markers[0].colour ) + 1
}
};
/*
Create the clusterer with NO markers
and assign the (undocumented) calculator.
The calculator function has been simplified
using the array of colours defined earlier.
*/
let oCluster=new MarkerClusterer( map, [], {
imagePath:'//developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
});
oCluster.setCalculator( calculator );
/*
Listen for maptype change events
and initialise the clusterer with
the respective set of markers if,
and only if, the selected maptype
is a named colour.
*/
map.addListener('maptypeid_changed',()=>{
let colour=map.getMapTypeId();
oCluster.clearMarkers();
if( Object.keys(colours).includes( colour ) ){
oCluster.addMarkers( rgb[colour].markers, false );
oCluster.fitMapToMarkers();
}
});
}
</script>
<script async defer src='//maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap'></script>
</head>
<body>
<div id='map'></div>
</body>
</html>
Proof of concept jsFiddle
I have the following code that draws a polyline between 13 GPS coordinates.The polyline is drawn correctly. I'm trying to put a marker on the distance of 5 KM from the starting point of the polyline. I'm trying to use GetPointAtDistance() from v3_epoly but when I reference it, using
flightPath.GetPointAtDistance(5000);
just before flightPath.setMap(map); but the polyline disappears and no new marker appears. I'm ripping my hair out about why this isn't working, any help would be much appreciated
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>VM 2</title>
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
<script type="text/javascript" src="scripts/v3_epoly.js"></script>
</head>
<body style="font-family: Arial; font-size: 12px;">
<div style="width: 100%;" id="mapDiv">
<div id="map" style="width: 70%; height: 600px; float: left;margin:0px;color:black;"></div>
<div id="panel" style="width: 30%; float: left;margin:0px;"></div>
</div>
<script type="text/javascript">
var locations = [
{
title: "Point 1",
lat : -0.004259,
lng : 36.96367099999998,
},
{
title: "Point 2",
lat : 0.3606,
lng : 36.782,
},
{
title: "Point 3",
lat : 0.3145033,
lng : 36.9755982,
},
{
title: "Point 4",
lat : 0.2336305,
lng : 37.3166943,
},
{
title: "Point 5",
lat : 0.2253856,
lng : 37.440852,
},
{
title: "Point 6",
lat : 0.0880828,
lng : 38.1899782,
},
{
title: "Point 7",
lat : -0.2356904,
lng : 36.8766403,
},
{
title: "Point 8",
lat : -0.4169027,
lng : 36.6666989,
},
{
title: "Point 9",
lat : -0.3666667,
lng : 36.0833333,
},
{
title: "Point 10",
lat : -1.4065513,
lng : 34.906551,
},
{
title: "Point 11",
lat : -1.3666667,
lng : 36.8333333,
},
{
title: "Point 12",
lat : -2.55143,
lng : 37.79738,
},
{
title: "Point 13",
lat : -3.3951791,
lng : 37.9572584,
},
];
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom : 2,
center : new google.maps.LatLng(10, -10),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].lat, locations[i].lng),
map : map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i].title);
infowindow.open(map, marker);
}
})(marker, i));
}
var flightPath = new google.maps.Polyline({
path : locations,
geodesic : true,
strokeColor : '#5589ca',
strokeOpacity: 1.0,
strokeWeight : 2
});
var latlngex = new google.maps.LatLng(-4.0434771,39.6682065);
var titleex = "Test Marker";
createMarker(map,latlngex,titleex);
flightPath.setMap(map);
}
function createMarker(map, latlng, title){
var marker = new google.maps.Marker({
position:latlng,
map:map,
title: title,
icon: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png'
});
}
google.maps.event.addDomListener(window, "load", initialize);
</script>
</body>
I had no luck getting v3_epoly to connect to JSfiddle.
Instead, I used the method from geocodezips implementation and added the function locally:
GetPointAtDistance = function(metres) {
// some awkward special cases
if (metres == 0) return flightPath.getPath().getAt(0);
if (metres < 0) return null;
if (flightPath.getPath().getLength() < 2) return null;
var dist = 0;
var olddist = 0;
for (var i = 1;
(i < flightPath.getPath().getLength() && dist < metres); i++) {
olddist = dist;
dist += google.maps.geometry.spherical.computeDistanceBetween(
flightPath.getPath().getAt(i),
flightPath.getPath().getAt(i - 1)
);
}
if (dist < metres) {
return null;
}
var p1 = flightPath.getPath().getAt(i - 2);
var p2 = flightPath.getPath().getAt(i - 1);
var m = (metres - olddist) / (dist - olddist);
return new google.maps.LatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m);
}
and called it using the following:
createMarker(map, GetPointAtDistance(30000), titleex);
And the green marker will appear.
I made some other slight altercation, here is JsFiddle : https://jsfiddle.net/cmjcs5eL/19/
This question already has an answer here:
An issue while showing a path on Google Maps
(1 answer)
Closed 6 years ago.
I'm developing a MVC app using google map API.
There are 4 or more coordinates in my program. According to that I need to draw road path. This is my code so far.
<div id="dvMap" style="width: 500px; height: 500px">
</div>
#section scripts
{
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyBZxYACsC1qz9gticRd4mbki9Tes9qexdw&sensor=false"></script>
<script type="text/javascript">
var markers = [
{
"title": 'Canberra',
"lat": '-35.2809',
"lng": '149.1300',
"description": ''
},
{
"title": 'Sydny',
"lat": '-33.8688',
"lng": '151.2093',
"description": ''
},
{
"title": 'Tamworth',
"lat": '-31.0927',
"lng": '150.9320',
"description": ''
}
,
{
"title": 'Brisbane',
"lat": '-27.465895',
"lng": '153.019519',
"description": ''
}
];
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Initialize the Path Array
var path = new google.maps.MVCArray();
//Initialize the Direction Service
var service = new google.maps.DirectionsService();
//Set the Path Stroke Color
var poly = new google.maps.Polyline({ map: map, strokeColor: '#4986E7' });
//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length; i++) {
if ((i + 1) < lat_lng.length) {
var src = lat_lng[i];
var des = lat_lng[i + 1];
path.push(src);
poly.setPath(path);
service.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
console.log('len ' + result.routes[0].overview_path.length)
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
}
});
}
}
}
</script>
}
The problem is the map is shown straight lines as well.
I need to remove straight lines from the map (should keep lines draw on road path) and what's wrong in my code? In addition, Markers should show only for starting point and destination point. But all points are shown as markers. So how to do it...? Please give me a direction for doing it....
At the beginning of your script you're drawing markers on the map. To avoid that comment out the line map: map,
var marker = new google.maps.Marker({
position: myLatlng,
// map: map,
title: data.title
});
To remove the straight lines from the map:
comment out the line
//poly.setPath(path);
You need to use a DirectionsRenderer to show routes on the map once the routes are returned by the directionsService.
Define a function to render the computed routes
function renderDirections(result) {
var directionsRenderer = new google.maps.DirectionsRenderer;
directionsRenderer.setMap(map);
directionsRenderer.setDirections(result);
};
Add the rendering to the callback function of the directionsService
directionsService.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function(result, status) {
// if route is computed successfully, render it on map
if (status == google.maps.DirectionsStatus.OK) {
console.log('len ' + result.routes[0].overview_path.length);
renderDirections(result);
} else {
console.log("Error: ", status);
}
});
The issue here is that you're trying to display multiple routes on your map, check this question for details.
Hope this helps.
I have one query regarding google map api .
I am drawing road map line between two Geo location(Suppose A and B) through one Geo point (Suppose C).
Problem is : First time when map is loaded there is always one straight line between point A and point B along with road map among these three points (A , B and C). But when map is reloaded again then straight line (Between A and B) vanishes as expected.
Could you please help me in this regard. My code is following.
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var markers = [
{
"title": 'Alibaug',
"lat": '28.4700',
"lng": '77.0300',
"description": 'Alibaug is a coastal town and a municipal council in Raigad District in the Konkan region of Maharashtra, India.'
}
,
{
"title": 'Mumbai',
"lat": '28.6139',
"lng": '77.2090',
"description": 'Mumbai formerly Bombay, is the capital city of the Indian state of Maharashtra.'
}
,
{
"title": 'Pune',
"lat": '28.5700',
"lng": '77.3200',
"description": 'Pune is the seventh largest metropolis in India, the second largest in the state of Maharashtra after Mumbai.'
}
];
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
lat_lng[i]=myLatlng;
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
});
latlngbounds.extend(marker.position);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Initialize the Path Array
var path = new google.maps.MVCArray();
//Initialize the Direction Service
var service = new google.maps.DirectionsService();
//Set the Path Stroke Color
var poly = new google.maps.Polyline({ map: map, strokeColor: '#4986E7' });
//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length; i++) {
if ((i + 1) < lat_lng.length) {
var src = lat_lng[i];
var des = lat_lng[i + 1];
poly.setPath(path);
service.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
} } );
} } }
</script>
<div id="dvMap" style="width: 500px; height: 500px">
</div>
Only send a single request. The Google Maps Directions Service supports waypoints if you have less than 10 total points (with the free API, 25 total points with Google Maps for Business), you can use a single request, with a source, a destination and a waypoint, which will reduce the load on Google servers and make the response more consistent.
One possible reason for the behavior you are seeing is the asynchronous behavior of the Directions Service. If the responses come back in a different order than they are sent, you could see the behavior you are describing.
proof of concept fiddle
code snippet:
window.onload = function() {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = [];
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i];
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
lat_lng[i] = myLatlng;
var marker = new google.maps.Marker({
position: myLatlng,
map: map
});
latlngbounds.extend(marker.position);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Initialize the Path Array
var path = new google.maps.MVCArray();
//Initialize the Direction Service
var service = new google.maps.DirectionsService();
//Set the Path Stroke Color
var poly = new google.maps.Polyline({
map: map,
strokeColor: '#4986E7'
});
//Loop and Draw Path Route between the Points on MAP
var request = {
travelMode: google.maps.DirectionsTravelMode.DRIVING
}
for (var i = 0; i < lat_lng.length; i++) {
if (i == 0) {
request.origin = lat_lng[i];
} else if (i == lat_lng.length - 1) {
request.destination = lat_lng[i];
} else {
if (!request.waypoints) {
request.waypoints = [];
}
request.waypoints.push({
location: lat_lng[i]
});
}
}
service.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
poly.setPath(path);
}
});
};
var markers = [{
"title": 'Alibaug',
"lat": '28.4700',
"lng": '77.0300',
"description": 'Alibaug is a coastal town and a municipal council in Raigad District in the Konkan region of Maharashtra, India.'
}, {
"title": 'Mumbai',
"lat": '28.6139',
"lng": '77.2090',
"description": 'Mumbai formerly Bombay, is the capital city of the Indian state of Maharashtra.'
}, {
"title": 'Pune',
"lat": '28.5700',
"lng": '77.3200',
"description": 'Pune is the seventh largest metropolis in India, the second largest in the state of Maharashtra after Mumbai.'
}
];
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="dvMap" style="width: 500px; height: 500px">
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.