redraw markers and clusters after location was inserted into collection - javascript

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

Related

Highlight an existing business on Google Maps API

I have a list of store addresses, and I'm trying to create a map out of it.
Using the Places API I am able to retrieve most of the informations and manually create and place the markers on the map:
const service = new google.maps.places.PlacesService(map);
service.findPlaceFromQuery({
query: '212 Enterprise Dr, Rockaway, Frank Pizza',
fields: ['all']
}, onPlaceFound);
However I'd like to select the original marker instead of overlapping a new one.
That is because I want the user to be able to open the default info window with store phone number, directions and stuff.
I know that I can re-create it, but it feels kinda lame since all the info is already there.
This SO post ask about the same, yet no solution has been found.
Based on the documentation found here, which shows findPlaceFromQuery(), the second parameter of findPlaceFromQuery should be a function where the first argument of that function is an Array of placeResults.
Therefore, after reviewing a link here and here your onPlaceFound function should be looking something like:
function onPlaceFound(placeResultsArray){
const firstResult = placeResultsArray[0], firstIconURL = firstResult.icon;
const latLng = firstResult.geometry.location, lat = latLng.lat(), lng = latLng.lng();
// do stuff with those variables here
}
Of course, that does not select Google's result as a Marker, but now you have the actual icon, and latitude and longitude.

How to use the viewParams option of a GeoServer layer defined as a SQL View in a Leaflet?

I set up a PostGIS database that I added in GeoServer via a parameterized SQL view. The parameter I set is 'year' : it permits to select only the polygons of my database that have this year as a property.
I know this worked because I can successfully use the layer preview of GeoServer on my layer with the local link : http://localhost:9999/geoserver/cite/wms?service=WMS&version=1.1.0&request=GetMap&viewParams=year:0&layers=cite%3Achoix_annee&bbox=-56.6015625%2C25.16517336866393%2C-16.875%2C47.040182144806664&width=768&height=422&srs=EPSG%3A404000&styles=&format=application/openlayers
The interesting option there is 'viewParams=year:0'.
In Leaflet, I used the following code to import my layer via wms:
<script>
// Find our map id
var map = L.map('map');
var wmsLayer = L.tileLayer.wms('/geoserver/gwc/service/wms', {
layers: 'cartowiki:choix',
format: 'image/png',
transparent: true,
viewparams: 'year:1000'
}).addTo(map);
// Set the map view
map.setView([46.988332, 2.605527], 2);
</script>
It works the first time but then GeoWebCache intervenes and prevents me from getting results fitted to the year I'm asking, it always gives me the results for the first year I asked. I tried to specify the year parameter with a regular expression in the tile caching module of my layer but it doesn't work and I cannot figure out why.
This is a view of my settings in geoserver: geoserver settings
Thanks,
you have to dynamically set viewparams value then refresh wms layer

Find leaflet id of the latest layer created in Leaflet

I am adding layers to a layergroup "drawnitems" using the leaflet draw library
drawnItems.addLayer(L.polygon(polygon));
I need to find the leaflet ID of the layer created using the above code immediately upon it's creation. This happens in a loop. I am adding multiple layers.
My goal is to save shapes that have been edited by the user into the DB. These shapes are previously created and then stored in the DB and then rendered on the map. For this I am planning to use leaflet id assigned to each shape and then find the corresponding db entry using some logic in the "draw:edited" event.
Okey to simply get the ID of the latest layer added you can do the following:
for(layer of polyLayers) {
drawnItems.addLayer(layer);
var leafletId = layer._leaflet_id
};
But I think for your approach that would not be the best solution, because leaflet ID are not stable. It would be better to create layer variables dynamically and assign an ID from you database, where the layers are stored. Then you are able to get every layer by it's database ID (e.g. myPolyLayers[idFromDataBase]). Just do:
var myPolyLayers = {};
for(layer of polyLayers) {
var id = Math.floor((Math.random() * 500) + 1); // The ID from the database
myPolyLayers[id] = layer
drawnItems.addLayer(layer);
//var leafletId = layer._leaflet_id
};
console.log(myPolyLayers[id]) // Get the layer with the ID given before
In this snippet, the ID where I choosed a random number should be the ID from you database.
I solved this. I created a "hashmap" between the database id and the leaflet shapes id (leaflet_id) while loading shapes on the map. Then in the "draw:edited" I found the database id of the object edited by the user with the help of the "key" = leaflet_id. Thus, I was able to save changes made by the user in the same database record.
var polygon = new L.Polygon([
[51.51, -0.1],
[51.5, -0.06],
[51.52, -0.03]
]);
polygon.options.id = 1;
drawnItems.addLayer(polygon);
As simple as get _leaflet_id of your latest layer created, for example as you if I am drawing polygons, for example:
let polygon = L.polygon([<my coords>], {color: 'red'});
// Added this way
let layer = polygon.addTo(this.drawElementsLayer);
// or this way (is the same)
this.drawElementsLayer.addLayer(polygon);
console.log(panelPolygon._leaflet_id) // n
>> 47 (in my eample case).

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.

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