I've tried many, many many, ways to find out if a point is in a GIS polygon based on many great posts, but I can't get any to work properly. Specifically I created a grid of points covering the bounding box of Japan, and now I want to keep only the ones that are actually over Japan.

Here is one way I tried to get a GIS shapefile for Japan:

world = gp.read_file(gp.datasets.get_path('naturalearth_lowres'))
JapanShapes =  world[world.name == "Japan"]
geoJapanShapes = gp.GeoDataFrame(JapanShapes2)
geoJapanShape = geoJapanShapes['geometry'].unary_union

I have millions of point data in a geodataframe, but here's just one point (Tokyo station).

allCoords = pd.DataFrame([[35.6812,139.7671]], columns=["lat","lon"])
allCoords['geometry'] = allCoords.apply(lambda row: "POINT ("+str(row.lat)+" "+str(row.lon)+")", axis=1)
allCoords = gp.GeoDataFrame(allCoords)
allCoords['geometry'] = allCoords['geometry'].apply(wkt.loads)

Now, if test whether Tokyo station is in Japan:

>>>> False

However, the last time I checked Tokyo station was within Japan. And if I do:

coordsWithinJapan = allCoords[allCoords.apply(lambda row: row['geometry'].within(geoJapanShapes), axis=1)]
>>>> AttributeError: ("'GeoDataFrame' object has no attribute '_geom'", 'occurred at index 0')

Based on several other posts I also tried:

from geopandas.tools import sjoin
gridWithinJapan = sjoin(geoHexData, geoJapanShapes, how='left', op='within')

Which just returns every point in the original data. If I try with the inner option I instead get an empty dataframe.

So both methods (kinda) run on my data, but neither method is working to accurately report whether a point is within the boundary. Other versions gave me crs errors, but I don't how to deal with that considering my points are hand-made. Another had a problem because maybe/apparently that shapefile is a multipolygon, which it couldn't handle. No matter what I try, I seem to be doing something wrong, but I can't find the error.

How do I actually determine whether my points are in my shape?

  • Have you tried leveraging the contains function to add a point when True or the intersect function? One thing I noticed is that you created a point in DataFrame using Pandas, so what if you try declaring it a GeoDataFrame first? – Trevor J. Smith Feb 26 '19 at 14:14
  • I think there is something wrong with your coordinates (or at least with the example): (35.6812,35.6812) is not located in Japan, but somewhere in the sea: google.be/maps/place/… – joris Feb 26 '19 at 16:48
  • @joris: yeah, that's for pointing it out. It was a copy and paste error from my workbook. I've fixed the post. – Aaron Bramson Feb 27 '19 at 1:51

The Geopandas docs mention coordinates should be created as a tuple of Longitude and Latitude (not latitude and longitude). Switching your lat/lon will give you the result you are expecting.

I was not able to run your code completely because I'm not sure what wkt.loads is, but the following is similar and returns True as expected:

import pandas as pd
import geopandas as gp
from shapely.geometry import Point

world = gp.read_file(gp.datasets.get_path('naturalearth_lowres'))
JapanShapes =  world[world.name == "Japan"]
geoJapanShapes = gp.GeoDataFrame(JapanShapes)
geoJapanShape = geoJapanShapes['geometry'].unary_union

TokyoStation = Point(139.7671, 35.6812)

| improve this answer | |
  • Yeah, I found my error an hour before you answered my question. Good catch. BTW, the wkt.loads is used to convert strings of geometries (such those saved in csv files) and convert them into actual geometries. Very useful. – Aaron Bramson Feb 28 '19 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.