電子国土地図に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構成で変更になる可能性があります。
プログラムとしては、簡単ですが、
-
GeoJSONファイルを読み込んで、stringに放り込みます。
-
Function OpenLayersGeoJsonでGeoJSONファイルを結合します。
簡単にGeoJSONのVector Layer作成部分は数行で書くことができます。
問題点
-
OpenLayersのStyleが崩れる。(これはcssなどで対応可能?)
-
Googlemapの表示のスクリプトを入れると動かない。
-
window.externalが使えない
-
webkitではObjectForScriptingにあたるものがない?(調査中)
なんでだろう???
いろいろと探しては見るものの、それらしい記述はあるが、なかなかたどり着かない。。。
Please Help me !!
プログラムの実行
それでは、実行してみましょう。
プログラムを起動すると地図が表示されます。
GooleMap表示ボタンをクリックした場合 真っ白。。。。 なんでやねん!!
GeoJSONファイルは800kb程度ですが、[Chapter 1]のプログラムで呼び出すと非常に遅い。
しかし、今回のプログラムでは処理スピードは十分に使用に耐えることができます。
今後は、webkitで行きたいけど。 問題山積みなんですよね。
サンプルコードとGeoJSONサンプルをこちらにアップしておきます。使用する際は自己責任にて使って下さい。
どなたか、わかる方いればうまくいく方法を教えてください。
よろしくお願いします。
最近のコメント