電子国土地図にGeoJSONを重ねてみる。[Chapter 1]

電子国土地図にGeoJSONを重ねてみる。[Chapter 1]

OpenLayersではKML,GML,GeoJSONなど様々なファイル形式を読み込んで描画することができます。
当初は、Shape file → kml と考えていたのですが、JSONの方が簡単でわかりやすいと考えて、Shape file → GeoJSONでいくことにしました。

準備

本来ならば、「Shape fileを読み込んで、GeoJSONに変換して」の部分から作成する予定でしたが、今回はGeoJSONを読み込んで描画させるテストとして、GeoJSONファイルは別途作成しました。

FWToolsのインストール

作成方法は、FEToolsからFwToolsをダウンロードしてインストールします。
これは、gdal/ogrのdllとexe群が含まれています。

GeoJSONファイルを作成する

今回は、ディスクトップ上のFWTools Shellを起動して、ogr2ogrコマンドを叩きます。

ogr2ogr -f "GeoJSON" -s_srs "EPSG:4326" -t_srs "EPSG:900913" kanagawk.json kanagawk.shp

たったこれだけでOKです。

gdal/ogrについては、http://www.gdal.org/月の杜工房- gdal/ogr小技集が非常に参考になります。

vb.netのデザイン

今回も、特に準備するものは、ありません。
Visual Basic 2010を使います。(たぶんvb.net2008でも大丈夫でしょう。)

まずは、vb.netを起動して、適当なプロジェクト名で新規作成します。
使用するコントロールは、Toolstrip,StatusStrip,WebBrowserの3つです。 いつもながらかんたんですな。
blog.godo-tys.jp_wp-content_gallery_geojson_image01.jpg
デザインイメージ

サンプルコード

GeoJSONファイルを読み込んで電子国土地図にoverlayをするコードはこんな感じです。

    ''' <summary>
    ''' GeoJSONを読み込む
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ToolStripButton3_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripButton3.Click
        'StreamReader の新しいインスタンスを生成する
        'E:japansample_test.jsonは各人変更すること
        'ogr2ogrでGeoJsonに変換してものを使用する。
        'ogr2ogr -f "GeoJSON"  -s_srs "EPSG:4326" -t_srs "EPSG:900913" kanagawk.json kanagawk.shp
 
 
        Dim openDlg As OpenFileDialog = New OpenFileDialog()
 
        'initialize dialog
        openDlg.Filter = "GeoJSON Formats|*.json"
        openDlg.CheckFileExists = True
 
        If (openDlg.ShowDialog(Me) = DialogResult.OK) Then
 
            stResult = ""
 
            Dim cReader As New System.IO.StreamReader(openDlg.FileName, System.Text.Encoding.Default)
 
            'E:W05-08_14_GMLKS-META-W05-08_14-g.xml
            '読み込みできる文字がなくなるまで繰り返す
            While (cReader.Peek() >= 0)
                ' ファイルを 1 行ずつ読み込む
                Dim stBuffer As String = cReader.ReadLine()
                ' 読み込んだものを追加で格納する
                stResult &= stBuffer & System.Environment.NewLine
            End While
 
            'cReaderを閉じる
            cReader.Close()
 
            '表示する
            'MessageBox.Show(stResult)
 
            WebBrowser1.ObjectForScripting = New ExtOpenLayersObj 'クラスのインスタンスを渡す
 
            '電子国土地図表示
            Dim lat As String = ToolStripTextBox1.Text
            Dim lng As String = ToolStripTextBox2.Text
 
 
            WebBrowser1.DocumentText = OpenLayersGeoJson(Double.Parse(lat), Double.Parse(lng))
 
 
        End If
    End Sub
 
    ''' <summary>
    ''' GeoJSONをOverlayする。
    ''' </summary>
    ''' <param name="lat"></param>
    ''' <param name="lng"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function OpenLayersGeoJson(ByRef lat As Double, ByRef lng As Double) As String
 
        Dim txtHtml As String = ""
 
        txtHtml = txtHtml & "<html>" & vbCrLf
        txtHtml = txtHtml & "<head>" & vbCrLf
        'txtHtml = txtHtml & "<script type=""text/javascript"" src=""http://openlayers.org/api/OpenLayers.js"" charset=""UTF-8""></script>"& vbCrLf
        'txtHtml = txtHtml & "<script type=""text/javascript"" src=""http://portal.cyberjapan.jp/sys/OpenLayers-2.11/OpenLayers.js"" charset=""UTF-8""></script>" & vbCrLf
        txtHtml = txtHtml & "<script type=""text/javascript"" src=""http://tys-yokohama.com/OpenLayers-2.11/OpenLayers.js"" charset=""UTF-8""></script>" & vbCrLf
        'txtHtml = txtHtml & "<script type=""text/javascript"" src=""http://portal.cyberjapan.jp/sys/v4/webtis/webtis_v4.js"" charset=""UTF-8""></script>" & vbCrLf
        txtHtml = txtHtml & "<script type=""text/javascript"" src=""http://tys-yokohama.com/v4source/webtis_v4.js"" charset=""UTF-8""></script>" & vbCrLf
        'txtHtml = txtHtml & "<link rel=""stylesheet"" href=""http://portal.cyberjapan.jp/sys/v4/css/webtis.css"" type=""text/css"">" & vbCrLf
        txtHtml = txtHtml & "<script type=""text/javascript"">" & vbCrLf
        txtHtml = txtHtml & "var map = null;" & vbCrLf
        txtHtml = txtHtml & "var markers = null;" & vbCrLf
        txtHtml = txtHtml & "var initCX = " & lng.ToString.Trim & ";" & vbCrLf
        txtHtml = txtHtml & "var initCY = " & lat.ToString.Trim & ";" & vbCrLf
        txtHtml = txtHtml & "var initZoomLv = 4;" & vbCrLf
        txtHtml = txtHtml & "var projection900913 = new OpenLayers.Projection(""EPSG:900913"");" & vbCrLf
        txtHtml = txtHtml & "var projection4326 = new OpenLayers.Projection(""EPSG:4326"");" & vbCrLf
        'txtHtml = txtHtml & "var projection4612 = new OpenLayers.Projection(""EPSG:4612"");" & vbCrLf
        txtHtml = txtHtml & "function init(){" & vbCrLf
        txtHtml = txtHtml & "   var maxExtent = new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508);" & vbCrLf
        txtHtml = txtHtml & "   var restrictedExtent = maxExtent.clone();" & vbCrLf
        txtHtml = txtHtml & "   var maxResolution = 156543.0339;" & vbCrLf
 
        txtHtml = txtHtml & "   var options = {" & vbCrLf
        txtHtml = txtHtml & "       controls: [" & vbCrLf
        txtHtml = txtHtml & "           new OpenLayers.Control.Navigation({mouseWheelOptions: {interval: 100}})," & vbCrLf
        txtHtml = txtHtml & "           new OpenLayers.Control.PanZoomBar()," & vbCrLf
        txtHtml = txtHtml & "           new OpenLayers.Control.KeyboardDefaults()," & vbCrLf
        txtHtml = txtHtml & "           new OpenLayers.Control.Attribution()," & vbCrLf
        txtHtml = txtHtml & "           new OpenLayers.Control.OverviewMap()," & vbCrLf
        txtHtml = txtHtml & "           new OpenLayers.Control.LayerSwitcher()" & vbCrLf
        txtHtml = txtHtml & "       ]," & vbCrLf
        txtHtml = txtHtml & "       projection: projection900913," & vbCrLf
        txtHtml = txtHtml & "       displayProjection: projection4326," & vbCrLf
        txtHtml = txtHtml & "       units: ""m""," & vbCrLf
        txtHtml = txtHtml & "       maxResolution: maxResolution," & vbCrLf
        txtHtml = txtHtml & "       maxExtent: maxExtent," & vbCrLf
        txtHtml = txtHtml & "       restrictedExtent: restrictedExtent" & vbCrLf
        txtHtml = txtHtml & "   };" & vbCrLf
        txtHtml = txtHtml & "   map = new OpenLayers.Map('map', options);" & vbCrLf
        txtHtml = txtHtml & "   map.addControl(new OpenLayers.Control.ScaleLine({maxWidth:200,bottomOutUnits: """" , bottomInUnits: """" ,geodesic:true}));" & vbCrLf
        txtHtml = txtHtml & "   webtisMap = new webtis.Layer.BaseMap(""webtismap"");" & vbCrLf
        txtHtml = txtHtml & "   map.addLayer(webtisMap);" & vbCrLf
        txtHtml = txtHtml & "   map.setCenter(new OpenLayers.LonLat(initCX,initCY).transform(projection4326,projection900913), initZoomLv);" & vbCrLf
        txtHtml = txtHtml & "   // Mapにクリックイベントを登録" & vbCrLf
        txtHtml = txtHtml & "   map.events.register('click', map, onMouseClick);" & vbCrLf
        txtHtml = txtHtml & "   map.events.register('mousemove', map, onMouseMove);" & vbCrLf
        txtHtml = txtHtml & "   markers = new OpenLayers.Layer.Markers( ""Markers"" );" & vbCrLf
        txtHtml = txtHtml & "   map.addLayer(markers);" & vbCrLf
 
        txtHtml = txtHtml & "   // Styleの設定" & vbCrLf
        txtHtml = txtHtml & "   var styleMap = new OpenLayers.StyleMap(OpenLayers.Util.applyDefaults(" & vbCrLf
        txtHtml = txtHtml & "       {fillColor: ""green"", fillOpacity: 1, strokeColor: ""black""}," & vbCrLf
        txtHtml = txtHtml & "       OpenLayers.Feature.Vector.style[""default""]" & vbCrLf
        txtHtml = txtHtml & "   ));" & vbCrLf
 
        '===========================================
        'Geojson
        txtHtml = txtHtml & "   var featurecollection = " & stResult & ";" & vbCrLf
        txtHtml = txtHtml & "   var geojson_format = new OpenLayers.Format.GeoJSON();" & vbCrLf
        txtHtml = txtHtml & "   var vector_layer = new OpenLayers.Layer.Vector(""神奈川県"",{styleMap: styleMap});" & vbCrLf
        txtHtml = txtHtml & "   vector_layer.setOpacity(0.5);" & vbCrLf
        txtHtml = txtHtml & "   map.addLayer(vector_layer);" & vbCrLf
        txtHtml = txtHtml & "   vector_layer.addFeatures(geojson_format.read(featurecollection));" & vbCrLf
        '===========================================
 
        txtHtml = txtHtml & "}" & vbCrLf
 
        txtHtml = txtHtml & "// mouseclickイベント" & vbCrLf
        txtHtml = txtHtml & "function onMouseClick(evt) {" & vbCrLf
        txtHtml = txtHtml & "   // クリック地点の座標を取得" & vbCrLf
        txtHtml = txtHtml & "   var lonlat = map.getLonLatFromViewPortPx(evt.xy);" & vbCrLf
        txtHtml = txtHtml & "   // 地図座標に変換" & vbCrLf
        txtHtml = txtHtml & "   lonlat.transform(projection900913, projection4326);" & vbCrLf
        'txtHtml = txtHtml & "   document.sample.boxLon.value = lonlat.lon;" & vbCrLf
        'txtHtml = txtHtml & "   document.sample.boxLat.value = lonlat.lat;" & vbCrLf
        '.NETのSubroutineを呼び出す。
        txtHtml = txtHtml & "   window.external.MouseClick(lonlat.lat, lonlat.lon);" & vbCrLf
        txtHtml = txtHtml & "}" & vbCrLf
 
        txtHtml = txtHtml & "// mousemoveイベント" & vbCrLf
        txtHtml = txtHtml & "function onMouseMove(evt) {" & vbCrLf
        txtHtml = txtHtml & "   var lonlat = map.getLonLatFromViewPortPx(evt.xy);" & vbCrLf
        txtHtml = txtHtml & "   // 地図座標に変換" & vbCrLf
        txtHtml = txtHtml & "   lonlat.transform(projection900913, projection4326);" & vbCrLf
        '.NETのSubroutineを呼び出す。
        txtHtml = txtHtml & "   window.external.MouseMove(lonlat.lat, lonlat.lon);" & vbCrLf
        txtHtml = txtHtml & "}" & vbCrLf
 
        'Markerの描画
        txtHtml = txtHtml & "// mousemoveイベント" & vbCrLf
        txtHtml = txtHtml & "function moveToPoint(Lat, Lng, strTitle) {" & vbCrLf
        txtHtml = txtHtml & "   var lonlat = new OpenLayers.LonLat(Lng,Lat).transform(projection4326,projection900913);" & vbCrLf
        txtHtml = txtHtml & "   map.setCenter(lonlat);" & vbCrLf
        txtHtml = txtHtml & "   // markerの描画" & vbCrLf
        txtHtml = txtHtml & "   var marker = new OpenLayers.Marker(lonlat);" & vbCrLf
        txtHtml = txtHtml & "   markers.addMarker(marker);" & vbCrLf
        txtHtml = txtHtml & "}" & vbCrLf
 
 
        txtHtml = txtHtml & "</script>" & vbCrLf
        txtHtml = txtHtml & "</head>" & vbCrLf
        txtHtml = txtHtml & "<body onload=""init();"">" & vbCrLf
        txtHtml = txtHtml & "<div id=""map"" name=""map"" style=""width: 100%; height:100%;""></div>" & vbCrLf
        'txtHtml = txtHtml & "<form name=""sample"">" & vbCrLf
        'txtHtml = txtHtml & "<div>チェックのためのhtml出力</div>" & vbCrLf
        'txtHtml = txtHtml & "<div>" & vbCrLf
        'txtHtml = txtHtml & "緯度:<input type=""text"" name=""boxLat"" />" & vbCrLf
        'txtHtml = txtHtml & "経度:<input type=""text"" name=""boxLon"" />" & vbCrLf
        'txtHtml = txtHtml & "</div>" & vbCrLf
        'txtHtml = txtHtml & "</form>" & vbCrLf
        txtHtml = txtHtml & "</body>" & vbCrLf
        txtHtml = txtHtml & "</html>" & vbCrLf
 
        OpenLayersGeoJson = txtHtml
 
    End Function

プログラムの説明

注意点jacascriptを弊社のURLに設置して呼び出しています。 この部分は、本家を参照してください。 弊社Serverのdirectory構成で変更になる可能性があります。

プログラムとしては、簡単ですが、

  1. GeoJSONファイルを読み込んで、stringに放り込みます。
  2. Function OpenLayersGeoJsonでGeoJSONファイルを結合します。

簡単にGeoJSONのVector Layer作成部分は数行で書くことができます。

プログラムの実行

注意点
WebBrowserコントロールはvisual studio標準のものを使っています。GeoJSONデータ数が多くなると描画に非常に時間がかかります。
これは、WEBレンダリングエンジンの影響と思われます。
今後はGoogle ChromeとかSafariとかAndroidとかで使われているレンダリングエンジンでのWebkitや、Firefoxとかで使われているレンダリングエンジンのGeckoを使うことで処理速度は速める必要があります。

それでは、実行してみましょう。
プログラムを起動すると地図が表示されます。

「ポイント移動」ボタンをクリックした場合、toolstrip内のtextboxの緯度経度に移動して、マーカーが描画されます。 Googlemapのサンプルと同じようにタイトルを入力しても、tooltipsでマーカーにmouseoverすると表示されません。ここのところは、作成中です。

blog.godo-tys.jp_wp-content_gallery_geojson_image02.jpg
初期画面

blog.godo-tys.jp_wp-content_gallery_geojson_image03.jpg
GeoJSON読み込みボタンをクリックしてGeoJSONファイルを選択した例

blog.godo-tys.jp_wp-content_gallery_geojson_image04.jpg
神奈川県のGeoJSONを描画した例

blog.godo-tys.jp_wp-content_gallery_geojson_image05.jpg
LayerSwticherでoverlayerを表示/非表示に変更した例

基本的は機能だけをチェックしてみましたが、いろいろと応用すれば、非常におもしろいソフトウェアができあがりますね。

次回は、Shape file → GeoJSONの実装を作成してみます。FwTools内にgdal_csharp.dllとogr_csharp.dllがあるので、これでできるのでは?と安易に考えていますが。。。

サンプルコードとGeoJSONサンプルをこちらにアップしておきます。使用する際は自己責任にて使って下さい。

参照したHP(先人に感謝します。

おまけ

GIS Data ConverterなんていうWEBサービスがありました。

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

WP-SpamFree by Pole Position Marketing

Social Widgets powered by AB-WebLog.com.