Sort computed areas - javascript

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

Related

Leaflet - Creating LayerGroups Dynamically

Is it possible to create LayerGroups Dynamically? I'm developing an web map that shows the tree species that exists in the parks, an i'm trying to create a LayerGroup for each species so that with a LayerControl i can hide and show certain species, for the sake of testing, i have been creating LayerGroups like this:
l1 = new L.LayerGroup();
//...
l100 = new L.LayerGroup();
And i'm sure that there is a way to do it depending on the number of species that exists, i have tried:
for (var i = 0; i < numberOfSpecies ; i++) {
l[i] = new L.LayerGroup();
}
But this way, i cant do this:
l[0].addLayer(marker);
What is the best way to do something like this?
Yes, you can.
For example:
var layerGroups = {}
for (var i = 0; i < 3; ++i) {
layerGroups[i] = L.layerGroup().addTo(map);
}
for (var i = 0; i < 3; ++i) {
layerGroups[i].addLayer(L.marker([i,i]))
}
You can try it here : https://jsfiddle.net/mckbda9y/6/

Leaflet: How to add multiple markers onto featureGroup

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).

How to compare and alter value for only one of them

I have got different markers .
For some of them, either the longitude or latitude is same .
In case for any of the markers if it has got same longitude or latitude, compared to other markers, I want to increase its latitude size .
But at the end I was ending up changing the coordinates for all the markers
Could you please let me know how to fix this ??
This is my fiddle
This is my code
function checkifgotsameLatitude(response , lator,lotor)
{
var a = 0;
for(var i=0;i<response.length;i++)
{
var latitusevalue = response[i].latitude;
var longitude = response[i].longititude;
if(latitusevalue==lator || lotor==longitude)
{
a++;
}
}
return a ;
}
This works if you want to offset one dealer from another if the difference is smaller than 0.0001 or similar
fiddle
function normaliseLat(num) {
var numDecimals = 4; // precision
return String(num.toFixed(numDecimals)).replace(".", "_");
}
function diffLng(lng, pos, response) {
return Math.abs(response[pos].longitude - lng)
}
var lats = [];
for (var i = 0; i < response.length; i++) {
var lat = parseFloat(response[i].latitude);
var lng = parseFloat(response[i].longitude);
var norm = normaliseLat(lat);
var pos = lats.indexOf(norm);
if (pos!=-1) { // found
if (diffLng(lng,pos,response) < 0.0002) {
lat = parseFloat(lat)+0.00001;
}
}
lats[i]=norm;
I had a look at your fiddle and I think the solution is to compare item N with other items where the index is greater than N. You can do this by passing the starting index to your checkifgotsameLatitude function.
function checkifgotsameLatitude(response , lator,lotor, startIndex)
{
for(var i=startIndex;i<response.length;i++)
{
var latitusevalue = response[i].latitude;
var longitude = response[i].longititude;
if(latitusevalue==lator || lotor==longitude)
{
return true;
}
}
return false;
}
Updated fiddle
EDIT: the function can now return when the first match is found. this will speed things up. Updated fiddle
Something that doesn't appear to be accounted for is if after moving the marker, it then matches another marker. Or if you had more than two overlapping markers, all but one would just move to the same new location. I also changed the "or the same" to "and the same" as that part didn't make sense to me, assuming you are trying to adjust them so they don't overlap. But of course that could be changed back easily. I also changed the float equality to use a range.
I believe this corrects these issues:
Fiddle
while(checkifgotsameLatitude(response,lat,lng))
{
lat = lat+0.222;
response[i].latitude = lat;
}
function checkifgotsameLatitude(response , lator,lotor)
{
var a = 0;
for(var i=0;i<response.length;i++)
{
var latitusevalue = Math.abs(parseFloat(response[i].latitude) - lator) < 0.1;
var longitude = Math.abs(parseFloat(response[i].longititude) - lotor) < 0.1;
if(latitusevalue && longitude)
{
a++;
}
}
return a > 1;
}

Google Maps MarkerClusterer v3 Return Cluster of Marker

I am currently using the Google Maps MarkerClusterer v3 (http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/reference.html) and have been very impressed with the functionality so far.
However, I now wish to add in an additional function to my map. When a user hovers over a list of the markers, the marker image is changed. This works great when the markers aren't clustered, but since I am also using the Clusterer, I need to be able to return the Cluster to which a specific marker belongs.
Does anyone know if this is possible? I checked the API documents, but couldn't find a method to return an array of the Clusters.
Essentially, here is a pseudo-code of what I need to do:
function changeClusterIcon(the_marker)
{
var clusters = _CLUSTERER.getClusters();
var clusters_length = clusters.length;
var marker_pos = the_marker.getPosition().toString();
for(var i = 0; i < clusters_length; i++)
{
var this_cluster = clusters[i];
var the_markers = this_cluster.markers.length;
for(var j = 0; j < the_markers; j++)
{
var this_marker = this_cluster.markers[i];
if(this_marker.getPosition().toString() == marker_pos)
{
return this_cluster;
}
}
}
return false;
}
The MarkerClusterer library does not provide a way to retrieve the clusters. But there is an enhanced version of the library, MarkerClustererPlus, which provides more capabilities. Using MarkerClustererPlusapi-doc, you may use the MarkerClusterer.getClusters() function to retrieve an Array of the Cluster class instances. Then, you may use the Cluster.getMarkers() function to retrieve an Array of the markers that are within that Cluster. And with that, you should have what you need to move forward.
Your function is almost correct, here the proper version:
function changeClusterIcon(the_marker)
{
var clusters = _CLUSTERER.getClusters();
var clusters_length = clusters.length;
var marker_pos = the_marker.getPosition().toString();
for(var i = 0; i < clusters_length; i++)
{
var this_cluster = clusters[i];
var the_markers = this_cluster.markers_.length;
for(var j = 0; j < the_markers; j++)
{
var this_marker = this_cluster.markers_[j];
if(this_marker.getPosition().toString() == marker_pos)
{
return this_cluster;
}
}
}
return false;
}
So the markers property should be called as markers_ and the second foreach uses j instead of i.

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