As shown in the below linked example, polygons support configuration of holes by providing outer and inner coordinates separately. Is there any such option in polylines?
Polygon With Hole
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 5,
center: { lat: 24.886, lng: -70.268 },
});
// Define the LatLng coordinates for the polygon's outer path.
const outerCoords = [
{ lat: 25.774, lng: -80.19 },
{ lat: 18.466, lng: -66.118 },
{ lat: 32.321, lng: -64.757 },
];
// Define the LatLng coordinates for the polygon's inner path.
// Note that the points forming the inner path are wound in the
// opposite direction to those in the outer path, to form the hole.
const innerCoords = [
{ lat: 28.745, lng: -70.579 },
{ lat: 29.57, lng: -67.514 },
{ lat: 27.339, lng: -66.668 },
];
// Construct the polygon, including both paths.
const bermudaTriangle = new google.maps.Polygon({
paths: [outerCoords, innerCoords],
strokeColor: "#FFC107",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FFC107",
fillOpacity: 0.35,
});
bermudaTriangle.setMap(map);
}
window.initMap = initMap;
var map;
var Sightings = [
{lat:20.735280,lng:-105.401653,title:"Tournefortia hartwegiana",code:'TOHA',sightingid:'40888'},
{lat:20.735280,lng:-105.401653,title:"Heermann's Gull",code:'HEGU',sightingid:'40869'},
{lat:20.735397,lng:-105.401703,title:"Belted Kingfisher",code:'BEKI',sightingid:'40877'}
];
const sightingIcon = {
path: "M 0 0 L 4 -4 L 4 -16 L 26 -16 L 26 -34 L -26 -34 L -26 -16 L -4 -16 L -4 -4 Z",
fillOpacity:1,
fillColor:"#ffcc00",
strokeWeight:1,
strokeColor:"#000",
scale:1,
labelOrigin: {x:0, y:-25}
};
function initMap(){
map = new google.maps.Map(document.getElementById('GoogleMap'), {mapTypeId: 'satellite',streetViewControl:false,overviewMapControl:true,scaleControl:true});
var bounds = new google.maps.LatLngBounds();
var oms = new OverlappingMarkerSpiderfier(map,
{markersWontMove: true,
markersWontHide: true,
basicFormatEvents: true,
nudgeRadius: 20,
nearbyDistance: 40,
circleSpiralSwitchover: 8,
spiralFootSeparation:20,
spiralLengthStart: 16,
spiralLengthFactor: 12,
circleFootSeparation:50,
circleStartAngle: 180});
var markers = new Array();
for (var i = 0; i < Sightings.length; i++) {
bounds.extend(Sightings[i]);
var markerData = Sightings[i];
var marker = new google.maps.Marker({position:Sightings[i], title: Sightings[i].title, label: Sightings[i].code, opacity: 1, icon: sightingIcon});
markers.push(marker);
marker.addListener('spider_click', function(e) {});
oms.addMarker(marker);
}
var markerCluster = new MarkerClusterer(map, markers,{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',maxZoom:18});
map.fitBounds(bounds);
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier/1.0.3/oms.min.js"></script>
<script src='https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js'></script>
<script defer src='https://maps.googleapis.com/maps/api/js?callback=initMap&key=YOUR_API_KEY'></script>
<body>
<h1>Hello World</h1>
<div id='GoogleMap' style='height: 600px; width: 100%;'></div>
</body>
</html>
I am using Google Maps API for Javascript on a web page. Creating several Markers from an array with Lat/Lng and using overlapping-marker-spiderfier and markerclusterer for their intended use from an example I found elsewhere.
My problem is that Markers still Overlap one another when de-spiderfied/de-clustered. Clicking on the overlapped markers correctly spiderfies them and shows each. This is confusing to the end-user as they don't know that some of the markers are hidden/overlapped and don't click.
I tried using the Nudge options in spiderfier, but they seem to have no effect. The Nudge options are defined here: https://openbase.com/js/overlapping-marker-spiderfier/documentation
I am wondering if I am not referencing the latest Spider code.
Any ideas how to prevent these overlapped markers? TO BE CLEAR, I am trying to get rid of the issue as shown in the 2nd screenshot below, where the markers are overlapping, but should be nudged a bit to the side in order to show multiple markers.
Use the latest version of the Overlapping Marker Spiderfier (1.1.4) the version that goes with the documentation you reference
To get the cdn link use the combination of the GitHub project: OverlappingMarkerSpiderfier by fritz-c and the version
<script src="https://cdn.jsdelivr.net/gh/fritz-c/OverlappingMarkerSpiderfier#1.1.4/dist/oms.min.js"></script>
proof of concept fiddle
Working code snippet:
var map;
var Sightings = [{
lat: 20.735280,
lng: -105.401653,
title: "Tournefortia hartwegiana",
code: 'TOHA',
sightingid: '40888'
},
{
lat: 20.740620,
lng: -105.394615,
title: "Rufous-bellied Chachalaca",
code: 'RBCH',
sightingid: '40862'
},
{
lat: 20.739182,
lng: -105.395732,
title: "Inca Dove",
code: 'INDO',
sightingid: '40863'
},
{
lat: 20.738601,
lng: -105.399059,
title: "Squirrel Cuckoo",
code: 'SQCU',
sightingid: '40864'
},
{
lat: 20.738876,
lng: -105.397491,
title: "Broad-billed Hummingbird",
code: 'BBHU',
sightingid: '40865'
},
{
lat: 20.736121,
lng: -105.403218,
title: "Whimbrel",
code: 'WHIM',
sightingid: '40866'
},
{
lat: 20.736850,
lng: -105.405225,
title: "Spotted Sandpiper",
code: 'SPSA',
sightingid: '40867'
},
{
lat: 20.736135,
lng: -105.403247,
title: "Willet",
code: 'WILL',
sightingid: '40868'
},
{
lat: 20.735280,
lng: -105.401653,
title: "Heermann's Gull",
code: 'HEGU',
sightingid: '40869'
},
{
lat: 20.739167,
lng: -105.395756,
title: "Magnificent Frigatebird",
code: 'MAFR',
sightingid: '40870'
},
{
lat: 20.735632,
lng: -105.401692,
title: "Blue-footed Booby",
code: 'BFBO',
sightingid: '40871'
},
{
lat: 20.738925,
lng: -105.397099,
title: "Brown Pelican",
code: 'BRPE',
sightingid: '40872'
},
{
lat: 20.736121,
lng: -105.403218,
title: "Snowy Egret",
code: 'SNEG',
sightingid: '40873'
},
{
lat: 20.737766,
lng: -105.401894,
title: "Black Vulture",
code: 'BLVU',
sightingid: '40874'
},
{
lat: 20.740601,
lng: -105.394636,
title: "Turkey Vulture",
code: 'TUVU',
sightingid: '40875'
},
{
lat: 20.738880,
lng: -105.397410,
title: "Gray Hawk",
code: 'GRHA',
sightingid: '40876'
},
{
lat: 20.735397,
lng: -105.401703,
title: "Belted Kingfisher",
code: 'BEKI',
sightingid: '40877'
},
{
lat: 20.740608,
lng: -105.394595,
title: "Orange-fronted Parakeet",
code: 'OFPA',
sightingid: '40878'
},
{
lat: 20.740620,
lng: -105.394615,
title: "Greenish Elaenia",
code: 'GREL',
sightingid: '40879'
},
{
lat: 20.740033,
lng: -105.394573,
title: "Social Flycatcher",
code: 'SOFL',
sightingid: '40880'
},
{
lat: 20.737745,
lng: -105.403846,
title: "Tropical Kingbird",
code: 'TRKI',
sightingid: '40881'
},
{
lat: 20.738877,
lng: -105.397251,
title: "Plumbeous Vireo",
code: 'PLVI',
sightingid: '40882'
},
{
lat: 20.738584,
lng: -105.399194,
title: "San Blas Jay",
code: 'SBJA',
sightingid: '40883'
},
{
lat: 20.739244,
lng: -105.396119,
title: "Blue-gray Gnatcatcher",
code: 'BGGN',
sightingid: '40884'
},
{
lat: 20.738886,
lng: -105.397373,
title: "Happy Wren",
code: 'HAWR',
sightingid: '40885'
},
{
lat: 20.738584,
lng: -105.399194,
title: "Sinaloa Wren",
code: 'SIWR',
sightingid: '40886'
},
{
lat: 20.739209,
lng: -105.396036,
title: "Streak-backed Oriole",
code: 'SBOR',
sightingid: '40887'
}
];
const sightingIcon = {
path: "M 0 0 L 4 -4 L 4 -16 L 26 -16 L 26 -34 L -26 -34 L -26 -16 L -4 -16 L -4 -4 Z",
fillOpacity: 1,
fillColor: "#ffcc00",
strokeWeight: 1,
strokeColor: "#000",
scale: 1,
labelOrigin: {
x: 0,
y: -25
}
};
function initMap() {
map = new google.maps.Map(document.getElementById('GoogleMap'), {
mapTypeId: 'satellite',
streetViewControl: false,
overviewMapControl: true,
scaleControl: true
});
google.maps.event.addListener(map, 'click', function(evt) {
console.log(evt.latLng.toUrlValue(6)+" zoom="+map.getZoom());
})
var bounds = new google.maps.LatLngBounds();
var oms = new OverlappingMarkerSpiderfier(map, {
markersWontMove: true,
markersWontHide: true,
basicFormatEvents: true,
nearbyDistance: 40,
circleSpiralSwitchover: 8,
spiralFootSeparation: 20,
spiralLengthStart: 16,
spiralLengthFactor: 12,
circleFootSeparation: 50,
circleStartAngle: 180,
keepSpiderfied: true,
});
var markers = new Array();
for (var i = 0; i < Sightings.length; i++) {
(function() {
bounds.extend(Sightings[i]);
var markerData = Sightings[i];
var marker = new google.maps.Marker({
position: Sightings[i],
title: Sightings[i].title,
label: Sightings[i].code,
opacity: 1,
icon: sightingIcon
});
markers.push(marker);
marker.addListener('spider_click', function(e) {
console.log(this.getPosition().toUrlValue(6)+" title:"+this.getTitle()+" spider_click")
});
marker.addListener('click', function(e) {
console.log(this.getPosition().toUrlValue(6)+" title:"+this.getTitle()+" click")
});
marker.addListener('format', function(e) {
console.log(this.getPosition().toUrlValue(6)+" title:"+this.getTitle()+" format")
});
marker.addListener('unspiderfy', function(e) {
console.log(this.getPosition().toUrlValue(6)+" title:"+this.getTitle()+" unspiderfy")
});
marker.addListener('spiderfy', function(e) {
console.log(this.getPosition().toUrlValue(6)+" title:"+this.getTitle()+" spiderfy")
});
oms.addMarker(marker);
})();
}
var markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m',
maxZoom: 18
});
// map.fitBounds(bounds);
map.setCenter({lat:20.736114,lng:-105.403252});
map.setZoom(19);
google.maps.event.addListener(markerCluster, 'click', function(evt) {
console.log("markerClusterer click:"+evt.markers_.length);
for (var i=0; i<evt.markers_.length; i++) {
console.log(evt.markers_[i].getPosition().toUrlValue(6)+" label="+evt.markers_[i].getLabel());
google.maps.event.trigger(evt.markers_[i],"click");
}
});
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
#GoogleMap {
height: 70%;
}
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<h1>Hello World</h1>
<div id='GoogleMap'></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&v=weekly&channel=2"></script>
<script src="https://cdn.jsdelivr.net/gh/fritz-c/OverlappingMarkerSpiderfier#1.1.4/dist/oms.min.js"></script>
<script src='https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js'></script>
</body>
</html>
I have been getting the "InvalidValueError: setPosition: not a LatLng or LatLngLiteral: in property lat: not a number" message and have reviewed previous posts but can't seem to find which line is causing the issue.
The below code seems to work but throws the above warning. I have tried parseFloat on lat and long values and on setPosition value but no joy.
const flightPlanCoordinates1100_0 = [{
lat: 51.52386762,
lng: -0.059058666
},
{
lat: 51.52394638,
lng: -0.058520453
},
{
lat: 51.52716833,
lng: -0.05617915
}, {
lat: 51.54674506,
lng: -0.059390801
},
];
// define the polyline attributes
const flightPath1100_0 = new google.maps.Polyline({
path: flightPlanCoordinates1100_0,
geodesic: true,
strokeColor: "Aqua",
strokeOpacity: 1.0,
strokeWeight: 2,
draggable: true,
map: map
});
// create an invisible marker for the label listener
labelMarker = new google.maps.Marker({
position: flightPath1100_0,
map: map,
visible: false
});
var myLabel = new Label();
// lets add an event listener, if you move the mouse over the line, it will tell you the track id
flightPath1100_0.addListener('mouseover', function(e) {
labelMarker.setPosition(e.latLng)
myLabel.bindTo('position', labelMarker, 'position');
// Type the Track Id name here, this can be loaded using excel macro
myLabel.set('text', "1100");
myLabel.setMap(map);
});
flightPath1100_0.setMap(map);
google.maps.event.addDomListener(window, 'load', initialize);
}
The issue as MrUpsidDown pointed out was that the position was not in latlng format, the below changes seemed to have worked
labelMarker = new google.maps.Marker({
position: new google.maps.LatLng(flightPath1100_0),
map: map,
visible: false
});
I want to get the content property of the array place of interest, so below the if marker.content is giving me undefined then I create the new google.maps.InfoWindow
Code:
var map = null;
placesOfInterest = [
{ name: 'Charme da paulista', lat: -23.562172, lng: -46.655794, content:'<h1>Charme</h1>' },
{ name: 'The Blue Pub', lat: -23.563112, lng: -46.650338, content:'<h1>The Blue Pub</h1>' },
{ name: 'Veloso', lat: -23.585107, lng: -46.635219 },
{ name: 'Let\'s Beer', lat: -23.586508, lng: -46.641739 },
{ name: 'O\'Malley\'s', lat: -23.558296, lng: -46.665923 },
{ name: 'Finnegan\'s', lat: -23.559547, lng: -46.676794 },
{ name: 'Partisans', lat: -23.561049, lng: -46.682555 },
{ name: 'Morrison', lat: -23.555106, lng: -46.690883 },
{ name: 'Cão Véio', lat: -23.558130, lng: -46.679508 },
{ name: 'Cervejaria Nacional', lat: -23.564740, lng: -46.690641 },
{ name: 'Brewdog', lat: -23.561309, lng: -46.693935 },
{ name: 'Rei das Batidas', lat: -23.570613, lng: -46.705977 }
];
const customIcon = {
path: 'M0-48c-9.8 0-17.7 7.8-17.7 17.4 0 15.5 17.7 30.6 17.7 30.6s17.7-15.4 17.7-30.6c0-9.6-7.9-17.4-17.7-17.4z',
fillColor: '#F7B217',
fillOpacity: 0.98,
scale: 0.98,
strokeColor: '#666666',
strokeWeight: 3
};
function addMarker(marker) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(marker.lat, marker.lng),
icon: customIcon,
title: marker.name,
});
if(marker.content){
var infoWindow = new google.maps.InfoWindow({
content:marker.content
});
marker.addListener('click',function(){
infoWindow.open(map, marker)
});
}
}
function initMap() {
var mapOptions = {
center: new google.maps.LatLng(-23.562172, -46.655794),
gestureHandling: 'greedy',
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP]
},
disableDefaultUI: true,
scaleControl: true,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.DEFAULT,
}
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
//Adicionando o primeiro marcador como exemplo
for(var i = 0;i< placesOfInterest.length;i++ ){
addMarker(placesOfInterest[i]);
}
}
In your addMarker function, you are overwriting the input marker data with a new google.maps.Marker object, so the marker.content property never exists.
Rename either the input argument or the internal marker variable to avoid the conflict:
function addMarker(marker) {
var gmarker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(marker.lat, marker.lng),
icon: customIcon,
title: marker.name,
});
if(marker.content){
var infoWindow = new google.maps.InfoWindow({
content:marker.content
});
gmarker.addListener('click',function(){
infoWindow.open(map, gmarker)
});
}
}
proof of concept fiddle
code snippet:
var map = null;
var placesOfInterest = [{
name: 'Charme da paulista',
lat: -23.562172,
lng: -46.655794,
content: '<h1>Charme</h1>'
}
];
const customIcon = {
path: 'M0-48c-9.8 0-17.7 7.8-17.7 17.4 0 15.5 17.7 30.6 17.7 30.6s17.7-15.4 17.7-30.6c0-9.6-7.9-17.4-17.7-17.4z',
fillColor: '#F7B217',
fillOpacity: 0.98,
scale: 0.98,
strokeColor: '#666666',
strokeWeight: 3
};
function addMarker(marker) {
var gmarker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(marker.lat, marker.lng),
icon: customIcon,
title: marker.name,
});
if (marker.content) {
var infoWindow = new google.maps.InfoWindow({
content: marker.content
});
gmarker.addListener('click', function() {
infoWindow.open(map, gmarker)
});
}
}
function initMap() {
var mapOptions = {
center: new google.maps.LatLng(-23.562172, -46.655794),
gestureHandling: 'greedy',
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP]
},
disableDefaultUI: true,
scaleControl: true,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.DEFAULT,
}
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
//Adicionando o primeiro marcador como exemplo
for (var i = 0; i < placesOfInterest.length; i++) {
addMarker(placesOfInterest[i]);
}
}
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
I want to click on the google marker which will show the google circle (radius). Not sure if the placement of addListener is wrong or am I missing some stuff.
coordinates = [
['Tan Tock Seng Hospital', {lat: 1.3213762, lng: 103.8457089}],
['Singapore General Hospital', {lat: 1.279421747, lng: 103.8345482}],
['Changi General Hospital', {lat: 1.340825885, lng: 103.9494655}],
['Khoo Teck Puat Hospital', {lat: 1.424081019, lng: 103.838578}],
['Ng Teng Fong General Hospital', {lat: 1.333463114, lng: 103.7455669}],
['National University Hospital', {lat: 1.29442026, lng: 103.7836869}]
];
for (var i = 0; i < coordinates.length; i++) {
// Google Marker for Hospital Coordinates
marker = new google.maps.Marker({
position: coordinates[i][1],
map: map,
icon: 'https://maps.google.com/mapfiles/kml/paddle/blu-stars.png',
title: coordinates[i][0]
});
marker_radius = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0,
map: map,
center: coordinates[i][1],
radius: 2000, // in metres
clickable: false
});
marker_radius.setVisible(true); // set circle to invisible
marker_radius.bindTo('center', marker, 'position'); // binds the circle to marker
google.maps.event.addListener(marker, 'click', function() {
marker_radius.setVisible(getVisible() ? false : true);
});
}
You need to use a closure in your event listener:
google.maps.event.addListener(marker, 'click', (function(marker, marker_radius) {
return function () {
marker_radius.setVisible(marker_radius.getVisible() ? false : true);
}
})(marker, marker_radius));
Read here for more information.
Also your Javascript console should tell you that getVisible() is not defined. So you need to change it to marker_radius.getVisible().