4

I am having trouble with using GeoDataFrame.buffer function. That is probably because of my lack of understanding crs. Here is the case: I have events dataset (points longs & lats) and locations dataset (points longs & lats). I want to check which of the events occurred within 2km radius circle from locations. I know how to perform spatial join in geopandas, but the problem is in buffer(distance, resolution) function. When creating both GeoDataFrames I used crs: 'epsg:4326' and in distance parameter use 0.2 (without any good reason). So my question is:

How to adjust crs and distance parameter to make it in kilometers?

Here is my sample code. The intersection should contain only events with id 1 & 2. However it does contain event 3 which is about 10km far from any of locations. Also it does not contain event with id 4, which is good, because that one is hundreds kilometers from any of locations.

events = pd.DataFrame([
    {'id': 1,
     'longitude': 54.606402,
     'latitude': 18.347709},
    {'id': 2,
     'longitude': 54.604681,
     'latitude': 18.346534},
    {'id': 3,
     'longitude': 54.544322,
     'latitude': 18.293896},
    {'id': 4,
     'longitude': 50.843233,
     'latitude': 11.130688}
])
locations = pd.DataFrame([
    {'id': 'a',
     'longitude': 54.604972,
     'latitude': 18.346815},
    {'id': 'b',
     'longitude': 54.605917,
     'latitude': 18.347249}
])

locations_gpd = gpd.GeoDataFrame(locations,
                                 geometry=gpd.points_from_xy(locations.longitude, locations.latitude).buffer(0.2, 16),
                                 crs={'init': 'epsg:4326'})

events_gpd = gpd.GeoDataFrame(events,
                              geometry=gpd.points_from_xy(events.longitude, events.latitude),
                              crs={'init': 'epsg:4326'})

intersection = gpd.sjoin(locations_gpd, events_gpd, how='left')

1 Answer 1

5

Reproject to a projected coordinate system in meters, for example EPSG:32634. Then the buffer distance will be in meters:

import geopandas as gpd
import pandas as pd

events = pd.DataFrame([
    {'id': 1,
     'longitude': 54.606402,
     'latitude': 18.347709},
    {'id': 2,
     'longitude': 54.604681,
     'latitude': 18.346534},
    {'id': 3,
     'longitude': 54.544322,
     'latitude': 18.293896},
    {'id': 4,
     'longitude': 50.843233,
     'latitude': 11.130688}
])
locations = pd.DataFrame([
    {'id': 'a',
     'longitude': 54.604972,
     'latitude': 18.346815},
    {'id': 'b',
     'longitude': 54.605917,
     'latitude': 18.347249}
])

locations_gpd = gpd.GeoDataFrame(locations,
                                 geometry=gpd.points_from_xy(locations.longitude, locations.latitude),
                                 crs='epsg:4326')

events_gpd = gpd.GeoDataFrame(events,
                              geometry=gpd.points_from_xy(events.longitude, events.latitude),
                              crs='epsg:4326')

locations_gpd = locations_gpd.to_crs("EPSG:32634")
locations_gpd.geometry = locations_gpd.geometry.buffer(2000, 6)

events_gpd = events_gpd.to_crs("EPSG:32634")

intersection = gpd.sjoin(locations_gpd, events_gpd, how='left')
2
  • Any thoughts on how to switch back? I switched from EPSG:4326 (world °) to EPSG:32662 (world meters),( tried 32662 and 4087 as well). Then I made a buffer, but I can't transform the buffer back to to degrees. Aug 30, 2022 at 18:57
  • 1
    .to_crs("EPSG:4326")
    – BERA
    Aug 31, 2022 at 5:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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