Currently, I am displaying 500-600 Markers on Google map, with their names as tooltip. Now,
I need to display the tool-tip of all overlapping markers as comma-separated i.e. Marker1, Marker2, Marker3 etc. if Marker1, Marker2, Marker3 are overlapped on map.
I found many other different examples on google map at internet especially at GeoCodeZip, but not of my requirement.
if this requirement is once filled, Am afraid of performance issues on zoom changed events, as tooltip needed to be updated (if overlapping is changed).
Update1 : I have already show Overlapping Marker spiderfier to client but not acceptable.
Does anyone have right path or working example ?
Thanks
-Anil
The core of this is to find the pixel distance between LatLngs. Then before adding each marker check the pixel distance between it and any existing markers. If there is another marker nearby add to the title otherwise create a new marker. jsFiddle
function init() {
var mapOptions = {
center: new google.maps.LatLng(0, -0),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
// to get the pixel position from the latlng
// https://stackoverflow.com/questions/1538681/how-to-call-fromlatlngtodivpixel-in-google-maps-api-v3
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
google.maps.event.addListenerOnce(map, 'idle', function() {
if (overlay.getProjection()) {
var points = [
{ latlng: new google.maps.LatLng(40, -100), title: '1' },
{ latlng: new google.maps.LatLng(40.125, -100.125), title: '2' },
{ latlng: new google.maps.LatLng(40.25, -100.25), title: '3' },
{ latlng: new google.maps.LatLng(40.5, -100.5), title: '4' },
{ latlng: new google.maps.LatLng(40.75, -100.75), title: '5' },
{ latlng: new google.maps.LatLng(41, -101), title: '6' },
{ latlng: new google.maps.LatLng(35, -95), title: '7' },
{ latlng: new google.maps.LatLng(45, 105), title: '8' },
{ latlng: new google.maps.LatLng(25, -115), title: '9' },
{ latlng: new google.maps.LatLng(55, -85), title: '10' },
{ latlng: new google.maps.LatLng(30, -34), title: '11' }
];
// for each point
var markers = [];
points.forEach(function (point) {
var nearby = false;
var pointPixelPosition = overlay.getProjection().fromLatLngToContainerPixel(point.latlng);
markers.forEach(function(marker) {
var markerPixelPosition = overlay.getProjection().fromLatLngToContainerPixel(marker.getPosition());
// check for marker 'near by'
if (Math.abs(pointPixelPosition.x - markerPixelPosition.x) < 10 || Math.abs(pointPixelPosition.y - markerPixelPosition.y) < 10) {
nearby = true;
marker.setTitle(marker.getTitle() + ', ' + point.title);
}
});
// create new marker
if (!nearby) {
markers.push(new google.maps.Marker({ map: map, position: point.latlng, title: point.title }));
}
});
}
map.setCenter(new google.maps.LatLng(39.8282, -98.5795));
});
}
Related
Pardon me if this question is silly. I've got an array in an object that I need to add to a map. I know it needs a for loop (likely in the object) to access the additional properties in the array. Only the last indexed value is shown on the map when I execute the code. Thanks in advance for your help.
var map = L.map('map', {
center: [29.940125, -90.08346],
zoom: 13
});
// Get basemap URL from Leaflet Providers
var basemap_url = 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png'
// Get basemap attributes from Leaflet Providers
var basemap_attributes = {
maxZoom: 18,
attribution: '© OpenStreetMap'
};
// requests some map tiles
var tiles = L.tileLayer(basemap_url, basemap_attributes);
map.addLayer(tiles);
var i = 0
// declare hotspots object
var hotspots = [{
name: "Mariza",
properties: {
description: "Italian-inspired fare dished out in an airy loft building with an industrial-chic vibe.",
coordinates: [29.9629337, -90.0501008],
url: 'http://marizaneworleans.com/',
phone: '(504) 598-5700',
icon: 'svgs/restaurant-15.svg'
},
name: "Tipitina's",
properties: {
description: "Founded as a clubhouse for Professor Longhair, Tip's has played host to NOLA music legends since opening its doors in 1977.",
coordinates: [29.917284, -90.042986],
url: 'https://www.tipitinas.com//',
phone: '(504) 895-8477',
icon: 'svgs/music-15.svg'
},
name: "Euclid Records New Orleans",
properties: {
description: "We’re 4000 square feet of boss vinyl both new and used.",
coordinates: [29.962066, -90.042970],
url: 'https://euclidnola.com/',
phone: '(504) 947-4348',
icon: 'svgs/music-11.svg'
}
}];
// declare variable for accessing object properties
var props = hotspots[i].properties;
var icon = L.icon({
iconUrl: props.icon,
iconSize: [40, 40],
popupAnchor: [0, -22],
className: "icon"
});
var popup = `<h3>${hotspots[i].name}</h3>
<p>${props.description}</p>
<p><b>website</b>: <a href='${props.url}'>${props.url}</a></p>
<p><b>phone</b>: ${props.phone}</p>`
var marker = L.marker(hotspots[i].properties.coordinates, {
icon: icon
})
.addTo(map)
.bindPopup(popup);
marker.on("mouseover", function () {
this.openPopup();
});
marker.on("mouseout", function () {
this.closePopup();
});
You need a for loop in order to iterate over all the hotspots and add them to the map:
var map = L.map('map', {
center: [29.940125, -90.08346],
zoom: 13
});
// Get basemap URL from Leaflet Providers
var basemap_url = 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png'
// Get basemap attributes from Leaflet Providers
var basemap_attributes = {
maxZoom: 18,
attribution: '© OpenStreetMap'
};
// requests some map tiles
var tiles = L.tileLayer(basemap_url, basemap_attributes);
map.addLayer(tiles);
// declare hotspots object
var hotspots = [{
name: "Mariza",
properties: {
description: "Italian-inspired fare dished out in an airy loft building with an industrial-chic vibe.",
coordinates: [29.9629337, -90.0501008],
url: 'http://marizaneworleans.com/',
phone: '(504) 598-5700',
icon: 'svgs/restaurant-15.svg'
},
name: "Tipitina's",
properties: {
description: "Founded as a clubhouse for Professor Longhair, Tip's has played host to NOLA music legends since opening its doors in 1977.",
coordinates: [29.917284, -90.042986],
url: 'https://www.tipitinas.com//',
phone: '(504) 895-8477',
icon: 'svgs/music-15.svg'
},
name: "Euclid Records New Orleans",
properties: {
description: "We’re 4000 square feet of boss vinyl both new and used.",
coordinates: [29.962066, -90.042970],
url: 'https://euclidnola.com/',
phone: '(504) 947-4348',
icon: 'svgs/music-11.svg'
}
}];
//// LOOP GOES HERE: ////
for ( let i = 0; i < hotspots.length; i++ ){
// declare variable for accessing object properties
let props = hotspots[i].properties;
let icon = L.icon({
iconUrl: props.icon,
iconSize: [40, 40],
popupAnchor: [0, -22],
className: "icon"
});
let popup = `<h3>${hotspots[i].name}</h3>
<p>${props.description}</p>
<p><b>website</b>: <a href='${props.url}'>${props.url}</a></p>
<p><b>phone</b>: ${props.phone}</p>`
let marker = L.marker(hotspots[i].properties.coordinates, {
icon: icon
})
.addTo(map)
.bindPopup(popup);
marker.on("mouseover", function() {
this.openPopup();
});
marker.on("mouseout", function() {
this.closePopup();
});
}
There isn't a loop anywhere, so i is always going to be 0
Put it in a for-loop?
for(var i = 0; i < hotspots.length; i++) {
var props = hotspots[i].properties;
var icon = L.icon({
iconUrl: props.icon,
iconSize: [40, 40],
popupAnchor: [0, -22],
className: "icon"
});
var popup = `<h3>${hotspots[i].name}</h3>
<p>${props.description}</p>
<p><b>website</b>: <a href='${props.url}'>${props.url}</a></p>
<p><b>phone</b>: ${props.phone}</p>`
var marker = L.marker(hotspots[i].properties.coordinates, {
icon: icon
})
.addTo(map)
.bindPopup(popup);
}
I'm going to initalize infowindows (for google map markers) through angular controller (i'm using ng-map module)
NgMap.getMap().then (map) ->
$scope.map = map
for marker in markers
latLng = new (google.maps.LatLng)(marker.latitude, marker.longitude)
#initialize infoWindows through google map api, not ng-map module
contentString = 'is an example string'
infoWindow = new (google.maps.InfoWindow)(content: contentString)
$scope.dynMarkers.push new (google.maps.Marker)(position: latLng)
marker.addListener 'click', ->
infoWindow.open map, marker
$scope.markerClusterer = new MarkerClusterer(map,$scope.dynMarkers, {})
I have an error in console:
marker.addListener is not a function
I can't use an ng-map 'infowindow' DOM element in my view.
What's wrong?
marker object needs to be of google.maps.Marker type, try to replace:
$scope.dynMarkers.push new (google.maps.Marker)(position: latLng)
marker.addListener 'click', ->
infoWindow.open map, marker
with
markerObject = new (google.maps.Marker)(position: latLng) #<-Marker object
$scope.dynMarkers.push markerObject
markerObject.addListener 'click', ->
infoWindow.open map, markerObject
Example
angular.module('mapApp', ['ngMap'])
.controller('mapController', function ($scope, NgMap) {
NgMap.getMap().then(function (map) {
$scope.map = map;
$scope.dynMarkers = [];
$scope.markers.forEach(function (marker) {
var latLng = new google.maps.LatLng(marker.latitude, marker.longitude);
var contentString = 'is an example string'
var infoWindow = new (google.maps.InfoWindow)({ content: contentString });
var dynMarker = new google.maps.Marker({ position: latLng });
$scope.dynMarkers.push(dynMarker);
google.maps.event.addListener(dynMarker, 'click', function () {
infoWindow.open(map,dynMarker);
});
});
var mcOptions = { imagePath: 'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m' };
$scope.markerClusterer = new MarkerClusterer(map, $scope.dynMarkers, mcOptions)
});
$scope.markers = [
{ id: 1, name: 'Oslo', latitude: 59.923043, longitude: 10.752839 },
{ id: 2, name: 'Stockholm', latitude: 59.339025, longitude: 18.065818 },
{ id: 3, name: 'Copenhagen', latitude: 55.675507, longitude: 12.574227 },
{ id: 4, name: 'Berlin', latitude: 52.521248, longitude: 13.399038 },
{ id: 5, name: 'Paris', latitude: 48.856127, longitude: 2.346525 }
];
});
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<script src="https://googlemaps.github.io/js-marker-clusterer/src/markerclusterer.js"></script>
<div ng-app="mapApp" ng-controller="mapController">
<ng-map default-style="true" zoom="3" center="59.339025, 18.065818">
</ng-map>
</div>
OBJECT
var malls = [{
id: 0,
name: 'Leclerc',
lastname: 'Paris,France',
address:'Boulevard Rahal El Meskini Casablanca Maroc',
]
},
{
/*Malls B*/
id: 1,
name: 'Carefour',
lastname: 'Toulouse,France',
address:'Angle Zaid Ou Hmad Rue Sidi Belyout, Casablanca Maroc', }, ];
MY CONTROLLER
var address = "";//document.getElementById('address').value;
var id_mall ="";
var malls = Malls.all();
for (var i = 0; i < malls.length; i++) {
mall = malls[i];
addMarker(mall);}
function addMarker(address) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 14,
center: latlng
}
id = mall.id;
address = mall.address;
console.debug(address);
map = new google.maps.Map(document.getElementById('map'), mapOptions);
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
title: 'shopping center',
position: results[0].geometry.location,
url:'#/tab/malls/'+id
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href=marker.url;
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
//google.maps.event.addDomListener(window, 'load', initialize);
}
I have 2 markers, and when I click on a marker , I receive :tab/malls/1 and the other the same thing normally have to be /tab/malls/0 and tab/malls/1 ,
I did not find the solution.
Please need help
Your object code appears malformed: there is an unmatched ] character on line 8. Try deleting this character and running it.
I am using the google maps API and am struggling with positioning of some of my markers.
I have 2 sets of markers one set coloured, and the other grey (to represent coming soon)
However the grey set load in the wrong position - and seem to be in a diagonal pattern with each other. It appears the longitude is more or less correct - but the latitudes have...well messed up.
I figure I've set up the two different sets of markers up wrong as I created a new variable for the grey markers.
<script type="text/javascript">
var locations = [
['London ', 51.500, 0.1167],
['Frankfurt ', 50.1167, 8.6833],
['Paris ', 48.8567, 2.3508],
['Dublin ', 53.3478, -6.2597],
['Amsterdam', 52.3667, 4.9000],
['Tokyo ', 35.6895, 139.6917],
['Hongkong ', 22.2670, 114.1880],
['Singapore ', 1.3000, 103.8000],
['Sydney ', -33.8600, 151.2094],
['NewYork ', 42.9047, -78.8494],
['LosAngeles ', 34.0500, -118.2500],
['Dallas ', 32.7758, -96.7967],
['Chicago ', 41.8369, -87.6847],
['SanFrancisco ', 37.7833, -122.4167],
];
var locationsCS = [
['Manchester - coming soon', 53.4667, 2.2333],
['Bucharest - coming soon', 44.4325, 26.1039],
['NewDelhi - coming soon', 28.6139, 77.2089],
['SaoPaulo - coming soon', -23.5500, -46.6333],
['Toronto - coming soon', 43.7000, 79.4000]
];
var map = new google.maps.Map(document.getElementById('map'), {
featureType: "administrative",
elementType: "geometry.fill",
stylers: [
{ visibility: "off" }
],
zoom: 3,
center: new google.maps.LatLng(40.4000, 3.6833),
disableDefaultUI: true,
zoomControl:false,
scrollwheel:false,
zoomControlOptions: {
style:google.maps.ZoomControlStyle.SMALL
},
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var mapStyle = [
{
featureType: "administrative",
elementType: "geometry.fill",
stylers: [
{ visibility: "off" },
]
}
];
var styledMap = new google.maps.StyledMapType(mapStyle);
map.mapTypes.set('myCustomMap', styledMap);
map.setMapTypeId('myCustomMap');
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][1], locations[i][2]),
size:(23,34),
map: map,
icon: 'img/cdn_marker.png'
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
for ( i = 0; i < locationsCS.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locationsCS[i][1], locationsCS[i][1]),
map: map,
icon: 'img/cdn_marker_grey.png'
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locationsCS[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
</script>
Goal: I want to display Multiple Markers and InfoWindow against Adress.
Searching got me to this code, shows Multiple Markers and InfoWindow against Lang & Lat
but in my case there will be address array that i have...
What function google provides to convert adress into lat , lang
var markers = [
{ lat: -33.85, lng: 151.05, name: "marker 1" },
{ lat: -33.90, lng: 151.10, name: "marker 2" },
{ lat: -33.95, lng: 151.15, name: "marker 3" },
{ lat: -33.85, lng: 151.15, name: "marker 4" }
];
//this puts lat and lng.. but i have array of Address's
// Create the markers
for (index in markers) addMarker(markers[index]);
function addMarker(data) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.lat, data.lng),
map: map,
icon: '/images/shorticon_13.png',
title: data.name
});
google.maps.event.addListener(marker, "click", function () {
openInfoWindow(marker);
});
}
AM newbie to Google maps API v3...
Thanks in advance
Geocoding is the process of converting addresses (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic coordinates (like latitude 37.423021 and longitude -122.083739), which you can use to place markers or position the map.
If you have more than about 10 addresses, you will run into the rate limit/quota. For known addresses, it is better to geocode them offline and use the coordinates to display them on page load (like your example).