zoukankan      html  css  js  c++  java
  • Python 的 Geodaisy 库转换带负号坐标的WKT时的Bug

    Geodaisy是一个Python库,用于创建由类型和坐标表示的地理对象,并在各种标准和表示之间进行转换,包括GeoJSON、Well - Known Text和Python的__geo_interface__协议,它被其他地理库使用。
    在使用其 converters.wkt_to_geo_interface()方法时转换带符号坐标的wkt字符串时,发现其转换的结果跟预期的不一样:
    例如:
    > wkt = "MULTILINESTRING ((3146.2134801800566 2556399.9823166174, -2611.53319329879 2564044.0076796883))"
    > converters.wkt_to_geo_interface(wkt)
    # {'type': 'MultiLineString', 'coordinates': (3146.2134801800566, 2556399.9823166174, -2611.53319329879, 2564044.0076796883)}
    

    我们看到 coordinates 的值并不是我们想要的结果:

    {'type': 'MultiLineString', 'coordinates': [(3146.2134801800566, 2556399.9823166174), (-2611.53319329879, 2564044.0076796883)]}
    

    原因是 wkt_to_geo_interface 方法源码采用正则匹配,并没有考虑带负数坐标的情况(或者根本就不考虑),但是在地方坐标系处理偏移的过程中是肯定有出现负值坐标的情况的。

    解决方法:

    修改wkt_to_geo_interface方法源码的正则匹配(匹配”-“号和数字):

     1 def wkt_to_geo_interface(wkt):
     2     # type: (str) -> dict
     3     """Converts a WKT string to a geo_interface dictionary."""
     4     try:
     5         wkt_type, coords = re.split(r'(?<=[A-Z])\s', wkt)
     6 
     7         geo_type = type_translations[wkt_type]
     8 
     9         # Clean up the strings so they'll covert correctly
    10         if geo_type in {'Polygon', 'MultiLineString', 'MultiPolygon'}:
    11             # coords = re.sub(r'(?<=\d)\), \((?=\d)', ')), ((', coords)
    12             coords = re.sub(r'(?<=[-\d])\), \((?=[-\d])', ')), ((', coords)   # modif by 举个栗子
    13 
    14         # Pairs of coordinates must be enclosed in parentheses
    15         # coords = re.sub(r'(?<=\d), (?=\d)', '), (', coords)
    16         coords = re.sub(r'(?<=[-\d]), (?=[-\d])', '), (', coords) # modif by 举个栗子
    17 
    18         # Coordinates within parentheses must be separated by commas
    19         # coords = re.sub(r'(?<=\d) (?=\d)', ', ', coords)
    20         coords = re.sub(r'(?<=[-\d]) (?=[-\d])', ', ', coords)    # # modif by 举个栗子
    21 
    22         # Now we can turn the string into a tuple or a tuple of tuples
    23         coords = literal_eval(coords)
    24 
    25         coords = reformat_coordinates(coords, 'geo_interface')  # type: ignore  # noqa: E501
    26 
    27         # If we only have a simple polygon (no hole), the coordinate array
    28         # won't be deep enough to satisfy the GeoJSON/geo_interface spec, so
    29         # we need to enclose it in a list.
    30         numbers = {float, int}
    31         if geo_type == 'Polygon' and type(coords[0][0]) in numbers:
    32             coords = [coords]  # type: ignore
    33         elif geo_type == 'MultiPolygon' and type(coords[0][0][0]) in numbers:
    34             coords = [coords]  # type: ignore
    35 
    36     except Exception:
    37         raise ValueError('{} is not a WKT string'.format(wkt))
    38 
    39     return {'type': geo_type, 'coordinates': coords}
  • 相关阅读:
    win10 创建安卓模拟器及启动的方法
    win10 virtualenv
    win10安装nodejs
    python模块打包方法
    win10 安装java
    git push后自动部署
    ubuntu配置无密码登录
    mysql while,loop,repeat循环,符合条件跳出循环
    centos 安装mysql密码修改后还是不能连接的原因
    查看SQLServer数据库信息的SQL语句
  • 原文地址:https://www.cnblogs.com/mzfly/p/15570909.html
Copyright © 2011-2022 走看看