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

你可能感兴趣的:(#,Python,python,MULTIPOLYGON,POLYGON,地理数据,Geo)