国土地理院地図Webサイト、またはGoogle Mapsマイマップで作成したKMLファイルから、Placemarkとして作成した地点の緯度・経度を抽出するスクリプト
Placemark以外の図形データ(直線など)は抽出出力されないようにしている
parse_kml.pl ソースコードをダウンロードする
#!/usr/bin/perl
#
# 国土交通省地図またはGoogle Mapsマイマップで作成したKMLファイルより
# 地点座標(Placemarkの緯度・軽度)を抜き出すスクリプト
use strict;
use warnings;
use XML::Simple;
use Encode;
use utf8;
# 処理対象ファイルのユーザ入力と存在確認
print "kml placemark parseer\ninput KML filename ? : ";
my $filename = <STDIN>;
chomp($filename);
if ( !-f $filename ) {
print "error: file $filename does not exist\.n";
exit;
}
print $filename . " exist.\n";
my $xs = new XML::Simple( NoSort => 1 );
my $myFile = $xs->XMLin($filename);
# 国土地理院地図 KML
{
while ( my ( $key, $folder ) = each %{ $myFile->{Document}{Placemark} } ) {
$key =~ s/[\r\n]//; # 改行を削除
my $coord = $folder->{Point}->{coordinates};
# Placemark以外の図形などのとき、その行の表示を省略する場合 次の行を有効化
if ( !$coord ) { next; }
# Placemarkが未定義または空白のとき、画面出力エラーを回避するためダミー文字を設定
$coord = ( !$coord || $coord eq '' ) ? "undefined" : $coord;
$coord =~ s/[\r\n ]+//g; # 改行と空白文字を削除
# 画面表示
print Encode::encode( 'utf-8', $key ) . "," . $coord . "\n";
}
}
# Google Maps KML (Folderタグでグループ分けされている場合)
{
while ( my ( $key0, $folder0 ) = each %{ $myFile->{Document}{Folder} } ) {
$key0 =~ s/[\r\n]//; # 改行を削除
if ( ref $folder0 ne ref {} ) {
# $folder0がハッシュのリファレンスでない場合は処理スキップ
next;
}
while ( my ( $key1, $folder1 ) = each %{ $folder0->{Placemark} } ) {
$key1 =~ s/[\r\n]//; # 改行を削除
my $coord = $folder1->{Point}->{coordinates};
# Placemark以外の図形などのとき、その行の表示を省略する場合 次の行を有効化
if ( !$coord ) { next; }
# Placemarkが未定義または空白のとき、画面出力エラーを回避するためダミー文字を設定
$coord = $coord ? $coord : "undefined";
$coord =~ s/[\r\n ]+//g; # 改行と空白文字を削除
# 画面表示
print Encode::encode( 'utf-8', $key0 ) . ","
. Encode::encode( 'utf-8', $key1 ) . ","
. $coord . "\n";
}
}
}
# Google Maps KML
{
while ( my ( $key, $folder ) =
each %{ $myFile->{Document}{Folder}{Placemark} } )
{
$key =~ s/[\r\n]//; # 改行を削除
my $coord = $folder->{Point}->{coordinates};
# Placemark以外の図形などのとき、その行の表示を省略する場合 次の行を有効化
if ( !$coord ) { next; }
# Placemarkが未定義または空白のとき、画面出力エラーを回避するためダミー文字を設定
$coord = ( !$coord || $coord eq '' ) ? "undefined" : $coord;
$coord =~ s/[\r\n ]+//g; # 改行と空白文字を削除
# 画面表示
print Encode::encode( 'utf-8', $key ) . "," . $coord . "\n";
}
}
入力KMLファイルの例
検証したサンプルKMLファイルは次のようなもの
Google Mapsのマイマップで作成したKMLファイルの例
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>テスト地図</name>
<description/>
<Style id="icon-1899-0288D1-nodesc-normal">
<IconStyle>
<color>ffd18802</color>
<scale>1</scale>
<Icon>
<href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
</Icon>
<hotSpot x="32" xunits="pixels" y="64" yunits="insetPixels"/>
</IconStyle>
<LabelStyle>
<scale>0</scale>
</LabelStyle>
<BalloonStyle>
<text><![CDATA[<h3>$[name]</h3>]]></text>
</BalloonStyle>
</Style>
<Style id="icon-1899-0288D1-nodesc-highlight">
<IconStyle>
<color>ffd18802</color>
<scale>1</scale>
<Icon>
<href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
</Icon>
<hotSpot x="32" xunits="pixels" y="64" yunits="insetPixels"/>
</IconStyle>
<LabelStyle>
<scale>1</scale>
</LabelStyle>
<BalloonStyle>
<text><![CDATA[<h3>$[name]</h3>]]></text>
</BalloonStyle>
</Style>
<StyleMap id="icon-1899-0288D1-nodesc">
<Pair>
<key>normal</key>
<styleUrl>#icon-1899-0288D1-nodesc-normal</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#icon-1899-0288D1-nodesc-highlight</styleUrl>
</Pair>
</StyleMap>
<Style id="line-000000-1200-nodesc-normal">
<LineStyle>
<color>ff000000</color>
<width>1.2</width>
</LineStyle>
<BalloonStyle>
<text><![CDATA[<h3>$[name]</h3>]]></text>
</BalloonStyle>
</Style>
<Style id="line-000000-1200-nodesc-highlight">
<LineStyle>
<color>ff000000</color>
<width>1.8</width>
</LineStyle>
<BalloonStyle>
<text><![CDATA[<h3>$[name]</h3>]]></text>
</BalloonStyle>
</Style>
<StyleMap id="line-000000-1200-nodesc">
<Pair>
<key>normal</key>
<styleUrl>#line-000000-1200-nodesc-normal</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#line-000000-1200-nodesc-highlight</styleUrl>
</Pair>
</StyleMap>
<Folder>
<name>無題のレイヤ</name>
<Placemark>
<name>六甲山</name>
<styleUrl>#icon-1899-0288D1-nodesc</styleUrl>
<Point>
<coordinates>
135.2637017,34.7782377,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>生駒山</name>
<styleUrl>#icon-1899-0288D1-nodesc</styleUrl>
<Point>
<coordinates>
135.6788864,34.6786909,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>愛宕山</name>
<styleUrl>#icon-1899-0288D1-nodesc</styleUrl>
<Point>
<coordinates>
135.6323964,35.062002,0
</coordinates>
</Point>
</Placemark>
<Placemark>
<name>京阪神</name>
<styleUrl>#line-000000-1200-nodesc</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
135.7684394,35.011648,0
135.1964637,34.6898955,0
135.502021,34.693283,0
135.7663795,35.006024,0
</coordinates>
</LineString>
</Placemark>
</Folder>
</Document>
</kml>
国土地理院地図Webサイトで作成したKMLファイルの例
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Document> <Style id="PolyStyle1"> <IconStyle> <Icon> <href>https://maps.gsi.go.jp/portal/sys/v4/symbols/080.png</href> </Icon> <scale>1</scale> </IconStyle> </Style> <Style id="LineStyle2"> <LineStyle> <color>7f000000</color> <width>3</width> </LineStyle> </Style> <Placemark> <name>六甲山</name> <styleUrl>#PolyStyle1</styleUrl> <Point> <coordinates>135.26371479034427,34.7779272998788</coordinates> </Point> </Placemark> <Placemark> <name>生駒山</name> <styleUrl>#PolyStyle1</styleUrl> <Point> <coordinates>135.678985118866,34.67847314663942</coordinates> </Point> </Placemark> <Placemark> <name>愛宕山</name> <styleUrl>#PolyStyle1</styleUrl> <Point> <coordinates>135.63432633876803,35.06001031133523</coordinates> </Point> </Placemark> <Placemark> <name>京阪神</name> <styleUrl>#LineStyle2</styleUrl> <LineString> <coordinates>135.7566833496094,35.0209997011147 135.1847076416016,34.69081552362161 135.5204772949219,34.68573411017608 135.75462341308597,35.01481391761678</coordinates> </LineString> </Placemark> </Document> </kml>
スクリプトの出力例
kml placemark parseer input KML filename ? : gmap2.kml gmap2.kml exist. 六甲山,135.2637017,34.7782377,0 愛宕山,135.6323964,35.062002,0 生駒山,135.6788864,34.6786909,0