• 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}
  • 相关阅读:
    JavaScript Object.prototype.toString 解析过程
    今天一定要纪念一下
    考验你的JavaScript底细
    2016-3-23
    记录一下最近的感受
    mac ox快捷键总结
    如何把开源的项目fork到自己的仓库并Down到本地
    使用vue-cli构建vue.js项目
    成为一名优秀的web前端工程师都需要做些什么?
    关于angularjs input上传图片前获取图片的Size 浅析
  • 原文地址:https://www.cnblogs.com/mzfly/p/15570909.html
Copyright © 2020-2023  润新知