1

このファイルのような KML があります (「ドキュメント」の部分だけが、各エントリの座標がわずかに異なり、さらに 2,000 回ほど繰り返されます)。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
    <Document>
        <Placemark>
            <Polygon>
                <extrude>1</extrude>
                <tesselate>1</tesselate>
                <altitudeMode>relativeToGround</altitudeMode>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>
                            -89.634425,40.73053,16  
                            -89.633951,40.73053,16  
                            -89.633951,40.73013,16  
                            -89.634425,40.73013,16
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
            <Style>
                <PolyStyle>
                    <color>#5a14F000</color>
                    <outline>1</outline>
                </PolyStyle>
            </Style>
        </Placemark>
    <Document> 
</kml>

ファイルは Google Earth からエクスポートされました。マッピング ツール (CartoDB や Mapbox など) にアップロードしようとしていますが、ファイルがエラーとして拒否されます。このファイルを次のような KML バリデーターで実行しました: KMLValidator。アップロードするために私が決定した変更は次のとおりです。

1) 行 2 を次のように置き換えます。

<kml xmlns="http://www.opengis.net/kml/2.2"
 xmlns:gx="http://www.google.com/kml/ext/2.2">

2) 「座標を閉じる」これは、現在リストされている座標が本質的に正方形 (4 つの角) であることを意味し、最初の座標セットを繰り返してポリゴンを閉じる必要があるバリデーターを満たします。したがって、ターゲットは次のようになります。

                <coordinates>
                    -89.634425,40.73053,16  
                    -89.633951,40.73053,16  
                    -89.633951,40.73013,16  
                    -89.634425,40.73013,16
                    -89.634425,40.73053,16  
                </coordinates>

ただし、私の問題は、効率的な方法で座標を更新するのに問題があることです。これまでのところ、これは私が思いつくことができる最高のものです(この投稿の助けを借りて:

pykml インポート パーサーから os インポート パスから

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

ご覧のとおり、値のセット (1,1,1) を追加することはできますが、

a)最初の座標の値を使用していません(むしろダミー値です)

b)最初のブランチのみを更新しています(さらに2,000回繰り返すようにスケーリングするにはどうすればよいですか?

c)また、出力ファイルを更新すると、このテキストが表示されます

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

これが過度に詳細な質問である場合はお詫びします。私はこれに長い間苦労しており、見逃している簡単な方法があるはずです。助けてくれてありがとう。

4

1 に答える 1

0

私自身の質問に答えました。行き詰まりを解消してくれたJaronに感謝します(ただし、正規表現ではなくElement Treeを使用することになりました)。ネストされたツリーをナビゲートすることに慣れると、なんとかそれを理解することができました。また、.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
于 2016-06-16T21:18:47.763 に答える