当前位置: 首页 > 知识库问答 >
问题:

正在寻找使用Shapely快速查找点所属多边形的方法

唐海阳
2023-03-14

我有一组约36000个多边形,它们代表国家的一个分区(~县)。我的python脚本接收很多点:pointId、经度、纬度。

对于每一个点,我想发回pointId,polygonId。对于每个点,循环到所有多边形并使用myPoint。在(myPolygon)中,效率非常低。

我认为shapely库提供了一种更好的方法来准备多边形,以便为一个点查找多边形成为一个树路径(国家、地区、子地区……)

以下是我目前的代码:

import sys
import os
import json
import time
import string
import uuid

py_id = str(uuid.uuid4())

sys.stderr.write(py_id + '\n')
sys.stderr.write('point_in_polygon.py V131130a.\n')
sys.stderr.flush()

from shapely.geometry import Point
from shapely.geometry import Polygon
import sys
import json
import string
import uuid
import time

jsonpath='.\cantons.json'
jsonfile = json.loads(open(jsonpath).read())

def find(id, obj):
    results = []

    def _find_values(id, obj):
        try:
            for key, value in obj.iteritems():
                if key == id:
                    results.append(value)
                elif not isinstance(value, basestring):
                    _find_values(id, value)
        except AttributeError:
            pass

        try:
            for item in obj:
                if not isinstance(item, basestring):
                    _find_values(id, item)
        except TypeError:
            pass

    if not isinstance(obj, basestring):
        _find_values(id, obj)
    return results


#1-Load polygons from json  
r=find('rings',jsonfile)
len_r = len(r)

#2-Load attributes from json
a=find('attributes',jsonfile)

def insidePolygon(point,json):
        x=0
    while x < len_r :
            y=0
            while y < len(r[x]) :
        p=Polygon(r[x][y])
        if(point.within(p)):
            return a[y]['OBJECTID'],a[y]['NAME_5']
        y=y+1
        x=x+1
    return None,None


while True:
    line = sys.stdin.readline()
    if not line:
        break
    try:
        args, tobedropped = string.split(line, "\n", 2)

        #input: vehicleId, longitude, latitude
        vehicleId, longitude, latitude = string.split(args, "\t")

        point = Point(float(longitude), float(latitude))
        cantonId,cantonName = insidePolygon(point,r)

        #output: vehicleId, cantonId, cantonName
        # vehicleId will be 0 if not found
        # vehicleId will be < 0 in case of an exception
        if (cantonId == None):
            print "\t".join(["0", "", ""])
        else:
            print "\t".join([str(vehicleId), str(cantonId), str(cantonName)])

    except ValueError:
        print "\t".join(["-1", "", ""])
        sys.stderr.write(py_id + '\n')
        sys.stderr.write('ValueError in Python script\n')
        sys.stderr.write(line)
        sys.stderr.flush()
    except:
        sys.stderr.write(py_id + '\n')
        sys.stderr.write('Exception in Python script\n')
        sys.stderr.write(str(sys.exc_info()[0]) + '\n')
        sys.stderr.flush()
        print "\t".join(["-2", "", ""])

共有2个答案

江展
2023-03-14

很好,

以下是示例代码

polygons_sf = shapefile.Reader("<shapefile>")
polygon_shapes = polygons_sf.shapes()
polygon_points = [q.points for q in polygon_shapes ]
polygons = [Polygon(q) for q in polygon_points]
idx = index.Index()
count = -1
for q in polygon_shapes:
    count +=1
    idx.insert(count, q.bbox)
[...]
for j in idx.intersection([point.x, point.y]):
    if(point.within(polygons[j])):
        geo1, geo2 = polygons_sf.record(j)[0], polygons_sf.record(j)[13]
        break

谢谢

孟鹤龄
2023-03-14

使用Rtree(示例)作为R-树索引:(1)索引36k多边形的边界(在读取jsonfile后就这样做),然后(2)非常快速地找到每个多边形到您感兴趣的点的交叉边界框。然后,(3)对于来自Rtree的交叉边界框,使用shapely来使用,例如point.within(p)来进行实际的多边形点分析。你应该会看到这种技术的巨大飞跃。

 类似资料:
  • 问题内容: 我有一组〜36,000个多边形,代表该国家的一个分区(〜县)。我的python脚本收到很多点:pointId,经度,纬度。 对于每个点,我想发送回pointId,polygonId。对于每个点,循环进入所有多边形并使用myPoint.within(myPolygon)效率很低。 我想匀称的库提供了一种更好的方式来准备多边形,以便找到一个点的多边形成为树路径(国家,地区,子地区…) 到目

  • 我有一个带有lat和lon的商店位置csv文件。我还有一个geojson文件,其中包含美国人口普查区的多边形特征。我想使用Python查看每个位置存在哪些多边形。 我使用Shapely Python库的包含()来循环通过存储位置的csv文件,获取lat和lon坐标,然后检查这些坐标是否存在于Geojson文件中的一个多边形中。 如果我先遍历每个位置/坐标,然后遍历每个多边形,使用contains(

  • 我有一个数据库,其中一个表(ca_licenses)是商业地址,另一个表是市议会区多边形的公共模式(ca_la_la_council)。 我运行此查询是为了将议会表中的地区号码放在企业地址表中: 我的问题是我总是得不到任何结果。两个几何列都是几何类型,SRID是4326。 示例ca_licenses数据:https://raw . githubusercontent . com/pour safe

  • 问题内容: 我对mysql,多边形的Geometric数据类型有一个典型的问题。 我有经度和纬度数组形式的面数据,例如: 我有一个经度和纬度坐标的点(顶点),例如: 现在,我想查找此顶点(点)是否在多边形内。我如何在php中做到这一点? 问题答案: 这是我从另一种语言转换为PHP的功能: 附加: 有关更多功能,我建议您使用此处提供的polygon.php类。使用顶点创建类,并以测试点作为输入调用该

  • 我正在寻找一种方法来创建一组多边形(rechtangles),沿着一条线在多个多边形中创建一组多边形(rechtangles),并将其水平隔开,如图所示。 我尝试生成点并将其用作多边形的中点,但问题是,通过创建等间距的点光栅,除了180度之外,不可能以任何其他方向旋转。 例子 给出了一个多多边形形状的对象和由宽度和高度以及每个多边形之间的垂直和水平间距定义的多边形。多边形应仅放置在多多边形内,且不

  • 我在location _ table(point _ location geometry)中存储了位置,现在我在谷歌地图上绘制了一个多边形,并将该多边形(几何)传递给后端,我想找到该多边形内的所有位置。 当我将多边形从谷歌地图传递到后端时,这给了我随机的结果。它没有给我多边形内的所有点。它给了我甚至在多边形之外的点。 在 postgis 中准确查找多边形内所有点的正确方法是什么(也包括边界情况)