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

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

電子国土地図にGeoJSONを重ねてみる。[Chapter 1]では.NET標準のwebbrowserコントロールを使いましたが、ちょっと大きなGeoJSONファイルを読み込むと「ハングアップしたのではないか?」と思うくらいに描画遅くなります。
これでは、たぶん使い物になりません。

そこで今回は、Google ChromeとかSafariとかAndroidとかで使われているレンダリングエンジンでのWebkitを使ってGeoJSONの表示をやることにしました。

でも、問題山積み。。。
webkitの情報があまりないので、試行錯誤してますが、うまくいきません。

とりあえず、現状のプログラムを見てみましょう。

準備

webkitの設定
webkitをダウンロードしてVisual studio 2010で使えるようにします。
こちらのサイトを参考にしました。 先人に感謝します。
WebKit.NETで簡素なWebブラウザを作る(C#)

vb.netのデザイン

いつも変わらないので、省略。

サンプルコード

GeoJSONファイルを読み込んで電子国土地図にoverlayをするコードはこんな感じです。
単純にwebbrowserからwebkitbowserになっただけです。

 
    ''' <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)
 
            'webkitではObjectForScriptingがない。
            'WebKitBrowser1.ObjectForScripting = New ExtOpenLayersObj 'クラスのインスタンスを渡す
 
            '電子国土地図表示
            Dim lat As String = ToolStripTextBox1.Text
            Dim lng As String = ToolStripTextBox2.Text
 
 
            WebKitBrowser1.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 src=""http://maps.google.co.jp/maps/api/js?v=3.5&sensor=false&language=ja""></script>" & vbCrLf
        txtHtml = txtHtml & "<link rel=""stylesheet"" href=""http://tys-yokohama.com/OpenLayers-2.11/theme/default/style.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 & "   // Google ROADMAP追加" & vbCrLf
        'txtHtml = txtHtml & "   var gmap = new OpenLayers.Layer.Google(""Google ROADMAP"");" & vbCrLf
        'txtHtml = txtHtml & "   map.addLayer(gmap);" & vbCrLf
        'txtHtml = txtHtml & "   // Google HYBRID追加" & vbCrLf
        'txtHtml = txtHtml & "   var gmap_hybrid = new OpenLayers.Layer.Google(""Google HYBRID""," & vbCrLf
        'txtHtml = txtHtml & "           {type: google.maps.MapTypeId.HYBRID}" & vbCrLf
        'txtHtml = txtHtml & "   );" & vbCrLf
        'txtHtml = txtHtml & "   map.addLayer(gmap_hybrid);" & 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(""GeoJSON"",{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
        txtHtml = txtHtml & "   document.sample.moveboxLon.value = lonlat.lon;" & vbCrLf
        txtHtml = txtHtml & "   document.sample.moveboxLat.value = lonlat.lat;" & 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:80%;""></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 & "<div>" & vbCrLf
        txtHtml = txtHtml & "緯度:<input type=""text"" name=""moveboxLat"" />" & vbCrLf
        txtHtml = txtHtml & "経度:<input type=""text"" name=""moveboxLon"" />" & 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作成部分は数行で書くことができます。

問題点

  1. OpenLayersのStyleが崩れる。(これはcssなどで対応可能?)
  2. Googlemapの表示のスクリプトを入れると動かない。
  3. window.externalが使えない
  4. webkitではObjectForScriptingにあたるものがない?(調査中)

なんでだろう???

いろいろと探しては見るものの、それらしい記述はあるが、なかなかたどり着かない。。。

Please Help me !!

プログラムの実行

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

blog.godo-tys.jp_wp-content_gallery_webkit_image01.jpg
初期画面 control類がずれずれですね。

blog.godo-tys.jp_wp-content_gallery_webkit_image02.jpg
神奈川県の3次メッシュのGeoJSONを描画した例

blog.godo-tys.jp_wp-content_gallery_webkit_image03.jpg
GooleMap表示ボタンをクリックした場合 真っ白。。。。 なんでやねん!!

GeoJSONファイルは800kb程度ですが、[Chapter 1]のプログラムで呼び出すと非常に遅い。
しかし、今回のプログラムでは処理スピードは十分に使用に耐えることができます。
今後は、webkitで行きたいけど。 問題山積みなんですよね。

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

どなたか、わかる方いればうまくいく方法を教えてください。 
よろしくお願いします。

Comments are closed.

Social Widgets powered by AB-WebLog.com.