Create dot density map using Google Maps - javascript

I would like to create a dot density map using Google Maps. I have all the counties of my state outlined, along with their corresponding populations. I want to know how I could place a number of dots randomly within each county to represent the population of that county. We want to make a dot density map instead of a choropleth map because we like the representation better, but I can't figure out how to distribute dots among a polygon outline.
This is a poor example of sort of what I'm looking to make.

Well, I've come to a very inefficient yet suitable solution to my problem. In case anybody would either like to help me improve my method or use it themselves, this is what I did.
I used this answer as a guide to test whether or not a point would fall in a particular polygon. As I create the polygons that outline the border of counties in my state, I add each latitude to one array, and each longitude to another. I then determine min and max values for each array as a bounding box that a point would have to be in in order to fall within the county lines. I then pick random numbers between those mins and maxes and test whether they fall within the county. If they do, I add a marker there. I do those within a loop that counts how many markers are added until it is proportional to the population of that particular county. Here is the code:
function addMarkers() {
var loc = "Resources/CaliforniaCounties.json";
$.getJSON(loc, function (data) {
$.each(data.features, function (key, val) {
var xArray = []; //
var yArray = []; //
var coords = [];
var latlng;
var bounds = new google.maps.LatLngBounds();
var polygon;
$.each(val.geometry.coordinates[0], function (i, item) {
latlng = new google.maps.LatLng(item[1], item[0]);
xArray.push(item[0]); //
yArray.push(item[1]); //
coords.push(latlng);
bounds.extend(latlng);
});
var nverts = xArray.length; //
var maxX = Math.max.apply(null, xArray); //
var maxY = Math.max.apply(null, yArray); //
var minX = Math.min.apply(null, xArray); //
var minY = Math.min.apply(null, yArray); //
polygon = new google.maps.Polygon({
paths: coords,
strokeColor: "#000000",
strokeOpacity: 1,
strokeWeight: 01,
fillColor: "#cccccc",
fillOpacity: .5
});
polygon.center = bounds.getCenter();
addPolygonClickListener(polygon, val);
polygon.setMap(map);
polygonArray[val.properties.Name] = polygon;
var i = 1;
while( i < populations[val.properties.Name] / 10000){
var testX = Math.random() * (maxX - minX) + minX; //
var testY = Math.random() * (maxY - minY) + minY; //
if(pnpoly(nverts, xArray, yArray, testX, testY) == 1){ //
var mlatlng = new google.maps.LatLng(testY, testX); //
var marker = new google.maps.Marker({ position: mlatlng, icon: "Resources/dot.png", map: map }); //
i++;
}
}
});
});
function pnpoly(nvert, vertx, verty, testx, testy)
{
var i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++)
{
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
{
c = !c;
}
}
return c;
}

I have a more efficient way to do this. You can use the same features to create color map, which is second, invisible canvas element. In this, each county is a unique color derived from it's index in the feature list. Using getImageData(), you can get the bit map of the canvas. Then, you can use it to test whether your random, bounding box constrained coordinates fall within the county by checking the color of the colormap at that coordinate. This test is a O(1) operation, where as yours looks like it's O(n).
I am using this technique to create a dot density map of counties in china, and the performance is fine. I started with this guy's code example:
https://gist.github.com/awoodruff/94dc6fc7038eba690f43

Related

Leaflet screen distance to LatLng distance

I want to combine markers based on the zoom level. I'm not using Markercluster but my own algorithm to detect which markers should be combined. This algorithm works perfectly fine. The only thing I have to add is a zoom-based condition when the markers should be combined. Currently, all markers within a distance of 0.001 get combined. What I want is that every marker within a distance of 0.5cm on the screen gets combined. So I need a function that converts a distance in cm, px, or something else into a distance in degree.
An example: On zoom-level 18, two markers with a distance of 0.00005 in the longitude have a distance of nearly 0.3cm on my screen.
EDIT:
So this is what I did:
function in_range(location1, location2, map) {
return get_distance_in_px(location1, location2, map) < 25;
}
function get_distance_in_px(location1, location2, map) {
var p1 = map.latLngToContainerPoint(L.latLng(location1[0], location1[1]));
var p2 = map.latLngToContainerPoint(L.latLng(location2[0], location2[1]));
var a = p1.x - p2.x;
var b = p1.y - p2.y;
return Math.sqrt(a * a + b * b);
}
You can get the containerPoint of the latlngs and then calculate the distance:
map.on('zoomend',(e)=>{
console.log(e);
recalcZoom();
});
var DISTANCE = 20; //px
function recalcZoom() {
var layers = findLayers(map);
var resultLayers = []; //sturcture: {main: layer, childs: [];
layers.forEach((layer)=>{
if(resultLayers.length === 0){ // set the first layer as main layer
resultLayers.push({
main: layer,
childs: []
});
}else{
var found = false;
var mainObj = null;
var lastDis = null;
resultLayers.forEach((rLayer)=>{
var main = rLayer.main;
var p1 = map.latLngToContainerPoint(main.getLatLng());
var p2 = map.latLngToContainerPoint(layer.getLatLng());
var dis = p1.distanceTo(p2);
if(dis <= DISTANCE){ // distance between main layer and current marker is lower then DISTANCE
if(lastDis == null || dis < lastDis) { // a main layer is found, where the distance between them is lower
if(mainObj && mainObj.childs.indexOf(layer) > -1){ // remove the layer from the old main layer childs array
mainObj.splice(mainObj.childs.indexOf(layer),1);
}
rLayer.childs.push(layer);
found = true;
mainObj = rLayer;
}
}
});
if(!found){ // if no main layer is found, add it as new main layer
resultLayers.push({
main: layer,
childs: []
});
}
}
});
console.log(resultLayers);
// Logic to find center of all childs + main
// remove the old layers and add the new clustered layer
// keep in mind, that you have to store somewhere the original markers, else you can't recalc the clusters
}
function findLayers(map) {
// your logic to get the original layers
let layers = [];
map.eachLayer(layer => {
if (layer instanceof L.Marker) {
layers.push(layer);
}
});
return layers;
}
You have to implement by yourself the logic to find center of all childs + main layer, then remove the old layers and add the new clustered layer.
But keep in mind, that you have to store somewhere the original markers, else you can't recalc the clusters.
Little Example: https://jsfiddle.net/falkedesign/ny9s17cb/ (look into the console)
A note from the Leaflet Examples
One of the disadvantages of using a cylindrical projection is that the
scale is not constant, and measuring distances or sizes is not
reliable, especially at low zoom levels.
In technical terms, the cylindrical projection that Leaflet uses is
conformal (preserves shapes), but not equidistant (does not preserve
distances), and not equal-area (does not preserve areas, as things
near the equator appear smaller than they are).
learn more
After that being said you're really getting yourself into so many more problems trying to get the dimension exact where they aren't reliable measurements to start with.

How to traverse an array of 50k accounts and display them on leaflet map?

I have 50k accounts that i have to display on a map as markers. Everything is fine if i call only for maximum 20k accounts but for a larger number of accounts page become unresponsive. I figure out that it take too long to go through all the array of objects. But i don't know how can I optimise the code more.
The elements that are in the loop are not really affect the traverse of the loop. I run it without anything in it and it still takes same amount of time till become unresponsive. The problem is that it has too many element.
Update: i use markerCluster to cluster all the markers. I use canvas in order to be rendered quicker. Also i read that addLayers is better than addLayer and thats why i use a normal list to add all elements and only after to add it in the markerClusterGroup. Map is automatically updated because if i add the markersGroup even if in the first place is empty any modification to the group will be noticed by the map (it has a watcher by default).
When i tested i just saw that the for is too slow.
Map is from leaflet
Thank you in advance
var map = L.map('map', {zoomControl: true, tap: false, preferCanvas:true});
var accounts = event.getParam('accounts');
var markerList = [];
//create a group of markers in order to have control over markers from map
var myRenderer = L.canvas({ padding: 0.5 });
var markers = L.markerClusterGroup( {
chunkedLoading: true,
renderer: myRenderer,
iconCreateFunction: function (cluster) {
var childCount = cluster.getChildCount();
var c = ' marker-cluster-';
if (childCount < 10) {
c += 'small';
}
else if (childCount < 100) {
c += 'medium';
}
else {
c += 'large';
}
return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>',
className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
}
});
map.addLayer(markers);
var markerColor;
var marker_blue = helper.initMarkers ('/resource/markers/markers/marker_blue.png',[30, 40], [22, 44], [-5, -43]);
markerColor = marker_blue;
for (var i=0, len = accounts.length; i<len; i++) {
var account = accounts[i];
var latLng = [account.Latitude, account.Longitude];
var marker = L.marker(latLng, {icon:markerColor},{account: account},{renderer: myRenderer});
markerList.push(marker);
}
markers.addLayers(markerList);

Javascript, finding first significant figure (values ranging from 87.352 to 0.0002432)

I have created a GPS system using coordinates.
I have found the highest and lowest longitude and latitude coordinates using this function:
var maxLng = 0;
var maxLat = 0;
var minLng = 180;
var minLat = 180;
for(var i=0; i<coordinates.length; i++)
{
//get max coordinates (the +90 is to remove negative numbers)
if (coordinates[i][0]+90 > maxLat)
{
maxLat = coordinates[i][0] + 90;
}
if (coordinates[i][1]+90 > maxLng)
{
maxLng = coordinates[i][1]+ 90;
}
//get min coordinates
if (coordinates[i][0]+90 < minLat)
{
minLat = coordinates[i][0] + 90;
}
if (coordinates[i][1]+90 < minLng)
{
minLng = coordinates[i][1] + 90;
}
}
console.log(maxLat, maxLng,minLat, minLng);
//calculate distance between max and min points
var lngDistance = maxLng - minLng;
var latDistance = maxLat - minLat;
console.log(lngDistance, latDistance);
This outputs the distance between the 2 furthest apart longitude and latitude points, which I then plan to use to create a basic 2d map looking like this:
I need to convert the points, they can be a range of value such as:
0.0009321
19.332
1.9432123
0.0013432423
0.23432423
0.000034324
I want to basically convert all the numbers to 2 significant figures in front of the decimal point and store the result in the array stating how many shifts I have used.
I would want the output to be something like this (original number, converted number, shifts used):
[0.0009321, 93.21, 4]
[19.332, 19.332, 0]
[1.9432123, 19.432123, 1]
[0.0013432423, 13.432423, 3]
...
I am thinking find the first significant figure then count how far away from the decimal point this is. I found a few posts about using REGEX to do this, but I have never used REGEX before.
Can anybody give me some pointers?
Cheers.
That was a fun one figuring out.
Made a basic function for you, and as far as I can see it works.
function change(data){
var ret=new Array();
for(var i=0,len=data.length;i<len;i++){
// make string from number, remove the dot
var st=(''+data[i]).replace('.','');
//remove leading zero's from string
var no_zero=st.replace(/^0+/,'');
//make value
var val=parseInt(no_zero)/(Math.pow(10,no_zero.length-2));
//calculate amount of steps
var steps=Math.round(Math.log(Math.round(val/data[i]))/Math.log(10));
//correction for floating point
if(data[i]<0.01)steps--;
ret.push([data[i],val,steps]);
}
return ret;
}
And a working Fiddle

Get size/area of google maps search result

I am developing a business directory site whose search will be driven by Google Maps. Users will be able to search for businesses in their area based on various criteria, but mainly the idea is that if you search for e.g. "plumbers in New Jersey", you'll get a result of all plumbers in New Jersey. However, if you search for "plumbers in Jersey Shore", you should get only the plumbers that operate in Jersey Shore, which for this example would be a suburb or other type of sub-division of greater New Jersey. As an aside, I'm stripping out "plumbers in", and only passing the actual geographic search term, so my actual google maps search is only "New Jersey" or "Jersey Shore". So don't focus on the actual search text itself.
This is my search snippet:
var latlng = results[0].geometry.location;//results is google maps search result for address
console.log(results[0]);
map.setCenter(latlng.lat(), latlng.lng());
map.addMarker({
lat: latlng.lat(),
lng: latlng.lng(),
icon: 'https://maps.google.com/mapfiles/kml/shapes/schools_maps.png'
});
var closestmarkers = [];
var MAXDISTANCE = 5;//radius of our search area in km
closestmarkers = find_n_closest_markers(latlng, n, MAXDISTANCE);//see below snippet for function definition
This is the javascript that figures out which markers are closest to the searched :
function find_n_closest_markers(latlng, n, MAXDISTANCE){
var lat = latlng.lat();
var lng = latlng.lng();
var R = 6371; // radius of earth in km
var distances = [];
var closest = -1;
for (i = 0; i < map.markers.length; i++) {
var mlat = map.markers[i].position.lat();
var mlng = map.markers[i].position.lng();
var dLat = rad(mlat - lat);
var dLong = rad(mlng - lng);
var a = Math.sin(dLat / 2)
* Math.sin(dLat / 2)
+ Math.cos(rad(lat))
* Math.cos(rad(lat))
* Math.sin(dLong / 2)
* Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
distances[i] = { distance: d, index: i };
}
distances.sort(comparedistances);
//remove all distances greater than MAXDISTANCE
toofarindex = -1;
for (j = 0; j < distances.length; j++)
{
if(distances[j].distance >= MAXDISTANCE)
{
toofarindex = j;
break;
}
}
if (toofarindex != -1)
{
distances = distances.splice(0, toofarindex - 1);
}
//return first n + 1 items(the closest marker is the one indicating the user's current/preferred location. which doesn't count)
if (distances.length > n + 1)
{
distances = distances.splice(0, n + 1);
}
return distances;
}
I am not concerned about the actual function. That works 100%. What I'm looking for is how to figure out, based on the search term, what the value of MAXDISTANCE should be. 5 is just a good compromise constant for now, but I need to know that New Jersey is e.g. 20 miles in diameter, whereas Jersey Shore is only 5 miles (those figures come straight out of my ear, not an actual map).
The geocoder also returns a viewport and a bounds for the result. If you need a diameter, you can convert one of those to a distance (the width or the height of the bounds will give you a diameter, if not use that bounds to bound your search.

D3: Finding the area of a geo polygon in d3

I've got a map that uses a geoJSON file to draw the countries. I then want to draw a circle centered on each country. But for countries with several bounding regions (the US has mainland, Hawaii, Alaska) I want the circle on the largest bounding region. I'm trying to do this by comparing the areas of the different bounding regions, but it isn't working for reasons I can't understand.
Here's an example from the geoJSON, showing how Australia has multiple bounding regions:
{"type":"Feature","properties":{"name":"Australia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[145.397978,-40.792549],[146.364121,-41.137695],[146.908584,-41.000546],[147.689259,-40.808258],[148.289068,-40.875438],[148.359865,-42.062445],[148.017301,-42.407024],[147.914052,-43.211522],[147.564564,-42.937689],[146.870343,-43.634597],[146.663327,-43.580854],[146.048378,-43.549745],[145.43193,-42.693776],[145.29509,-42.03361],[144.718071,-41.162552],[144.743755,-40.703975],[145.397978,-40.792549]]],[[[143.561811,-13.763656],[143.922099,-14.548311],[144.563714,-14.171176],[144.894908,-14.594458],[145.374724,-14.984976],[145.271991,-15.428205],[145.48526,-16.285672],[145.637033,-16.784918],[145.888904,-16.906926],[146.160309,-17.761655],[146.063674,-18.280073],[146.387478,-18.958274],[147.471082,-19.480723],[148.177602,-19.955939],[148.848414,-20.39121],[148.717465,-20.633469],[149.28942,-21.260511],[149.678337,-22.342512],[150.077382,-22.122784],[150.482939,-22.556142],[150.727265,-22.402405],[150.899554,-23.462237],[151.609175,-24.076256],[152.07354,-24.457887],[152.855197,-25.267501],[153.136162,-26.071173],[153.161949,-26.641319],[153.092909,-27.2603],[153.569469,-28.110067],[153.512108,-28.995077],[153.339095,-29.458202],[153.069241,-30.35024],[153.089602,-30.923642],[152.891578,-31.640446],[152.450002,-32.550003],[151.709117,-33.041342],[151.343972,-33.816023],[151.010555,-34.31036],[150.714139,-35.17346],[150.32822,-35.671879],[150.075212,-36.420206],[149.946124,-37.109052],[149.997284,-37.425261],[149.423882,-37.772681],[148.304622,-37.809061],[147.381733,-38.219217],[146.922123,-38.606532],[146.317922,-39.035757],[145.489652,-38.593768],[144.876976,-38.417448],[145.032212,-37.896188],[144.485682,-38.085324],[143.609974,-38.809465],[142.745427,-38.538268],[142.17833,-38.380034],[141.606582,-38.308514],[140.638579,-38.019333],[139.992158,-37.402936],[139.806588,-36.643603],[139.574148,-36.138362],[139.082808,-35.732754],[138.120748,-35.612296],[138.449462,-35.127261],[138.207564,-34.384723],[137.71917,-35.076825],[136.829406,-35.260535],[137.352371,-34.707339],[137.503886,-34.130268],[137.890116,-33.640479],[137.810328,-32.900007],[136.996837,-33.752771],[136.372069,-34.094766],[135.989043,-34.890118],[135.208213,-34.47867],[135.239218,-33.947953],[134.613417,-33.222778],[134.085904,-32.848072],[134.273903,-32.617234],[132.990777,-32.011224],[132.288081,-31.982647],[131.326331,-31.495803],[129.535794,-31.590423],[128.240938,-31.948489],[127.102867,-32.282267],[126.148714,-32.215966],[125.088623,-32.728751],[124.221648,-32.959487],[124.028947,-33.483847],[123.659667,-33.890179],[122.811036,-33.914467],[122.183064,-34.003402],[121.299191,-33.821036],[120.580268,-33.930177],[119.893695,-33.976065],[119.298899,-34.509366],[119.007341,-34.464149],[118.505718,-34.746819],[118.024972,-35.064733],[117.295507,-35.025459],[116.625109,-35.025097],[115.564347,-34.386428],[115.026809,-34.196517],[115.048616,-33.623425],[115.545123,-33.487258],[115.714674,-33.259572],[115.679379,-32.900369],[115.801645,-32.205062],[115.689611,-31.612437],[115.160909,-30.601594],[114.997043,-30.030725],[115.040038,-29.461095],[114.641974,-28.810231],[114.616498,-28.516399],[114.173579,-28.118077],[114.048884,-27.334765],[113.477498,-26.543134],[113.338953,-26.116545],[113.778358,-26.549025],[113.440962,-25.621278],[113.936901,-25.911235],[114.232852,-26.298446],[114.216161,-25.786281],[113.721255,-24.998939],[113.625344,-24.683971],[113.393523,-24.384764],[113.502044,-23.80635],[113.706993,-23.560215],[113.843418,-23.059987],[113.736552,-22.475475],[114.149756,-21.755881],[114.225307,-22.517488],[114.647762,-21.82952],[115.460167,-21.495173],[115.947373,-21.068688],[116.711615,-20.701682],[117.166316,-20.623599],[117.441545,-20.746899],[118.229559,-20.374208],[118.836085,-20.263311],[118.987807,-20.044203],[119.252494,-19.952942],[119.805225,-19.976506],[120.85622,-19.683708],[121.399856,-19.239756],[121.655138,-18.705318],[122.241665,-18.197649],[122.286624,-17.798603],[122.312772,-17.254967],[123.012574,-16.4052],[123.433789,-17.268558],[123.859345,-17.069035],[123.503242,-16.596506],[123.817073,-16.111316],[124.258287,-16.327944],[124.379726,-15.56706],[124.926153,-15.0751],[125.167275,-14.680396],[125.670087,-14.51007],[125.685796,-14.230656],[126.125149,-14.347341],[126.142823,-14.095987],[126.582589,-13.952791],[127.065867,-13.817968],[127.804633,-14.276906],[128.35969,-14.86917],[128.985543,-14.875991],[129.621473,-14.969784],[129.4096,-14.42067],[129.888641,-13.618703],[130.339466,-13.357376],[130.183506,-13.10752],[130.617795,-12.536392],[131.223495,-12.183649],[131.735091,-12.302453],[132.575298,-12.114041],[132.557212,-11.603012],[131.824698,-11.273782],[132.357224,-11.128519],[133.019561,-11.376411],[133.550846,-11.786515],[134.393068,-12.042365],[134.678632,-11.941183],[135.298491,-12.248606],[135.882693,-11.962267],[136.258381,-12.049342],[136.492475,-11.857209],[136.95162,-12.351959],[136.685125,-12.887223],[136.305407,-13.29123],[135.961758,-13.324509],[136.077617,-13.724278],[135.783836,-14.223989],[135.428664,-14.715432],[135.500184,-14.997741],[136.295175,-15.550265],[137.06536,-15.870762],[137.580471,-16.215082],[138.303217,-16.807604],[138.585164,-16.806622],[139.108543,-17.062679],[139.260575,-17.371601],[140.215245,-17.710805],[140.875463,-17.369069],[141.07111,-16.832047],[141.274095,-16.38887],[141.398222,-15.840532],[141.702183,-15.044921],[141.56338,-14.561333],[141.63552,-14.270395],[141.519869,-13.698078],[141.65092,-12.944688],[141.842691,-12.741548],[141.68699,-12.407614],[141.928629,-11.877466],[142.118488,-11.328042],[142.143706,-11.042737],[142.51526,-10.668186],[142.79731,-11.157355],[142.866763,-11.784707],[143.115947,-11.90563],[143.158632,-12.325656],[143.522124,-12.834358],[143.597158,-13.400422],[143.561811,-13.763656]]]]},"id":"AUS"},
And here's the code where I try to compare areas of different bounding regions. In that if statement, I'm trying to figure out if the country has more than one bounding region (that seems to work) and then in the for block, pick the largest one.
The problem: The "area" values I'm getting are all 0 and coords is always being chosen from the first bounding region, rather than the largest.
function calculateCountryCenter(country) {
var coords;
//Check if the country has more than one bounding region.
if (country.geometry.coordinates.length > 1) {
coords = country.geometry.coordinates[0][0];
var regionArea = path.area(country.geometry.coordinates[0]);
for (var i=0; i<country.geometry.coordinates.length; i++) {
if (path.area(country.geometry.coordinates[i]) > regionArea) {
coords = country.geometry.coordinates[i][0];
}
}
} else {
coords = country.geometry.coordinates[0];
}
var averageCoords = [0,0];
coords.forEach(function(coord) {
averageCoords[0] += coord[0]
averageCoords[1] += coord[1]
});
averageCoords[0] = averageCoords[0] / coords.length
averageCoords[1] = averageCoords[1] / coords.length
return averageCoords;
}
Here's the definition of the path.
var path = d3.geo.path().projection(projection)
Any guidance would be much appreciated. Many thanks.
You can calculate the area of an arbitrary polygon using the Shoelace algorithm.
function polygonArea(points) {
var sum = 0.0;
var length = points.length;
if (length < 3) {
return sum;
}
points.forEach(function(d1, i1) {
i2 = (i1 + 1) % length;
d2 = points[i2];
sum += (d2[1] * d1[0]) - (d1[1] * d2[0]);
});
return sum / 2;
}
polygonArea([[0,0], [4,0], [4,3]]); // 6
Be aware that counterclockwise polygons will have a positive area, and clockwise polygons will have a negative area. Self-intersecting polygons typically have both clockwise and counterclockwise regions so their area will cancel out.
Just because nobody has added a fully implemented answer yet, I've decided to answer my own question. Here's code that takes geoJSON, as specified in the original question, and returns the coordinates of the largest bounding region for countries with more than one bounding region. For countries with only one bounding region, it returns the coords of the one bounding region. (I had to modify the code a bit to make it a standalone method here, but I'm pretty sure it's error-free.)
function getLargestBoundingRegion(country) {
var largestRegionCoords;
var path = d3.geo.path()
//Check if the country has more than one bounding region.
if (country.geometry.coordinates.length > 1) {
var regionToReturn = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": country.geometry.coordinates[0]},
};
for (var i=1; i<country.geometry.coordinates.length; i++) {
var testRegion = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": country.geometry.coordinates[i]},
};
if (path.area(testRegion) > path.area(regionToReturn)) {
regionToReturn = testRegion;
largestRegionCoords = country.geometry.coordinates[i][0];
}
}
} else {
largestRegionCoords = country.geometry.coordinates[0];
}
return largestRegionCoords;
The path.area function expects a feature and doesn't work with just a list of coordinates. The easiest way to make it work is probably to copy the original object, delete all the coordinates that you're not interested in and pass that to path.area. The code would look something like
for (var i=0; i<country.geometry.coordinates.length; i++) {
var copy = JSON.parse(JSON.stringify(country));
copy.geometry.coordinates = [copy.geometry.coordinates[i]];
path.area(copy);
...
}

Categories

Resources