XML/KML - 如何在 bash 脚本中测试一个多边形 'touches' 另一个多边形
XML/KML - How to test if a polygon 'touches' another polygon in a bash script
我正在使用 Google 我的地图在一层上绘制郊区(作为多边形),然后在第二层上绘制存在于其内部和周围的所有(农村)属性(也作为多边形)那个郊区。多边形使用地理坐标来定义点。例如(略有编辑):
<Polygon>
<outerBoundaryIs>
<LinearRing>
<tessellate>1</tessellate>
<coordinates>
150.523000,-34.720000,0
150.524000,-34.719000,0
150.524000,-34.719000,0
150.524000,-34.719000,0
150.523000,-34.719000,0
150.523000,-34.720000,0
150.523000,-34.720000,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
然后我使用 bash 脚本修改 XML/KML 以满足我的要求。
我希望有人有灵丹妙药,可以通过命令行指定一个 XML 文件和两个多边形的 XPATH(在 XML 文件中)和让它告诉我这两个多边形是否相交 - 例如:
check_polygons "/path/to/XML" "//_:xpath/to/polygon1" "//_:xpath/to/polygon2"
它以某种方式(文本或退出状态)告诉我这两个多边形是否在任何点相交。
非常感谢任何帮助。
感谢 Paul Hodges 鼓励我,让我努力想出解决方案。
这非常适合我使用 Google 我的地图创建两层地图的情况。第一层名为 'Locality',是一个绘制郊区的多边形。第二层名为 'Property',包含映射 属性 边界的多个多边形。
下面的脚本有 2 个或 3 个参数。第一个(可选)参数是 XML 命名空间(默认为 http://www.opengis.net/kml/2.2
),第二个参数是 'Property' 图层上的地标名称,最后一个参数是 KML 文件名。该脚本检查两个多边形是否相交。如果他们这样做,它会打印 True
并且 return 代码为 0(零)。如果它们不相交,它会打印 False
并且 return 代码为 1。return 代码为 2 表示在 XML 中找不到 XPath文件或存在使用错误。
#!/usr/bin/python
from lxml import etree
from shapely.geometry import Polygon
import sys
def getPoly(XmlFile, XmlNS, XPath):
tree = etree.parse(XmlFile)
root = tree.getroot()
XmlNamespace = {"NS": XmlNS}
xmlList = root.xpath(XPath, namespaces=XmlNamespace)
if not xmlList:
return(False)
polyCoordList = xmlList[0].text.replace(' ', '')
coordinates = []
for point_text in polyCoordList.split():
floats = point_text.split(",")
coordinates.append((float(floats[0]), float(floats[1])))
return(Polygon(coordinates))
if __name__ == "__main__":
XmlNS = "http://www.opengis.net/kml/2.2"
if len(sys.argv) == 4:
XmlNS = sys.argv[1]
XmlPlacemarkName = sys.argv[2]
XmlFile = sys.argv[3]
elif len(sys.argv) == 3:
XmlPlacemarkName = sys.argv[1]
XmlFile = sys.argv[2]
else:
print("Usage: %s [NameSpace] PlacemarkName KmlFile" % (sys.argv[0]))
print("The default namespace is %s" % XmlNS)
exit(2)
XPath = "./NS:Document/NS:Folder[contains(., 'Locality')]/NS:Placemark/NS:Polygon/NS:outerBoundaryIs/NS:LinearRing/NS:coordinates"
LocalityPoly = getPoly(XmlFile, XmlNS, XPath)
if LocalityPoly == False:
print("Invalid XPath - %s" % XPath)
exit(2)
XPath = "./NS:Document/NS:Folder[contains(., 'Property')]/NS:Placemark[contains(., '%s')]/NS:Polygon/NS:outerBoundaryIs/NS:LinearRing/NS:coordinates" % XmlPlacemarkName
PlacemarkPoly = getPoly(XmlFile, XmlNS, XPath)
if PlacemarkPoly == False:
XPath = "./NS:Document/NS:Folder[contains(., 'Property')]/NS:Placemark[contains(., '%s')]/NS:MultiGeometry/NS:Polygon/NS:outerBoundaryIs/NS:LinearRing/NS:coordinates" % XmlPlacemarkName
PlacemarkPoly = getPoly(XmlFile, XmlNS, XPath)
if PlacemarkPoly == False:
print("Invalid XPath - %s" % XPath)
exit(2)
result = LocalityPoly.intersects(PlacemarkPoly)
print(result)
exit(not result)
希望对其他人有所帮助。
我正在使用 Google 我的地图在一层上绘制郊区(作为多边形),然后在第二层上绘制存在于其内部和周围的所有(农村)属性(也作为多边形)那个郊区。多边形使用地理坐标来定义点。例如(略有编辑):
<Polygon>
<outerBoundaryIs>
<LinearRing>
<tessellate>1</tessellate>
<coordinates>
150.523000,-34.720000,0
150.524000,-34.719000,0
150.524000,-34.719000,0
150.524000,-34.719000,0
150.523000,-34.719000,0
150.523000,-34.720000,0
150.523000,-34.720000,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
然后我使用 bash 脚本修改 XML/KML 以满足我的要求。
我希望有人有灵丹妙药,可以通过命令行指定一个 XML 文件和两个多边形的 XPATH(在 XML 文件中)和让它告诉我这两个多边形是否相交 - 例如:
check_polygons "/path/to/XML" "//_:xpath/to/polygon1" "//_:xpath/to/polygon2"
它以某种方式(文本或退出状态)告诉我这两个多边形是否在任何点相交。
非常感谢任何帮助。
感谢 Paul Hodges 鼓励我,让我努力想出解决方案。
这非常适合我使用 Google 我的地图创建两层地图的情况。第一层名为 'Locality',是一个绘制郊区的多边形。第二层名为 'Property',包含映射 属性 边界的多个多边形。
下面的脚本有 2 个或 3 个参数。第一个(可选)参数是 XML 命名空间(默认为 http://www.opengis.net/kml/2.2
),第二个参数是 'Property' 图层上的地标名称,最后一个参数是 KML 文件名。该脚本检查两个多边形是否相交。如果他们这样做,它会打印 True
并且 return 代码为 0(零)。如果它们不相交,它会打印 False
并且 return 代码为 1。return 代码为 2 表示在 XML 中找不到 XPath文件或存在使用错误。
#!/usr/bin/python
from lxml import etree
from shapely.geometry import Polygon
import sys
def getPoly(XmlFile, XmlNS, XPath):
tree = etree.parse(XmlFile)
root = tree.getroot()
XmlNamespace = {"NS": XmlNS}
xmlList = root.xpath(XPath, namespaces=XmlNamespace)
if not xmlList:
return(False)
polyCoordList = xmlList[0].text.replace(' ', '')
coordinates = []
for point_text in polyCoordList.split():
floats = point_text.split(",")
coordinates.append((float(floats[0]), float(floats[1])))
return(Polygon(coordinates))
if __name__ == "__main__":
XmlNS = "http://www.opengis.net/kml/2.2"
if len(sys.argv) == 4:
XmlNS = sys.argv[1]
XmlPlacemarkName = sys.argv[2]
XmlFile = sys.argv[3]
elif len(sys.argv) == 3:
XmlPlacemarkName = sys.argv[1]
XmlFile = sys.argv[2]
else:
print("Usage: %s [NameSpace] PlacemarkName KmlFile" % (sys.argv[0]))
print("The default namespace is %s" % XmlNS)
exit(2)
XPath = "./NS:Document/NS:Folder[contains(., 'Locality')]/NS:Placemark/NS:Polygon/NS:outerBoundaryIs/NS:LinearRing/NS:coordinates"
LocalityPoly = getPoly(XmlFile, XmlNS, XPath)
if LocalityPoly == False:
print("Invalid XPath - %s" % XPath)
exit(2)
XPath = "./NS:Document/NS:Folder[contains(., 'Property')]/NS:Placemark[contains(., '%s')]/NS:Polygon/NS:outerBoundaryIs/NS:LinearRing/NS:coordinates" % XmlPlacemarkName
PlacemarkPoly = getPoly(XmlFile, XmlNS, XPath)
if PlacemarkPoly == False:
XPath = "./NS:Document/NS:Folder[contains(., 'Property')]/NS:Placemark[contains(., '%s')]/NS:MultiGeometry/NS:Polygon/NS:outerBoundaryIs/NS:LinearRing/NS:coordinates" % XmlPlacemarkName
PlacemarkPoly = getPoly(XmlFile, XmlNS, XPath)
if PlacemarkPoly == False:
print("Invalid XPath - %s" % XPath)
exit(2)
result = LocalityPoly.intersects(PlacemarkPoly)
print(result)
exit(not result)
希望对其他人有所帮助。