Search code examples
pythonfolium

Filter on diagonal geo coordinates


I am trying to filter my file on geo coordinates to keep only coordinates located in Manhattan using Python and Folium. I've tried setting my own limits:

top_left = [40.806470, -73.973205]
bottom_left = [40.709729, -74.035690]
bottom_right = [40.696715, -73.992431]
top_right = [40.781518, -73.934066]

low_lat = bottom_right[0]
high_lat = top_left[0]       
low_lon = top_right[1]
high_lon = bottom_left[1]

df_bad = df.loc[
    (df["Point_latitude"] < high_lat) & 
    (df["Point_latitude"] > low_lat) &
    (df["Point_longitude"] > high_lon) &
    (df["Point_longitude"] < low_lon)
]

My problem with this method is that it includes parts of NYC I don't want to include. It is a straight box like this:

Before

I would like to filter my map like this: enter image description here

Is there a way to do that? Or maybe a new library that would allow me to do that?

Thank you


Solution

  • Use can use shapely for that. https://pypi.python.org/pypi/Shapely . In fact, you can create polygons and other geospatial features with it. Potentially, you do not need any df. Here is a complete example using your polygon and random points. You do not need all of these modules, but I show you that you can solve your problem in many ways:

    import json
    import geojson
    from shapely.geometry import mapping, shape, Polygon, MultiPoint
    import shapely.wkt as wkt
    import folium
    
    top_left = [-73.973205, 40.806470]
    bottom_left = [-74.035690, 40.709729]
    bottom_right = [-73.992431, 40.696715]
    top_right = [-73.934066, 40.781518]
    
    coordinates =[(-74, 40.74),(-74, 40.76),(-74, 40.78),(-74, 40.81)]
    coordinates_shapely = MultiPoint(coordinates)
    
    # 1. create a polygon:
    polyNY_shapely = Polygon([(top_left), (bottom_left), (bottom_right), (top_right)])
    # OR 
    polyNY_json = {
    "coordinates": [[top_left, bottom_left, bottom_right, top_right, top_left]], 
    "type": "Polygon"
    }
    
    
    # 2. create the geojson of the polygon
    g1 = wkt.loads(polyNY_shapely.wkt)
    g2a = geojson.Feature(geometry=g1)
    # OR
    g2b = json.dumps(mapping(shape(polyNY_json)))
    
    # 3. create map with polygon and all coordinates
    map_osm = folium.Map(location=[40.7, -74.0],zoom_start=12)
    folium.GeoJson(
    g2a,
    style_function=lambda feature: {
        'fillColor': '#ffff00',
        'color' : 'blue',
        'weight' : 2
        }).add_to(map_osm)
    for cc in coordinates:
        folium.Marker(cc[::-1], popup='point '+str(cc)).add_to(map_osm)
    map_osm.save('shapelyfolium.html')
    
    # add points to map after filtering
    for pp in range(len(list(coordinates_shapely))):
        print polyNY_shapely.contains(coordinates_shapely[pp])
        if polyNY_shapely.contains(coordinates_shapely[pp]):
            folium.Marker(coordinates[pp][::-1], popup='point '+str(pp),icon = folium.Icon(color='red')).add_to(map_osm)
    # OR
    # if pp.within(polyNY_shapely):
    #     folium.Marker(row, popup='point '+str(index),icon = folium.Icon(color='red')).add_to(map_osm)
    map_osm.save('shapelyfoliumAfterfiltering.html')
    

    map before filtering map after filtering