在Python中查找从点到最近多边形的距离

问题描述

我有一个带有位置坐标的地理数据框,另一个带有表示洪水区域的多边形。对于每个位置点,我需要找到到最近洪水区的距离,但我无法这样做。这就是数据的样子和我所做的。

points.head()

    Latitude    Longitude   geometry
0   29.873542   -95.300914  POINT (-95.30091 29.87354)
1   29.689952   -95.528468  POINT (-95.52847 29.68995)
2   29.789688   -95.090620  POINT (-95.09062 29.78969)
3   29.559194   -95.145382  POINT (-95.14538 29.55919)
4   29.817562   -95.720350  POINT (-95.72035 29.81756)


shape3.head()

    geometry    flood2
2   polyGON ((-96.17839 29.80032,-96.17845 29.800...   AV
3   polyGON ((-96.14694 30.05772,-96.14695 30.057...   AV
5   polyGON ((-96.09303 29.65069,-96.09323 29.650...   AV
8   polyGON ((-96.46769 29.86118,-96.46754 29.861...   AV
10  polyGON ((-96.42751 29.84184,-96.42716 29.841...   AV

编辑:没有截断,多边形看起来像这样

    geometry    flood2
2   polyGON ((-96.17839 29.80032,-96.17845 29.80025,-96.17855 29.80013,-96.17870 29.79998,-96.17882 29.79982,-96.17886 29.79977,-96.17908 29.79942,-96.17919 29.79922,-96.17931 29.79906,-96.17944 29.79890,-96.17948 29.79883,-96.17964 29.79866,-96.17969 29.79868,-96.17977 29.79869,-96.17987 29.79878,-96.17994 29.79879,-96.18019 29.79877,-96.18042 29.79870,-96.18063 29.79861,-96.18071 29.79858,-96.18073 29.79858,-96.18075 29.79857,-96.18080 29.79855,-96.18085 29.79856,-96.18085 29.79860,-96.18080 29.79864,-96.18077 29.79867,-96.18075 29.79868,-96.18065 29.79873,-96.18044 29.79883,-96.18031 29.79890,-96.18017 29.79899,-96.18000 29.79913,-96.17977 29.79938,-96.17967 29.79948,-96.17949 29.79973,-96.17918 29.79998,-96.17902 29.80014,-96.17895 29.80023,-96.17891 29.80031,-96.17887 29.80039,-96.17884 29.80045,-96.17839 29.80032))  AV
3   polyGON ((-96.14694 30.05772,-96.14695 30.05772,-96.14697 30.05770,-96.14702 30.05765,-96.14707 30.05762,-96.14713 30.05756,-96.14720 30.05750,-96.14721 30.05749,-96.14733 30.05739,-96.14756 30.05711,-96.14768 30.05692,-96.14775 30.05667,-96.14784 30.05621,-96.14786 30.05615,-96.14787 30.05599,-96.14769 30.05600,-96.14764 30.05598,-96.14761 30.05596,-96.14758 30.05589,-96.14757 30.05576,-96.14761 30.05559,-96.14763 30.05547,-96.14761 30.05517,-96.14755 30.05503,-96.14740 30.05493,-96.14728 30.05481,-96.14724 30.05468,-96.14711 30.05459,-96.14704 30.05451,-96.14704 30.05435,-96.14703 30.05434,-96.14696 30.05425,-96.14689 30.05416,-96.14676 30.05410,-96.14668 30.05403,-96.14665 30.05400,-96.14642 30.05388,-96.14618 30.05374,-96.14590 30.05360,-96.14574 30.05347,-96.14562 30.05327,-96.14561 30.05323,-96.14563 30.05324,-96.14575 30.05332,-96.14580 30.05338,-96.14582 30.05340,-96.14600 30.05348,-96.14618 30.05351,-96.14632 30.05354,-96.14649 30.05357,-96.14656 30.05359,-96.14668 30.05362,-96.14685 30.05366,-96.14703 30.05368,-96.14726 30.05372,-96.14734 30.05372,-96.14753 30.05378,-96.14761 30.05374,-96.14768 30.05361,-96.14764 30.05345,-96.14750 30.05325,-96.14745 30.05292,-96.14746 30.05281,-96.14744 30.05273,-96.14738 30.05265,-96.14687 30.05239,-96.14678 30.05231,-96.14674 30.05224,-96.14680 30.05220,-96.14697 30.05220,-96.14720 30.05225,-96.14748 30.05240,-96.14761 30.05242,-96.14773 30.05238,-96.14790 30.05223,-96.14796 30.05207,-96.14799 30.05190,-96.14826 30.05164,-96.14840 30.05157,-96.14845 30.05161,-96.14844 30.05170,-96.14828 30.05196,-96.14830 30.05203,-96.14840 30.05216,-96.14839 30.05224,-96.14822 30.05239,-96.14799 30.05267,-96.14795 30.05281,-96.14802 30.05318,-96.14812 30.05330,-96.14822 30.05333,-96.14836 30.05318,-96.14852 30.05307,-96.14865 30.05306,-96.14868 30.05316,-96.14866 30.05328,-96.14854 30.05357,-96.14855 30.05370,-96.14849 30.05382,-96.14832 30.05411,-96.14832 30.05420,-96.14836 30.05434,-96.14845 30.05450,-96.14877 30.05484,-96.14885 30.05498,-96.14885 30.05509,-96.14884 30.05521,-96.14884 30.05546,-96.14882 30.05558,-96.14882 30.05574,-96.14882 30.05577,-96.14880 30.05581,-96.14873 30.05585,-96.14863 30.05588,-96.14863 30.05589,-96.14862 30.05606,-96.14868 30.05615,-96.14877 30.05621,-96.14915 30.05622,-96.14950 30.05613,-96.14967 30.05614,-96.14962 30.05623,-96.14947 30.05641,-96.14936 30.05651,-96.14931 30.05657,-96.14919 30.05666,-96.14912 30.05672,-96.14905 30.05677,-96.14898 30.05683,-96.14895 30.05703,-96.14895 30.05732,-96.14904 30.05737,-96.14912 30.05745,-96.14918 30.05757,-96.14915 30.05762,-96.14905 30.05769,-96.14893 30.05772,-96.14879 30.05776,-96.14862 30.05781,-96.14847 30.05798,-96.14843 30.05811,-96.14843 30.05827,-96.14847 30.05847,-96.14847 30.05858,-96.14866 30.05882,-96.14866 30.05883,-96.14872 30.05890,-96.14874 30.05893,-96.14876 30.05898,-96.14878 30.05902,-96.14879 30.05906,-96.14879 30.05908,-96.14879 30.05913,-96.14879 30.05915,-96.14878 30.05916,-96.14877 30.05921,-96.14874 30.05926,-96.14871 30.05929,-96.14871 30.05930,-96.14848 30.05910,-96.14817 30.05882,-96.14711 30.05787,-96.14698 30.05776,-96.14694 30.05772))  AV
5   polyGON ((-96.09303 29.65069,-96.09323 29.65046,-96.09334 29.65036,-96.09360 29.65013,-96.09420 29.64981,-96.09474 29.64954,-96.09494 29.64951,-96.09509 29.64951,-96.09528 29.64951,-96.09548 29.64945,-96.09580 29.64928,-96.09603 29.64921,-96.09622 29.64903,-96.09642 29.64895,-96.09665 29.64900,-96.09690 29.64905,-96.09732 29.64888,-96.09756 29.64882,-96.09777 29.64881,-96.09795 29.64892,-96.09789 29.64900,-96.09775 29.64901,-96.09749 29.64907,-96.09720 29.64922,-96.09692 29.64936,-96.09656 29.64935,-96.09632 29.64937,-96.09600 29.64959,-96.09565 29.64981,-96.09543 29.64985,-96.09522 29.64999,-96.09503 29.64999,-96.09473 29.65015,-96.09449 29.65029,-96.09428 29.65037,-96.09392 29.65061,-96.09363 29.65075,-96.09343 29.65086,-96.09337 29.65092,-96.09327 29.65113,-96.09303 29.65069))  AV
8   polyGON ((-96.46769 29.86118,-96.46754 29.86110,-96.46706 29.86111,-96.46687 29.86117,-96.46670 29.86131,-96.46666 29.86140,-96.46663 29.86164,-96.46649 29.86163,-96.46636 29.86158,-96.46603 29.86136,-96.46583 29.86125,-96.46555 29.86116,-96.46546 29.86114,-96.46544 29.86120,-96.46540 29.86123,-96.46530 29.86119,-96.46517 29.86115,-96.46502 29.86109,-96.46497 29.86103,-96.46497 29.86097,-96.46459 29.86073,-96.46414 29.86051,-96.46391 29.86031,-96.46384 29.86022,-96.46376 29.86007,-96.46372 29.85991,-96.46372 29.85978,-96.46373 29.85947,-96.46367 29.85938,-96.46351 29.85921,-96.46333 29.85900,-96.46324 29.85895,-96.46298 29.85886,-96.46280 29.85875,-96.46268 29.85862,-96.46256 29.85838,-96.46249 29.85835,-96.46229 29.85840,-96.46221 29.85837,-96.46205 29.85832,-96.46198 29.85831,-96.46185 29.85833,-96.46171 29.85842,-96.46152 29.85842,-96.46134 29.85832,-96.46116 29.85830,-96.46112 29.85823,-96.46117 29.85815,-96.46119 29.85814,-96.46120 29.85812,-96.46129 29.85805,-96.46141 29.85799,-96.46151 29.85796,-96.46157 29.85794,-96.46163 29.85791,-96.46173 29.85786,-96.46178 29.85780,-96.46178 29.85776,-96.46170 29.85757,-96.46166 29.85750,-96.46144 29.85727,-96.46124 29.85708,-96.46108 29.85694,-96.46090 29.85675,-96.46081 29.85657,-96.46077 29.85640,-96.46075 29.85620,-96.46071 29.85606,-96.46062 29.85592,-96.46043 29.85572,-96.46030 29.85552,-96.46025 29.85547,-96.46016 29.85541,-96.46001 29.85538,-96.45984 29.85541,-96.45943 29.85551,-96.45901 29.85553,-96.45886 29.85556,-96.45848 29.85567,-96.45826 29.85577,-96.45800 29.85589,-96.45784 29.85594,-96.45770 29.85594,-96.45745 29.85588,-96.45732 29.85583,-96.45708 29.85575,-96.45681 29.85574,-96.45655 29.85576,-96.45622 29.85570,-96.45599 29.85572,-96.45586 29.85575,-96.45579 29.85578,-96.45561 29.85592,-96.45551 29.85604,-96.45541 29.85617,-96.45526 29.85639,-96.45513 29.85652,-96.45500 29.85660,-96.45491 29.85664,-96.45481 29.85667,-96.45459 29.85669,-96.45403 29.85667,-96.45384 29.85662,-96.45356 29.85652,-96.45341 29.85654,-96.45332 29.85657,-96.45313 29.85666,-96.45292 29.85671,-96.45287 29.85678,-96.45279 29.85691,-96.45267 29.85698,-96.45249 29.85698,-96.45235 29.85695,-96.45221 29.85687,-96.45208 29.85678,-96.45188 29.85661,-96.45174 29.85654,-96.45159 29.85650,-96.45138 29.85651,-96.45127 29.85657,-96.45115 29.85669,-96.45110 29.85682,-96.45106 29.85697,-96.45096 29.85697,-96.45092 29.85693,-96.45081 29.85676,-96.45071 29.85668,-96.45062 29.85664,-96.45050 29.85661,-96.45027 29.85660,-96.44983 29.85660,-96.44965 29.85657,-96.44947 29.85649,-96.44925 29.85632,-96.44915 29.85629,-96.44900 29.85631,-96.44871 29.85630,-96.44854 29.85636,-96.44851 29.85634,-96.44837 29.85623,-96.44807 29.85607,-96.44786 29.85601,-96.44765 29.85597,-96.44758 29.85594,-96.44734 29.85577,-96.44720 29.85570,-96.44706 29.85565,-96.44669 29.85556,-96.44655 29.85545,-96.44645 29.85525,-96.44636 29.85497,-96.44630 29.85491,-96.44620 29.85488,-96.44599 29.85487,-96.44579 29.85493,-96.44567 29.85493,-96.44551 29.85491,-96.44524 29.85488,-96.44521 29.85499,-96.44517 29.85523,-96.44513 29.85531,-96.44501 29.85547,-96.44481 29.85564,-96.44462 29.85573,-96.44451 29.85576,-96.44436 29.85577,-96.44419 29.85574,-96.44402 29.85568,-96.44395 29.85564,-96.44384 29.85557,-96.44374 29.85554,-96.44368 29.85553,-96.44346 29.85553,-96.44337 29.85548,-96.44334 29.85539,-96.44337 29.85532,-96.44346 29.85516,-96.44347 29.85505,-96.44344 29.85501,-96.44332 29.85485,-96.44331 29.85456,-96.44346 29.85467,-96.44370 29.85484,-96.44384 29.85481,-96.44402 29.85477,-96.44414 29.85474,-96.44453 29.85448,-96.44499 29.85388,-96.44534 29.85384,-96.44590 29.85421,-96.44630 29.85482,-96.44638 29.85489,-96.44656 29.85504,-96.44794 29.85544,-96.44809 29.85557,-96.44837 29.85573,-96.44859 29.85580,-96.44881 29.85584,-96.44906 29.85581,-96.44928 29.85578,-96.44952 29.85584,-96.44967 29.85593,-96.44988 29.85610,-96.45003 29.85615,-96.45041 29.85616,-96.45058 29.85614,-96.45088 29.85608,-96.45103 29.85605,-96.45114 29.85602,-96.45135 29.85597,-96.45155 29.85591,-96.45170 29.85587,-96.45188 29.85582,-96.45207 29.85573,-96.45213 29.85566,-96.45221 29.85565,-96.45237 29.85563,-96.45383 29.85560,-96.45386 29.85558,-96.45395 29.85554,-96.45408 29.85529,-96.45414 29.85519,-96.45426 29.85496,-96.45443 29.85478,-96.45455 29.85465,-96.45470 29.85455,-96.45481 29.85448,-96.45490 29.85443,-96.45513 29.85438,-96.45525 29.85435,-96.45529 29.85434,-96.45635 29.85438,-96.45641 29.85440,-96.45664 29.85448,-96.45779 29.85485,-96.45792 29.85483,-96.45795 29.85482,-96.45827 29.85477,-96.45910 29.85463,-96.45923 29.85461,-96.45934 29.85460,-96.45967 29.85456,-96.45977 29.85455,-96.45998 29.85466,-96.46039 29.85536,-96.46056 29.85566,-96.46086 29.85618,-96.46322 29.85838,-96.46365 29.85877,-96.46373 29.85893,-96.46381 29.85910,-96.46384 29.85923,-96.46402 29.86001,-96.46432 29.86040,-96.46456 29.86050,-96.46481 29.86059,-96.46703 29.86057,-96.46719 29.86060,-96.46777 29.86069,-96.47021 29.86246,-96.47092 29.86340,-96.47177 29.86428,-96.47214 29.86467,-96.47229 29.86495,-96.47233 29.86501,-96.47244 29.86537,-96.47231 29.86527,-96.47214 29.86519,-96.47206 29.86517,-96.47180 29.86517,-96.47168 29.86515,-96.47146 29.86515,-96.47141 29.86501,-96.47128 29.86463,-96.47118 29.86446,-96.47104 29.86427,-96.47075 29.86396,-96.47054 29.86379,-96.47034 29.86366,-96.46981 29.86341,-96.46967 29.86333,-96.46961 29.86326,-96.46948 29.86308,-96.46938 29.86302,-96.46917 29.86292,-96.46898 29.86275,-96.46887 29.86255,-96.46886 29.86247,-96.46882 29.86220,-96.46875 29.86211,-96.46863 29.86205,-96.46857 29.86203,-96.46829 29.86196,-96.46813 29.86183,-96.46793 29.86164,-96.46780 29.86155,-96.46778 29.86151,-96.46777 29.86128,-96.46769 29.86118))  AV
10  polyGON ((-96.42751 29.84184,-96.42716 29.84154,-96.42699 29.84142,-96.42690 29.84139,-96.42665 29.84131,-96.42653 29.84120,-96.42647 29.84106,-96.42642 29.84090,-96.42641 29.84082,-96.42635 29.84055,-96.42627 29.84034,-96.42617 29.84018,-96.42600 29.83999,-96.42582 29.83980,-96.42551 29.83951,-96.42530 29.83929,-96.42505 29.83897,-96.42487 29.83867,-96.42478 29.83842,-96.42473 29.83817,-96.42471 29.83774,-96.42468 29.83762,-96.42462 29.83753,-96.42453 29.83745,-96.42443 29.83738,-96.42431 29.83735,-96.42396 29.83728,-96.42387 29.83724,-96.42374 29.83715,-96.42356 29.83694,-96.42347 29.83679,-96.42342 29.83666,-96.42338 29.83645,-96.42338 29.83625,-96.42343 29.83627,-96.42363 29.83634,-96.42378 29.83635,-96.42389 29.83635,-96.42391 29.83635,-96.42399 29.83631,-96.42429 29.83619,-96.42439 29.83615,-96.42449 29.83615,-96.42455 29.83615,-96.42462 29.83621,-96.42472 29.83628,-96.42480 29.83653,-96.42486 29.83670,-96.42476 29.83771,-96.42480 29.83794,-96.42484 29.83821,-96.42504 29.83864,-96.42507 29.83870,-96.42507 29.83871,-96.42558 29.83927,-96.42607 29.83961,-96.42665 29.84003,-96.42720 29.84028,-96.42798 29.84040,-96.42817 29.84043,-96.42865 29.84050,-96.43037 29.84076,-96.43089 29.84084,-96.43125 29.84090,-96.43130 29.84090,-96.43231 29.84090,-96.43305 29.84090,-96.43329 29.84097,-96.43336 29.84100,-96.43357 29.84106,-96.43396 29.84133,-96.43415 29.84146,-96.43434 29.84169,-96.43436 29.84178,-96.43437 29.84184,-96.43441 29.84203,-96.43437 29.84225,-96.43436 29.84226,-96.43436 29.84227,-96.43434 29.84221,-96.43425 29.84202,-96.43415 29.84188,-96.43402 29.84182,-96.43390 29.84179,-96.43376 29.84178,-96.43359 29.84180,-96.43334 29.84187,-96.43320 29.84192,-96.43300 29.84204,-96.43279 29.84218,-96.43266 29.84229,-96.43265 29.84230,-96.43261 29.84233,-96.43246 29.84248,-96.43241 29.84254,-96.43232 29.84266,-96.43223 29.84279,-96.43220 29.84300,-96.43212 29.84307,-96.43184 29.84316,-96.43173 29.84320,-96.43165 29.84324,-96.43146 29.84333,-96.43125 29.84351,-96.43118 29.84351,-96.43112 29.84348,-96.43100 29.84335,-96.43089 29.84323,-96.43067 29.84300,-96.43045 29.84284,-96.43036 29.84279,-96.43020 29.84270,-96.42996 29.84259,-96.42973 29.84250,-96.42936 29.84232,-96.42911 29.84222,-96.42892 29.84217,-96.42891 29.84217,-96.42884 29.84216,-96.42871 29.84214,-96.42839 29.84209,-96.42790 29.84205,-96.42767 29.84195,-96.42751 29.84184))  AV

检查它们是否具有相同的 CRS

points.crs
<Geographic 2D CRS: epsg:4269>
Name: NAD83
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: north America - NAD83
- bounds: (167.65,14.92,-47.74,86.46)
Datum: north American Datum 1983
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich

shape3.crs

<Geographic 2D CRS: epsg:4269>
Name: NAD83
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: north America - NAD83
- bounds: (167.65,86.46)
Datum: north American Datum 1983
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich

计算距离:

dist_point_pol = points.boundary.distance(shape3.geometry)

UserWarning: Geometry is in a geographic CRS. Results from 'distance' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

我重新投影使用

points2 = points.to_crs(epsg=3857)
shape4 = shape3.to_crs(epsg=3857)

dist_point_pol2 = points2.boundary.distance(shape4.geometry)
UserWarning: The indices of the two GeoSeries are different.
  warn("The indices of the two GeoSeries are different.")

我认为 .reset_index() 之类的东西可以解决这个问题,但事实并非如此。最后,我要么得到没有意义的东西,要么只是NaN

我可能弄错了函数。我实际上需要一些东西来计算从每个点到最近的洪水区的距离(因此,不像 .distance 假设的那样对齐,但是添加 align=False 会给我一条错误消息,好像 align 不是预期的输入),从 this 的答案我认为 .boundary.distance() 是正确的,但似乎并非如此。

解决方法

为了回答您的问题,我们使用了 nearest_pointsshapely 函数。

  1. 准备一些数据:
df1 = points.to_crs(epsg=3857)
df2 = shape3.to_crs(epsg=3857)

# Extract point from you GeoDataFrame
point = df1.geometry

# Compute centroid of your area
centroid = df2.centroid

# Create unary union from centroid of area
centroids = unary_union(centroid)
>>> point.to_wkt()
0    POINT (-10608848.77333559 3487304.924649447)
1    POINT (-10634180.63666051 3463757.741176611)
2    POINT (-10585439.39761668 3476544.997885468)
3     POINT (-10591535.25293251 3447012.74414724)
4    POINT (-10655540.62055392 3480120.372628092)
dtype: object

>>> centroid.to_wkt()
2     POINT (-10706645.37489606 3477794.283230069)
3       POINT (-10703147.61430024 3510692.1568683)
5     POINT (-10697256.38062128 3458615.305393973)
8     POINT (-10737620.52149788 3485241.842837139)
10      POINT (-10734474.301016 3483131.295266777)
dtype: object

>>> centroids.to_wkt()
'MULTIPOINT (-10737620.5214978829026222 3485241.8428371394984424,-10734474.3010160010308027 3483131.2952667772769928,-10706645.3748960644006729 3477794.2832300686277449,-10703147.6143002416938543 3510692.1568683004006743,-10697256.3806212786585093 3458615.3053939728997648)'
  1. 计算每个 pointcentroids 之间的距离
out = point.apply(lambda p: centroid == nearest_points(p,centroids)[1])

nearest_points 返回一个元组,在本例中:

  • [0]POINT p
  • [1]POINT 中最近的 MULTIPOINT

只剩下在质心列表中找到POINT[1],所以我们有以下交叉表:

>>> out
      2      3     5      8      10
0  False  False  True  False  False
1  False  False  True  False  False
2  False  False  True  False  False
3  False  False  True  False  False
4  False  False  True  False  False

>>> out.idxmax(axis="columns")
0    5
1    5
2    5
3    5
4    5
dtype: int64

单线

>>> df1.apply(lambda p: df2.centroid == \
                        nearest_points(p.geometry,df2.centroid.unary_union)[1],axis="columns").idxmax(axis="columns")
0    5
1    5
2    5
3    5
4    5
dtype: int64

编辑:另一种方法

df1 = points.to_crs(epsg=3857)
df2 = shape3.to_crs(epsg=3857)

point = df1.geometry
polygon = df2.geometry

out = point.apply(lambda p: polygon.distance(p))
>>> out
              2              3              5              8              10
0   98131.524964   96824.778253   92693.462319  127194.722351  125043.444702
1   73719.669946   83033.617116   63047.492025  104004.590418  101372.084859
2  121097.679806  122221.621814  113001.243242  150810.634442  148482.376394
3  119072.273823  128120.650093  106140.417246  149361.810890  146630.045936
4   51036.728734   56191.958501   46675.287835   80619.485414   78297.679404

>>> out.idxmin(axis="columns")
0    5
1    5
2    5
3    5
4    5
dtype: int64