VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • Python 的 Geodaisy 库转换带负号坐标的WKT时的Bug

Geodaisy是一个Python库,用于创建由类型和坐标表示的地理对象,并在各种标准和表示之间进行转换,包括GeoJSON、Well - Known Text和Python的__geo_interface__协议,它被其他地理库使用。
在使用其 converters.wkt_to_geo_interface()方法时转换带符号坐标的wkt字符串时,发现其转换的结果跟预期的不一样:
例如:
1
2
3
> 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 的值并不是我们想要的结果:

1
{'type''MultiLineString''coordinates': [(3146.21348018005662556399.9823166174), (-2611.533193298792564044.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}
复制代码

 

 
来源:https://www.cnblogs.com/mzfly/p/15570909.html


相关教程