I'm now use the node.js platform. And I want to use googlemap cluster library. However I can't execute the source code.
googlemaps cluster api url : https://github.com/googlemaps/js-marker-clusterer
This library's index is below.
dosc
examples
images
src
etc..
In the directory of examples, I want to test a "simple_example.html".
My node.js source code is below.
[app.js]
var express = require("express");
var app = express();
app.set('view engine','ejs');
var path = require("path");
app.set("public", path.join(__dirname, "public"));
app.get('/', function(req, res){
res.render("simple_example", {} )
});
app.listen(3000);
console.log("Running at Port 3000");
[simple_example.ejs] (important script part)
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="public/data.json"></script>
<script type="text/javascript" src="public/src/markerclusterer.js"></script>
<script>
function initialize() {
var center = new google.maps.LatLng(37.4419, -122.1419);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markers = [];
for (var i = 0; i < 100; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude,
dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers, {imagePath: 'public/images/m'});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
This picture is result of execute by my source code. but the picture doesn't have markered in the map. I expected picture is below.
I tried path change of src, change web platform(as python) but I can't solve the problem. Who know the solution?
Once you create a marker cluster, support it by using addMarker() method or by providing a array of markers to the constructor.
When they say add marker to constructor by providing a array of markers it's similar to doing this:
var markers = []; //create a global array where you store your markers
for (var i = 0; i < 100; i++) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude);
var marker = new google.maps.Marker({'position': latLng});
markers.push(marker); //push individual marker onto global array
}
var markerCluster = new MarkerClusterer(map, markers); //create clusterer and push the global array of markers into it.
To add it using addMarker() you basically add it to the cluster like the following:
var markerCluster //cluster object created on global scope
//do your marker creation and add it like this:
markerCluster.addMarker(newMarker, true); //if specify true it'll redraw the map
Here's a reference to MarkerCluster: https://googlemaps.github.io/js-marker-clusterer/docs/examples.html
Also, here's a demo app how to use markercluster: https://github.com/googlemaps/js-marker-clusterer
Related
I've searhced the site for this error and, while there were several answers, none of them worked for me (or weren't applicable).
I am using google maps API v3 and am trying to implement OverlappingMarkerSpiderfier to solve my problem of overlapping markers. My problem is that I cannot create an instance of an OMS:
function getStateInfo(){
//do stuff
var lat = 42.5724;
var lon = -74.948052;
var map = new google.maps.Map(document.getElementById("map"),{draggableCursor:'pointer'});
var oms = new OverlappingMarkerSpiderfier(map,{markersWontMove: true, markersWontHide: true});
// do more stuff
var whiteicon = new GIcon();
whiteicon.image = "images/whiteCircle.png";
whiteicon.iconSize = new GSize(11, 11);
whiteicon.iconAnchor = new GPoint(6, 6);
whiteicon.infoWindowAnchor = new GPoint(6,6);
var marker = new GMarker(new GLatLng(lat,lon), {
draggable: false,
title: ($(this).find('COMPANY_NAME').text()),
icon: whiteicon,
map: map
});
oms.addMarker(marker);
}
I get the following error:
InvalidValueError: setMap: not an instance of Map; and not an instance of StreetViewPanorama
I have verified that the error occurs at the time of instantiation and not at marker creation/placement. For thoroughness, here is the code I am trying to use to place markers:
var marker = new GMarker(new GLatLng(lat,long), {
draggable: false,
title: ($(this).find('COMPANY_NAME').text()),
icon: whiteicon,
map: map});
...
oms.addMarker(marker);
I have also retrieved a different copy of OMS in the event that there was something wonky with the original (downloaded from github).
If you need to see more code, just let me know what you are looking for. I just posted the lines which are the problem. My map generates properly without OMS - it's just the oms instantiation that is the problem.
You are using a deprecated Google Maps JavaScript API v2 map with a Google Maps JavaScript API v3 spiderifier.
This is v2 code (GSize, GPoint, GLatLng):
whiteicon.iconSize = new GSize(11, 11);
whiteicon.iconAnchor = new GPoint(6, 6);
var marker = new GMarker(new GLatLng(lat,lon), {
I'm trying to create a heatmap using Google's API, but running into a few issues. The main issue I have run into so far is converting a large set of about ~25000 addresses into geocoordinates for use in the API. The two approaches I have used are Google's own API, which has heavy limitations, and Python's Geopy module, which also has limitations. Since I am trying to convert ~25000, Geopy's one second delay is a pretty steep issue.
The second issue I can see coming is a size limitation. Once I have a list of ~25000 geocoordinates, putting those into an array in Javascript seems ridiculous. Assuming a user would upload a text file in a format like this:
12.3456,-12.3456
23.4567,-23.4567
...
Would there be a way to process the file in blocks, or some other work around?
In case it helps, this is my current Javascript code for processing a file of addresses. I'm planning on changing the file reading format to find a better system.
var map, heatmap, geocoder;
var MVCarr;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 36.85, lng: -75.97},
zoom: 7
});
MVCarr = new google.maps.MVCArray();
heatmap = new google.maps.visualization.HeatmapLayer({
data: MVCarr,
map: map
})
}
window.onload = function() {
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('fileDisplayArea');
geocoder = new google.maps.Geocoder();
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var mySplit = (reader.result).split("\n");
for(var i = 0, len = mySplit.length; i < len; i++) {
//console.log(mySplit[i]);
geocodeAddress(geocoder, mySplit[i]);
}
}
reader.readAsText(file);
});
}
function geocodeAddress(geocoder, address) {
geocoder.geocode({'address': address}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
MVCarr.push(results[0].geometry.location);
console.log(MVCarr.length);
} else {
console.log('Failed: ' + status);
}
});
}
I would like to output multiple Google Map routes on to a single Google Map. The data is taken from an XML file which feature multiple markers. Each marker has a start point and an end point (in the form of latitude and longitude values). These markers are then added to the map and a call to the Google Maps Directions Service is made to draw a route between the start and end points of each marker.
The issue I'm having is that only one route is drawn (if I refresh the page it seems to just pick one of the markers at random and draw the directions between those two markers). The other markers aren't displayed at all.
I've console.logged the for loop to check it is running for each marker in the XML (it is). I'm guessing it is something to do with these two lines here, but that is a guess...
directionsDisplay = new google.maps.DirectionsRenderer();
directionsService = new google.maps.DirectionsService();
I've read this question - Using Google Maps 3 API to get multiple routes on a Map, but don't really understand the answer/know how relevant it is to my situation. Thanks.
jQuery(document).ready(function($) {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 13,
mapTypeId: 'roadmap'
});
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(pos);
map.setZoom(13);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
directionsDisplay = new google.maps.DirectionsRenderer();
directionsService = new google.maps.DirectionsService();
// Change this depending on the name of your PHP file
downloadUrl("xml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var title = markers[i].getAttribute("title");
mode = markers[i].getAttribute("mode");
startpoint = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("startlat")),
parseFloat(markers[i].getAttribute("startlng")));
endpoint = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("endlat")),
parseFloat(markers[i].getAttribute("endlng")));
calcRoute();
console.log('marker');
}
});
directionsDisplay.setMap(map);
});
function calcRoute() {
var request = {
origin: startpoint,
destination: endpoint,
//waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode[mode]
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
I think the key point in the answer you linked to is that each route needs its own DirectionsRenderer object. And it doesn't mention it, but it seems likely that each route should also have its own DirectionsService object. You're sharing a single one of each these objects among all your routes. I suspect that these shared objects are getting overwritten for each route.
Here's an update that should fix that by creating new objects for each route:
jQuery(document).ready(function($) {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 13,
mapTypeId: 'roadmap'
});
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(pos);
map.setZoom(13);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
// Change this depending on the name of your PHP file
$.get("xml.php", function( xml ) {
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
addMarkerPair( markers[i] );
}
}, 'xml' );
});
function addMarkerPair( pair ) {
function get( name ) {
return pair.getAttribute( name );
}
var title = get("title");
var mode = get("mode");
var startpoint = new google.maps.LatLng(
+get("startlat"),
+get("startlng")
);
var endpoint = new google.maps.LatLng(
+get("endlat"),
+get("endlng")
);
calcRoute( mode, startpoint, endpoint );
console.log('marker');
}
function calcRoute( mode, startpoint, endpoint ) {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
var request = {
origin: startpoint,
destination: endpoint,
//waypoints: waypts,
travelMode: google.maps.DirectionsTravelMode[mode]
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
I also took the liberty of fixing and simplifying a few things:
Moved the marker loop body out to a separate addMarkerPair function for better readability.
Added a get function inside addMarkerPair as a shorthand for pair.getAttribute.
Used + instead of parseInt. Either one will do the same thing; I like + for its brevity.
Add several missing var declarations.
Passed the necessary parameters to calcRoute as function parameters instead of global variables.
Used $.get instead of downloadUrl. No need for your own function when jQuery has it already.
Also, as another alternative to the XML parsing, you could use jQuery to access the XML elements. But I stuck with code closer to how you're already doing it.
I am creating a web page that lets a user enter a start location and an end location into textbox's and the distance between the two locations is output (this is using a google API). I have successfully been able to create a single instance of this that works as I want it to. However my problem is that I need multiple rows of this but as soon I duplicate the code I cannot seem to get it to work. This is my first real attempt at using javascript so my understanding of it is not that great. I realise that I need to change variables etc. but am unsure exactly as what to change. Sorry if I have not been clear enough but any help would be great, thanks.
Here is my code:
<body onload="initialize()">
<script type="text/javascript">
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var belfast = new google.maps.LatLng(55, -5)
var myOptions = {
zoom:5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: belfast,
}
map = new google.maps.Map(document.getElementById("map_canvas1"), myOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById("pc1").value;
var end = document.getElementById("pc2").value;
var distanceInput = document.getElementById("distance");
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
distanceInput.value = response.routes[0].legs[0].distance.value / 1000;
}
});
}
<td><input type="text" id="pc1" /></td>
If you're creating multiple instances of Google Maps, you need to make sure you're not mixing up global variables. These variables you're declaring on a global level:
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
So if you try to create a second map and assign the map to the map variable, which should destroy the previous map. Likewise your DirectionsService. So you need to create a variable for each of those for each instance.
I'm having a conflict, between Directions & user GeoCode Detection.
If I do this:
var MapCenter = new google.maps.LatLng(-33.8665433, 151.1956316);
function initialize(lat,lng) {
geocoder = new google.maps.Geocoder();
// var MapCenter = new google.maps.LatLng(lat,lng);
geocodeThis(MapCenter);
the directions work fine, but the GeoCoder doesn't get the user's location.
And if I do it like this:
// var MapCenter = new google.maps.LatLng(-33.8665433, 151.1956316);
function initialize(lat,lng) {
geocoder = new google.maps.Geocoder();
var MapCenter = new google.maps.LatLng(lat,lng);
geocodeThis(MapCenter);
the GeoCoder gets the user location, but when you click on the InfoWindow, and then in directions, the script doesn't do anything. Instead it should give you directions to that marker from your current (just GeoCoded) location.
Here is my full code.
You should call the variables with different names. They are both called "MapCenter", of course they conflict...
What are you trying to achieve?