Фильтр по диагональным геокоординатам

Я пытаюсь отфильтровать свой файл по географическим координатам, чтобы сохранить только координаты, расположенные на Манхэттене, с помощью Python и Folium. Я попытался установить свои собственные ограничения:

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)
]

Моя проблема с этим методом заключается в том, что он включает части Нью-Йорка, которые я не хочу включать. Это прямое поле, как это:

До

Я хотел бы отфильтровать свою карту следующим образом: введите здесь описание изображения

Есть ли способ сделать это? Или, может быть, новая библиотека, которая позволит мне это сделать?

Спасибо


person nickfrenchy    schedule 09.07.2016    source источник
comment
Почти уверен, что фолиум поддерживает полилинии: github.com/python-visualization/ folium/blob/master/examples/   -  person Benjamin    schedule 09.07.2016


Ответы (1)


Для этого можно использовать shapely. https://pypi.python.org/pypi/Shapely . Фактически, с его помощью вы можете создавать полигоны и другие геопространственные объекты. Потенциально вам не нужен никакой df. Вот полный пример использования полигона и случайных точек. Вам не нужны все эти модули, но я покажу вам, что вы можете решить свою проблему разными способами:

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 перед фильтрацией карта после фильтрации

person giosans    schedule 09.07.2016
comment
Здравствуйте, не могли бы вы подробнее рассказать о том, как использовать его для этого варианта использования? Похоже, это может быть полезно, но я не уверен, что понимаю, как его применять в этом случае. - person nickfrenchy; 09.07.2016
comment
создание многоугольника выполняется с помощью toblerity.org/shapely/manual.html#polygons . Когда вы говорите фильтровать мой файл, я предполагаю, что вы хотите иметь точки только в этой области. В этом случае следуйте этому руководству streamhacker.com/2010/03. /23/python-point-in-polygon-shapely . Если это не то, что вы имеете в виду под фильтром моего файла, мне придется попросить вас уточнить ваш вопрос. - person giosans; 09.07.2016
comment
Да, я хочу сохранить очки в этом районе. Shapely выглядит как правильный инструмент, но я не уверен, как его использовать. Когда я использую функцию Polygon с моими координатами ограничения области, я получаю TypeError: __init__() принимает от 1 до 3 позиционных аргументов, но было задано 9... - person nickfrenchy; 09.07.2016
comment
Не могу сказать, что вызвало у вас ошибку, потому что вы не ввели свой код. Что принимает функция Polygon, объясняется здесь stackoverflow.com/questions/30457089/ или в руководстве. - person giosans; 10.07.2016
comment
Хорошо, да, я делал это неправильно, я думаю. Теперь у меня есть многоугольник, использующий координаты в качестве точек. Теперь, я думаю, мне следует преобразовать координаты в моих файлах в точки и использовать point.within(polygon) по ссылке, которую вы разместили выше, верно? - person nickfrenchy; 10.07.2016
comment
Вы можете использовать polygon.contains(point) после создания точечного объекта с использованием красивого класса Point. - person giosans; 11.07.2016
comment
У меня есть широта и долгота в 2 столбцах. Я объединил их в один столбец «точка». Я пытаюсь преобразовать его в формат точки, но я не думаю, что делаю это правильно, поскольку он запрашивает поплавок... Concat: df_co['point'] = df_co[Pickup_latitude].map(str) + ','+df_co[Pickup_longitude].map(str) Точка и карта: для индекса, строки в df_co.iterrows(): point = Point(df_co['point']) loc = [df['Pickup_latitude'], df ['Pickup_longitude']] if poly.contains(point): map_osm.polygon_marker(location= loc ,fill_color='#FFFFFF', num_sides=5, radius=5) - person nickfrenchy; 11.07.2016
comment
Извините, у меня было мало времени в последнее время. Я обновляю полное решение вашего вопроса. Надеюсь, вы довольны этим. - person giosans; 15.07.2016