Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Legacy geospatial-tools 벡터 변환

geospatial-tools는 Python 변환에서 벡터 정리, 공간 계산과 조인을 제공하는 Legacy 라이브러리입니다. 더 이상 적극적으로 개발하거나 유지보수하지 않으며 환경에 따라 정상 동작하지 않을 수 있습니다. 새 작업은 Pipeline Builder의 지리공간 기능을 사용합니다. 기존 라이브러리의 공식 사용 중단 전까지는 이 인터페이스를 유지 및 이전 작업의 참조로 사용할 수 있습니다.

설치와 실행 환경

기존 저장소에서 geospatial-tools 라이브러리와 GEOSPARK Spark 프로필을 준비합니다. 숨김 파일을 표시하고 transforms-python/build.gradle 아래에 필요한 JAR 의존성을 구성합니다.

dependencies {
    condaJars "org.apache.sedona:sedona-spark-shaded-3.5_2.13:1.7.1"
    condaJars "org.datasyslab:geotools-wrapper:1.7.0-28.5"
}

이 Sedona 좌표는 Spark3.5 및 Scala2.13용입니다. 실제 저장소의 런타임과 설치 라이브러리에 맞는 구성이 필요하며, 설치나 호환성 문제는 Palantir 담당자에게 문의합니다.

라이브러리를 사용하는 Foundry 변환에는 @geospatial()을 다른 모든 데코레이터보다 위에 둡니다. 이 설정은 Spark에서 Apache Sedona와 데이터프레임 공간 조인 바인딩을 활성화합니다. 아래 변환 예제는 GEOSPARK 프로필을 명시합니다.

예제의 /Examples/Geospatial 경로와 열은 가상 입력 및 출력 계약입니다. 실제 리소스로 바꾸고 필요한 예제를 독립적인 변환으로 등록합니다. 함수의 geometry, geometry1과 geometry2 인자는 도형 값 자체가 아니라 열 이름 문자열입니다.

정리할 데이터의 조건

Spark에서 처리할 표 형식 데이터와 유효한 도형을 준비하고, 지도 및 공간 조인에 맞춰 EPSG:4326으로 정규화합니다. 서로 다른 입력 CRS를 같은 것으로 이름만 바꾸지 않습니다. 좌표 참조계와 온톨로지 허용 도형의 조건도 충족해야 합니다.

이 라이브러리에서 geohash라는 형식 이름은 latitude,longitude 좌표 문자열에 사용합니다. 온톨로지 geopoint가 별도로 받는 Base32 Geohash 코드와 구분합니다. 파일 형태의 GeoJSON, Shapefile, GDB, KML과 KMZ는 아래 파서로 표를 만들 수 있습니다.

도형 정리

clean_geometry

clean_geometry(geometry, input_crs, geometry_format='geojson', lat_long=False, output_format='geojson')

geometry 열을 유효한 도형으로 정리하고 EPSG:4326으로 정규화합니다. input_crs는 실제 입력 좌표계입니다.

인자유형과 기본값의미
geometrystr입력 열 이름
input_crsstr입력 CRS
geometry_formatstr, geojsongeojson, geohash, wkt, wkb 중 입력 형식
lat_longbool, False입력 좌표가 위도, 경도 순서이면 True
output_formatstr, geojsongeojson 또는 geohash

이 라이브러리의 geohash 형식은 latitude,longitude 좌표 문자열을 뜻합니다. GeoJSON과 WKT의 일반적인 좌표 순서와 구분합니다. 아래 입력은 EPSG:26910 좌표를 가진 geometry 열이라는 전제입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import clean_geometry

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/clean_geometry/output'),
    raw_df=Input('/Examples/Geospatial/input'),
)
def compute(raw_df):
    clean_df = raw_df.withColumn('geometry', clean_geometry('geometry', 'EPSG:26910'))
    return clean_df

lat_long_to_geometry

lat_long_to_geometry(lat, long, input_crs, output_format='geojson')

lat와 long은 각각 위치 좌표를 가진 열 이름이며 input_crs의 좌표를 정리한 geometry 열로 변환합니다. output_format은 geojson 또는 geohash이며 기본값은 geojson입니다.

아래는 EPSG:26910, 즉 NAD83 / UTM zone10N의 미터 단위 northing과 easting 열을 받는 예제입니다. 인자 순서는 북향 좌표, 동향 좌표입니다. 일반 위도와 경도 도 단위 값이면 실제 입력에 맞는 EPSG:4326을 지정합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import lat_long_to_geometry

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/lat_long_to_geometry/output'),
    raw_df=Input('/Examples/Geospatial/input'),
)
def compute(raw_df):
    clean_df = raw_df.withColumn('geohash', lat_long_to_geometry('northing', 'easting', 'EPSG:26910', output_format='geohash'))
    return clean_df.drop('northing', 'easting')

파일 파서

geojson_to_dataframe

geojson_to_dataframe(dataset, properties=None, glob='*.geojson', batch_size=100000)

입력 데이터셋의 GeoJSON 파일을 스트리밍과 배치 방식으로 처리합니다.

인자기본값의미
dataset필수변환에 주입된 파일 입력
propertiesNone별도 열로 가져올 속성 이름 목록. 생략하면 모든 속성을 JSON properties 열에 포함
glob*.geojson읽을 파일 패턴
batch_size100000한 번에 처리할 레코드 수. 드라이버 메모리가 부족하면 축소

파일 전체를 한 번에 로드하는 방식을 피하지만 배치의 폭과 레코드 크기에 맞는 메모리는 필요합니다.

from transforms.api import transform, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.parsers import geojson_to_dataframe

@geospatial()
@configure("GEOSPARK")
@transform(
    output=Output('/Examples/Geospatial/geojson_to_dataframe/output'),
    raw=Input('/Examples/Geospatial/input'),
)
def compute(raw, output):
    return output.write_dataframe(
        geojson_to_dataframe(raw)
    )

shapefile_to_dataframe

shapefile_to_dataframe(dataset, glob='*.shp')

Shapefile을 데이터프레임으로 읽습니다. dataset은 변환 입력이며 glob 기본값은 *.shp입니다. 해당 파일과 함께 필요한 .shx, .dbf 등 관련 파일도 입력에 있어야 합니다.

from transforms.api import transform, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.parsers import shapefile_to_dataframe

@geospatial()
@configure("GEOSPARK")
@transform(
    output=Output('/Examples/Geospatial/shapefile_to_dataframe/output'),
    raw=Input('/Examples/Geospatial/input'),
)
def compute(raw, output):
    return output.write_dataframe(
        shapefile_to_dataframe(raw)
    )

gdb_to_dataframe

gdb_to_dataframe(dataset, glob='*.gdb.zip', layer=None)

ZIP으로 묶인 GeoDatabase를 읽습니다. glob 기본값은 *.gdb.zip이며, 선택적인 layer로 읽을 레이어를 지정합니다.

from transforms.api import transform, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.parsers import gdb_to_dataframe

@geospatial()
@configure("GEOSPARK")
@transform(
    output=Output('/Examples/Geospatial/gdb_to_dataframe/output'),
    raw=Input('/Examples/Geospatial/input'),
)
def compute(raw, output):
    return output.write_dataframe(
        gdb_to_dataframe(raw)
    )

kml_to_dataframe

kml_to_dataframe(dataset, glob='*.kml', drop_invalid_layers=False)

KML 파일을 읽으며 glob 기본값은 *.kml입니다. drop_invalid_layers는 기본값 False로, 비어 있거나 파싱할 수 없는 레이어가 있으면 오류를 발생시킵니다. True로 지정하면 해당 레이어를 알림 없이 제외하므로 데이터 누락을 허용하는 처리인지 확인해야 합니다.

from transforms.api import transform, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.parsers import kml_to_dataframe

@geospatial()
@configure("GEOSPARK")
@transform(
    output=Output('/Examples/Geospatial/kml_to_dataframe/output'),
    raw=Input('/Examples/Geospatial/input'),
)
def compute(raw, output):
    return output.write_dataframe(
        kml_to_dataframe(raw)
    )

kmz_to_dataframe

kmz_to_dataframe(dataset, glob='*.kmz')

KMZ 파일을 읽습니다. dataset은 변환 입력이고 glob 기본값은 *.kmz입니다.

from transforms.api import transform, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.parsers import kmz_to_dataframe

@geospatial()
@configure("GEOSPARK")
@transform(
    output=Output('/Examples/Geospatial/kmz_to_dataframe/output'),
    raw=Input('/Examples/Geospatial/input'),
)
def compute(raw, output):
    return output.write_dataframe(
        kmz_to_dataframe(raw)
    )

공간 함수

geohash_to_geojson

geohash_to_geojson(geometry)

latitude,longitude 문자열이 들어 있는 geometry 열을 GeoJSON으로 변환합니다. 여기서 geohash라는 이름은 표준 Base32 Geohash 코드가 아니라 이 라이브러리의 좌표 문자열 형식입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import geohash_to_geojson

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/geohash_to_geojson/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('geometry', geohash_to_geojson('geohash'))

geojson_to_geohash

geojson_to_geohash(geometry)

Point GeoJSON 열을 latitude,longitude 문자열로 바꿉니다. 입력 geometry는 Point 도형 열 이름입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import geojson_to_geohash

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/geojson_to_geohash/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('geohash', geojson_to_geohash('geometry'))

buffer

buffer(geometry, meters, metric_crs='EPSG:3395')

GeoJSON 도형에 meters 거리의 버퍼를 만듭니다. metric_crs 기본값은 EPSG:3395이며 계산 중간에 사용하는 투영입니다. 반환 도형은 입력의 좌표계를 유지합니다. 목표 지역 주변에서 왜곡이 작은 미터 단위 CRS를 선택합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import buffer

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/buffer/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('geometry', buffer('geometry', meters=10))

convex_hull

convex_hull(geometry)

geometry 열의 도형을 포함하는 볼록 껍질을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import convex_hull

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/convex_hull/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('convex_hull', convex_hull('geometry'))

bounding_box

bounding_box(geometry)

geometry 열 도형의 경계 사각형을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import bounding_box

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/bounding_box/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('bounding_box', bounding_box('geometry'))

bounding_circle

bounding_circle(geometry, segments=100)

geometry 열 도형의 경계 원을 반환합니다. segments는 원을 구성하는 선분 수이며 기본값은 100입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import bounding_circle

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/bounding_circle/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('bounding_circle', bounding_circle('geometry'))

simplify

simplify(geometry, tolerance, metric_crs='EPSG:3395')

도형의 꼭짓점 수를 줄입니다. tolerance는 새 꼭짓점과 원래 도형 사이에 허용하는 최대 거리이며 미터 단위 숫자입니다. metric_crs 기본값은 EPSG:3395로 중간 계산에 사용하고 출력은 입력 CRS를 유지합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import simplify

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/simplify/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('geometry', simplify('geometry', tolerance=10.0))

start_point

start_point(geometry)

GeoJSON LineString 열의 첫 점을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import start_point

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/start_point/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('start_point', start_point('geometry'))

end_point

end_point(geometry)

GeoJSON LineString 열의 마지막 점을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import end_point

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/end_point/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('end_point', end_point('geometry'))

centroid

centroid(geometry)

GeoJSON 도형 열의 중심점을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import centroid

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/centroid/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('centroid', centroid('geometry'))

intersection

intersection(geometry1, geometry2)

geometry1과 geometry2가 교차하는 부분의 도형을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import intersection

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/intersection/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('intersection', intersection('geometry1', 'geometry2'))

difference

difference(geometry1, geometry2)

geometry1에서 geometry2와 겹치는 부분을 제외한 도형을 반환합니다. 두 입력의 순서에 따라 결과가 달라집니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import difference

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/difference/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('difference', difference('geometry1', 'geometry2'))

symmetric_difference

symmetric_difference(geometry1, geometry2)

두 도형에서 서로 겹치지 않는 부분들을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import symmetric_difference

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/symmetric_difference/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('symmetric_difference', symmetric_difference('geometry1', 'geometry2'))

union

union(geometry1, geometry2)

두 도형의 합집합을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import union

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/union/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('union', union('geometry1', 'geometry2'))

distance

distance(geometry1, geometry2, metric_crs='EPSG:3395')

두 도형 사이의 유클리드 거리를 미터로 반환합니다. metric_crs 기본값은 EPSG:3395이며 목표 지역에 맞게 선택합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import distance

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/distance/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('distance', distance('geometry1', 'geometry2'))

length

length(geometry, metric_crs='EPSG:3395')

도형의 길이 또는 둘레를 미터로 반환합니다. metric_crs 기본값은 EPSG:3395입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import length

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/length/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('perimeter', length('geometry'))

area

area(geometry, metric_crs='EPSG:3395')

다각형의 면적을 제곱미터로 반환합니다. metric_crs 기본값은 EPSG:3395입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import area

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/area/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('area', area('geometry'))

contains

contains(geometry1, geometry2)

geometry1이 geometry2를 포함하는지 Boolean 값으로 반환합니다. geometry1이 판정의 기준 도형입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import contains

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/contains/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('geometry1_contains_geometry2', contains('geometry1', 'geometry2'))

intersects

intersects(geometry1, geometry2)

두 GeoJSON 도형이 교차하는지 Boolean 값으로 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import intersects

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/intersects/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.withColumn('geometry1_intersecting_geometry2', intersects('geometry1', 'geometry2'))

agg_union

agg_union(geometry)

그룹 안의 모든 geometry를 합친 도형을 반환합니다. 아래 예제는 country별로 집계합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import agg_union

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/agg_union/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.groupBy('country').agg(agg_union('geometry').alias('geometry'))

agg_intersection

agg_intersection(geometry)

그룹 안의 모든 geometry에 공통으로 포함되는 교차 도형을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import agg_intersection

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/agg_intersection/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.groupBy('country').agg(agg_intersection('geometry').alias('geometry'))

agg_bounding_box

agg_bounding_box(geometry)

그룹 안의 모든 geometry를 포함하는 경계 사각형을 반환합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import agg_bounding_box

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/agg_bounding_box/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return df.groupBy('country').agg(agg_bounding_box('geometry').alias('geometry'))

subdivide_explode

subdivide_explode(df, geometry, max_vertices)

복잡한 도형을 작은 구성 요소로 나누고 요소마다 행을 반환합니다. 공간 조인을 최적화할 때 사용할 수 있습니다. df는 PySpark DataFrame, geometry는 도형 열 이름, max_vertices는 구성 요소별 최대 꼭짓점 수입니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial
from geospatial_tools.functions import subdivide_explode

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/subdivide_explode/output'),
    df=Input('/Examples/Geospatial/input'),
)
def compute(df):
    return subdivide_explode(df, 'geometry', max_vertices=1000)

공간 조인

DataFrame.spatial_join

DataFrame.spatial_join(right_df, on, how='inner', **kwargs)

왼쪽과 오른쪽 데이터프레임을 공간 교차 조건으로 조인합니다. on은 왼쪽 및 오른쪽 도형 열 이름의 튜플입니다. how 기본값은 inner이며 일반 PySpark 조인 유형을 사용합니다.

선택 인자기본값과 조건
libraryh3. h3 또는 sedona 선택
resolutionH3 최적화 해상도. 생략하면 추정. 결과 자체가 아닌 최적화에 영향을 주며 sedona에 지정하면 예외
left_partitions, right_partitionssedona의 기본 재파티션을 덮어쓸 수 있음. H3에 지정하면 예외
left_pk, right_pk양쪽 기본 키 열. 생략하면 자동 생성
from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/spatial_join/output'),
    df1=Input('/Examples/Geospatial/left'),
    df2=Input('/Examples/Geospatial/right'),
)
def compute(df1, df2):
    return df1.spatial_join(df2, ('df1_geometry', 'df2_geometry'), 'left')

DataFrame.distance_join

DataFrame.distance_join(right_df, on, distance_meters, how='inner', metric_crs='EPSG:3395', **kwargs)

두 도형 사이 거리가 distance_meters 조건에 맞는 행을 조인합니다. on은 양쪽 도형 열 이름의 튜플이고 how 기본값은 inner입니다. metric_crs 기본값은 EPSG:3395입니다.

선택 인자기본값과 조건
left_pk, right_pk양쪽 기본 키 열. 생략하면 자동 생성
libraryh3. h3 또는 sedona 선택
resolutionH3 최적화 해상도. 생략하면 추정하며 sedona에 지정하면 예외
left_partitions, right_partitionssedona의 재파티션 설정. H3에 지정하면 예외

해상도는 결과가 아니라 최적화에 영향을 줍니다. 거리 계산에는 목표 지역의 왜곡이 작은 CRS를 사용합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/distance_join/output'),
    df1=Input('/Examples/Geospatial/left'),
    df2=Input('/Examples/Geospatial/right'),
)
def compute(df1, df2):
    return df1.distance_join(df2, ('df1_geometry', 'df2_geometry'), 10, 'left')

DataFrame.knn_join

DataFrame.knn_join(right_df, on, k, metric_crs='EPSG:3395', **kwargs)

각 왼쪽 행에 대해 오른쪽 데이터프레임의 가까운 k개 이웃을 찾는 left join입니다. on은 양쪽 도형 열 이름의 튜플이고 k는 정수입니다.

metric_crs 기본값은 EPSG:3395입니다. 선택적인 resolution은 H3 최적화에만 영향을 주며 생략하면 추정합니다. left_pk와 right_pk를 생략하면 키를 자동 생성합니다.

from transforms.api import transform_df, Input, Output, configure
from geospatial_tools import geospatial

@geospatial()
@configure("GEOSPARK")
@transform_df(
    Output('/Examples/Geospatial/knn_join/output'),
    df1=Input('/Examples/Geospatial/left'),
    df2=Input('/Examples/Geospatial/right'),
)
def compute(df1, df2):
    return df1.knn_join(df2, ('df1_geometry', 'df2_geometry'), k=1)

geopandas_spatial_join

geopandas_spatial_join(df_left, df_right, geometry_left, geometry_right, how='inner', op='intersects')

작은 데이터를 메모리 안의 pandas 데이터프레임으로 처리하는 공간 조인입니다. geometry_left와 geometry_right에는 각 입력의 GeoJSON 열 이름을 전달합니다.

인자기본값과 범위
df_left, df_right실제 입력 pandas.DataFrame
geometry_left, geometry_right양쪽 GeoJSON 열 이름
howinner. left, right, inner 지원
opintersects. intersects, contains, within 지원

큰 데이터에는 분산 DataFrame.spatial_join을 사용합니다. Foundry 입력을 dataframe().toPandas()로 읽으면 데이터를 드라이버 메모리로 가져오므로 입력 크기를 제한해야 합니다.

다음 함수는 실제로 제공받은 두 데이터프레임을 조인하여 pandas 결과를 반환합니다. Spark 출력으로 옮기는 호출자는 결과 열과 자료형에 맞는 명시적 스키마를 사용합니다. 빈 조인 결과에서 행만으로 스키마를 추론하지 않습니다.

import pandas as pd
from geospatial_tools.spatial_joins import geopandas_spatial_join


def join_in_memory(
    df_left: pd.DataFrame,
    df_right: pd.DataFrame,
) -> pd.DataFrame:
    return geopandas_spatial_join(
        df_left,
        df_right,
        geometry_left="geometry",
        geometry_right="geometry",
        how="inner",
        op="intersects",
    )