強大的GeoPandas,幾行代碼實現點轉線功能

強大的GeoPandas,幾行代碼實現點轉線功能

在GIS數據處理操作時,經常會用到點轉線操作。一般ArcGIS、QGIS等等都會提供相應的工具。
這裏提供一種利用Python實現點轉線的方法。

1、原料 Pandas、GeoPandas、Shapely

Pandas及GeoPandas的強大之處,誰用誰知道

先來看以下點文件,格式是帶經緯度座標的csv文件。我們先用pandas將數據呈現出來。內容如下:

import pandas as pd
import geopandas as gpd
from shapely.geometry import LineString,Point

fp = r'E:\Dev\data\BigRoads31.csv'
df = pd.read_csv(fp)
df
FID Name State Speed Num Lng Lat
0 0 科技六路 3 10.0 0 108.888107 34.211662
1 1 科技六路 3 10.0 0 108.889725 34.211670
2 2 瞪羚路 2 15.0 1 108.856926 34.201595
3 3 瞪羚路 2 15.0 1 108.857033 34.201599
4 4 瞪羚路 2 15.0 1 108.859413 34.201637
5 5 瞪羚路 2 15.0 1 108.861893 34.201626
6 6 瞪羚路 2 15.0 1 108.863655 34.201611
7 7 瞪羚路 2 15.0 1 108.868385 34.201630
8 8 瞪羚路 2 15.0 1 108.869408 34.201630
9 9 瞪羚路 2 25.0 2 108.869408 34.201710
10 10 瞪羚路 2 25.0 2 108.869308 34.201710
11 11 瞪羚路 2 25.0 2 108.868408 34.201698
12 12 瞪羚路 2 25.0 2 108.863556 34.201675
13 13 瞪羚路 2 25.0 2 108.859413 34.201695
14 14 瞪羚路 2 25.0 2 108.857033 34.201706
15 15 瞪羚路 2 25.0 2 108.856926 34.201702
16 16 高新六路 2 25.0 3 108.877281 34.211655
17 17 高新六路 2 25.0 3 108.877281 34.211735
18 18 高新六路 2 25.0 3 108.877266 34.212143
19 19 高新六路 2 25.0 3 108.877274 34.214108
20 20 高新六路 2 25.0 3 108.877243 34.216526
21 21 高新六路 2 25.0 3 108.877243 34.220024
22 22 高新六路 2 25.0 3 108.877281 34.220097
23 23 高新四路 2 25.0 4 108.895088 34.235291
24 24 高新四路 2 25.0 4 108.895073 34.235027
25 25 高新四路 2 25.0 4 108.895088 34.232681
26 26 高新四路 2 25.0 4 108.895096 34.232456
27 27 高新四路 2 25.0 4 108.895058 34.231377
28 28 高新四路 2 25.0 4 108.895042 34.228569
29 29 高新四路 2 25.0 4 108.895042 34.228458
... ... ... ... ... ... ... ...
17517 17517 太華南路 0 NaN 580 108.972366 34.278843
17518 17518 太華南路 0 NaN 580 108.972359 34.280804
17519 17519 太華南路 0 NaN 580 108.972359 34.280850
17520 17520 太華南路 0 NaN 580 108.972336 34.280907
17521 17521 太華南路 0 NaN 580 108.972321 34.280968
17522 17522 太華南路 0 NaN 580 108.972305 34.281017
17523 17523 太華南路 0 NaN 580 108.972267 34.281063
17524 17524 太華南路 0 NaN 580 108.972038 34.281368
17525 17525 太華南路 0 NaN 580 108.971718 34.281731
17526 17526 太華南路 0 NaN 580 108.971619 34.281895
17527 17527 太華南路 0 NaN 580 108.971573 34.282001
17528 17528 太華南路 0 NaN 580 108.971535 34.282070
17529 17529 太華南路 0 NaN 580 108.971535 34.282116
17530 17530 太華南路 0 NaN 580 108.971519 34.282173
17531 17531 太華南路 0 NaN 580 108.971512 34.282421
17532 17532 太華南路 0 NaN 580 108.971558 34.285145
17533 17533 太華南路 0 NaN 580 108.971558 34.286316
17534 17534 太華南路 0 NaN 580 108.971573 34.289368
17535 17535 太華南路 0 NaN 580 108.971573 34.292759
17536 17536 太華南路 0 NaN 580 108.971581 34.293903
17537 17537 太華南路 0 NaN 580 108.971573 34.300178
17538 17538 太華南路 0 NaN 580 108.971581 34.301437
17539 17539 太華南路 0 NaN 580 108.971588 34.301540
17540 17540 太華南路 0 NaN 580 108.971603 34.302830
17541 17541 太華南路 0 NaN 580 108.971603 34.303635
17542 17542 太華北路 0 NaN 581 108.971519 34.309315
17543 17543 太華北路 0 NaN 581 108.971519 34.309181
17544 17544 太華北路 0 NaN 581 108.971512 34.307926
17545 17545 太華北路 0 NaN 581 108.971519 34.305836
17546 17546 太華北路 0 NaN 581 108.971519 34.303631

17547 rows × 7 columns

可以看出,每一行代表一個點,每一行的最後兩列爲座標。另外有兩列是我們需要關注的,FID列是數據的自增ID,Num是一個編號。後面的點轉線,將依據這兩列。

用Geopandas將點打印出來,可以看到點的地理分佈情況,如下圖:

xy = [Point(xy) for xy in zip(df.Lng,df.Lat)]
pointDataFrame = gpd.GeoDataFrame(df,geometry=xy)
pointDataFrame.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x276c20cba90>

png

熟悉GIS矢量數據結構的人都知道,線是由點構成的,其在物理結構上表現的就是一連串有序排列的點。根據這一特徵,我們來進行點轉線操作。

2、點轉線

有規則才成方圓,不,有規則才能連成線,通過查看上面的表,我們按照如下規則,將點轉換爲線:
1、num值相同的點,合併成一根線段;
2、線段上的點的排列順序,按照其在表中的排列順序FID
轉換過程如下:

#分組
dataGroup = df.groupby('Num')

#構造數據
tb = []
geomList = []
for name,group in dataGroup:
    # 分離出屬性信息,取每組的第1行前5列作爲數據屬性
    tb.append(group.iloc[0,:5])
    # 把同一組的點打包到一個list中
    xyList = [xy for xy in zip(group.Lng, group.Lat)]
    
    line = LineString(xyList)
    geomList.append(line)

# 點轉線
geoDataFrame = gpd.GeoDataFrame(tb, geometry = geomList)
#我們打印下結果看看
geoDataFrame
FID Name State Speed Num geometry
0 0 科技六路 3 10.0 0 LINESTRING (108.888107 34.21166229999999, 108....
2 2 瞪羚路 2 15.0 1 LINESTRING (108.856926 34.2015953, 108.857033 ...
9 9 瞪羚路 2 25.0 2 LINESTRING (108.869408 34.2017097, 108.869308 ...
16 16 高新六路 2 25.0 3 LINESTRING (108.877281 34.2116547, 108.877281 ...
23 23 高新四路 2 25.0 4 LINESTRING (108.895088 34.2352905, 108.895073 ...
31 31 科技一路 2 20.0 5 LINESTRING (108.900749 34.2257996, 108.900589 ...
38 38 210國道 1 40.0 6 LINESTRING (108.781281 33.8055725, 108.781242 ...
2914 2914 210國道 1 45.0 7 LINESTRING (108.8955 34.19851679999999, 108.89...
3131 3131 太白南路 1 35.0 8 LINESTRING (108.895638 34.1985016, 108.89666 3...
3174 3174 丈八三路 1 30.0 9 LINESTRING (108.875626 34.1899567, 108.87558 3...
3180 3180 丈八三路 1 30.0 10 LINESTRING (108.875481 34.19846339999999, 108....
3187 3187 唐延南路 1 35.0 11 LINESTRING (108.881477 34.1797485, 108.881508 ...
3229 3229 唐延南路 1 35.0 12 LINESTRING (108.890282 34.19849779999999, 108....
3267 3267 丈八東路 1 35.0 13 LINESTRING (108.874435 34.2050018, 108.874565 ...
3339 3339 丈八東路 1 35.0 14 LINESTRING (108.945831 34.19813920000001, 108....
3408 3408 丈八六路 1 35.0 15 LINESTRING (108.855911 34.1825256, 108.855934 ...
3430 3430 丈八六路 1 40.0 16 LINESTRING (108.857033 34.2045937, 108.856934 ...
3451 3451 錦業路 1 35.0 17 LINESTRING (108.841652 34.1938324, 108.841728 ...
3482 3482 丈八五路 1 40.0 18 LINESTRING (108.864204 34.1888275, 108.86409 3...
3497 3497 丈八五路 1 35.0 19 LINESTRING (108.863541 34.20478060000001, 108....
3511 3511 丈八二路 1 35.0 20 LINESTRING (108.880165 34.1901054, 108.880142 ...
3518 3518 丈八二路 1 35.0 21 LINESTRING (108.884537 34.1985245, 108.884178 ...
3527 3527 錦業一路 1 35.0 22 LINESTRING (108.846642 34.1911011, 108.846901 ...
3549 3549 錦業一路 1 35.0 23 LINESTRING (108.89061 34.1916618, 108.888481 3...
3572 3572 丈八四路 1 35.0 24 LINESTRING (108.869232 34.1797409, 108.869209 ...
3595 3595 丈八四路 1 35.0 25 LINESTRING (108.869316 34.2062225, 108.869308 ...
3613 3613 丈八一路 1 35.0 26 LINESTRING (108.884712 34.1902275, 108.884705 ...
3624 3624 科技六路 1 30.0 27 LINESTRING (108.877266 34.2116547, 108.879601 ...
3629 3629 科技六路 1 30.0 28 LINESTRING (108.889725 34.2116699, 108.892159 ...
3649 3649 唐延路 1 40.0 29 LINESTRING (108.890419 34.19849779999999, 108....
... ... ... ... ... ... ...
16779 16779 華清西路 1 40.0 552 LINESTRING (108.995522 34.2850761, 108.995415 ...
16799 16799 華清東路 1 40.0 553 LINESTRING (108.995522 34.2850189, 108.996872 ...
16818 16818 華清東路 1 45.0 554 LINESTRING (109.014343 34.28803629999999, 109....
16837 16837 太華南路 1 35.0 555 LINESTRING (108.971519 34.30363079999999, 108....
16894 16894 西安高架快速幹道 1 70.0 556 LINESTRING (108.995911 34.2907372, 108.995949 ...
16981 16981 西安高架快速幹道 1 60.0 557 LINESTRING (109.052925 34.2957687, 109.052406 ...
17097 17097 礦山路 1 30.0 558 LINESTRING (108.995697 34.3014565, 108.996246 ...
17110 17110 礦山路 1 30.0 559 LINESTRING (109.020103 34.3016586, 109.018806 ...
17130 17130 玄武路 1 40.0 560 LINESTRING (108.947319 34.3048973, 108.947769 ...
17151 17151 玄武路 1 30.0 561 LINESTRING (108.971581 34.3058472, 108.971519 ...
17175 17175 太元路 1 35.0 562 LINESTRING (108.971512 34.3014908, 108.971581 ...
17187 17187 太元路 1 30.0 563 LINESTRING (108.995705 34.3015594, 108.995415 ...
17203 17203 太和路 1 30.0 564 LINESTRING (108.984474 34.2986145, 108.984482 ...
17206 17206 太和路 1 30.0 565 LINESTRING (108.98407 34.3100739, 108.98407 34...
17212 17212 太華北路 1 35.0 566 LINESTRING (108.971603 34.3036346, 108.971581 ...
17240 17240 太華北路 1 30.0 567 LINESTRING (108.971588 34.3395691, 108.971588 ...
17263 17263 北辰路 1 40.0 568 LINESTRING (108.995834 34.3084831, 108.995789 ...
17308 17308 北辰路 1 40.0 569 LINESTRING (108.995682 34.3673172, 108.995628 ...
17341 17341 含元路 1 25.0 570 LINESTRING (108.971512 34.2862816, 108.971573 ...
17365 17365 含元路 1 25.0 571 LINESTRING (108.994949 34.29107279999999, 108....
17392 17392 自強東路 1 25.0 572 LINESTRING (108.947289 34.280201, 108.950539 3...
17414 17414 自強東路 1 25.0 573 LINESTRING (108.950539 34.2802086, 108.947289 ...
17416 17416 建強路 1 30.0 574 LINESTRING (108.955788 34.29272460000001, 108....
17427 17427 建強路 1 30.0 575 LINESTRING (108.955238 34.3052254, 108.955223 ...
17439 17439 龍首北路 0 NaN 576 LINESTRING (108.92231 34.2926826, 108.92469 34...
17465 17465 龍首北路 0 NaN 577 LINESTRING (108.960281 34.29281229999999, 108....
17486 17486 長纓西路 0 NaN 578 LINESTRING (108.972626 34.2773285, 108.973923 ...
17500 17500 長纓東路 0 NaN 579 LINESTRING (108.995468 34.27758789999999, 108....
17504 17504 太華南路 0 NaN 580 LINESTRING (108.972733 34.2774429, 108.97271 3...
17542 17542 太華北路 0 NaN 581 LINESTRING (108.971519 34.30931470000001, 108....

582 rows × 6 columns

可以看到,數據已經按Num分組,並合併成了一個LineString對象。
可以通過地圖顯示查看結果。
geoDataFrame.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x276c0abdcc0>

png


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章