【问题标题】:Python: assign point to roads shapefilePython:将点分配给道路形状文件
【发布时间】:2015-10-25 23:00:14
【问题描述】:

我有一些来自 gps 数据 (Lat,Lon) 的数据点和我正在考虑的区域的相对 shapefile。所以:

import pandas as pd
import shapefile
sf = shapefile.Reader('roadshape')
df = pd.read_csv('gpsdata.csv')

现在df 包含我正在分析的数据是这样的:

 ID          x          y
3447    11.400427   48.816806
3448    11.400759   48.816772
3449    11.401424   48.816684
3450    11.401758   48.816631
3451    11.402090   48.816566
3452    11.402422   48.816490

我想为每个相应的shapefile 段分配。我正在尝试执行以下操作。我正在考虑边界框,我想尝试查看数据在哪个边界框中指向数据栏。

dfs = pd.DataFrame()
shapes = sf.shapes()
X =list()
Y=list()
for i in range(0,len(shapes)):
      X.append([shapes[i].bbox[0],shapes[i].bbox[2]])
      Y.append([shapes[i].bbox[1],shapes[i].bbox[3]])
dfs['X'] = X
dfs['Y'] = Y

现在如何查看我的积分在哪个 bbox 中? dfs 是这样的

dfs = 
                 X                             Y
0   [10.9467244189, 10.9704393002]  [48.2671975178, 48.2697440003]
1   [11.5138847999, 11.5143541004]  [48.6497096997, 48.6515363002]
2   [11.4618209998, 11.4620896004]  [48.9305448001, 48.9307776004]
3   [10.6196591004, 10.6207268996]  [48.8635958001, 48.8665684003]
4   [10.652098, 10.6559025999]  [48.8005320998, 48.8042877999]
5   [11.1863882997, 11.1884544004]  [48.3726685999, 48.3738253996]
6   [11.1580075998, 11.1593822] [48.3785226999, 48.3791247996]
7   [11.1077987, 11.1112508996] [48.3829125003, 48.3830440999]
8   [11.0842697004, 11.0886483996]  [48.3840543003, 48.3879626001]
9   [11.0910959001, 11.0926532003]  [48.3903297003, 48.3916850002]
10  [11.4766434001, 11.4822778002]  [49.0389071001, 49.0399456003]
11  [11.7037148998, 11.7073818] [48.6927748996, 48.6961230001]
12  [11.7767894997, 11.7770049998]  [48.6279809001, 48.6279908997]

【问题讨论】:

  • 我是否正确理解 shape[i].bbox[0] 是最左边的 X 坐标,bbox[1] - 顶部 Y 坐标,bbox[2] - 右 X,bbox[3] - 底部Y.这两点定义边界框?因此,您想要获取从每个 GPS 点映射到相应 BBOX 的字典(例如)?
  • 有更健壮的模块,如 shapely、fiona、ogr 来处理几何!
  • 你有什么更新吗?你可以将 panda df (bounds) 适配到我的 csv 中!
  • Ssllam 的解决方案对您的应用程序来说是否足够快?注意:我知道一种更快的方法。
  • 你为什么要从官方来源寻求答案?

标签: python geolocation shapefile


【解决方案1】:

我会选择 fiona,身材匀称,内置 csv!

假设我有两个文件:1) 一个包含多个行记录的行 shapefile。 2) 一个三列的csv文件,即id, longitude(x), latitude(y)

CSV 文件内容(经纬度为 UTM)-

id,lat,long

0,207726.012448,2733349.10914
0,197599.591396,2730510.17345
0,203187.5176,2736670.5686
0,207301.877268,2730639.81898
0,200929.610894,2726377.9799
0,204604.214301,2737608.342
0,203780.386032,2734372.2709
0,203077.172106,2731166.44271
0,202477.371994,2728622.46292
0,202249.861606,2734889.33996
0,201794.840831,2732159.21531

现在下面的代码为 line shapefile 的每条记录生成 bbox,并在打印状态后检查 csv 文件的哪个点在该 bbox 内!

import fiona
from shapely import geometry
import csv
csv_file = open(r"C:\data_test.csv",'rb')
reader = csv.reader(csv_file)
pnts = []
for i in reader:
    pnts.append ((i[1],i[2]))
bboxes = []   
fiona_collection = fiona.open(r"C:\Rd.shp")
for i in fiona_collection:
    bboxes.append(geometry.asShape(i['geometry']).bounds)


for i in pnts:
    for j in bboxes:
        shape = geometry.box(*map(float,j))
        pnt = geometry.Point(*map(float,i))
        if shape.contains(pnt):
            print "bbox {0} contains {1} ".format(j,i)

打印出来-

bbox (197306.68136754428, 2729718.6493367185, 197823.7504301681, 2732035.118737273) contains ('197599.591396', '2730510.17345') 
bbox (202799.29018572776, 2728807.5534000006, 204604.21430105247, 2737608.342) contains ('203187.5176', '2736670.5686') 
bbox (202799.29018572776, 2728807.5534000006, 204604.21430105247, 2737608.342) contains ('203780.386032', '2734372.2709') 
bbox (202799.29018572776, 2728807.5534000006, 204604.21430105247, 2737608.342) contains ('203077.172106', '2731166.44271') 
bbox (201237.0747999996, 2727558.2885, 203336.7932000002, 2728807.5534000006) contains ('202477.371994', '2728622.46292') 

您可以在here下载测试数据。

【讨论】:

    猜你喜欢
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多