LoginSignup
2

More than 5 years have passed since last update.

kml編集 Google Earthに経緯線を引く

Posted at

抱えている悩み

ローカルにダウンロードしたGoogle Earth Proにおいて、表示タブのグリッドにチェックを入れると緯線経線が描かれる。しかし、その幅を固定化する方法が見つからず、結局自ら強引に線を引っ張ってみることに。ちゃんと調べればもっといい方法はありそうなんだけど...。今回は1度ごとに線を引くことを目標にする

とりあえず図形を描く

地図に乗せる点や線のデータを記述するkmlに関する知識はほとんどないため、ひな形を手に入れてからその中をいじる作戦で進める。
- Google Earthの「ポリゴンを追加します」でtestという名前で適当な三角形を描く。
- 線色は赤で2pt、枠線のみに設定してOK。

キャプチャ.PNG

  • 「名前を付けて場所を保存」でkmlファイルとして出力(kmzはkml圧縮ファイルの拡張子)。

中身は以下の通り。

test.kml
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>test.kml</name>
    <Style id="sh_ylw-pushpin">
        <IconStyle>
            <scale>1.3</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
        <LineStyle>
            <color>ff0000ff</color>
            <width>2</width>
        </LineStyle>
        <PolyStyle>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <StyleMap id="msn_ylw-pushpin">
        <Pair>
            <key>normal</key>
            <styleUrl>#sn_ylw-pushpin</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#sh_ylw-pushpin</styleUrl>
        </Pair>
    </StyleMap>
    <Style id="sn_ylw-pushpin">
        <IconStyle>
            <scale>1.1</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
        <LineStyle>
            <color>ff0000ff</color>
            <width>2</width>
        </LineStyle>
        <PolyStyle>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <Placemark>
        <name>test</name>
        <styleUrl>#msn_ylw-pushpin</styleUrl>
        <Polygon>
            <tessellate>1</tessellate>
            <outerBoundaryIs>
                <LinearRing>
                    <coordinates>
                        144.6191266497737,34.24943785758673,0 144.8011046916909,32.1403153422666,0 146.5999914902476,33.55924655111003,0 144.6191266497737,34.24943785758673,0 
                    </coordinates>
                </LinearRing>
            </outerBoundaryIs>
        </Polygon>
    </Placemark>
</Document>
</kml>

実験

<Placemark></Placemark>の中身<Polygon></Polygon>で多角形を定義。<styleUrl>でその上のほうで定義している線色などのスタイルを参照している。<coordinates></coordinates>の中身で 経度・緯度・高度 の順に4点が連続しており、始点終点はそろっている。この部分をいじってみた結果が以下の通り。

キャプチャ2.PNG

  • 確かにこの部分をいじることで線が動く(小さく映った赤い三角形が元の三角形)。
  • 赤道に関しては、経度120度ごとに点を打った三角形で表現が可能。
  • しかし、緯度が0からずれると三角形での表現ができなくなる(赤線)。

この点については、Google プロダクト フォーラムで質問されていたようで、n角形のnを増やす以外に方法はなさそう。

  • 経度については、両極と赤道上2点の計4点を結んだ四角形で問題なし(180度子午線上の赤線がそれ)。

緑線が経度1度ごとに点を拾った360角形。自分の場合見栄えとしてはこれで十分なので、以上の知見をもとにkmlを書き換えるコードを作成した。

Multigeometryを用いる方法

2つ目以降のをどう入れるのだろうと少しググるとというのが見つかったため、

Multigeometryひな形.kml
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>meshline.kml</name>
(中略)
    <Placemark> 
        <name>meshline</name> 
        <visibility>1</visibility> 
        <styleUrl>#msn_ylw-pushpin</styleUrl>
        <MultiGeometry> 
            <Polygon> 
                <outerBoundaryIs> 
                    <LinearRing> 
                        <coordinates> 
                            LON_LAT_ELEV
                        </coordinates> 
                    </LinearRing> 
                </outerBoundaryIs> 
            </Polygon> 
         <MultiGeometry> 
    </Placemark> 
</Document>
</kml>

内の<Polygon></Polygon>を複製。結果は以下の通り。

キャプチャ3.PNG

経線がえらいことになっている。地面を貫通しているのかしら。四角形で表現した影響がよくわからないタイミングで出現。
原因はわからないが、Multigeometryを使うとなぜか経線がおかしくなった。

folderを用いる方法

Google Earthにおけるフォルダのツリー構造はkml内で表現されている。例えば左側のウィンドウで保留フォルダを右クリックすると「名前を付けて場所を保存」が存在し、保存ファイルは下記のようになっている。

Folderひな形.kml
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>meshline.kml</name>
(中略)
    <Folder>
        <name>meshline</name>
        <open>1</open>
        <Placemark>
            <name>LINE_NAME</name>
            <styleUrl>#msn_ylw-pushpin</styleUrl>
            <Polygon>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>
                            LON_LAT_ELEV
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <name>LINE_NAME</name>
            <styleUrl>#msn_ylw-pushpin</styleUrl>
            <Polygon>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>
                            LON_LAT_ELEV
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>
</Document>
</kml>

<Placemark></Placemark>を複製すればよさそう。というわけでこのひな形(厳密には2つ目のPlacemarkを除いたもの)を用いてpythonで編集。一応、各ポリゴンに名前も付けている。

makemash.py
tmp = []
l = ''
with open('meshline.kml','w') as out:
    with open('folderひな形.kml','r') as src:
        while '<open>1</open>' not in l:
            l = src.readline()
            out.write(l.replace('test','meshline'))
        while  '</Placemark>' not in l:
            l = src.readline()
            tmp.append(l)
        for lon in range(0,180):
            LINE_NAME = 'lon_%s' %lon
            LON_LAT_ELEV = '%d,0,0 %d,90,0 %d,0,0 %d,-90,0 %d,0,0' %(lon,lon,lon-180,lon,lon)
            tmp[1] = tmp[1].replace('LINE_NAME',LINE_NAME)  
            tmp[8] = tmp[8].replace('LON_LAT_ELEV',LON_LAT_ELEV) 
            for t in tmp:
                out.write(t)
            tmp[1] = tmp[1].replace(LINE_NAME,'LINE_NAME')  
            tmp[8] = tmp[8].replace(LON_LAT_ELEV,'LON_LAT_ELEV') 

        for lat in range(-89,90):
            LINE_NAME = 'lat_n%s' %abs(lat) if lat < 0 else 'lat_p%s' %abs(lat)
            LON_LAT_ELEV = ''
            for n in range(-180,180):
                LON_LAT_ELEV += '%d,%d,0 ' %(n,lat)
            LON_LAT_ELEV += '-180,%d,0' %lat
            tmp[1] = tmp[1].replace('LINE_NAME',LINE_NAME)  
            tmp[8] = tmp[8].replace('LON_LAT_ELEV',LON_LAT_ELEV) 
            for t in tmp:
                out.write(t)
            tmp[1] = tmp[1].replace(LINE_NAME,'LINE_NAME')  
            tmp[8] = tmp[8].replace(LON_LAT_ELEV,'LON_LAT_ELEV') 

        out.write(src.read())

結果はこのような感じ。

キャプチャ4.PNG

Folderだとうまくいく。

おまけ 

作成した画像をWindowsのタスクバーサムネイルで見ると不思議。

図1.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2