Leaflet: How to add multiple markers onto featureGroup - javascript

I am trying to do something like : https://github.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/blob/master/demo-group.gif
where I have multiple markers.
In the example code https://github.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/blob/master/demo-group.html
each location has been manually added using
var trd = [63.5, 11],
mad = [40.5, -3.5],
lnd = [51.5, -0.5],
ams = [52.3, 4.75],
vlc = [39.5, -0.5];
var route = L.featureGroup([
L.marker(trd),
L.polyline([trd, ams]),
L.marker(ams),
L.polyline([ams, lnd]),
L.marker(lnd),
L.polyline([lnd, mad]),
L.marker(mad),
L.polyline([mad, vlc]),
L.marker(vlc)
]);
My question is, if I have many markers (e.g. 500 markers), how can I create the route without manually adding each marker and polyline to the L.featureGroup.
var bounds = new L.LatLngBounds();
for (var i = 0; i < mTool.length; i++) {
var loc = new L.LatLng(mTool[i].lat, mTool[i].lon);
bounds.extend(loc);
var marker = new L.Marker(loc);
map.addLayer(marker);
}
map.fitBounds(bounds);

EDIT: What you want to do is provided by the same github project of IvanSanchez. Please read demo.html instead of demo-group.html
This is easily done by looping through an array of markers, as you rightly hinted at it. The code could be as below:
var markers = [[63.5, 11],
[40.5, -3.5],
[51.5, -0.5],
[52.3, 4.75],
[39.5, -0.5]];
var route = L.featureGroup().addTo(map);
var n = markers.length;
for (var i = 0; i < n-1; i++) {
var marker = new L.Marker(markers[i]);
var line = new L.polyline([markers[i],markers[i+1]]);
route.addLayer(marker);
route.addLayer(line);
};
route.addLayer(new L.Marker(markers[n-1]));
map.fitBounds(route.getBounds());
I created a working example on gist (here).

Related

How get coordinates from polygons inside a Layer

I have a LayerGroup
var mapLayer = new L.layerGroup();
This is how I add several polygons to this LayerGroup:
var buffered = turf.buffer(polyline, path_alarmweight, 'meters');
bufferedPolygon = L.geoJson(buffered, bufferedOptions).addTo(mapLayer);`
How can I get the coordinates from a single or several polygons which I added to the mapLayer?
First of all you need to get all layers from LayerGroup, use getLayers() function, in documentation. You will get layers in LayerGroup:
var arrayOfLayers = mapLayer.getLayers();
Then you can iterate over arrayOfLayers and for every layer you can get coordinates of polygon with getLatLngs() function. See the reference:
for(var i=0; i < arrayOfLayers.length; i++) {
// first get array of coordinates
var arrayOfPoints = arrayOfLayers[i].getLatLngs();
//then iterate over coordinates
for(var j=0; j < arrayOfPoints.length; j++) {
console.log(arrayOfPoints[j]);
}
}

Using XMLHttpRequest to load KML google maps, cannot load KML

I have to use XMLHttpRequest to grab a kml file, because I cannot directly make changes to the KML and needed to draw out polygons with their own separate infowindows with details on them that is stored in the KML but not as a description tag or anything like that so I couldn't just grab it easily. I managed to do this, and the polygons display and the infowindows work. Its a sizable program so I didn't display it here, but basically when I load the getKML function of mine, it would not work in the development environment or present issues. Whereas it would work well on my localhost.
This is the error message I keep getting:
Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://someURL/polygons_live.kml'.
Heres the code, you really only need the first couple lines to look at because thats where xmlhttprequest is used, also excuse me for the messy code, still an intern and refactoring:
/** Calls using xmlhttprequest to grab the kml file
* and later prints it out as one or more polygons
*/
function getKML(kmlUrl) {
var xmlRequest = new XMLHttpRequest();
xmlRequest.open("GET", kmlUrl, false);
xmlRequest.send();
xmlDoc = xmlRequest.responseXML;
var x = xmlDoc.getElementsByTagName("Placemark");
// travels through each Placemark tag in the kml files
var outage_time, restoration_time, event_number_value, fillColour, borderColour;
var objArray = [];
for (var i = 0; i < x.length; i++) {
// uses momentjs api to create human readable dates
var date_format = "MMM DD, hh:mm a";
// gets the event number
event_number_value = x[i].getElementsByTagName("SimpleData")[2].childNodes[0].nodeValue;
// gets outage start time
var outage_time_value = x[i].getElementsByTagName("SimpleData")[3].childNodes[0].nodeValue;
var outage_time_moment = moment(outage_time_value);
outage_time = outage_time_moment.format(date_format);
// gets estimated restoration time
var restoration_time_value = x[i].getElementsByTagName("SimpleData")[5].childNodes[0].nodeValue;
// checks to see if we have a restoration time or not
if (restoration_time_value === "2001-01-01T00:00:00") {
restoration_time = "Not yet determined";
} else {
var restoration_time_moment = moment(restoration_time_value);
restoration_time = restoration_time_moment.format(date_format);
}
// gets the coordinates of the polygon
var coords = x[i].getElementsByTagName("coordinates")[0].childNodes[0].nodeValue;
var coordinate = coords.split(",0 ");
var coordJoined = coordinate.join();
var coordAgain = coordJoined.split(",");
// gets the colour of the polygon
var colour = x[i].getElementsByTagName("styleUrl")[0].childNodes[0].nodeValue;
// determines the colour out of yellow, orange and red
if (colour === "#Style1") {
fillColour = '#f1c40f';
borderColour = '#f1c40f';
} else if (colour === "#Style2") {
fillColour = '#e67e22';
borderColour = '#e67e22';
} else {
fillColour = '#c0392b';
borderColour = '#c0392b';
}
// creates objects and adds it to array to be later used as data
var obj = {
eventID : event_number_value,
offTime : outage_time,
restoreTime : restoration_time,
fill : fillColour,
borderCol : borderColour
};
objArray.push(obj);
// create a LatLng array out of the coordinate string
var polygonCoords = new Array();
var j = 0;
var z = j + 1;
//var firstCoord = new google.maps.LatLng();
while (z < coordAgain.length) {
// adds the first and last latLng to the array of polygonCoords
if ((j % 2) == 0) {
var co1 = parseFloat(coordAgain[z]);
var co2 = parseFloat(coordAgain[j]);
var newLatLng = new google.maps.LatLng(co1, co2);
polygonCoords.push(newLatLng);
} else {
var co1 = parseFloat(coordAgain[j]);
var co2 = parseFloat(coordAgain[z]);
var newLatLng = new google.maps.LatLng(co1, co2);
polygonCoords.push(newLatLng);
}
j++;
z++;
}
//removes last coordinate as its useless as its not a number
polygonCoords.pop();
/** Adds the polygon to a polygon array
* and maps it onto the map
*/
var newPoly = new google.maps.Polygon({
paths : polygonCoords,
strokeColor : objArray[i].borderCol,
strokeOpacity : 0.35,
strokeWeight : 2,
fillColor : objArray[i].fill,
fillOpacity : 0.35
})
newPoly.setMap(map);
newPoly.set("eventNum", objArray[i].eventID);
newPoly.set("offTime", objArray[i].offTime);
newPoly.set("resTime", objArray[i].restoreTime);
google.maps.event.addListener(newPoly, 'click',
attachInfoWindow(newPoly));
polyArray.push(newPoly);
}
}
Update 1: I actually found this error later on appearing in my console:
XMLHttpRequest cannot load https://someurl/polygons_live.kml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://someurl' is therefore not allowed access.
Its a cross-domain request issue, I'm going to start using relative addresses to point to when grabbing my kml.
It resolved my issue.

How would i iterate over a polygon?

I am reading a polygon using OpenLayers by
var features = format.read(strGML);
This is the GML string structure
<gml:featureMember xmlns:gml="http://www.opengis.net/gml xsi:schemaLocation="http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<feature:feature xmlns:feature="http://example.com/feature">
<feature:geometry>
<gml:Polygon>
<gml:exterior>
<gml:LinearRing>
<gml:posList>591674.39 5022898.05 545682.5 4722908.1 571701.44 5322909.29 651691.25 5022904.6 591674.39 5022898.05
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</feature:geometry>
</feature:feature>
After reading (which works) I need to iterate over each point of this polygon and read coordinates. I tried with various attempts with for...in, but can't get it to work. What would be the correct way to do this?
Anyways, I found a solution:
var newPoints = [];
var feature = features[0];
var points = feature.geometry.getVertices();
for (var i=0; i<points.length; i++) {
var lon = points[i].x;
var lat = points[i].y;
var point = new OpenLayers.Geometry.Point(lon, lat);
// do something with Points
newPoints.push(point);
}

Sort computed areas

I have a google maps and I get all markers that are close a locaton (lat, lng).
This point is OK.
Now i want to sort theses markers, like in SQL we can do a "order by distance ASC" for example.
I saw in javascript have a method call sort() which can sort some numbers asc or desc for example.
markers have some informations: name, title, gender, city, postcode ...
my code:
var nbMeters = 50000;
for (var i = 0; i < markers.length; i++) {
var myMarker = markers[i];
coord2 = new google.maps.LatLng(myMarker.lat, myMarker.lng);
var distance = google.maps.geometry.spherical.computeDistanceBetween(coords, coords2);
if(distance <= nbMeters) {
alert(myMarker.name);
//OK my marker is close the variable coords, good !
//But how to know which marker is the closer, which is the second, the third ... and the less closer ??
}
}
Have you an idea?
Maybe try sth like this:
for (var i = 0; i < markers.length; i++) {
var myMarker = markers[i];
coord2 = new google.maps.LatLng(myMarker.lat, myMarker.lng);
var distance = google.maps.geometry.spherical.computeDistanceBetween(coords, coords2);
markers[i].distance = distance;
}
function sortMarkers(marker1, marker2) {
return marker1.distance - marker2.distance;
}
markers.sort(sortMarkers);
It's untested and based on http://www.w3schools.com/jsref/jsref_sort.asp

Creating new markers from an array in Javascript google maps API

I am trying to add markers onto a google map to identify the states using:
function initialize() {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(-25.641526,134.472656), 4);
map.setMapType(G_NORMAL_MAP);
map.setUIToDefault();
var states =["-35.083236,138.503909","-24.607069,144.667969","-18.229351,133.417969","-24.686952,123.574219","-32.398516,146.953125","-35.46067,149.150391","-37.020098,143.701172","-42.682435,146.733398"];
for (i = 0; i == states.length; i++) {
var point = new GLatLng(parseFloat(states[i]));
map.addOverlay(new GMarker(point));
}
}
But no markers come up when I load the map (which loads fine, properly centered and of the correct map type). What am I doing wrong here?
EDIT: I changed it to this and now it works:
var lats =[-35.083236,-24.607069,-18.229351,-24.686952,-32.398516,-35.46067,-37.020098,-42.682435];
var longs =[138.503909,144.667969,133.417969,123.574219,146.953125,149.150391,143.701172,146.733398];
for (i = 0; i <= lats.length; i++) {
var point = new GLatLng(lats[i],longs[i]);
map.addOverlay(new GMarker(point));
It looks like a typo in your for loop. Try it as follows:
for (i = 0; i < states.length; i++) {
Also note the float problem that Tomas pointed out.
You are parsing a single float value and try to use that as both latitude and longitude.
This ...
var point = new GLatLng(parseFloat("-35.083236,138.503909"));
won't parse two distinct float values and pass them to the GLatLng. One solution is to split the values in the array:
function initialize() {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(-25.641526,134.472656), 4);
map.setMapType(G_NORMAL_MAP);
map.setUIToDefault();
var states =[-35.083236, 138.503909, -24.607069, 144.667969, ...
for (i = 0; i < states.length; i+=2) {
var point = new GLatLng(states[i], states[i+1]);
map.addOverlay(new GMarker(point));
}
}
Also note that your for loop was incorrect as Daniel pointed out.

Categories