I am learning leaflet . My idea was to create map with clusters
, everything works but when I move map new markers keep
overlay old ones.I could see that every time i move map marker gets bolder, so i assume they overlay each other.
How to remove old ones ? I tried everything , cant figure out,
here is code:
var map;
var ajaxRequest;
var plotlist;
var plotlayers=[];
var marker;
var clusters = {}; // key is lat/lon, value is a L.MarkerClusterGroup
var nodecounts = {};// key is lat/lon, value is the number of nodes at that location
var markers = {}; // key is plot id, value is an L.Marker
// Browsable map
function initMap(lat,lon,zoom){
// set up the AJAX stuff
ajaxRequest=GetXmlHttpObject();
if (ajaxRequest==null) { return; }
// set up the map
map = new L.Map('map');
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 8, maxZoom: 20, attribution: osmAttrib});
if (!lat) { lat=44.3008813; lon=-79.6114973; zoom=14; }
map.setView(new L.LatLng(lat,lon),zoom);
map.addLayer(osm);
askForPlots();
map.on('moveend', onMapMove);
}
function askForPlots() {
// request the marker info with AJAX for the current bounds
var bounds=map.getBounds();
var minll=bounds.getSouthWest();
var maxll=bounds.getNorthEast();
$("#regTitle").html("Hello World");
$("#listings").load('/engine/boxlistings.php?w='+minll.lng+'&s='+minll.lat+'&e='+maxll.lng+'&n='+maxll.lat);
var msg='/engine/box.php?w='+minll.lng+'&s='+minll.lat+'&e='+maxll.lng+'&n='+maxll.lat;
ajaxRequest.onreadystatechange = gotPlots;
ajaxRequest.open('GET', msg, true);
ajaxRequest.send(null);
}
function onMapMove(e) {
askForPlots();
}
function gotPlots() {
if (ajaxRequest.readyState!=4 || ajaxRequest.status!=200) return;
var resp = JSON.parse(ajaxRequest.responseText);//.replace(/[^\u000A\u0020-\u007E]/g, "")
var plotlist = resp.plots;
// First, tot up the number at each position, so we know whether to cluster
for (var i=0; i<plotlist.length; i++) {
var plot = plotlist[i];
if (markers[plot.id]) continue;
var ll = new L.LatLng(plot.lat,plot.lon, true);
var key= locationKey(ll);
nodecounts[key] = (nodecounts[key] || 0) + 1;
}
// Custom
var mapcluster = L.markerClusterGroup({ chunkedLoading: true,maxClusterRadius:60 });
for (var i = 0; i < plotlist.length; i++) {
var a = plotlist[i];
var title = a.name;
var marker = L.marker(L.latLng(a.lat, a.lon), {
icon: new L.DivIcon({
className: 'tooltips',
html: ''+
'<div class="triangle" id="'+a.id+'"><strong>'+a.price+'</strong></div>'
})
});
marker.bindPopup(title);
mapcluster.addLayer(marker);
}
map.addLayer(mapcluster);
console.log(mapcluster);
}
function locationKey(ll) { return ll.lat.toFixed(5)+","+ll.lng.toFixed(5); }
// Single plot map
// AJAX support
function GetXmlHttpObject() {
if (window.XMLHttpRequest) { return new XMLHttpRequest(); }
if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); }
return null;
}
Any help appreciated
I use this function:
function removeMarkers() {
map.eachLayer(function (layer) {
layer.remove();
});
}
But it also removes the map so I follow with:
L.imageOverlay(imageUrl, imageBounds).addTo(map);
Related
I have added on a google map some polygons and multipolygons from geojson data.
My need is to print out the name of the countries in an infowindow when the event "mousemove" is in the polygon. I have also set a legend and i want to reload it when the event "dblclick" is on the polygon.
Here's my problem: I can't do the "mousemove" and the "dblclick" event for all the polygons and multipolygons, it just take the last one polygon and multipolygon casted by my function.
Here's my full code (UPDATE):
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var countries = ['Germany','France','Moldova','Italy','Spain'];
var infoWindow = document.createElement('div');
infoWindow.id = 'infoWindow';
var content1 = [];
content1.push('<h3>Default </h3>');
infoWindow.innerHTML = content1.join('');
infoWindow.index = 2;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(infoWindow);
var state = new google.maps.Data();
var poly ;
var polys = new Array();
var gaArr = new Array();
var p = 0;
var mp = 0;
//the problem is here
state.addListener('addfeature',function(evt) {
//my 5 objects pass here
var CouName = evt.feature.getProperty('name');
if (evt.feature.getProperty('type') == 'Polygon') {
var ga = state.getFeatureById(CouName);
var gaGeom = ga.getGeometry();
gaArr = gaGeom.getAt(0).getArray();
poly = new google.maps.Polygon({paths:gaArr, map:map,clickable:false,visible:false});
google.maps.event.addListener(map,'dblclick',function(evt){
if (google.maps.geometry.poly.containsLocation(evt.latLng, poly)) {
legend.innerHTML = CouName;
}
});
google.maps.event.addListener(map,'mousemove',function(evt){
if (google.maps.geometry.poly.containsLocation(evt.latLng, poly)) {
infoWindow.innerHTML = CouName;
}
});
p++;
}
if (evt.feature.getProperty('type') == 'MultiPolygon') {
var ga = state.getFeatureById(CouName);
var gaGeom = ga.getGeometry();
gaArr = gaGeom.getArray();
for (var i=0;i<gaGeom.getArray().length;i++){
polys[i]= new google.maps.Polygon({paths:gaArr[i].getAt(0).getArray(), map:map,clickable:false,visible:false});
}
google.maps.event.addListener(map,'dblclick',function(evt){
for(var i=0;i<gaArr.length;i++){
if (google.maps.geometry.poly.containsLocation(evt.latLng, polys[i])) {
legend.innerHTML = CouName;
}
}
});
google.maps.event.addListener(map,'mousemove',function(evt){
for(var i=0;i<gaArr.length;i++){
if (google.maps.geometry.poly.containsLocation(evt.latLng, polys[i])) {
infoWindow.innerHTML = CouName;
}
}
});
mp++;
}
});
for (var country in countries){
state.loadGeoJson('http://.../GoogleMaps/'+countries[country]+'.geojson', {
idPropertyName: 'name'
});
}
state.setMap(map);
//to color the polygons
state.setStyle(function(feature) {
var k = feature.getProperty('color');
return {
fillOpacity:0.6,
fillColor:k,
strokeWeight:1,
clickable: false
}
});
I Think the problem is the Polygon array polys and the polygon poly are deleted when state.addListener pass to another polygon or multipolygon, and as i said, the addlistener works for the last ones polygon and multipolygon casted by the function.
I don't know if it can help but below is an example of my geojson files:
{"type":"Feature","properties":{"color":"purple","name":"Germany","type":
"MultiPolygon"},"geometry":{"type": "MultiPolygon","coordinates":
[[[[8.5636100769042969,54.684165954589844],
[8.5948600769042969,54.719856262207031],[8.5851364135742187,54.7445068359375],
[8.5511093139648437,54.753883361816406],[8.4447212219238281,54.74832...]]]]}}
{"type":"Feature","properties":{"name": "Moldova","color":"green","type":
"Polygon"},"geometry":{"type": "Polygon","coordinates":
[[[28.108325958251953,46.102291107177734],[28.0...]]]]}}
I thought about looping on all multipolygons and polygons and making an array of polygons and an array of array of polygons but it didn't work.
I found the answer. I update below state.addListener:
state.addListener('addfeature',function(evt) {
var CouName = evt.feature.getProperty('name');
if (evt.feature.getProperty('type') == 'Polygon') {
var c = p;
var ga = state.getFeatureById(CouName);
var gaGeom = ga.getGeometry();
gaArr = gaGeom.getAt(0).getArray();
//here I push all my polygons in my array poly
poly.push(new google.maps.Polygon({paths:gaArr, map:map,clickable:false,visible:false}));
google.maps.event.addListener(poly[c],'dblclick',function(evt){
alert(poly.length);
if (google.maps.geometry.poly.containsLocation(evt.latLng, poly[c])) {
legend.innerHTML = CouName;
}
});
google.maps.event.addListener(map,'mousemove',function(evt){
if (google.maps.geometry.poly.containsLocation(evt.latLng, poly[c])) {
infoWindow.innerHTML = CouName;
}
});
p++;
}
if (evt.feature.getProperty('type') == 'MultiPolygon') {
var cp= mp;
var ga = state.getFeatureById(CouName);
var gaGeom = ga.getGeometry();
gaArr = gaGeom.getArray();
for (var i=0;i<gaGeom.getArray().length;i++){
//here I push all my polygons of my multipolygons in my array polys
polys.push(new google.maps.Polygon({paths:gaArr[i].getAt(0).getArray(), map:map,clickable:false,visible:false}));
}
google.maps.event.addListener(map,'dblclick',function(evt){
for(var i=cp;i<cp+gaGeom.getArray().length;i++){
if (google.maps.geometry.poly.containsLocation(evt.latLng, polys[i])) {
legend.innerHTML = CouName;
}
}
});
google.maps.event.addListener(map,'mousemove',function(evt){
for (var i=cp;i<cp+gaGeom.getArray().length;i++){
if (google.maps.geometry.poly.containsLocation(evt.latLng, polys[i])) {
infoWindow.innerHTML = CouName;
}
}
});
mp=mp+gaGeom.getArray().length;
}
});
I am trying to load Map data using a CSV file using Google's Map API. I tried following this example: https://wrightshq.com/playground/placing-multiple-markers-on-a-google-map-using-api-3/
I was trying to load it which shows some information on clicking the markers.
My CSV data looks something like this
LGA_NAME Lat Long Information
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
https://jsfiddle.net/sourabhtewari/ye96s94c/2/
I cant seem to load any of the data. It shows up a blank. Not sure what could be the problem. If someone could correct it, I would be thankful.
function initialize() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'roadmap'
};
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = [];
// Info Window Content
var infoWindowContent = [];
$.get('https://dl.dropboxusercontent.com/u/97162408/crashdata.csv', function(data) {
var data = csvToArray(data);
data.forEach(function(item) {
{
markers.push([item.LGA_NAME, parseFloat(item.Lat), parseFloat(item.Long)]);
infoWindowContent.push([item.Information]);
}
});
});
console.log(infoWindowContent);
function csvToArray(csvString) {
// The array we're going to build
var csvArray = [];
// Break it into rows to start
var csvRows = csvString.split(/\n/);
// Take off the first line to get the headers, then split that into an array
var csvHeaders = csvRows.shift().split(',');
// Loop through remaining rows
for (var rowIndex = 0; rowIndex < csvRows.length; ++rowIndex) {
var rowArray = csvRows[rowIndex].split(',');
// Create a new row object to store our data.
var rowObject = csvArray[rowIndex] = {};
// Then iterate through the remaining properties and use the headers as keys
for (var propIndex = 0; propIndex < rowArray.length; ++propIndex) {
// Grab the value from the row array we're looping through...
var propValue = rowArray[propIndex];
// ...also grab the relevant header (the RegExp in both of these removes quotes)
var propLabel = csvHeaders[propIndex];
rowObject[propLabel] = propValue;
}
}
return csvArray;
}
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(),
marker, i;
// Loop through our array of markers & place each one on the map
for (i = 0; i < markers.length; i++) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
}
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(14);
google.maps.event.removeListener(boundsListener);
});
}
$.get was out of scope for the needed objects. Silly mistake but a fix is easy.
fiddle: https://jsfiddle.net/sourabhtewari/aLk0c2fa/
$.get('https://dl.dropboxusercontent.com/u/97162408/crashdata.csv', function(data) {
function initialize() {
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Display a map on the page
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = [];
// Info Window Content
var infoWindowContent = [];
data = csvToArray(data);
data.forEach(function(item) {
markers.push([item.LGA_NAME, parseFloat(item.Lat), parseFloat(item.Long)]);
infoWindowContent.push([item.Information]);
});
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(),
marker, i;
// Loop through our array of markers & place each one on the map
for (i = 0; i < markers.length - 1; i++) {
console.log(markers[i][1]);
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
}
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(8);
google.maps.event.removeListener(boundsListener);
});
}
initialize();
});
function csvToArray(csvString) {
// The array we're going to build
var csvArray = [];
// Break it into rows to start
var csvRows = csvString.split(/\n/);
// Take off the first line to get the headers, then split that into an array
var csvHeaders = csvRows.shift().split(',');
// Loop through remaining rows
for (var rowIndex = 0; rowIndex < csvRows.length; ++rowIndex) {
var rowArray = csvRows[rowIndex].split(',');
// Create a new row object to store our data.
var rowObject = csvArray[rowIndex] = {};
// Then iterate through the remaining properties and use the headers as keys
for (var propIndex = 0; propIndex < rowArray.length; ++propIndex) {
// Grab the value from the row array we're looping through...
var propValue = rowArray[propIndex];
// ...also grab the relevant header (the RegExp in both of these removes quotes)
var propLabel = csvHeaders[propIndex];
rowObject[propLabel.trim()] = propValue;
}
}
return csvArray;
}
I'm implementing google maps roads API to pick up the coordinates where I clicked on the roads. But it returns more than expected coordinates and placeids. Suppose I set a direction from place A to place B using directions API then I clicked some points (lets say 10 points) on the roads to draw the route. In response the roads API is returning more than 10 placeIds and coordinates where I need only 10. Here is the code.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=drawing,places"></script>
<script>
//GOOGLE_API_KEY
var apiKey = '';
if(!apiKey)
alert("Please provide API Key");
var map;
var elevator;
var directionsDisplay;
var directionsService;
var placeDetailsService;
var drawingManager;
var placeIdArray = [];
var polylines = [];
var snappedCoordinates = [];
var initialLocation;
var siberia = new google.maps.LatLng(60, 105);
var newyork = new google.maps.LatLng(40.69847032728747, -73.9514422416687);
var browserSupportFlag = new Boolean();
function initialize()
{
document.getElementById("save").style.display="none";
var mapOptions = {
zoom: 17,
center: {lat: 40.69847032728747, lng: -73.9514422416687}
};
directionsService = new google.maps.DirectionsService();
var polylineOptionsActual = new google.maps.Polyline({
strokeColor: '#FF0000',
strokeOpacity: 0.6,
strokeWeight: 2
});
directionsDisplay = new google.maps.DirectionsRenderer({polylineOptions: polylineOptionsActual});
map = new google.maps.Map(document.getElementById('map'), mapOptions);
directionsDisplay.setMap(map);
//Place Details
placeDetailsService= new google.maps.places.PlacesService(map);
// Create an ElevationService
elevator = new google.maps.ElevationService();
// Adds a Places search box. Searching for a place will center the map on that location
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(
document.getElementById('bar'));
//Start Location Searchbox
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocStart'));
autocomplete.bindTo('bounds', map);
autocomplete.addListener('place_changed', function () {
var placeStart = autocomplete.getPlace();
//alert(placeStart.place_id);
placeDetailsService.getDetails({
placeId: placeStart.place_id
}, function(place, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
console.log(place.geometry.location);
//alert("Start Location: "+place.geometry.location.G);
document.getElementById("startPlaceLat").value=place.geometry.location.G;
document.getElementById("startPlaceLng").value=place.geometry.location.K;
}
});
});
//End Location Searchbox
var autocomplete1 = new google.maps.places.Autocomplete(document.getElementById('autocEnd'));
autocomplete1.bindTo('bounds', map);
autocomplete1.addListener('place_changed', function () {
var placeEnd = autocomplete1.getPlace();
//alert(placeEnd.place_id);
placeDetailsService.getDetails({
placeId: placeEnd.place_id
}, function(place, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
console.log(place.geometry.location);
//alert("End Location: "+place.geometry.location.G);
document.getElementById("endPlaceLat").value=place.geometry.location.G;
document.getElementById("endPlaceLng").value=place.geometry.location.K;
}
});
});
// Enables the polyline drawing control. Click on the map to start drawing a
// polyline. Each click will add a new vertice. Double-click to stop drawing.
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.POLYLINE,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYLINE
]
},
polylineOptions: {
strokeColor: '#696969',
strokeWeight: 2
}
});
drawingManager.setMap(map);
// Snap-to-road when the polyline is completed.
drawingManager.addListener('polylinecomplete', function (poly) {
var path = poly.getPath();
polylines.push(poly);
placeIdArray = [];
runSnapToRoad(path);
});
// Clear button. Click to remove all polylines.
$('#clear').click(function (ev) {
for (var i = 0; i < polylines.length; ++i) {
polylines[i].setMap(null);
}
polylines = [];
ev.preventDefault();
document.getElementById("snappedCoordinatesArray").value = "";
document.getElementById("snappedPaceIdArray").value = "";
document.getElementById("altitudeArray").value = "";
document.getElementById("dataDisplay").style.display = "none";
document.getElementById("autocStart").value = "";
document.getElementById("autocEnd").value = "";
document.getElementById("startPlaceLat").value = "";
document.getElementById("startPlaceLng").value = "";
document.getElementById("endPlaceLat").value = "";
document.getElementById("endPlaceLng").value = "";
document.getElementById("save").style.display="none";
directionsDisplay.set('directions', null);
return false;
});
_init();
}
// Snap a user-created polyline to roads and draw the snapped path
function runSnapToRoad(path) {
var pathValues = [];
for (var i = 0; i < path.getLength(); i++) {
pathValues.push(path.getAt(i).toUrlValue());
}
$.get('https://roads.googleapis.com/v1/snapToRoads', {
interpolate: true,
key: apiKey,
path: pathValues.join('|')
}, function (data) {
processSnapToRoadResponse(data);
drawSnappedPolyline();
//getAndDrawSpeedLimits();
});
}
// Store snapped polyline returned by the snap-to-road method.
function processSnapToRoadResponse(data)
{
snappedCoordinates = [];
placeIdArray = [];
for (var i = 0; i < data.snappedPoints.length; i++)
{
var latlng = new google.maps.LatLng(
data.snappedPoints[i].location.latitude,
data.snappedPoints[i].location.longitude);
//getElevation(latlng);
snappedCoordinates.push(latlng);
placeIdArray.push(data.snappedPoints[i].placeId);
}
//get Altitude in meters
getElevation(snappedCoordinates);
document.getElementById("snappedCoordinatesArray").value = snappedCoordinates;
document.getElementById("snappedPaceIdArray").value = placeIdArray;
}
// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
var snappedPolyline = new google.maps.Polyline({
path: snappedCoordinates,
strokeColor: 'black',
strokeWeight: 3
});
snappedPolyline.setMap(map);
polylines.push(snappedPolyline);
}
// Gets speed limits (for 100 segments at a time) and draws a polyline
// color-coded by speed limit. Must be called after processing snap-to-road
// response.
function getAndDrawSpeedLimits() {
for (var i = 0; i <= placeIdArray.length / 100; i++) {
// Ensure that no query exceeds the max 100 placeID limit.
var start = i * 100;
var end = Math.min((i + 1) * 100 - 1, placeIdArray.length);
drawSpeedLimits(start, end);
}
}
// Gets speed limits for a 100-segment path and draws a polyline color-coded by
// speed limit. Must be called after processing snap-to-road response.
function drawSpeedLimits(start, end) {
var placeIdQuery = '';
for (var i = start; i < end; i++) {
placeIdQuery += '&placeId=' + placeIdArray[i];
}
$.get('https://roads.googleapis.com/v1/speedLimits',
'key=' + apiKey + placeIdQuery,
function (speedData) {
processSpeedLimitResponse(speedData, start);
}
);
}
// Draw a polyline segment (up to 100 road segments) color-coded by speed limit.
function processSpeedLimitResponse(speedData, start) {
var end = start + speedData.speedLimits.length;
for (var i = 0; i < speedData.speedLimits.length - 1; i++) {
var speedLimit = speedData.speedLimits[i].speedLimit;
var color = getColorForSpeed(speedLimit);
// Take two points for a single-segment polyline.
var coords = snappedCoordinates.slice(start + i, start + i + 2);
var snappedPolyline = new google.maps.Polyline({
path: coords,
strokeColor: color,
strokeWeight: 6
});
snappedPolyline.setMap(map);
polylines.push(snappedPolyline);
//passDataToObjC();
}
}
//Color of the roads depends upon speed limit
function getColorForSpeed(speed_kph) {
if (speed_kph <= 40) {
return 'purple';
}
if (speed_kph <= 50) {
return 'blue';
}
if (speed_kph <= 60) {
return 'green';
}
if (speed_kph <= 80) {
return 'yellow';
}
if (speed_kph <= 100) {
return 'orange';
}
return 'red';
}
//Call Elevation API to get Altitude
function getElevation(snappedCoordinatesArr)
{
var locations = [];
// Retrieve the latlng and push it on the array
for (var i = 0; i < snappedCoordinatesArr.length; i++)
{
locations.push(snappedCoordinatesArr[i]);
}
// Create a LocationElevationRequest object using the array's one value
var positionalRequest =
{
'locations': locations
}
//alert(positionalRequest);
// Initiate the location request
elevator.getElevationForLocations(positionalRequest, function (results, status)
{
if (status == google.maps.ElevationStatus.OK)
{
// Retrieve the first result
if (results)
{
var altitudeArr = [];
for (var j = 0; j < results.length; j++)
{
altitudeArr.push(results[j].elevation);
}
document.getElementById("altitudeArray").value = altitudeArr;
document.getElementById("dataDisplay").style.display = "block";
document.getElementById("save").style.display="block";
//alert(altitudeArr);
}
else
{
alert('No results found');
}
}
else
{
alert('Elevation service failed due to: ' + status);
}
});
}
//Call Directions API to draw route
function calcRoute()
{
var start = document.getElementById("autocStart").value;
var end = document.getElementById('autocEnd').value;
var selectedMode = document.getElementById("travelType").value;
//alert(start);
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode[selectedMode]
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
//Save Details into Database
function _init()
{
document.getElementById("geodata-form").onsubmit = function (e) {
e.preventDefault();
var f = e.target,
formData = new FormData(f),
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.responseText) {
alert('Geodata successfully saved.');
document.getElementById("save").style.display="none";
// location.reload();
} else {
alert('Error occured !');
}
}
}
xhr.open("POST", f.action);
xhr.send(formData);
}
}
$(window).load(initialize);
</script>
I have created a JSfiddle here. Just give a google API key and then tell me whats wrong with this code?
You are calling the Roads API with interpolate: true. According to the documentation, that causes it to behave the way you say it is.
from the documentation:
interpolate — Whether to interpolate a path to include all points forming the full road-geometry. When true, additional interpolated points will also be returned, resulting in a path that smoothly follows the geometry of the road, even around corners and through tunnels. Interpolated paths will most likely contain more points than the original path. Defaults to false.
$(document).ready(function(){
// Initialise global variables
var geoJson = getMarkers();
var homeLatitude = 50.351;
var homeLongitude = -3.576;
var initialZoom = 15;
var mapInitialised = 0;
// Initialise map
var map = mapInit();
function mapInit() {
// initialise map
if ( mapInitialised===0 ) {
var map = L.mapbox.map('map', 'mapIdentifier.234grs')
.setView([homeLatitude, homeLongitude], initialZoom);
mapInitialised = 1;
}
return map;
}
});
I get the error Uncaught ReferenceError: mapInitialised is not defined inside the 'mapInit' function.
I'm still learning here and am unsure of what I'm doing wrong.
Edit: here's the whole code that I'm using in this app:
$(document).ready(function(){
// Initialise global variables
var geoJson = getMarkers();
var homeLatitude = 50.351;
var homeLongitude = -3.576;
var initialZoom = 15;
var mapInitialised = 0;
// Initialise map
var map = mapInit();
// Add features to map
var myLayer;
addFeaturesToMap(map, myLayer);
// Define map behaviour
myLayer.on('click', function(e) {
e.layer.openPopup();
});
// define button behaviour for switching between map and list
$('#buttonMap').click(function(){
switchToMap();
});
// define button behaviour for switching between map and list
$('#buttonList').click(function(){
switchFromMap();
});
$('.view-on-map').click(function(e){
// Scroll to the top of the map
$(document).scrollTo(0,500);
// get lat, long, and name for event location
var latitude = $(this).attr("data-latitude");
var longitude = $(this).attr("data-longitude");
var name = $(this).attr("data-name");
// go to map
switchToMap();
// show popup
var popup = L.popup()
.setLatLng([latitude, longitude])
.setContent('<p><strong>' + name + '</strong></p>' )
.openOn(map);
}); // end of view-on-map click function
}); // end of document ready function
function getMarkers() {
// define geoJson object
var geoJson = {
type: 'FeatureCollection',
features: []
};
var arrayLength = events.length;
// loop through events array and push into geoJson object
for (var i = 0; i < arrayLength; i++) {
var latitude = events[i].location[0].latitude;
var longitude = events[i].location[0].longitude;
var name = events[i].location[0].name;
var pageId = events[i].location[0].pageId;
var link = events[i].location[0].link;
var description = events[i].location[0].description;
var feature = {
type: 'Feature',
properties: {
title: name,
other: "text",
'marker-color': '#54a743',
'stroke': '#428334',
url: link
},
geometry: {
type: 'Point',
coordinates: [longitude, latitude]
}
}
// push to geoJson.features array
geoJson.features.push(feature);
}
return geoJson;
}
function switchToMap() {
// show map
$('#map').fadeIn();
// change button states
$('#buttonMap').attr("disabled", "disabled");
$('#buttonList').removeAttr("disabled");
}
function switchFromMap() {
// hide map
$('#map').fadeOut();
// change button states
$('#buttonList').attr("disabled", "disabled");
$('#buttonMap').removeAttr("disabled");
}
function mapInit() {
// initialise map
if ( mapInitialised===0 ) {
var map = L.mapbox.map('map', 'mapIdentifier.234grs')
.setView([homeLatitude, homeLongitude], initialZoom);
mapInitialised = 1;
}
return map;
}
function addFeaturesToMap(map, myLayer) {
// declare feature layer
myLayer = L.mapbox.featureLayer().addTo(map);
// Pass features and a custom factory function to the map
myLayer.setGeoJSON(geoJson);
// set template for popup
myLayer.eachLayer(function(layer) {
var content = 'Location:' + layer.feature.properties.title;
layer.bindPopup(content);
});
}
Isn't "mapInitialised" only in the scope of the function in which it is declared? I think once you fix the scoping of that variable, you will then run into similar issues with other variables used in "mapInit()", like "homeLatitude".
I am new to JavaScript.
Writing a script that uses GooogleMaps API
Working OK. Get Lat Lngs from Database, Make markers, put on Map.
Decided to move a function call up a level, (it was in the OnSuccess method of a PageMethod call). Stopped working.
Put in alerts to diagnose. Starts working.
Narrowed down to having alert at top of called function MakeLatLngs().
MakeLatLngs code appears to execute regardless of alert being present or commented out.
It is just that the map displays with alert statement in and doesn't display with alert statement commented out.
The alert is just text and not using any variable. So I am at a loss to understand what is going on here.
The same thing is happening in the function that draws the map DrawMap(). I put an informative alert at the start of the function and the map draws. Leave it out and the map doesn't.
Any clues as to what is going on would be appreciated?
The script is below.
Flow starts at function Initialise at bottom of script.
thanks
var myPositions = [];
var myRoutes = [];
var myString = [];
var myLatLngs = [];
var myTitles = [];
var NumPoints;
var map;
var poly;
var RouteName;
var myMarkers = [];
var myMapCentre = new google.maps.LatLng(-41.2954168187213, 174.767133718655);
function DrawMap() {
alert("Generating Points for " + RouteName);// Need this to display
var thisLatLng = myLatLngs[0];
var myOptions = {
zoom: 8,
center: thisLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
MakeMarkers();
RouteLine();
}
function OnSuccess1(response) {
myPositions = new Array();
myString = response;
NumPoints = response.length;
for (var i = 0; i < NumPoints; i++) {
myPositions[i] = response[i];
}
}
function OnError1(response) {
}
function Marker()
{
this.meterId=0;
this.latLng="";
}
function OnSuccess(response) {
myPositions = new Array();
myString = response;
NumPoints = response.length;
alert("Numpoints is " + NumPoints);
for (var i = 0; i < NumPoints; i++) {
myPositions[i] = response[i];
}
alert("Exiting OnSuccess");
//MakeLatLngs(); //ORIGINAL POSITION OF LATLNG CALL
return true;
}
function setRoute() {
RouteName = prompt(' What route?', '');
}
function OnError(error) {
alert("In Error");
}
function RouteLine() {
var polyOptions = {
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
var path = poly.getPath();
for (var i = 0; i < NumPoints; i++) {
path.push(myLatLngs[i]);
}
}
function MakeLatLngs() {
alert("You need me now " );//Got to have this to display OK when called from LoadData
myLatLngs = new Array();
for (var i = 0; i < NumPoints; i++) {
var sMarker = myPositions[i];
var SeqPos = sMarker.indexOf(";");
var latLngPos = sMarker.indexOf(";", SeqPos + 1);
var marker = sMarker.substring(0, latLngPos);
//alert("Marker is " + marker);
//var Seq = sMarker.substring(latLngPos + 1, SeqPos - latLngPos);
myTitles[i] = marker;
//alert("MeterId is " + marker);
var sLatLng = sMarker.substring(latLngPos + 1)
//alert("SLatLng is " + sLatLng);
var pos = sLatLng.indexOf(",");
//alert("pos is " + pos);
var sLat = sLatLng.substring(0, pos);
//alert("sLat is " + sLat);
var sLng = sLatLng.substring(pos + 1, sLatLng.length - 1);
//alert("sLng is " + sLng);
var lat = parseFloat(sLat);
var lng = parseFloat(sLng);
//alert("Lat is " + lat + " Long is " + lng);
if (!isNaN(lng) && !isNaN(lat) && lat != 0 && lng != 0 ) {
var latlng = new google.maps.LatLng(lat, lng);
myLatLngs[i] = latlng;
}
}
alert("Exiting MakeLatLngs")
}
function MakeMarkers() {
for (var i = 0; i < NumPoints; i++) {
var sTitle = "MyValue " + i;
var marker = new google.maps.Marker({
position: myLatLngs[i],
map: map,
title: myTitles[i]
});
}
}
function LoadData() {
setRoute();//Get the desired route from the user
PageMethods.GetMarkers(RouteName, OnSuccess, OnError);
MakeLatLngs(); //Works here ONLY WHEN AN ALERT IS FIRST LINE in FUNCTION. Orginal call was at end of OnSuccess
//PageMethods.GetRouteBoundaries(OnSuccess1, OnError1);
return false;
}
function initialize() {
LoadData();
DrawMap();
}
google.maps.event.addDomListener(window, 'load', initialize);//yes you do need this with or without <body onload="initialise">
The reason is that your PageMethods.GetMarkers is asynchronous, so the data hasn't loaded when you invoke DrawMap. I guess when you use the alert, it pauses execution long enough for the data to load. Put the DrawMap method inside the OnSuccess of the page method, and that should solve the problem.