-1

I have a list of customers lat and long and I want to define which ones are within a given polygon. But the results I got are none of them in that polygon and it is not correct.

Could you please help? Thanks!

from shapely.geometry import Polygon
from shapely.geometry import Point
import pandas as pd
import geopandas as gpd
df=pd.read_csv("C:\\Users\\n.nguyen.2\\Documents\\order from May 1.csv")

geometry=[Point(xy) for xy in zip(df['customer_lat'],df['customer_lng'])]
crs={'init':'epsg:4326'}
gdf=gpd.GeoDataFrame(df,crs=crs,geometry=geometry)
gdf.head()

polygon= Polygon ([(103.85362669999994, 1.4090082), (103.8477709, 1.4051988), (103.84821190000002, 1.4029509), (103.84933950000004, 1.4012179), (103.85182859999998, 1.4001453), (103.85393150000004, 1.3986867), (103.85745050000001, 1.3962412), (103.85809410000002, 1.3925516), (103.85843750000004, 1.3901491), (103.8583946, 1.3870601), (103.8585663, 1.3838853), (103.8582659, 1.3812682), (103.85822299999997, 1.3792946), (103.85843750000004, 1.3777931), (103.85882370000002, 1.3748757), (103.86015410000005, 1.3719582), (103.8607978, 1.3700276), (103.86092659999998, 1.368097), (103.86036880000006, 1.3657372), (103.8593174, 1.3633562), (103.85852339999995, 1.3607605), (103.85745050000001, 1.3581005), (103.8571071, 1.355655), (103.85736459999998, 1.3520941), (103.85873790000007, 1.3483615), (103.86187100000006, 1.3456583), (103.86488409999993, 1.340689), (103.87096889999998, 1.3378933), (103.87519599999996, 1.3373354), (103.88178349999998, 1.3408963), (103.88508790000004, 1.3433418), (103.89186870000005, 1.3436426), (103.89742610000008, 1.342355), (103.91813279999997, 1.3805388), (103.91824964404806, 1.3813377489306), (103.91433759243228, 1.38607494841128), (103.91607279999994, 1.3895484), (103.91942029999996, 1.3940104), (103.92903330000001, 1.4009604), (103.9342689, 1.402076), (103.93289559999994, 1.4075675), (103.92534249999994, 1.4146035), (103.92517090000003, 1.4211246), (103.90972139999997, 1.4238704), (103.89942169999993, 1.4202666), (103.89744760000008, 1.4224117), (103.89315599999998, 1.425758), (103.88740540000003, 1.4285896), (103.88148309999995, 1.4328798), (103.87478829999998, 1.4331372), (103.85918850000007, 1.4249644), (103.85401679999995, 1.4114284), (103.85362669999994, 1.4090082)])

gdf['answer']=gdf['geometry'].within(polygon)
writer = pd.ExcelWriter("C:\\Users\\n.nguyen.2\\Documents\\order may define1.xlsx")
gdf.to_excel(writer, 'Sheet1', index=False)
writer.save()

The results are all false.

Raw data:

Raw data

Result:

Result

Nazim Kerimbekov
  • 4,712
  • 8
  • 34
  • 58
  • 1
    add raw data file or as text – Zaraki Kenpachi Jun 02 '19 at 10:01
  • You need `from shapely.wkt import loads`, and `geometry=[loads(Point(xy)) for xy in zip(df['customer_lat'],df['customer_lng'])]` to get correct geospatial dataframe. – swatchai Jun 02 '19 at 10:06
  • Hi, thanks for the answer but I got another issue as: \AppData\Local\Continuum\anaconda3\lib\site-packages\shapely\geos.py in read(self, text) 248 """Returns geometry from WKT""" 249 if sys.version_info[0] >= 3: --> 250 text = text.encode('ascii') 251 geom = self._lgeos.GEOSWKTReader_read(self._reader, c_char_p(text)) 252 if not geom: AttributeError:'Point' object has no attribute 'encode' – Ngoc Nguyen Jun 02 '19 at 14:50
  • This is a new code: ```python geometry=[loads(Point(xy)) for xy in zip(df['customer_lat'],df['customer_lng'])] ``` But it does not work ``` AttributeError:'Point' object has no attribute 'encode' ``` – Ngoc Nguyen Jun 02 '19 at 14:52
  • The comment from @swatchai is not true, your original code should work fine. You have switched longitude and latitude in the order. Look at coordinates of your polygon and those of points. Points you have generated are not within your polygon, so the result is correct. – martinfleis Jun 02 '19 at 19:38
  • But I have a 7 thousand rows in the data set and there should be points in. – Ngoc Nguyen Jun 02 '19 at 22:03
  • It all gives false answers with my code for all of the zones I plugged in. So it is not correct. – Ngoc Nguyen Jun 02 '19 at 23:27
  • Of course it is not, because coordinates of points you have generated are (Lat, Lon), while your polygon (Lon, Lat). So these points are not within this polygon. Do `geometry=[Point(xy) for xy in zip(df['customer_lng'],df['customer_lat'])]` instead and it will work. Btw, geopandas has helper function for creating points from polygons `points_from_xy()` (http://geopandas.org/gallery/create_geopandas_from_pandas.html?highlight=points_from_xy). – martinfleis Jun 03 '19 at 08:34

1 Answers1

1

Adding my comments as an answer for future reference.

You have switched longitude and latitude in the order of coordinates. Look at coordinates of your polygon and those of points. Coordinates of points you have generated are (Lat, Lon), while your polygon (Lon, Lat). So these points are not within this polygon. Do

geometry=[Point(xy) for xy in zip(df['customer_lng'],df['customer_lat'])] 

instead and it will work.

To make your life easier, geopandas has helper function for creating points from polygons points_from_xy() (http://geopandas.org/gallery/create_geopandas_from_pandas.html?highlight=points_from_xy)

martinfleis
  • 7,124
  • 2
  • 22
  • 30
  • 2
    Also, I would *hightly* recommend using a projected coordinate system instead of geographic coordinates. – Paul H Jun 03 '19 at 13:55