I switched my code from the lat-lang system to the geocode API in order to resolve addresses, but unfortunately, the Google Maps Infowindows don't work properly. Only a few of them are displayed, with wrong information.
Here there is my code.
<script type="text/javascript">
if(document.getElementById("{idMap}")) {
let geocoder;
let map;
let locations = [
[ "Location 1" , "Via Pavia 57, 80021" ] ,
[ "Location 2" , "Via Palermo 24, 80021" ] ,
[ "Location 3" , "Via Milano 15, 80021" ] ,
];
function initializeMap() {
geocoder = new google.maps.Geocoder();
let infowindow = new google.maps.InfoWindow();
let bounds = new google.maps.LatLngBounds();
let mapSettings = {
zoomControl: false,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
};
map = new google.maps.Map(document.getElementById("{idMap}"), mapSettings);
for (i = 0; i < locations.length; i++) {
codeAddress(locations[i][1], i, bounds);
}
}
function codeAddress(address, index, bounds) {
geocoder.geocode({ address: address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
let latLng = {
lat: results[0].geometry.location.lat(),
lng: results[0].geometry.location.lng(),
};
if (status == "OK") {
let marker = new google.maps.Marker({
position: latLng,
map: map,
icon: "https://maps.google.com/mapfiles/ms/icons/blue-dot.png",
});
bounds.extend(marker.position);
map.fitBounds(bounds);
map.panToBounds(bounds);
if(locations[0][index] && locations[0][index].length > 0) {
let infowindow = new google.maps.InfoWindow({
content: locations[0][index],
});
marker.addListener("click", function () {
infowindow.open(map, marker);
});
}
} else {
console.log(
"Geocode was not successful for the following reason: " + status
);
}
}
});
}
window.initMap = null;
window.initMap = initializeMap();
}
</script>
All the markers are correctly positioned, the issue is only related to the infoWindow.
I fixed the issue, passing the id from the marker to the location array, in this way it works:
let infowindow = new google.maps.InfoWindow({
content: locations[marker.id][1],
});
Related
I'm currently trying to Google Geocoder API to convert an address into Lat/Lng coordinates, however, when using the example on their dev documentation(https://developers.google.com/maps/documentation/javascript/geocoding), I am running into an error of "InvalidValueError: unknown property function"
In my HTML file, I have the call to google map API and a map div, where my map should be rendered. (of course i have other stuff too, but just for the sake of getting straight to the point i will only post the relevant code)
<script src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap" async defer></script>
<div id="map"></div>
And in my JS file:
window.initMap = function(){
var fromLocation = new google.maps.LatLng(37.09024, -95.712891),
destLocation = new google.maps.LatLng(37.09024, -95.712891),
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 37.09024 , lng: -95.712891}, // center of USA
zoom: 4 // continet level
}),
directionService = new google.maps.DirectionsService(),
directionRender = new google.maps.DirectionsRenderer({
map: map
}),
markerA = new google.maps.Marker({
position: fromLocation,
title: "Point A",
label: "From",
map:map
}),
markerB = new google.maps.Marker({
position: destLocation,
title: "Point B",
label:"Destination",
map:map
});
getLatLng("Los Angeles");
} // end of initMap
function getLatLng(address){
geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address, function(results,status){
if(status === 'OK'){
console.log(results[0].geometry.location);
}
else{
console.log("Geocoding couldn't convert string address to lat/long points");
}
}
});// end of geocoder method.
}
Any idea on how to fix the unknown property function error?
Thanks!
You have a typo in the function getLatLng:
geocoder.geocode({
address: address,
There needs to be a "}" after address: address
function getLatLng(address) {
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: address},
function(results, status) {
if (status === 'OK') {
console.log(results[0].geometry.location);
} else {
console.log("Geocoding couldn't convert string address to lat/long points");
}
}); // end of geocoder method.
}
window.initMap = function() {
var fromLocation = new google.maps.LatLng(37.09024, -95.712891),
destLocation = new google.maps.LatLng(37.09024, -95.712891),
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 37.09024,
lng: -95.712891
}, // center of USA
zoom: 4 // continet level
}),
directionService = new google.maps.DirectionsService(),
directionRender = new google.maps.DirectionsRenderer({
map: map
}),
markerA = new google.maps.Marker({
position: fromLocation,
title: "Point A",
label: "From",
map: map
}),
markerB = new google.maps.Marker({
position: destLocation,
title: "Point B",
label: "Destination",
map: map
});
getLatLng("Los Angeles");
} // end of initMap
function getLatLng(address) {
geocoder = new google.maps.Geocoder();
geocoder.geocode({
address: address
},
function(results, status) {
if (status === 'OK') {
console.log(results[0].geometry.location);
} else {
console.log("Geocoding couldn't convert string address to lat/long points");
}
}); // end of geocoder method.
}
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>
<div id="map"></div>
I am using the google maps api and using grid clustering for the markers. I wanted to know if there is a way to exclude a single marker from clustering. I want a "You are here" marker that is always visible. I tried using a different array for just that marker and not including it the cluster function but that didn't work.
Does anyone have a solution for this?
Here is how i am doing the clustering
$(document).on('click', '#mapbut', function() {
var items, distances, you_are_here = [], markers_data = [], markers_data2 = [], fred, clust1, markss;
you_are_here.push({
lat : Geo.lat,
lng : Geo .lng,
animation: google.maps.Animation.DROP,
title : 'Your are here',
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
infoWindow: {
content: '<p>You are Here</p>'
}
});
function loadResults (data) {
if (data.map.length > 0) {
items = data.map;
for (var i = 0; i < items.length; i++)
{
var item = items[i];
var distances = [];
var dist2;
if (item.Lat != undefined && item.Lng != undefined)
{
markers_data.push({
lat : item.Lat,
lng : item.Lng,
title : item.Site,
infoWindow: {
content: '<p>' + item.Site + '</p><p>' + Math.round(item.distance) + ' miles away</p>'
}
});
}
}
}
map.addMarkers(markers_data);
map = new GMaps({
el: '#map',
lat: Geo.lat,
lng: Geo.lng,
zoom: 10,
mapTypeControl: false,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
markerClusterer: function(map) {
options = {
gridSize: 50
}
clust1 = new MarkerClusterer(map,[], options);
return clust1;
},
scaleControl: true,
streetViewControl: false
});
map.addMarkers(you_are_here);
The GMaps clusters all the markers you add to it with the addMarker method (if you provide a MarkerClusterer).
One option: add your "special" marker (the one that you don't want clustered) to the map manually, so it isn't added to the MarkerClusterer:
The GMaps.map property is a reference to the Google Maps Javascript API v3 map object. So this will add a marker to the map without letting the GMaps library know about it:
you_are_here = new google.maps.Marker({
position: {lat: Geo.lat,lng: Geo.lng},
animation: google.maps.Animation.DROP,
title: 'Your are here',
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
map: map.map
});
proof of concept fiddle
code snippet:
var Geo = {
lat: 40.7281575,
lng: -74.07764
};
$(document).on('click', '#mapbut', function() {
var items, distances, you_are_here = [],
markers_data = [],
markers_data2 = [],
fred, clust1, markss;
function loadResults(data) {
if (data.map.length > 0) {
items = data.map;
for (var i = 0; i < items.length; i++) {
var item = items[i];
var distances = [];
var dist2;
if (item.Lat != undefined && item.Lng != undefined) {
markers_data.push({
lat: item.Lat,
lng: item.Lng,
title: item.Site,
infoWindow: {
content: '<p>' + item.Site + '</p><p>' + Math.round(item.distance) + ' miles away</p>'
}
});
}
}
}
map = new GMaps({
el: '#map',
lat: Geo.lat,
lng: Geo.lng,
zoom: 8,
mapTypeControl: false,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
markerClusterer: function(map) {
options = {
gridSize: 50,
imagePath: "https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m"
}
clust1 = new MarkerClusterer(map, [], options);
return clust1;
},
scaleControl: true,
streetViewControl: false
});
map.addMarkers(markers_data);
you_are_here = new google.maps.Marker({
position: {
lat: Geo.lat,
lng: Geo.lng
},
animation: google.maps.Animation.DROP,
title: 'Your are here',
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
infoWindow: {
content: '<p>You are Here</p>'
},
map: map.map
});
// map.addMarkers(you_are_here);
}
loadResults(data);
});
var data = {
map: [{
Lat: 40.7127837,
Lng: -74.005941,
Site: "New York, NY",
distance: 1
}, {
Site: "Newark, NJ",
Lat: 40.735657,
Lng: -74.1723667,
distance: 2
}]
};
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://rawgit.com/HPNeo/gmaps/master/gmaps.js"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/src/markerclusterer.js"></script>
<input id="mapbut" type="button" value="map" />
<div id="map"></div>
To get around this is relatively simple, just after I send the markers array to MarkerClusterer I then add my location.
// Setup cluster markers
var markerCluster = new MarkerClusterer( gmap.map, options )
// add my location
gmap.addMarker({
lat: data.latitude,
lng: data.longitude
...
})
Thanks
I'm using the google maps API V3 in javascript and Vue.js for my application and i have found a strange bug, when i click the first time to put a marker on the map, the web app froze during 1-3seconds. Here is my code:
var vueMap = new Vue({
el: '#map-canvas',
data: {
infowindow: new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
}),
marker: null
},
ready:function(){
this.initialize();
},
methods: {
createMarker: function (latlng, name, html, point1, map) {
var distanceKm = google.maps.geometry.spherical.computeDistanceBetween(point1, latlng);
distanceKm = distanceKm/1000;
distanceKm = distanceKm.toFixed(2);
var contentString = "Distance en KM ---- " + distanceKm + '<br/>Score de 123';
// HERE IS WHERE THE FROZE HAPPEN
this.marker = new google.maps.Marker({
position: latlng,
map: map,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
// TODO onclick
google.maps.event.addListener(this.marker, 'click', function() {
this.infowindow.setContent(contentString);
this.infowindow.open(map,this.marker);
}.bind(this));
google.maps.event.trigger(this.marker, 'click');
return this.marker;
},
initialize: function () {
var styles = [/*some style*/];
var styledMap = new google.maps.StyledMapType(styles,
{name: "Styled Map"});
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(48.815145,2.244830),
new google.maps.LatLng(48.902137, 2.417864)
);
var point1 = new google.maps.LatLng(48.858230, 2.372566);
var center = bounds.getCenter();
var x = bounds.contains(center);
var mapOptions = {
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style']
},
center: center,
zoom: 1,
minZoom: 13,
streetViewControl: false,
mapTypeControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.RIGHT_CENTER
},
panControl: true,
panControlOptions: {
position: google.maps.ControlPosition.RIGHT_CENTER
}
};
console.log(document.getElementById('map-canvas'));
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var lastValidCenter = map.getCenter();
map.mapTypes.set('map_style', styledMap);
map.setMapTypeId('map_style');
google.maps.event.addListener(map, 'center_changed', function() {
if (bounds.contains(map.getCenter())) {
// still within valid bounds, so save the last valid position
lastValidCenter = map.getCenter();
return;
}
// not valid anymore => return to last valid position
map.panTo(lastValidCenter);
});
google.maps.event.addListener(map, 'click', function(event) {
//call function to create marker
if (this.marker != null) {
this.marker.setMap(null);
this.marker = null;
}
this.marker = vueMap.createMarker(event.latLng, "name", "<b>Location</b><br>"+event.latLng, point1, map);
}.bind(this));
}
}
});
module.exports = vueMap;
It's longer on Chrome than with Firefox and Safari...
Does someone knows why ? (Or have a clue about it ?)
Thanks in advance
How do I get multiple markers on a Google Map, using Javascript API v3? Below, when my code adds the second marker it's removing the first one.
var locations = {
"1" : {
"name": "location1",
"address": "10000 N Scottsdale Rd",
"city": "Scottsdale",
"state": "AZ",
"zipcode": "85253"
},
"2" : {
"name": "location2",
"address": "15440 N 71st Street",
"city": "Scottsdale",
"state": "AZ",
"zipcode": "85254"
}
}
var geocoder = new google.maps.Geocoder();
for (item in locations) {
var loc = locations[item].address + ", " + locations[item].city + " " +
locations[item].state + " " + locations[item].zipcode;
geocoder.geocode( { 'address': loc}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var options = {
zoom: 10,
center: results[0].geometry.location,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true,
zoomControl: true
}
if (map) {
new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: locations[item].name
});
} else {
var map = new google.maps.Map(document.getElementById("map"), options);
new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: locations[item].name
});
}
var infowindow = new google.maps.InfoWindow({ content: "test"});
} else { // if map lookup fails, display a map of phoenix
var phoenix = new google.maps.LatLng(33.4483771,-112.07403729999999);
var options = {
zoom: 11,
center: phoenix,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true,
zoomControl: true
}
map = new google.maps.Map(document.getElementById("map"), options);
}
});
}
The map variable is only defined in the callback function, (e.g. function(results, status) {...}), so when the second geocoded point comes back, you are still creating a new map (for the second time), since that map is not initialized.
You should declare and initialize the map separately from the marker adding code.
loop through your marker construction from your data set. Each item in your set, create a marker as you normally would. instatiate your map only once and use the variable assigned to this in your marker creation.
This is what I have so far.
function init_map() {
var places = [
{ name: "Place 1", coords: new google.maps.LatLng(30.728752, -73.995525)},
{ name: "Place 2", coords: new google.maps.LatLng(30.733673, -73.990028)},
{ name: "Place 3", coords: new google.maps.LatLng(40.725778, -73.992249)}
]
var myOptions = {
zoom: 14,
center: places[0].coords,
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
for ( var x=0; x < places.length; x++ ){
var place = places[x];
var marker = new google.maps.Marker({
position: place.coords,
title: place.name,
icon: icon,
clickable: true,
infowindow: new google.maps.InfoWindow({content:"hello world"})
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', function() {
marker.infowindow.open(map, marker);
console.log(marker);
});
}
};
I'd like to have the default InfoWindow which you'd see when searching for an address on Google Maps appear instead of my own custom window. How is this possible?
What do you mean by its default Google content?
Also it might be better for you to create just 1 infowindow object and then share it amongst your markers.