2016-06-14 24 views
0

このファイルのように見えるKMLがあります(「文書」部分のみが2,000回繰り返し、各エントリの座標が少し異なります)。Pythonを使用してKMLファイルの座標を更新する

<?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)これは、現在記載されている座標が本質的であることを意味し、「座標を閉じて」バリデーターを満たすために四角形(四隅)を使用すると、最初の座標セットを繰り返してポリゴンを閉じる必要があります。だから、ターゲットは次のようになります。

   <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> 

しかし、私の問題は、私は効率的な方法で座標を更新するとのトラブルを抱えているということです。あなたは、私は追加のセットを追加するために管理することができます見ることができるように、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 

からpykml輸入パーサ から

:今のところ、これは私が(this postからの助けを借りて思い付くことが最高です値(1,1,1)が、

A)私はそれだけで私はどのように拡張することができます(最初の分岐を更新しています)

b)の第1の座標(というだけでダミーの値からの値を使用していませんよ2000回繰り返すのですか?

C)私が更新した際にも、出力ファイルは、このテキストを示し

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

謝罪これは過度の深さの問題である場合、私はあまりにも長い間これで苦労して、そこのように思えるしてきました簡単に私が行方不明になっているはずです。助けを前にありがとう。

+0

を待って、私は実際に私はこれがものになるかどうか役に立つわからないんだけど、HTTPSを見て良いかもしれません私はあなたに[OK]をリンク –

+0

をつかむせ、前にPythonで、ほぼこれと同じ事をしました//github.com/thatchej/kml-parse/blob/master/parse_kml.py –

+0

ありがとうございましたJaron、それは私を助けてくれました。私はあなたの正規表現関数を使ってツリーを繰り返し処理する人を見つけ出し、座標を取得し更新することができますが、ツリーに値を格納する方法を理解することはできません。それを得る。 –

答えて

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 
関連する問題