30

Is it possible to determine whether a GeoJSON point at a given lat,lon lies within a given GeoJSON polygon using only JavaScript (either through d3, topojson, or any other way)?

For example, I can draw a map showing countries in the UK based on the tutorial here.

I then have a some points which have coordinates but no indication as to which country they lie within.

I would like to display a total point count for each country.

Can I work out which country contains each point in the browser, or do I need to preprocess my point data on the server using PostGIS or similar?

user5325596
  • 2,310
  • 4
  • 25
  • 42
  • 1
    See [*"Node.js/Javascript library to test if point is in geojson multipolygon"*](/q/20379194). – altocumulus Nov 19 '15 at 12:06
  • 1
    @altocumulus - Your comment led me to [JavaScript Clipper](http://sourceforge.net/projects/jsclipper/) - looks interesting. Also, it would never have occurred to me that 'point-in-polygon' would be a tag. – user5325596 Nov 19 '15 at 12:28
  • 1
    Agreed, that [tag:point-in-polygon] tag took me completely by suprise ;-) And there are almost 120 questions associated with it. If you come up with a solution to your problem by yourself, please post an answer to this question. – altocumulus Nov 19 '15 at 12:35
  • See also https://stackoverflow.com/questions/22521982/js-check-if-point-inside-a-polygon – Lars Kotthoff Nov 19 '15 at 16:37
  • 2
    You can also take a look at https://github.com/turfjs/turf, perhaps too big for this simple task. – Jonatas Walker Nov 20 '15 at 08:08
  • 3
    @jonatas_walker Turfjs has a modular ecosystem so you could just use @turfjs/inside via https://www.npmjs.com/package/turf-inside or if you don't use npm then find it on github – Andi-lo Dec 01 '16 at 16:00
  • @Andi-lo yes, turf did it for me. Thanks. – surfrider Aug 31 '17 at 12:39

3 Answers3

20

Seems like d3 has you covered: https://github.com/d3/d3-geo#geoContains

d3.geoContains(object, point)

Returns true if and only if the specified GeoJSON object contains the specified point, or false if the object does not contain the point. The point must be specified as a two-element array [longitude, latitude] in degrees. For Point and MultiPoint geometries, an exact test is used; for a Sphere, true is always returned; for other geometries, an epsilon threshold is applied.

thedude
  • 9,388
  • 1
  • 29
  • 30
  • 3
    This is correct. It would be fair to note, though, that this is a new method of D3 **v4** and was not available at the time the question was posted. However, as the question is not targeting any specific version, this answer totally legit. – altocumulus Apr 19 '17 at 08:54
  • I can't get this work. `geoContains` returns `false` for point which is actually a center of area. I validated geoJson of this area (it's valid) and checked on google maps if given point belongs to this area (it belongs). – surfrider Aug 31 '17 at 07:55
  • 3
    So it seems to my polygon be counterclockwise, but `d3` expects clockwise. I tested `turf` library (thx to Jonatas Walker comment for aiming to) and it 'eats' counterclockwise polygon. – surfrider Aug 31 '17 at 18:31
  • 1
    If you are using typescript, make sure you npm i @types/d3 instead of npm i d3. I spend like a day trying to find a library for my angular project. – Darrow Hartman Jun 24 '20 at 01:54
5

Expanding the @thedude answer's you can also use geojson-lookup if you need to do this check more than once on a given GeoJSON.

simonepri
  • 493
  • 6
  • 11
4

Turf.js provides a function called boolean-point-in-polygon

For example:

var pt = turf.point([-77, 44]);

var poly = turf.polygon([[
  [-81, 41],
  [-81, 47],
  [-72, 47],
  [-72, 41],
  [-81, 41]
]]);

turf.booleanPointInPolygon(pt, poly);
//= true
Ivan -Oats- Storck
  • 4,096
  • 3
  • 30
  • 39