You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache Sedona将CSV经纬度数据与Overture Maps建筑物数据集进行空间关联的技术咨询

Apache Sedona将CSV经纬度数据与Overture Maps建筑物数据集进行空间关联的技术咨询

嗨,看你是Sedona和Spark的新手,想要把自己CSV里的经纬度点和Overture Maps的建筑物数据做空间关联,这个需求在地理空间分析里很常见,我来帮你梳理下可行的方案、代码优化点,以及更高效的实现思路~

核心思路:空间关联的正确姿势

你的需求本质是点-in-多边形的空间匹配——找到每个经纬度点所在的建筑物多边形。最直接的方式就是用Sedona的空间判断函数结合关联操作,但要注意性能优化,不然大数据量下会很慢。

完整代码示例(补全并优化你的代码)

先把你没写完的代码补全,同时加入关键的预处理和优化步骤:

from sedona.spark import *
from pyspark.sql import functions as F
from pyspark.sql.types import DoubleType
import time

# 初始化Sedona上下文(适配Spark 3.x,确保依赖包版本兼容)
config = (
    SedonaContext.builder()
    .config("spark.hadoop.fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider")
    .config("fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider")
    # 指定Sedona和GeoTools的依赖包,版本要和Spark版本匹配
    .config('spark.jars.packages', 'org.apache.sedona:sedona-spark-shaded-3.0_2.12:1.5.1,org.datasyslab:geotools-wrapper:1.5.1-28.2')
    .getOrCreate()
)
sedona = SedonaContext.create(config)

# ----------------------
# 1. 处理自己的CSV经纬度数据
# ----------------------
# 加载CSV,关闭自动推断类型,手动转换经纬度为Double
df_csv = sedona.read.csv("s3a://your-bucket/your-latlon-data.csv", header=True, inferSchema=False)
df_csv = df_csv.withColumn("lat", F.col("lat").cast(DoubleType()))
df_csv = df_csv.withColumn("lon", F.col("lon").cast(DoubleType()))

# 生成WGS84坐标系(EPSG:4326)的点几何对象(注意Sedona中点的顺序是lon, lat)
df_csv = df_csv.withColumn("point_geom", F.expr("ST_Point(lon, lat)"))

# 过滤无效经纬度(避免后续空间计算出错)
df_csv = df_csv.filter((F.col("lat").between(-90, 90)) & (F.col("lon").between(-180, 180)))

# ----------------------
# 2. 加载并预处理Overture建筑物数据
# ----------------------
# Overture Maps公开建筑数据的路径(注意版本可能更新,确认最新路径)
overture_buildings_path = "s3://overturemaps-us-west-2/release/2024-03-15-alpha.0/theme=buildings/type=building/"
df_buildings = sedona.read.parquet(overture_buildings_path)

# 只保留需要的列(减少数据量,提升性能),比如几何列、建筑ID、名称、高度
df_buildings = df_buildings.select("geometry", "id", "names", "height")

# ----------------------
# 3. 空间索引与关联(关键优化)
# ----------------------
# 给建筑物的几何列创建空间索引,大幅提升点-in-多边形的匹配速度
df_buildings = df_buildings.createSpatialIndex("geometry")

# 用ST_Within做空间关联:判断点是否在建筑物多边形内
# 用left join保留所有CSV里的点,即使没有匹配到建筑物
result_df = df_csv.join(
    df_buildings,
    F.expr("ST_Within(point_geom, geometry)"),
    how="left"
)

# 查看前10条结果
result_df.show(10)

# 保存匹配结果(可选,比如存到S3的Parquet文件)
result_df.write.parquet("s3a://your-bucket/matched-building-results.parquet", mode="overwrite")

更高效的优化方案

如果你的经纬度点数量很多,或者Overture数据范围太大(比如全球建筑),可以先缩小数据范围再关联:

  1. 计算CSV数据的边界框:先找出你所有经纬度点的最小/最大经纬度,生成一个边界多边形
  2. 预过滤建筑物数据:只保留和这个边界框相交的建筑物,减少后续关联的数据量

示例代码:

# 计算CSV数据的边界框
bbox = df_csv.select(
    F.min("lon").alias("min_lon"),
    F.max("lon").alias("max_lon"),
    F.min("lat").alias("min_lat"),
    F.max("lat").alias("max_lat")
).first()

# 用边界框过滤建筑物数据,只保留范围内的建筑
df_buildings_filtered = df_buildings.filter(
    F.expr(f"ST_Intersects(geometry, ST_PolygonFromEnvelope({bbox.min_lon}, {bbox.min_lat}, {bbox.max_lon}, {bbox.max_lat}))")
)

# 再给过滤后的建筑数据创建索引,然后关联
df_buildings_filtered = df_buildings_filtered.createSpatialIndex("geometry")
result_df = df_csv.join(df_buildings_filtered, F.expr("ST_Within(point_geom, geometry)"), how="left")

注意事项

  • 版本兼容:Sedona的依赖包版本要和你的Spark版本匹配,比如Spark 3.2+可以用Sedona 1.5.x
  • CRS一致性:Overture Maps的几何数据默认是WGS84(EPSG:4326),所以你的点几何也要用这个坐标系,不要做不必要的投影转换
  • 分区调整:如果数据量很大,可以调整Spark的分区数(比如spark.sql.shuffle.partitions),避免小分区或超大分区影响性能

备注:内容来源于stack exchange,提问作者user28073171

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 13:39:51