XML/KML - 如何在 bash 脚本中测试多边形是否“接触”另一个多边形

时间:2021-05-29 12:45:48

标签: xml polygon kml line-intersection

我正在使用 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"

它以某种方式(文本或退出状态)告诉我两个多边形是否在任何点相交。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

感谢 Paul Hodges 给了我一个鼓励,让我努力想出一个解决方案。

这非常适合我使用 Google 我的地图创建具有两层的地图的情况。第一层名为“Locality”,是一个映射郊区的多边形。第二层名为“Property”,包含多个映射属性边界的多边形。

下面的脚本需要 2 或 3 个参数。第一个(可选)参数是 XML 命名空间(默认为 http://www.opengis.net/kml/2.2),第二个参数是“属性”图层上地标的名称,最后一个参数是 KML 文件名。该脚本检查两个多边形是否相交。如果是,则打印 True 并返回 0(零)代码。如果它们不相交,它会打印 False 并且返回码为 1。返回码为 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)

希望可以帮助别人。

相关问题