LatLong falls within a given polygon in D3 + Leafl

2019-07-18 19:34发布

问题:

I am trying to learn how to use the Javascript library leaflet along with d3 to create various map visualisations.

I have been following this tutorial which creates a choropleth map of the United States with some interactivity. This provides some of what I need, but the main functionality I want is to have a list of lat/long coordinates classified according to which region they belong to.

This would mean, in the tutorial map for example, if I had a lat long value (55, -3) which fell within the state of Arizona's polygon, the program could classify this point as belonging to Arizona.

Is there a function in the leaflet (or d3) library which will allow me to enter a lat long coordinate as a parameter and return the name of the feature it belongs to? The tutorial above allows you to attach a function to every feature via the onEveryFeature property and can fire mouseover events when each feature is hovered over. Surely there is a way to extend this functionality to numerically entered data instead of mouse points?

回答1:

Leaflet would need some tweaking if you wish to do this. It leaves the handling of mouseclicks to the browser and therefore does not need logic for determining if a point lies inside a polygon.

I am not very knowledgeable about d3 but it's not glaringly obvious to me how it'd do this out of the box. Looking at the polygon code, I do find a clipping algorithm and intersection of infinite lines.

If you add a third library, however, this should be rather simple. The OpenLayers Geometry library can determine if a point lies inside a polygon.

EDIT: I got this to work, see also http://jsfiddle.net/VaY3E/4/

var parser = new OpenLayers.Format.GeoJSON();
var vectors = parser.read(statesData);
var lat = 36;
var lon = -96;
var point = new OpenLayers.Geometry.Point(lon, lat);
for( var i = 0; i< vectors.length; i++ ){
    if(vectors[i].geometry.intersects(point)){
       alert(vectors[i].attributes['name']);
    }
}

Or you could use https://github.com/maxogden/geojson-js-utils , a bit more specific library. It looks like it knows how to read GeoJSON and it has a method gju.pointInPolygon. I've not tested it though.