Python 2.7 使用python更新KML文件中的坐标

Python 2.7 使用python更新KML文件中的坐标,python-2.7,kml,elementtree,pykml,Python 2.7,Kml,Elementtree,Pykml,我有一个类似于此文件的KML(只有“文档”部分会重复2000次左右,每个条目的坐标略有不同) 如您所见,我可以设法添加一组附加值(1,1,1),但是 a) 我没有使用第一个坐标的值(而只是虚拟值) b) 它只更新了第一个分支(我如何扩展它以重复2000次 c) 当我更新输出文件时,也会显示此文本 "coordinates xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str">" 道歉如果这是一个过于深

我有一个类似于此文件的KML(只有“文档”部分会重复2000次左右,每个条目的坐标略有不同)

如您所见,我可以设法添加一组附加值(1,1,1),但是

a) 我没有使用第一个坐标的值(而只是虚拟值)

b) 它只更新了第一个分支(我如何扩展它以重复2000次

c) 当我更新输出文件时,也会显示此文本

 "coordinates xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str">"

道歉如果这是一个过于深入的问题,我只是挣扎了太久,似乎有一个简单的方式,我错过了。提前感谢您的帮助

回答了我自己的问题。感谢Jaron让我摆脱困境(尽管我最终没有使用正则表达式,而是使用元素树)。当我更加熟悉在嵌套树中导航时,我设法找到了它。也有助于更熟悉.findall()并在for子句中使用它。谢谢

def close_the_polygons(kml_file,color_name):
    # # Get the tree from KML File, add get color_name (only used when writing the file name )

    tree  = ET.parse(kml_file)
    root = tree.getroot()

    # iterate through tree to get to coordinate level

    for Document in root:
        for Placemark in Document.findall('Placemark'):
            for Polygon in Placemark.findall('Polygon'):
                for outerBoundaryIs in Polygon.findall('outerBoundaryIs'):
                    for LinearRing in outerBoundaryIs: # don't use Findall here because only 1 subelement
                        for coordinates in LinearRing: # don't use Findall here because only 1 subelement

                            ### convert the co-ordinate to text and delimiters become ordinary text (i.e. repr)
                            coordinates_text_before  =  repr(coordinates.text)

                            # ## Split the text (identifying the delimters)
                            coordinates_split_before = coordinates_text_before.split("\\t")

                            # # Store each entry of the array
                            entry_1 = coordinates_split_before[1]
                            entry_2 = coordinates_split_before[2][2:]
                            entry_3 = coordinates_split_before[3][2:]
                            entry_4 = coordinates_split_before[4][2:-10]
                            entry_5 = entry_1    #this solves the underlying problem of closing the polygon  

                            # # # consolidate into a single item array, goal with delimiters is to get it back to original text
                            string_updated_coordinates = "'\\n\\t"+entry_1+"\\t\\n"+entry_2+"\\t\\n"+entry_3+"\\t\\n"+entry_4+"\\t\\n"+entry_5+"\\n'"
                            updated_coordinates = literal_eval(string_updated_coordinates)

                            # # Store Updated Coordinates into original coordinates location
                            coordinates.text = updated_coordinates

    # # Write back to a file once all updates are complete
    tree = ET.ElementTree(root)
    tree.write('new_data_%s_closedPolygon_v1.0.kml' %color_name, xml_declaration=True)

    return

回答了我自己的问题。感谢Jaron让我摆脱困境(尽管我最终没有使用正则表达式,而是使用元素树)。当我更加熟悉在嵌套树中导航时,我设法找到了它。也有助于更熟悉.findall()并在for子句中使用它。谢谢

def close_the_polygons(kml_file,color_name):
    # # Get the tree from KML File, add get color_name (only used when writing the file name )

    tree  = ET.parse(kml_file)
    root = tree.getroot()

    # iterate through tree to get to coordinate level

    for Document in root:
        for Placemark in Document.findall('Placemark'):
            for Polygon in Placemark.findall('Polygon'):
                for outerBoundaryIs in Polygon.findall('outerBoundaryIs'):
                    for LinearRing in outerBoundaryIs: # don't use Findall here because only 1 subelement
                        for coordinates in LinearRing: # don't use Findall here because only 1 subelement

                            ### convert the co-ordinate to text and delimiters become ordinary text (i.e. repr)
                            coordinates_text_before  =  repr(coordinates.text)

                            # ## Split the text (identifying the delimters)
                            coordinates_split_before = coordinates_text_before.split("\\t")

                            # # Store each entry of the array
                            entry_1 = coordinates_split_before[1]
                            entry_2 = coordinates_split_before[2][2:]
                            entry_3 = coordinates_split_before[3][2:]
                            entry_4 = coordinates_split_before[4][2:-10]
                            entry_5 = entry_1    #this solves the underlying problem of closing the polygon  

                            # # # consolidate into a single item array, goal with delimiters is to get it back to original text
                            string_updated_coordinates = "'\\n\\t"+entry_1+"\\t\\n"+entry_2+"\\t\\n"+entry_3+"\\t\\n"+entry_4+"\\t\\n"+entry_5+"\\n'"
                            updated_coordinates = literal_eval(string_updated_coordinates)

                            # # Store Updated Coordinates into original coordinates location
                            coordinates.text = updated_coordinates

    # # Write back to a file once all updates are complete
    tree = ET.ElementTree(root)
    tree.write('new_data_%s_closedPolygon_v1.0.kml' %color_name, xml_declaration=True)

    return

等等,我以前在Python中做过几乎完全相同的事情,让我给你拿链接好吧,我不确定这会有多大帮助,但是看看谢谢Jaron,这确实帮了我一些忙。我用你的正则表达式函数找到了谁在树上迭代,我可以获取并更新坐标,但我不知道如何在树中存储值,我想我会找到的。是的,你可以看到我的用例略有不同,我需要创建大量不同的文件,所以我可以适当地重写它们。用Python重写文件是一个相当困难的问题。一些(可能是黑客)解决方案可以完全按照您的需要重写整个文件,或者以某种方式使用
subprocess.popen()
使用
awk
进行更改。这些可能是非常平庸的解决方案,所以请恕我直言:)另外,关于:使用正则表达式解析HTML/XML/KML:等等,我以前在Python中做过几乎完全相同的事情,让我给你一个链接好吧,我不确定这会有多大帮助,但看看可能会很好,谢谢Jaron,这确实帮了我一些忙。我用你的正则表达式函数找到了谁在树上迭代,我可以获取并更新坐标,但我不知道如何在树中存储值,我想我会找到的。是的,你可以看到我的用例略有不同,我需要创建大量不同的文件,所以我可以适当地重写它们。用Python重写文件是一个相当困难的问题。一些(可能是黑客)解决方案可以完全按照您的需要重写整个文件,或者以某种方式使用
subprocess.popen()
使用
awk
进行更改。这些可能是非常平庸的解决方案,因此对它们持保留态度:)另外,关于:使用正则表达式解析HTML/XML/KML:
from lxml import etree

kml_file = path.join( \
     'C:\Development', \
      'sample.kml')

# Source: https://stackoverflow.com/questions/13712132/extract-coordinates-from-kml-batchgeo-file-with-python
root = parser.fromstring(open(kml_file, 'r').read())

coordinates_before = root.Document.Placemark.Polygon.outerBoundaryIs.LinearRing.coordinates

# Print the coordinates  (only prints the first branch )
print 'coordinates before'
print coordinates_before

# Set the coordinates to a new value - Attempting to update to new values 
# Get Errors from this
root.Document.Placemark.Polygon.outerBoundaryIs.LinearRing.coordinates
= coordinates_before+"1,1,1"

coordinates_after = root.Document.Placemark.Polygon.outerBoundaryIs.LinearRing.coordinates

print 'coordinates after'
print coordinates_after


# # Create and store a string representation of full KML tree
root_string = etree.tostring(root, pretty_print=True)

# # # Print the string representation using pretty_print
print root_string
 "coordinates xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str">"
def close_the_polygons(kml_file,color_name):
    # # Get the tree from KML File, add get color_name (only used when writing the file name )

    tree  = ET.parse(kml_file)
    root = tree.getroot()

    # iterate through tree to get to coordinate level

    for Document in root:
        for Placemark in Document.findall('Placemark'):
            for Polygon in Placemark.findall('Polygon'):
                for outerBoundaryIs in Polygon.findall('outerBoundaryIs'):
                    for LinearRing in outerBoundaryIs: # don't use Findall here because only 1 subelement
                        for coordinates in LinearRing: # don't use Findall here because only 1 subelement

                            ### convert the co-ordinate to text and delimiters become ordinary text (i.e. repr)
                            coordinates_text_before  =  repr(coordinates.text)

                            # ## Split the text (identifying the delimters)
                            coordinates_split_before = coordinates_text_before.split("\\t")

                            # # Store each entry of the array
                            entry_1 = coordinates_split_before[1]
                            entry_2 = coordinates_split_before[2][2:]
                            entry_3 = coordinates_split_before[3][2:]
                            entry_4 = coordinates_split_before[4][2:-10]
                            entry_5 = entry_1    #this solves the underlying problem of closing the polygon  

                            # # # consolidate into a single item array, goal with delimiters is to get it back to original text
                            string_updated_coordinates = "'\\n\\t"+entry_1+"\\t\\n"+entry_2+"\\t\\n"+entry_3+"\\t\\n"+entry_4+"\\t\\n"+entry_5+"\\n'"
                            updated_coordinates = literal_eval(string_updated_coordinates)

                            # # Store Updated Coordinates into original coordinates location
                            coordinates.text = updated_coordinates

    # # Write back to a file once all updates are complete
    tree = ET.ElementTree(root)
    tree.write('new_data_%s_closedPolygon_v1.0.kml' %color_name, xml_declaration=True)

    return