Google Maps markerClusterer.MarkerClusterer not working with geoJSON - javascript

Any ideas why my markers aren't clustering? I've tried many different ways and nothing will make them cluster. I realize there might be something wrong with the arguments I'm passing the markerClusterer but I can't find a way to make it work with anything. There's also little to no documentation on markerClusterer.MarkerClusterer (which is required when using unpkg).
function initMap() {
//set map options
var myMapOptions = {
center: {lat: 40.7498024, lng: -73.9774375},
zoom: 12,
}
//fill the html div with a map and pass in map options
var myNewMap = new google.maps.Map(document.getElementById('mymap'), myMapOptions);
//pass in data
myNewMap.data.loadGeoJson('missedConnections.geojson');
//define popup windows
var infowindow = new google.maps.InfoWindow({maxWidth: 750, autopanMargin: 10,});
//create new popup windows on marker click
myNewMap.data.addListener('click', function(event) {
console.log(event);
// set variables
let videourl = event.feature.getProperty('videoURL');
//padding/margin is wonky on mobile vs desktop
let html = '<video style="padding-bottom: 5px; padding-right: 3px;" preload="none" autoplay width=" 90%"><source src="' + videourl + '"></video>';
// show the html variable in the infowindow
infowindow.setContent(html);
infowindow.setPosition(event.latLng);
infowindow.setOptions({pixelOffset: new google.maps.Size(0, -30)});
// move the infowindow up 42 pixels to the top of the default marker icon
infowindow.open(myNewMap);
});
new markerClusterer.MarkerClusterer({myNewMap.data, myNewMap});
}

First, you are using object shorthand incorrectly.
Second, that isn't the interface for the library.
const markerCluster = new MarkerClusterer({ map, markers });
where markers is an array of google.maps.Markers. See MarkerClustererOptions.

Into your html:
<script src="https://unpkg.com/#googlemaps/markerclusterer/dist/index.min.js"></script>
Into your js, code both of these works
var mc = new markerClusterer.MarkerClusterer({ markers, map });
or
new markerClusterer.MarkerClusterer({ markers, map });

Related

Marker clusterer

I would like to ask whether is my code's error or wrong arrangement of code.
The sidebar is shown and the infowindow also. But the marker still can't be clustered.(why?)
<!DOCTYPE html >
<html>
<head>
<title>Google Maps</title>
<script type="text/javascript" src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
</head>
<body >
<table border=1>
<tr>
<td>
<div id="map" style="width: 550px; height: 450px"></div>
</td>
<td width = 150 valign="top" style="text-decoration: underline; color: #4444ff;">
<div id="side_bar"></div>
</td>
</tr>
</table>
<script type="text/javascript">
// this variable will collect the html which will eventually be placed in the side_bar
var side_bar_html = "";
// arrays to hold copies of the markers and html used by the side_bar
// because the function closure trick doesnt work there
var gmarkers = [];
// A function to create the marker and set up the event window
function createMarker(point,name,html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
// save the info we need to use later for the side_bar
gmarkers.push(marker);
// add a line to the side_bar html
side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
return marker;
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
GEvent.trigger(gmarkers[i], "click");
}
// create the map
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng( 43.907787,-79.359741), 8);
// add the points
var point = new GLatLng(43.65654,-79.90138);
var marker = createMarker(point,"This place","Some stuff to display in the<br>First Info Window")
map.addOverlay(marker);
var point = new GLatLng(43.91892,-78.89231);
var marker = createMarker(point,"That place","Some stuff to display in the<br>Second Info Window")
map.addOverlay(marker);
var point = new GLatLng(43.82589,-78.89231);
var marker = createMarker(point,"The other place","Some stuff to display in the<br>Third Info Window")
map.addOverlay(marker);
var markers = [];
var markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m2.png',
gridSize: 10,
minimumClusterSize: 2
});
var mc = new MarkerClusterer(map, markers);
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
</script>
</body>
</html>
Hope someone can take a look at this,your help will be appreciated .Thank you.
You have got a few problems there.
1st problem:
You should not be using gMap2 because it has been deprecated since 2013. Google have since rewritten its maps javascript library, making it more lightweight and compatible for mobile devices and it is version 3.
V3 example:
var map = new google.maps.Map(document.getElementById("map"),
{
zoom: 6,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
2nd problem:
Array markers is empty. You are creating the MarkerClusterer object correctly but it has been fed with an empty array. It should be an array of markers that you want the clusterer object to consider for clustering.
var markers = [];
...
var mc = new MarkerClusterer(map, markers);
3rd problem:
You are re-instantiating the variable marker over and over again. Try to give them distinct names like marker1, marker2... This is so that you can reference back the markers later in code.
var marker = createMarker(point,"This place","Some stuff to display in the<br>First Info Window")
var marker = createMarker(point,"That place","Some stuff to display in the<br>Second Info Window")
...
4th problem
This is the MOST important one. You should not EXPOSE your Google map API keys to the public!!! This gives me an opportunity to do malicious things to it and I believe you may have breach the license agreement. Please don't do it again. I'll modify your post to censor that part off.
Here is a clusterer example that I have made in JSFiddle previously.
JSFiddle

2 Google Maps Conflicting With Each Other

I am creating a web app that has 2 instances of Google Maps API: one which has many points, and one which only has one point.
They seem to be conflicting with each other, because when I view one page before the other, the other map is not centered in the correct spot.
First Page:
Second Page:
Here is a link to my project: http://jakeserver.com/Apps/BostonLandmarks/B12/index.html
Here is the code that is generating the Google Maps:
var detailsMap = new google.maps.Map(document.getElementById("map_" + this.id), {
zoom: 10,
center: new google.maps.LatLng(landmarkList[rowCount].landmarkGPSNorth, landmarkList[rowCount].landmarkGPSWest),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var detailsInfoWindow = new google.maps.InfoWindow();
var detailsMarker, j;
detailsMarker = new google.maps.Marker({
position: new google.maps.LatLng(landmarksArray[rowCount].landmarkGPSNorth, landmarksArray[rowCount].landmarkGPSWest),
map: detailsMap,
icon: "Icons/red-pin.pdf"
});
detailsInfoWindow.setContent(landmarksArray[rowCount].landmarkName);
detailsInfoWindow.open(detailsMap, detailsMarker);
google.maps.event.addListener(detailsMarker, 'click', (function(detailsMarker, j) {
return function() {
detailsInfoWindow.open(detailsMap, detailsMarker);
}
})(detailsMarker, j));
}
document.getElementById("map_" + this.id).style.height = 300 + "px";
document.getElementById("map_" + this.id).style.width = 300 + "px";
Any ideas?
A long ago I'd a similar problem with a Ajax-Based navigation in a website, each page had a map, the first one working normally, but the next ones had the same problem you're having.
Before displaying the map you should create a new bound object. Just like this:
var bounds = new google.maps.LatLngBounds();
After that. You've to extend the bounds passing your markers positions. Like this:
bounds.extend(marker.position);
And finally, when the map is actually visible and rendered. Run the following lines.
google.maps.event.trigger(secondMapInstance, 'resize');
secondMapInstance.fitBounds(bounds);

Google Maps centre changing issue

I'm using a combination of Google Maps, GeoXML and MarkerClusterer to map historic texts to places. The user can choose the texts they want to map, and the page goes and gets the KML for those group of texts and displays it with MarkerClusterer.
Something is causing the page to recenter over India/China when new texts are selected (bottom left corner: http://lakes.jhadley.net/lit_file.htm.
Here is the primary function that deals with the map:
function loadMap(myLat, myLong, zoomLevel, generatedUrl) {
var mapOptions = {
center: new google.maps.LatLng(myLat, myLong),
zoom: zoomLevel,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mcOptions = {gridSize: 80, maxZoom: 15};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
markerclusterer = new MarkerClusterer(map, [], mcOptions);
var myParser = new geoXML3.parser({
map: map,
singleInfoWindow:true,
suppressInfoWindows:true,
createMarker:function(placemark){
var point = placemark.latlng;
var info = "<pre" + placemark.name + "<br /><br />" + placemark.description + "</pre>";
var marker = new google.maps.Marker({position:point});
//Suppress the speachbubbles and have them appear in a text window instead
google.maps.event.addListener(marker, 'click', function() {
var text = placemark.description.replace(/ target="_blank"/ig, "");
showInContentWindow(text);
}); //Add listener
markerclusterer.addMarker(marker);
}
});
myParser.parse("http://lakes.jhadley.net/generateKml/"+generatedUrl);
function showInContentWindow(text) {
var sidediv = document.getElementById('kwic_window');
sidediv.innerHTML = text;
} //showInContentWindow
} //function loadMap
I can't personally see why the map centre is being repositioned over India/China when new texts are loaded. Can anyone tell me what I'm missing?
by default geoxml3 attempts to zoom to fit the data. If you don't want it to do that, set the "zoom" option to false. From the documentation:
zoom | boolean (true) | If true, the parser will automatically move the map to a best-fit of the geodata after parsing of a KML document completes.
That is where the "center" of the markers are:
http://www.geocodezip.com/geoxml3_test/v3_geoxml3_kmltest_linktoB.html?filename=http://www.geocodezip.com/geoxml3_test/SO_20140312_1,4.kml
http://www.geocodezip.com/geoxml3_test/v3_geoxml3_kmltest_linktoB.html?filename=http://www.geocodezip.com/geoxml3_test/SO_20140312_1.kml

ArcGIS simple example dynamically rendering a marker

I am having a hard time trying to add a simple clickable marker to an ArcGIS, map purely using JavaScript. All of the ArcGIS Samples seem to get their marker and related popup information from the server. How can I achieve the same result with ArcGIS as this Google Maps sample code below?
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<div id="map" style="width: 500px; height: 500px;"></div>
<script type="text/javascript">
window.onload = function() {
var myOptions = {
zoom: 2,
center: new google.maps.LatLng(40, -75),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var icon = new google.maps.MarkerImage("http://cinnamonthoughts.org/wp-content/uploads/2010/01/Custom-Marker-Avatar.png");
var markerOptions = {
icon: icon,
map: map,
position: new google.maps.LatLng(37.7699298, -122.4469157),
};
var marker = new google.maps.Marker(markerOptions);
google.maps.event.addListener(marker, 'click', function() {
var infoWindow = new google.maps.InfoWindow();
infoWindow.setContent("hello world");
infoWindow.open(map, marker);
});
};
</script>
Try this:
Create a Point for you longitude and latitude
Convert the point to Web Mercator spatial reference, if it's necessary
Create a PictureMarkerSymbol for you custom picture marker
Create a Graphic using the point and the symbol
Create a GraphicsLayer
Add the graphic to the graphic layer
Add the graphic layer to your map
Add a custom onClick event listener to your layer
Some equivalent code:
var point = new esri.geometry.Point(longitude, latitude);
point = esri.geometry.geographicToWebMercator(point);
var symbol = new esri.symbol.PictureMarkerSymbol("marker.png", 32, 32);
var graphic = new esri.Graphic(point, symbol);
var layer = new esri.layers.GraphicsLayer();
layer.add(graphic);
map.addLayer(layer);
dojo.connect(layer, "onClick", onClick);
On the event listener you can open a custom infoWindow or whatever you like:
function onClick(event) {
map.infoWindow(...)
...
Change "marker.png" and 32x32 to use your custom marker image and dimensions.
Try placing your image icon anywhere on the screen X Y using the CSS positioning then just put your onClick handler inside the actual DIV or IMG tag. Try playing with combination relative vs. absolute to get it just right.
div#header {
position: relative;
}
img#headimg {
position: absolute;
left: whatever you like
top: whatever you like
}

Google Maps API v3: Close infowindow when DOM element is clicked

I'm playing around with Google maps for the first time, so I looked at a nice tutorial over at CSS Tricks: http://css-tricks.com/google-maps-slider/ I like working with jQuery better than pure JS, and this tutorial makes a nice way to click on a place in a list to display the marker in the map.
I liked it that way, but I need to add infowindows to the marker. Which I did, but when I click on a place on the list and the map pans away, the infowindow stays open! I think it's because I need to attach the infowindow.close() to the event of clicking on a "#locations li".
Here's my code, which runs on document.ready:
$(function() {
var chicago = new google.maps.LatLng(41.924832, -87.697456),
pointToMoveTo,
first = true,
curMarker = new google.maps.Marker({}),
$el;
var myOptions = {
zoom: 10,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($("#map_canvas")[0], myOptions);
$("#locations li").click(function() {
$el = $(this);
if (!$el.hasClass("hover")) {
$("#locations li").removeClass("hover");
$el.addClass("hover");
if (!first) {
// Clear current marker
curMarker.setMap();
// Set zoom back to Chicago level
// map.setZoom(10);
}
// Move (pan) map to new location
function move(){
pointToMoveTo = new google.maps.LatLng($el.attr("data-geo-lat"), $el.attr("data-geo-long"));
map.panTo(pointToMoveTo);
}
move();
// Add new marker
curMarker = new google.maps.Marker({
position: pointToMoveTo,
map: map
});
// Infowindow: contenido
var contentString = '<p>'+$el.find("h3").html()+'</p>';
contentString += 'hola' ;
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50),
content: contentString
});
// On click, zoom map
google.maps.event.addListener(curMarker, 'click', function() {
//map.setZoom(14);
infowindow.open(map,curMarker);
});
It looks like you're creating a new InfoWindow for each marker. Quoting from the Google Maps API Docs:
If you only want one info window to display at a time (as is the behavior on Google Maps), you need only create one info window, which you can reassign to different locations or markers upon map events (such as user clicks).
Therefore, you may simply want to create one InfoWindow object just after you initialize your map, and then handle the click event handler as follows:
google.maps.event.addListener(curMarker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, curMarker);
});
Then the InfoWindow should automatically close when you click on a new marker without having to call the close() method.

Categories