Meteor and Populating an Array with Values - javascript

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
}
});

Related

Get coordinates from title in Mapbox GL JS

Is it possible to get a marker/point's coordinates, based on it's title?
I'm, loading in several points, which all have specific IDs as their title.
What i need now, is the ability to flyTo one of these markers when i enter the view and one is highlighted.
I'm highlighting with the below function, and would like to implement the flyTo in it.
$scope.$on('$ionicView.afterEnter', function(){
if(ShowOnMap.story()){
var storyId = ShowOnMap.story();
map.setFilter("highlight", ["==", "title", storyId]);
map.flyTo({
center: [---->storyId<-----],
zoom: 18
});
ShowOnMap.setStory(false);
}
});
So all i need, is a way to get the position(coordinates) of the point, based on the ID/Title i receive.
Bonus info: The storyID is sent from another view, and i am currently not able to send the coordinates and would like to avoid requesting the coordinates from server, based on ID.

redraw markers and clusters after location was inserted into collection

I have a map where my markers and clusters are rendered with leaflet. I have a collection where I have stored information like latitude/longtitude.
I iterate over the collection like this to insert the markers in
in Template.map.rendered
Locations.find({}).forEach(function(obj){
console.log("Adding: lat " + obj.latitude + " - long " + obj.longtitude);
var m = L.marker([obj.latitude,obj.longtitude]);
markers.addLayer(m);
});
How can I also draw new inserted locations after the template was finished rendering that the map will be live updated?
Exactly the same as you do in your template. If you have a reference to the MarkerCluster layer (i'm assuming markers), just use the addLayer method of the layer:
markers.addLayer(L.Marker([0,0]);
If you want to bulk add markers you can use the method addLayers:
markers.addLayers([
L.Marker([0,0]),
L.Marker([1,1])
]);
MarkerCluster will take care of the rest, you can also animated the new inserts by using animateAddingMarkers in the options when instanciating the MarkerCluster:
new L.MarkerClusterGroup({
'animateAddingMarkers': true
});
animateAddingMarkers: If set to true then adding individual markers to the MarkerClusterGroup after it has been added to the map will add the marker and animate it in to the cluster. Defaults to false as this gives better performance when bulk adding markers. addLayers does not support this, only addLayer with individual Markers.
Check the README.MD on their Github: https://github.com/Leaflet/Leaflet.markercluster

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.

Passing googlemapsv3 through web sockets?

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);
});

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