Passing googlemapsv3 through web sockets? - javascript

Is it possible to pass a googlemap through a web socket like this? (from client)
var mapOptions = {
center: pathCoordinates[0],
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var gmap = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
$(function(){
socket.emit('smap', pathCoordinates, data, gmap);
});
I am trying to pass my map to the server side code where it can use it to plot new markers on it. I'm getting this error with the way it's currently set up:
Uncaught TypeError: Converting circular structure to JSON

When passing objects via web-sockets, the object gets converted into a JSON string. The particular error Converting circular structure to JSON is due to the object gmap containing circular references, which JSON.stringify does not support.
Furthermore, JSON does not support functions, so even if you could pass the gmap object to the server, calling gmap.doSomething wont work, as the functions are not preserved.
A better solution would be to pass marker data to the client, and have the client plot it on the map:
socket.on('data', function(markerData){
map.doSomething(markerData);
});

Related

How to pass LatlngBounds object to nodejs server using javascript

I want to pass a LatlngBounds object from a client to nodejs server.
var bounds = map.getBounds();
socket.emit('sendbounds', bounds);
In the server:
socket.on('sendbounds',function(data){
console.log(data);
data.getNorthEast();// undefined method getNorthEast()
}
The server can get the data sent from the client. However I am unable to use method getNorthEast().
My solution is to create an object LatlngBounds:
bounds = new google.maps.LatLng(data.Ea.k, data.va.j),
new google.maps.LatLng(data.Ea.j, data.va.k));
However this is not recommended because we cannot sure the key names are always 'Ea' and 'va'.
I notice that sometimes the key names are "Fa" and wa". They are "undocumented properties". They change with API releases.
Any solution to solve this problem?
I tried it that way, too, but had the same problem: Can't rely on the variable names.
Instead, I passed it to the server as a string instead of an object:
corners = map.getBounds();
var c = corners.toString();`
Then use whatever AJAX library to send the string to the server.
It looks something like this:
((33.94310833405608, -118.44952616442868), (33.985820303992334, -118.34120783557125))
You will have to pick it apart using a regexp, but at least it's reliably formatted.

Meteor and Populating an Array with Values

I'm playing around with Meteor and I'm having trouble trying to wrap my head around a few concepts. One of the issues I'm currently dealing with is I'm trying to build a dynamic heat map using Google and Meteor. I've got an external to Meteor Mongo database (i.e. not the local MongoDB that Meteor provisions) located on my computer and within the database I've got a collection that has many documents, each document has a latitude value and a longitude value.
The problem I've having right now is that when I try and parse through the result set of the find() on my collection it's not getting populated and therefore my heatmap values aren't being drawn onto the screen. However, when I run the same command on the console I can get results. I figure the code and the data retrival running at the same time and one is beating out the other.
//Global scope
DestinationCollection = new Meteor.Collection("Destinations");
destinations = DestinationCollection.find();
if (Meteor.isClient) {
Template.searchMap.rendered = function () {
var airportData = [];
var mapOptions = {
zoom: 3,
center: new google.maps.LatLng(45.4158, -89.2673),
mapTypeId: google.maps.MapTypeId.HYBRID,
mapTypeControl: false,
panControl: false,
streetViewControl: false
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var airportArray = new google.maps.MVCArray([]);
destinations.forEach(function(destination){
airportArray.push(new google.maps.LatLng(destination.Geolocation.Latitude, destination.Geolocation.Longitude));
});
var heatmap = new google.maps.visualization.HeatmapLayer({
data: airportArray,
radius: 20
});
heatmap.setMap(map);
};
}
The only solution I've come up with is to wrap the destinations.forEach with Deps.autorun:
Deps.autorun(function(){
destinations.forEach(function(destination) {
airportArray.push(new google.maps.LatLng(destination.Geolocation.Latitude, destination.Geolocation.Longitude));
});
});
This works but whenever I add a new document to the collection the count doubles and increases by 1. For example, if I had 10 items and I added 1 more to the collection the MVCArray would have 21 array elements rather than just 11.
Long story short, what is the proper way to get a collection, parse through a local collection initially and then only get the new value that was added to the collection rather than the entire thing again.
Look into observe or observeChanges (docs) rather than Deps.autorun:
destinations.observe({
added: function (doc) {
airportArray.push(new google.maps.LatLng(doc.Geolocation.Latitude,
doc.Geolocation.Longitude));
// Add code to refresh heat map with the updated airportArray
}
});

Reload points on a Map in using the Google Maps API v3

I'm trying to reload points on a map based on when someone clicks a button.
I have a couple json objects saved in memory, "data" and "data2". The following code takes the "data2" JSON file and sets it equal to the "data" JSON file and then triggers a map reload event.
dataholder = data
function myFunction() {
data = dataholder
window.data = data2;
google.maps.event.trigger(map, 'resize');
}
Currently, the map won't reload with the new set of data. However, I am not getting any error messages.
There's no map reload event. The resize event, when it comes from a window resize, will at most recalculate the map bounds and reproject the existing features (markers, polylines, polygons). For this case in particular, I don't think that manually triggering the resize event will have any effect.
In second place, you say you have two json files, but your code suggest you instead have two json objects already in memory (meaning you don't need to perform aditional requests to retrieve the value of data2). The rest of the answer will assume that.
If your original collection of markers came from "data", which is a collection of LatLng pairs, and you want to replace the markers for the contents of "data2" the process would be:
1.- Push the markers into an object where you can find them later on
var markers=[];
for(onemarker in data) {
var newmarker=new google.maps.Marker({map: map, position: new google.maps.LatLng({onemarker.lat, onemarker.lng}) });
markers.push(newmarker);
}
2.- When you want to replace the markers, first purge the markers array
while(markers.length) {
var oldmarker=markers.pop();
oldmarker.setMap(null);
};
3.- Fill the markers array with the data from the data2 object
for(onemarker in data2) {
var newmarker=new google.maps.Marker({map: map, position: new google.maps.LatLng({onemarker.lat, onemarker.lng}) });
markers.push(newmarker);
}
For this kind of markers, as for the regular features, there's no instantaneous binding between the object and the underlying data. This is slightly different for the new google.maps.Data() layer for which you can skip the iteration and just feed it a geoJSON array. You still need to have an object to store the current markers, or else you won't have a way to access them when you want to remove them.

Can't save polygon in google maps

I have a google maps polygon object:
var poly = new google.maps.Polygon({
paths: [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.75737)
]
});
I'm trying to send it to MySQL db via jquery's AJAX:
$.post("savePolygon.php", {polygon: poly});
I get this error in console:
TypeError: Cannot call method 'lat' of undefined
I've seen some other posts about saving polygons, and they all say to extract the latLng's from the poly's and save them in a db. When I do this though:
var latLngs = poly.getPath().getArray();
$.post("savePolygon.php", {polygon: latLngs});
I get the same error. It seems there is a function in array's prototype called 'lat'. I'd like to know how exactly can I extract those values and send them via AJAX, and also why do I get this error?
Use google.maps.geometry.encoding.encodePath() to encode the path. This method returns a string, perfect for storing into a DB. For reuse decode the string by using google.maps.geometry.encoding.decodePath()
Please note: the geometry-library isn't loaded by default, you must load it by appending &libraries=geometry to the src of the maps-API-script.
To explain why you can't store the path directly(e.g. as JSON):
when you store the path(array), which contains the LatLng's, you will lose the prototype of the LatLng's, which is essential because it defines the methods for retrieving the properties(lat() and lng() )

Fetching data from database every five seconds to Google Map

I am developing a Google maps application, latitudes and longitudes are coming from external device and storing into the database for every five seconds.
So I have to query the database every five seconds and get the new latitude and longitude of the database and moving the marker according to that.
How it can be done? Is it good to write ajax call?
Here is an example that pulls data every few seconds and replots the markers: http://www.robotwoods.com/dev/so_septa.html
here's the PHP it's calling:
<?php
$route=(isset($_REQUEST['route']))?$_REQUEST['route']:23;
echo file_get_contents("http://www3.septa.org/transitview/bus_route_data/".$route);
?>
I will guide you in the right way. I guess I could do that atleast:
a) You could have a function that queries your server at intervals using ajax (check out a library like jquery) and in the callback function of the function process the response.
b) your server will send a response to the server Ideally it will be a json response of the form
{
id:<>,
lat:
lng:
}
c) walk through google maps api to see how you can remove markers etc. you can probably maintain hash of markers in an associative array like markers[key] where key will be the identifier of a marker, if and when the marker updates you can use this associative array to remove the marker as:
markers[id].setMap(null);
Code to add markers in callback:
var options = {
position: new google.maps.LatLng(lat, lng);,
icon: image,
zIndex: zIndex,
};
options.map=map;
var marker = new google.maps.Marker(options); //construct marker
markers[key] = marker; //store the marker in array

Categories

Resources