Python处理Point, MultiPolygon, Polygon, LineString等Geo地理形状数据
依赖库
from shapely import Polygon, Point, LineString
import re
自编写函数
1. 将 字符串Polygon/MultiPolygon数据 转换为 坐标数据
输入输出
调用方式:fork_MULTIPOLYGON_POLYGON_to_POLYGONLIST(str_polygon)
输入:字符串形式的Polygon/MultiPolygon数据(支持三种格式)
输出:一个双层嵌套列表,顶层列表的元素是一个个POLYGON,底层列表的元素是一个POLYGON里的一个个坐标点
功能描述:将 Polygon/MultiPolygon 转化为 一个列表,这个列表里有多个POLYGON列表,每个POLYGON列表中的经纬度坐标用元组表示
样例
格式一:
MULTIPOLYGON (((-73.97535722895489 40.79358795668606, -73.97550491442216 40.7932206693501, -73.97571880885164 40.79329900902139, -73.97557038329896 40.793666024933465, -73.97535722895489 40.79358795668606)), ((-73.97552582561218 40.79316866412968, -73.97558333155439 40.79302564935169, -73.97579761926521 40.79310413236238, -73.97573982501896 40.793247041771274, -73.97552582561218 40.79316866412968)))
输出
[
[(-73.97535722895489, 40.79358795668606), (-73.97550491442216, 40.7932206693501), (-73.97571880885164, 40.79329900902139), (-73.97557038329896, 40.793666024933465), (-73.97535722895489, 40.79358795668606)],
[(-73.97552582561218, 40.79316866412968), (-73.97558333155439, 40.79302564935169), (-73.97579761926521, 40.79310413236238), (-73.97573982501896, 40.793247041771274), (-73.97552582561218, 40.79316866412968)]
]
格式二:
POLYGON ((-73.97759524402524 40.7618905, -73.97760683658178 40.76183484508208, -73.9776404794912 40.76178463805529, -73.97769287955111 40.76174479353323, -73.97775890747857 40.76171921177534, -73.9778321 40.761710396902316, -73.97790529252143 40.76171921177534, -73.97797132044889 40.76174479353323, -73.9780237205088 40.76178463805529, -73.97805736341822 40.76183484508208, -73.97806895597476 40.7618905, -73.97805736341822 40.76194615491792, -73.9780237205088 40.76199636194471, -73.97797132044889 40.76203620646677, -73.97790529252143 40.762061788224656, -73.9778321 40.76207060309768, -73.97775890747857 40.762061788224656, -73.97769287955111 40.76203620646677, -73.9776404794912 40.76199636194471, -73.97760683658178 40.76194615491792, -73.97759524402524 40.7618905))
输出
[
[(-73.97759524402524, 40.7618905), (-73.97760683658178, 40.76183484508208), (-73.9776404794912, 40.76178463805529), (-73.97769287955111, 40.76174479353323), (-73.97775890747857, 40.76171921177534), (-73.9778321, 40.761710396902316), (-73.97790529252143, 40.76171921177534), (-73.97797132044889, 40.76174479353323), (-73.9780237205088, 40.76178463805529), (-73.97805736341822, 40.76183484508208), (-73.97806895597476, 40.7618905), (-73.97805736341822, 40.76194615491792), (-73.9780237205088, 40.76199636194471), (-73.97797132044889, 40.76203620646677), (-73.97790529252143, 40.762061788224656), (-73.9778321, 40.76207060309768), (-73.97775890747857, 40.762061788224656), (-73.97769287955111, 40.76203620646677), (-73.9776404794912, 40.76199636194471), (-73.97760683658178, 40.76194615491792), (-73.97759524402524, 40.7618905)]
]
格式三:
POLYGON ((-73.98635378499995 40.764514924000025, -73.98637627999994 40.76448596900008, -73.98622909499994 40.764422067000055, -73.98624709199999 40.76439890300003, -73.98608441399995 40.764328275000025, -73.98613390299994 40.76426457500003, -73.98599446599997 40.764204035000034, -73.98598546799997 40.76421561700005, -73.98560588899994 40.764050816000065, -73.98557889499995 40.76408556100006, -73.98553241599996 40.76406538100008, -73.98555491099995 40.764036427000065, -73.98557815099997 40.764046517000054, -73.98560064599997 40.76401756200005, -73.98557740699994 40.76400747300005, -73.98567188699997 40.76388586200005, -73.98639231199996 40.76419864800005, -73.98637881499997 40.76421602000005, -73.98653374599996 40.76428328600008, -73.98654724199997 40.76426591300003, -73.98671766799998 40.76433990400005, -73.98672666499994 40.76432832300003, -73.98679638399994 40.764358591000075, -73.98678288799994 40.76437596400007, -73.98689133999994 40.76442305000006, -73.98690483699994 40.76440567700007, -73.98709075499994 40.76448639400007, -73.98707275899994 40.76450955800004, -73.98712698499997 40.76453310000005, -73.98711348899997 40.76455047300004, -73.98733039399997 40.764644643000054, -73.98736188599997 40.764604106000036, -73.98740836599995 40.764624285000025, -73.98742186299995 40.76460691200003, -73.98777046199996 40.76475825500006, -73.98740154699993 40.765233118000026, -73.98737055999999 40.76521966400003, -73.98736156199993 40.76523124600004, -73.98676506899994 40.76497227900006, -73.98678756299995 40.76494332400006, -73.98646995199994 40.76480543100007, -73.98646095399994 40.76481701300003, -73.98620531599994 40.764706025000066, -73.98619181899994 40.76472339800006, -73.98589744899994 40.76459559400007, -73.98605041699994 40.76439870100006, -73.98625182799998 40.764486146000024, -73.98624282899993 40.76449772900003, -73.98635128199999 40.76454481400003, -73.98634678299999 40.76455060600006, -73.98630804999993 40.76453378900004, -73.98624506299996 40.76461486200003, -73.98626055599993 40.76462158900006, -73.98622006499994 40.76467370700004, -73.98628203699997 40.76470061300006, -73.98630003399995 40.76467744900003, -73.98626904799994 40.76466399700007, -73.98630953899993 40.76461187800004, -73.98636376499996 40.76463542100004, -73.98631427599997 40.764699122000025, -73.98638399499998 40.76472939100006, -73.98652796399995 40.764544080000064, -73.98650472399999 40.764533990000075, -73.98647772999993 40.76456873600006, -73.98635378499995 40.764514924000025), (-73.98698650299997 40.764820600000064, -73.98700449999995 40.76479743600004, -73.98715943199994 40.76486470000003, -73.98712793899995 40.76490523700005, -73.98715117899997 40.76491532700004, -73.98711518699997 40.76496165400005, -73.98714617299999 40.764975108000044, -73.98725864899995 40.76483033300008, -73.98698751699999 40.76471262100006, -73.98697401999993 40.76472999400005, -73.98678035399996 40.76464591300004, -73.98676685699996 40.76466328600003, -73.98680095699996 40.76475940500006, -73.98683156999994 40.76475333500008, -73.98698650299997 40.764820600000064))
输出
/home/lizhicheng/UrbanKG/venv/bin/python /home/lizhicheng/UrbanKG/src/test.py
[
[(-73.98635378499995, 40.764514924000025), (-73.98637627999994, 40.76448596900008), (-73.98622909499994, 40.764422067000055), (-73.98624709199999, 40.76439890300003), (-73.98608441399995, 40.764328275000025), (-73.98613390299994, 40.76426457500003), (-73.98599446599997, 40.764204035000034), (-73.98598546799997, 40.76421561700005), (-73.98560588899994, 40.764050816000065), (-73.98557889499995, 40.76408556100006), (-73.98553241599996, 40.76406538100008), (-73.98555491099995, 40.764036427000065), (-73.98557815099997, 40.764046517000054), (-73.98560064599997, 40.76401756200005), (-73.98557740699994, 40.76400747300005), (-73.98567188699997, 40.76388586200005), (-73.98639231199996, 40.76419864800005), (-73.98637881499997, 40.76421602000005), (-73.98653374599996, 40.76428328600008), (-73.98654724199997, 40.76426591300003), (-73.98671766799998, 40.76433990400005), (-73.98672666499994, 40.76432832300003), (-73.98679638399994, 40.764358591000075), (-73.98678288799994, 40.76437596400007), (-73.98689133999994, 40.76442305000006), (-73.98690483699994, 40.76440567700007), (-73.98709075499994, 40.76448639400007), (-73.98707275899994, 40.76450955800004), (-73.98712698499997, 40.76453310000005), (-73.98711348899997, 40.76455047300004), (-73.98733039399997, 40.764644643000054), (-73.98736188599997, 40.764604106000036), (-73.98740836599995, 40.764624285000025), (-73.98742186299995, 40.76460691200003), (-73.98777046199996, 40.76475825500006), (-73.98740154699993, 40.765233118000026), (-73.98737055999999, 40.76521966400003), (-73.98736156199993, 40.76523124600004), (-73.98676506899994, 40.76497227900006), (-73.98678756299995, 40.76494332400006), (-73.98646995199994, 40.76480543100007), (-73.98646095399994, 40.76481701300003), (-73.98620531599994, 40.764706025000066), (-73.98619181899994, 40.76472339800006), (-73.98589744899994, 40.76459559400007), (-73.98605041699994, 40.76439870100006), (-73.98625182799998, 40.764486146000024), (-73.98624282899993, 40.76449772900003), (-73.98635128199999, 40.76454481400003), (-73.98634678299999, 40.76455060600006), (-73.98630804999993, 40.76453378900004), (-73.98624506299996, 40.76461486200003), (-73.98626055599993, 40.76462158900006), (-73.98622006499994, 40.76467370700004), (-73.98628203699997, 40.76470061300006), (-73.98630003399995, 40.76467744900003), (-73.98626904799994, 40.76466399700007), (-73.98630953899993, 40.76461187800004), (-73.98636376499996, 40.76463542100004), (-73.98631427599997, 40.764699122000025), (-73.98638399499998, 40.76472939100006), (-73.98652796399995, 40.764544080000064), (-73.98650472399999, 40.764533990000075), (-73.98647772999993, 40.76456873600006), (-73.98635378499995, 40.764514924000025)],
[(-73.98698650299997, 40.764820600000064), (-73.98700449999995, 40.76479743600004), (-73.98715943199994, 40.76486470000003), (-73.98712793899995, 40.76490523700005), (-73.98715117899997, 40.76491532700004), (-73.98711518699997, 40.76496165400005), (-73.98714617299999, 40.764975108000044), (-73.98725864899995, 40.76483033300008), (-73.98698751699999, 40.76471262100006), (-73.98697401999993, 40.76472999400005), (-73.98678035399996, 40.76464591300004), (-73.98676685699996, 40.76466328600003), (-73.98680095699996, 40.76475940500006), (-73.98683156999994, 40.76475333500008), (-73.98698650299997, 40.764820600000064)]
]
函数代码
def extract_content_from_MULTIPOLYGON(string):
pattern = r'\(\((.*?)\)\)' # 定义正则表达式模式,使用非贪婪匹配
matches = re.findall(pattern, string) # 使用findall函数查找所有匹配项
if not matches: # 如果没有匹配项,返回空列表
return []
else:
return matches
def MULTIPOLYGON_to_POLYGONLIST(multpolygon):
prefix = 'MULTIPOLYGON'
multpolygon = multpolygon[len(prefix):]
multpolygon = multpolygon[2:-1]
list_polygon_str = extract_content_from_MULTIPOLYGON(multpolygon)
if not list_polygon_str:
return []
else:
list_POLYGON = []
for polygon_str in list_polygon_str:
list_point_str = polygon_str.split(',')
POLYGON = []
for point in list_point_str:
if point[0] == ' ':
point_str = point[1:]
else:
point_str = point
point_list = point_str.split(' ')
# dest_str = point_list[0] + ',' + point_list[1]
longitude = float(point_list[0])
latitude = float(point_list[1])
Tuple = (longitude, latitude)
POLYGON.append(Tuple)
# POLYGON.append(dest_str)
list_POLYGON.append(POLYGON)
return list_POLYGON
def fork_MULTIPOLYGON_POLYGON_to_POLYGONLIST(input):
if input.startswith('MULTIPOLYGON'):
return MULTIPOLYGON_to_POLYGONLIST(input)
else:
prefix = 'POLYGON'
input = input[len(prefix):]
input = input[3:-2]
if '(' in input or ')' in input:
input = '(' + input + ')'
arr = input.split('), (')
list_str = []
for item in arr:
new_item = item
if item[0] == '(':
new_item = item[1:]
if item[-1] == ')':
new_item = item[:-1]
list_str.append(new_item)
list_POLYGON = []
for polygon_str in list_str:
list_point_str = polygon_str.split(',')
POLYGON = []
for point in list_point_str:
if point[0] == ' ':
point_str = point[1:]
else:
point_str = point
point_list = point_str.split(' ')
# dest_str = point_list[0] + ',' + point_list[1]
longitude = float(point_list[0])
latitude = float(point_list[1])
Tuple = (longitude, latitude)
POLYGON.append(Tuple)
# POLYGON.append(dest_str)
list_POLYGON.append(POLYGON)
return list_POLYGON
else: # 只可能有一个polygon
# 按 ,split 如果以‘ ’开头,把空格去掉
arr_str_coordinate = input.split(',')
str_coordinate = []
for coordinate in arr_str_coordinate:
if coordinate[0] == ' ':
str_coordinate.append(coordinate[1:]) # 如果开头有空格,则去掉空格
else:
str_coordinate.append(coordinate)
list_point = []
for str_coord in str_coordinate:
a, b = str_coord.split(' ')
longitude = float(a)
latitude = float(b)
list_point.append((longitude, latitude))
list_POLYGON = [list_point]
return list_POLYGON
2. 将 Polygon/MultiPolygon坐标数据 转换为 shapely库中的Polygon类对象的列表
输入输出
调用方式:list_polygon = list_POLYGON2POLYGONs(list_POLYGON)
输入:1函数的输出——“一个双层嵌套列表,顶层列表的元素是一个个POLYGON,底层列表的元素是一个POLYGON里的一个个坐标点”
输出:shapely库中的Polygon类对象的列表
功能描述:将 Polygon/MultiPolygon坐标数据 转换为 shapely库中的Polygon类对象的列表
样例
# input为1函数介绍中的格式一样例
input = 'MULTIPOLYGON (((-73.97535722895489 40.79358795668606, -73.97550491442216 40.7932206693501, -73.97571880885164 40.79329900902139, -73.97557038329896 40.793666024933465, -73.97535722895489 40.79358795668606)), ((-73.97552582561218 40.79316866412968, -73.97558333155439 40.79302564935169, -73.97579761926521 40.79310413236238, -73.97573982501896 40.793247041771274, -73.97552582561218 40.79316866412968)))'
list_POLYGON = fork_MULTIPOLYGON_POLYGON_to_POLYGONLIST(input)
list_polygon = list_POLYGON2POLYGONs(list_POLYGON)
print(list_polygon)
控制台输出的内容为:
[
<POLYGON ((-73.975 40.794, -73.976 40.793, -73.976 40.793, -73.976 40.794, -...>,
<POLYGON ((-73.976 40.793, -73.976 40.793, -73.976 40.793, -73.976 40.793, -...>
]
函数代码
def list_POLYGON2POLYGONs(list_POLYGON):
list_polygon = []
for POLYGON in list_POLYGON:
polygon = Polygon(POLYGON)
list_polygon.append(polygon)
return list_polygon
3. 将字符串形式的LineString 转化为 shapely库中的LineString类对象
输入输出
调用方式:line_string = get_LINESTRING(geometry)
输入:字符串形式的LineString
形如:
LINESTRING (-73.9477940 40.7203470, -73.9478810 40.7209187, -73.9479402 40.7213083, -73.9479510 40.7213790)
输出:shapely库中的LineString类对象
样例
geometry = 'LINESTRING (-73.9477940 40.7203470, -73.9478810 40.7209187, -73.9479402 40.7213083, -73.9479510 40.7213790)'
line_string = get_LINESTRING(geometry)
print(line_string)
print(type(line_string))
控制台输出如下:
LINESTRING (-73.947794 40.720347, -73.947881 40.7209187, -73.9479402 40.7213083, -73.947951 40.721379)
<class 'shapely.geometry.linestring.LineString'>
函数代码
def get_LINESTRING(input):
prefix = 'LINESTRING '
input = input[len(prefix):]
input = input[1:-1]
cord_arr = input.split(',')
points = []
for cord in cord_arr:
point_str = cord
if cord[0] == ' ':
point_str = point_str[1:]
x, y = point_str.split(' ')
tup = (float(x), float(y))
points.append(tup)
line_string = LineString(points)
return line_string