I am building an widget where user can upload an excel file and the places are get marked in the google map.
The following code works, but issue comes when i am reading an large excel file with 10k amount of data, the browser gets stuck. I am using a for loop and adding some timeout to get the data from the google api.
I pass the city name and get the latitude and longitude and mark it on the map.
Is there a better way i can implement?
Here is the code:
function googleMapsInit(widId, $scope, $http, $rootScope, $mdDialog) {
$scope.finish = function() {
var objIndex = getRootObjectById(widId, $rootScope.dashboard.widgets);
$mdDialog.hide();
document.getElementById('map').innerHTML = "";
//excel data
var array = JSON.parse($rootScope.json_string);
$scope.locationData = [];
//dividing it to chunks
var k,j,temparray,chunk = 8;
for (k=0,j=array.length; k<j; k+=chunk) {
temparray = array.slice(k,k+chunk);
var i;
//getting the longitude and latitude from the google geo api
for(i=0;i < temparray.length ; i++){
Geocode(temparray[i].PLACE_OF_ACCIDENT);
}
}
//sometimes data gets delayed
setTimeout(function(){ googleMap(); }, 5000);
};
function Geocode(address) {
var obj = {};
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': address}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
obj = {
lat : results[0].geometry.location.G,
lng : results[0].geometry.location.K
};
setTimeout(function(){ $scope.locationData.push(obj); }, 100);
}
else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(function() {
Geocode(address);
}, 100);
}
else if (status === google.maps.GeocoderStatus.ZERO_LIMIT) {
setTimeout(function() {
Geocode(address);
}, 100);
}
else {
}
});
}
function googleMap() {
var dataStore = $scope.locationData;
var array = JSON.parse($rootScope.json_string);
var map = new google.maps.Map(document.getElementById('map'),{
center: {lat: 7.85, lng: 80.65},
zoom: 6 });
var pinImageGreen = new google.maps.MarkerImage("http://maps.google.com/mapfiles/ms/icons/green-dot.png");
var pinImageBlue = new google.maps.MarkerImage("http://maps.google.com/mapfiles/ms/icons/blue-dot.png");
var marker = [];
var k;
for(k=0; k < array.length; k++){
marker[k] = new google.maps.Marker({
position: {lat: $scope.locationData[k].lat, lng: $scope.locationData[k].lng},
map: map,
title: array[k].PLACE_OF_ACCIDENT,
icon: pinImageGreen,
VEHICLE_TYPE: array[k].VEHICLE_TYPE,
VEHICLE_USAGE: array[k].VEHICLE_USAGE,
VEHICLE_CLASS: array[k].VEHICLE_CLASS
});
marker[k].addListener('click', function(data) {
var j;
for(j=0;j<array.length;j++){
if(($scope.locationData[j].lat == data.latLng.G) && ($scope.locationData[j].lng == data.latLng.K )){
document.getElementById("details").innerHTML =
array[j].PLACE_OF_ACCIDENT + "</br>" +
array[j].VEHICLE_TYPE + "</br>" +
array[j].VEHICLE_USAGE + "</br>" +
array[j].VEHICLE_CLASS + "</br>" ;
}
}
});
}
}
$scope.cancel = function() {
$mdDialog.hide();
};
}
One way to slightly improve performance is this: Instead of adding markers to the map one at a time, just create the markers array separately and then add them all at once to the map. Here is a sample code:
var markersData = [];
for (var i = 0; i < myArray.length; i++) {
var item = scope.myArray[i];
if (item.lat != undefined && item.lon != undefined) {
var icon = 'icon.png';
markersData.push({
lat: item.lat,
lng: item.lon,
title: 'xyz'
});
}
}
map.addMarkers(markersData);
By the way I have used "gmaps.js" for this which simplifies coding google maps, but you don't necessarily need it. The general idea is to avoid adding markers to the map inside the loop, one by one.
Related
I have included google map for the project that I'm working with. I have few checkboxes which are dynamic and when click on a checkbox according to that those locations will be displayed on google map. As follows: The thing is it is not refreshing and remove the previous markers when I check or uncheck those checkboxes again and again.
Vue Component:
<div v-for="vnos in vehicle_nos">
<input class="" type="checkbox" name="vehicle_num" :value="vnos.name" v-model="vehicle_nums" #change="getVehicleNumbers(vehicle_nums)">
<label for="vehicle_num">{{vnos.name}}</label><br>
</div>
functions I trigger:
getVehicleNumbers(vehicle_num){
this.allSelectedVehicles = vehicle_num;
axios.post('gps/get-gps-location/'+this.allSelectedVehicles)
.then(response => {
for (let i = 0; i < response.data.data.length; i++) {
this.all_data = JSON.parse(response.data.data[i]);
this.longtitudes = this.all_data.item.pos.x;
this.latitudes = this.all_data.item.pos.y;
let longlatitude = this.latitudes+','+this.longtitudes;
this.geocoder = new google.maps.Geocoder;
this.infowindow = new google.maps.InfoWindow;
//here I pass those coordinates to geocodeLatLng() function
this.geocodeLatLng(this.geocoder, this.map, this.infowindow, longlatitude);
}
}).catch(Erors => {
console.log('errors');
});
},
geocodeLatLng(geocoder, map, infowindow, longlatitude = null) {
var input = longlatitude;
var latlngStr = input.split(',', 2);
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
//latlng looks like '6.916333,79.861018' this
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: latlng,
map: map,
});
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
} else {
// alert('No results found');
}
} else {
// alert('Geocoder failed due to: ' + status);
}
});
},
In my controller I pass the data as an array to the response in axios.post('gps/get-gps-location/'+this.allSelectedVehicles) this one.
Then I loop all those and set markers one by one. But what I need is to remove all markers from the google map and display the upcoming response data. It's not removing and shows the upcoming markers as well as existing markers also. So there are few markers on same point.
I tried most of the given examples and links on stackoverfow also but couldn't able to find a better solution. Your help is appreciated a lot.
Finally changed the previous code and can be used it as follows
getVehicleNumbers(vehicle_num){
this.loading = false;
if (vehicle_num.length == 0) {
this.allSelectedVehicles = 0;
} else {
this.allSelectedVehicles = vehicle_num;
}
axios.post('gps/get-gps-location/'+this.allSelectedVehicles)
.then(response => {
this.deleteMarkers();
for (let i = 0; i < response.data.data.length; i++) {
this.all_data = JSON.parse(response.data.data[i]);
this.longtitudes = this.all_data.item.pos.x;
this.latitudes = this.all_data.item.pos.y;
let longlatitude = {lat: this.latitudes, lng: this.longtitudes};
this.addMarker(longlatitude);
this.loading = true;
}
}).catch(Erors => {
this.loading = true;
});
},
addMarker(location) {
let marker = new google.maps.Marker({
position: location,
map: this.map,
});
this.markersArray.push(marker);
},
setMapOnAll(map) {
for (var i = 0; i < this.markersArray.length; i++) {
this.markersArray[i].setMap(map);
}
},
clearMarkers() {
this.setMapOnAll(null);
},
deleteMarkers() {
this.clearMarkers();
this.markersArray = [];
},
Once check the checkbox then it'll trigger getVehicleNumbers function. and through that the markers will be shown in the map. And if the checkbox is unchecked again the function will trigger and reset the map. then it'll show the new markers only.
Hi everyine please help me, I am trying to do a search filter on my vehicle tracking, the flow is, the servlet queries all data when there is no parameter filter is being sent by ajax. for example, I do have 5 data on query result so there will be 5 markers on the map, the ajax runs every two seconds so when I request a parameter for example only this spesific vehicle would be shown the query result would only be one, supposedly only marker on the screen, but the previous markers are not vanishing and keep up on the screen. how can I reset the markers into 0? can anyone please help me thanks! here is my code
<script type="text/javascript">
var values = [];
var map;
var markers = [];
function initMap()
{
var options = {
center: {lat: -33.890542, lng: 151.274856},
zoom: 4
};
map = new google.maps.Map(document.getElementById('map'), options);
var count = 0;
setInterval(function() {
getGps();
for(var i = 0; i <= markers.length; i++){
markers[i].setPosition(new google.maps.LatLng(values[count][1],values[count][2]));
count++;
}
}, 2000);
}
function removeMarkers(){
for(var i=0; i<markers.length; i++){
markers[i].setMap(null);
}
markers=[];
}
function getGps() {
xmlhttp.onreadystatechange=function() {
if( xmlhttp.readyState==4 && xmlhttp.status==200 ) {
removeMarkers();
var res = xmlhttp.responseText;
console.log(res);
var split1 = res.split("|");
if(split1[0] != "NOK"){
for(var i = 0; i < split1.length; i++){
var split2 = split1[i].split(",");
String(split2);
var holder1 = holder = [split2[0],split2[1],split2[2]];
values.push(holder1);;
var marker1 = marker = new google.maps.Marker({map: map, icon: 'images/mapvehicle.png', draggable: true});
markers.push(marker1);
}
}
}
};
xmlhttp.open("POST","GpsPost",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("txtTerminal="+document.getElementById('txtTerminal').value+"&txtMerchant="+document.getElementById('txtMerchant').value+"&txtAccount="+document.getElementById('txtAccount').value);
}
add this function and call it after this line .
if( xmlhttp.readyState==4 && xmlhttp.status==200 ) {
function removeMarkers(){
for(i=0; i<markers.length; i++){
markers[i].setMap(null);
}
markers=[]
values=[]
}
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.
I have a problem because i want to use this Json Result that returns Json List but my problem is how should i call the json result that i will be using to geocode and add marker to my Google Maps ? I used getJson and its not functioning but i dont tried yet the .ajax function
Here is my sets of codes:
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
var minZoomLevel = 4;
var zooms = 7;
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById('map'), {
zoom: minZoomLevel,
center: new google.maps.LatLng(38.50, -90.50),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Bounds for North America
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(15.70, -160.50),
new google.maps.LatLng(68.85, -55.90)
);
// Listen for the dragend event
google.maps.event.addListener(map, 'dragend', function () {
if (strictBounds.contains(map.getCenter())) return;
// We're out of bounds - Move the map back within the bounds
var c = map.getCenter(),
x = c.lng(),
y = c.lat(),
maxX = strictBounds.getNorthEast().lng(),
maxY = strictBounds.getNorthEast().lat(),
minX = strictBounds.getSouthWest().lng(),
minY = strictBounds.getSouthWest().lat();
if (x < minX) x = minX;
if (x > maxX) x = maxX;
if (y < minY) y = minY;
if (y > maxY) y = maxY;
map.setCenter(new google.maps.LatLng(y, x));
});
// Limit the zoom level
google.maps.event.addListener(map, 'zoom_changed', function () {
if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
});
}
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
function codeAddress() {
var infowindow = new google.maps.InfoWindow();
$.getJson("Dashboard/DashboardIndex",null , function(address) {
$.each(address, function () {
var currVal = $(this).val();
address.each(function () {
geocoder.geocode({ 'address': currVal }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
icon: iconBase + 'man.png',
position: results[0].geometry.location,
title: currVal
})
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(currVal);
infowindow.open(map, marker);
}
})(marker, currVal));
address.push(marker);
}
else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(codeAddress, 2000);
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
});
});
});
return false;
}
window.onload = function () {
initialize();
codeAddress();
}
</script>
And my JsonResult at my Controller
public JsonResult LoadWorkerList()
{
var workerList = new List<Worker_Address>();
// check if search string has value
// retrieve list of workers filtered by search criteria
var list = (from a in db.Worker_Address
where a.LogicalDelete == false
select a).ToList();
List<WorkerAddressInfo> wlist = new List<WorkerAddressInfo>();
foreach (var row in list)
{
WorkerAddressInfo ci = new WorkerAddressInfo
{
ID = row.ID,
Worker_ID = row.WorkerID,
AddressLine1 = row.Address_Line1 + " " + row.Address_Line2+ " " +row.City + " "+ GetLookupDisplayValById(row.State_LookID),
LogicalDelete = row.LogicalDelete
};
wlist.Add(ci);
}
return Json(wlist.ToList().OrderBy(p => p.AddressLine1), JsonRequestBehavior.AllowGet);
}
Im thanking some who could help me in Advance :)
It's hard to guess where it goes wrong since you didn't post the JSON format and are getting errors (toLowerCase) of code you haven't posted. I think it's in the following area:
function codeAddress() {
var infowindow = new google.maps.InfoWindow();
$.getJson("Dashboard/DashboardIndex",null , function(address) {
console.log("full json object",address);//<--should show an array of objects
$.each(address, function () {
console.log(this);//<--here you can see what the JSON object is
var currVal = this["AddressLine1"];//<--guess from what your C# code looks like
//next each doesn't make much sense unless you have an array of arrays
// but the C# code makes json for a list (not a list of lists)
You can use IE for your console output but don't bother posting the output here because I can already tell you it's going to be [Object, object]. To get useful info you're going to have to use firefox with firebug or Chrome. To see the console you can press F12
The line:
setTimeout(codeAddress, 2000);
Could be optimized since now when you are making too many requests you'll fetch the entire address list again and start from the beginning instead of "waiting" for 2 seconds and continue where you were.
The following code:
map.setCenter(results[0].geometry.location);
Why set the center of the map within the loop? It'll just end up having the center of the last found address so you may as well do it outside the loop to set the center to last found address.
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.