OpenlayersとGeoExtで電子国土地図を使ってみる。 [Chapter 2]
気づいた部分は全角の'¥'に置き換えています。
現在、dokuwikiへの移動を進めていますので、今しばらくお待ちください。
さて、今回はGeoJSONデータと電子国土地図v.4をGeoExtで表示させます。
GeoExtのexampleがたくさんあるので、その中からpopup,toolbarやtreeなどを使ってみます。
電子国土地図の詳細情報は、こちらのHPを参照してください。
動作確認環境は、ms4wです。 linuxでも動作します。
電子国土とGeoJSONのOverlay
電子国土地図にGeoJSONを重ねてみる。[Chapter 1]でvb.netでGeoJSONを読み込んで、htmlを作成しましたが、今回はGeoJSONファイルを読み込んで表示してみます。
そのGeoJSON読み込みコードは
// GeoJSONファイルを読み込んでVectorLayerを作成 vectorLayer = new OpenLayers.Layer.Vector("GeoJSON", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: "http://localhost/test/data/kanagawk.json", format: new OpenLayers.Format.GeoJSON() }) });
OpenLayers.Protocol.HTTPでlocalhost/test/data/kanagawk.jsonデータを読み込みます。
kmlやxml、gmlにも適応できますので、詳しくはOpenLayersのマニュアルを読んでください。
C:/ms4w/Apache/htdocs/testフォルダーにdataフォルダーを作成して、kanagawk.jsonデータをコピーします。
kanagawk.jsonデータは、電子国土地図にGeoJSONを重ねてみる。[Chapter 1のサンプルのダウンロードに添付しています。
testフォルダーに、GeoExt-json.htmlを作成します。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>GeoExt GeoJSON Example</title> <script type="text/javascript" src="http://localhost/ext-3.4.0/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="http://localhost/ext-3.4.0/ext-all.js"></script> <link rel="stylesheet" type="text/css" href="http://localhost/ext-3.4.0/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="http://localhost/ext-3.4.0/examples/shared/examples.css" /> <script src="http://localhost/OpenLayers-2.12/OpenLayers.js"></script> <script type="text/javascript" src="http://localhost/GeoExt-1.1/script/GeoExt.js"></script> <script type="text/javascript" src="http://localhost/v4/webtis/webtis_v4.js" charset="UTF-8"></script> <link rel="stylesheet" href="http://localhost/v4/css/webtis.css" type="text/css"> <script src="http://maps.google.com/maps/api/js?v=3.9&sensor=false"></script> <script type="text/javascript"> //初期の経度 var initCX = 139.4; //初期の緯度 var initCY = 35.4; //真球メルカトル投影 var projection900913 = new OpenLayers.Projection("EPSG:900913"); //等経緯度投影を定義 var projection4326 = new OpenLayers.Projection("EPSG:4326"); //真球メルカトル投影のときの最大範囲(単位はm) var maxExtent = new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508); //真球メルカトル投影のときの最大範囲に範囲を制限 var restrictedExtent = maxExtent.clone(); //真球メルカトル投影のときの最大解像度 var maxResolution = 156543.0339; var map, webtisLayer, vectorLayer; Ext.onReady(function () { map = new OpenLayers.Map('map', { projection: projection900913, maxResolution: 'auto', maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508), units: 'm', displayProjection: projection4326, controls: [ //new OpenLayers.Control.Attribution(), new OpenLayers.Control.Navigation({mouseWheelOptions: {interval: 50}}), new OpenLayers.Control.KeyboardDefaults(), //new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.LayerSwitcher(), new OpenLayers.Control.MousePosition(), new OpenLayers.Control.ScaleLine(), new OpenLayers.Control.PanPanel(), new OpenLayers.Control.ZoomPanel() //new OpenLayers.Control.OverviewMap() ], }); // GeoJSONファイルを読み込んでVectorLayerを作成 vectorLayer = new OpenLayers.Layer.Vector("GeoJSON", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: "http://localhost/test/data/kanagawk.json", format: new OpenLayers.Format.GeoJSON() }) }); // webtisLayer = new webtis.Layer.BaseMap("電子国土"); map.addLayers([webtisLayer, vectorLayer]); map.zoomToMaxExtent(); // マップパネルの表示 new GeoExt.MapPanel({ renderTo: ‘mappanel’, // マップ描画のための id height: 480, // パネル高さ width: 600, // パネル幅 map: map, // OpenLayers.Map //初期の中心座標を指定(経緯度で入力して、内部的に真球メルカトル座標に変換して表示) center: new OpenLayers.LonLat(initCX,initCY).transform(projection4326,projection900913), zoom: 4, //電子国土地図の地理座標系 projection: projection900913, //表示の地理座標系 displayProjection: projection4326, //電子国土地図の最大解像度 maxResolution: maxResolution, //電子国土地図の最大範囲 maxExtent: maxExtent, //電子国土地図の表示制限範囲 restrictedExtent: restrictedExtent, //電子国土地図の単位 units: "m", title: ‘A Simple GeoExt GeoJSON Example Map’ // パネル上部に表示されるタイトル }); }); </script> </head> <body> <h1 id="title">GeoExt GeoJSON Example</h1> <p id="shortdesc">GeoExt GeoJSON Example.</p> <div id="mappanel"></div> <div id="docs"> <p>GeoExtで電子国土と神奈川県のGeoJSONデータを表示します。</p> </div> </body> </html>
ブラウザーから、http://localhost/test/GeoExt-json.htmlと入力して実行すると。
toolbarを付け加えたexample
次に、toolbarとzoombarとvectorデータの作成、Layer透過度を加えたものをサンプルとして作成します。
C:/ms4w/Apache/htdocs/testフォルダーに2つファイルを作成します。
-
GeoExt-toolbar.html
-
GeoExt-toolbar.js
GeoExt-toolbar.htmlのコード
<html> <head> <title>GeoExt Toolbar Example</title> <script type="text/javascript" src="http://localhost/ext-3.4.0/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="http://localhost/ext-3.4.0/ext-all.js"></script> <link rel="stylesheet" type="text/css" href="http://localhost/ext-3.4.0/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="http://localhost/ext-3.4.0/examples/shared/examples.css" /> <script src="http://localhost/OpenLayers-2.12/OpenLayers.js"></script> <script type="text/javascript" src="http://localhost/GeoExt-1.1/script/GeoExt.js"></script> <script type="text/javascript" src="http://localhost/v4/webtis/webtis_v4.js" charset="UTF-8"></script> <link rel="stylesheet" href="http://localhost/v4/css/webtis.css" type="text/css"> <script src="http://maps.google.com/maps/api/js?v=3.9&sensor=false"></script> <script type="text/javascript" src="GeoExt-toolbar.js"></script> <style type="text/css"> /* work around an Ext bug that makes the rendering of menu items not as one would expect */ .ext-ie .x-menu-item-icon { left: -24px; } .ext-strict .x-menu-item-icon { left: 3px; } .ext-ie6 .x-menu-item-icon { left: -24px; } .ext-ie7 .x-menu-item-icon { left: -24px; } </style> </head> <body> <h1>GeoExt 電子国土 toolbar</h1> <p>This example shows how to add OpenLayers controls in an Ext toolbar.</br> GeoExt provides the GeoExt.Action class for adapating a control to an </br> object that can be inserted in a toolbar or in a menu.</p> <p>The js is not minified so it is readable. See <a href="GeoExt-toolbar.js">GeoExt-toolbar.js</a>.</p> <div id="mappanel"></div> <div id="slider" style="clear:both"></div> </body> </html>
GeoExt-toolbar.jsのコード
/** api: example[toolbar] * Toolbar with Actions * -------------------- * Create a toolbar with GeoExt Actions. */ //初期の経度 var initCX = 139.4; //初期の緯度 var initCY = 35.4; //真球メルカトル投影 var projection900913 = new OpenLayers.Projection("EPSG:900913"); //等経緯度投影を定義 var projection4326 = new OpenLayers.Projection("EPSG:4326"); var mapPanel, slider; Ext.onReady(function() { Ext.QuickTips.init(); //真球メルカトル投影のときの最大範囲(単位はm) var maxExtent = new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508); //真球メルカトル投影のときの最大範囲に範囲を制限 var restrictedExtent = maxExtent.clone(); //真球メルカトル投影のときの最大解像度 var maxResolution = 156543.0339; // var map = new OpenLayers.Map(); var map = new OpenLayers.Map('map', { controls: [ //new OpenLayers.Control.Attribution(), new OpenLayers.Control.Navigation({mouseWheelOptions: {interval: 50}}), new OpenLayers.Control.KeyboardDefaults(), new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.LayerSwitcher(), new OpenLayers.Control.MousePosition(), new OpenLayers.Control.ScaleLine(), new OpenLayers.Control.OverviewMap() ], allOverlays: false, projection: projection900913, maxResolution: maxResolution, maxExtent: maxExtent, units: 'm', displayProjection: projection4326 }); webtisLayer = new webtis.Layer.BaseMap("webtisLayer"); // GeoJSONファイルを読み込んでVectorLayerを作成 vectorLayer = new OpenLayers.Layer.Vector("GeoJSON", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: "http://localhost/test/data/kanagawk.json", format: new OpenLayers.Format.GeoJSON() }) }); // var gmaplayerRoad = new OpenLayers.Layer.Google( '道路地図', {numZoomLevels: 20}, {visibility: true} ); var gmaplayerHybrid = new OpenLayers.Layer.Google( '衛星写真', {type: google.maps.MapTypeId.HYBRID}, {numZoomLevels: 20}, {visibility: true} ); var drawLayer = new OpenLayers.Layer.Vector("vector"); map.addLayers([webtisLayer, gmaplayerRoad, gmaplayerHybrid, vectorLayer, drawLayer]); //ZoomSelectorの定義 var scaleStore = new GeoExt.data.ScaleStore({map: map}); var zoomSelector = new Ext.form.ComboBox({ store: scaleStore, emptyText: "Zoom Level", tpl: '<tpl for="."><div class="x-combo-list-item">1 : {[parseInt(values.scale)]}</div></tpl>', editable: false, triggerAction: 'all', // needed so that the combo box doesn't filter by its current content mode: 'local' // keep the combo box from forcing a lot of unneeded data refreshes }); zoomSelector.on('select', function(combo, record, index) { map.zoomTo(record.data.level); }, this ); map.events.register('zoomend', this, function() { var scale = scaleStore.queryBy(function(record){ return this.map.getZoom() == record.data.level; }); if (scale.length > 0) { scale = scale.items[0]; zoomSelector.setValue("1 : " + parseInt(scale.data.scale)); } else { if (!zoomSelector.rendered) return; zoomSelector.clearValue(); } }); // create a separate slider bound to the map but displayed elsewhere slider = new GeoExt.LayerOpacitySlider({ layer: vectorLayer, aggressive: true, width: 200, isFormField: true, inverse: true, fieldLabel: "opacity", renderTo: "slider", //id=slider plugins: new GeoExt.LayerOpacitySliderTip({template: '<div>透過度: {opacity}%</div>'}) }); //toolbarの定義 var ctrl, toolbarItems = [], action, actions = {}; // MaxExtentがおかしいので、とりあえず非表示 // ZoomToMaxExtent control, a "button" control /*action = new GeoExt.Action({ control: new OpenLayers.Control.ZoomToMaxExtent(), map: map, text: "全体表示", tooltip: "全体を表示" }); actions["max_extent"] = action; toolbarItems.push(action); toolbarItems.push("-");*/ // Navigation control and DrawFeature controls // in the same toggle group action = new GeoExt.Action({ text: "ナビゲーション", control: new OpenLayers.Control.Navigation(), map: map, // button options toggleGroup: "draw", allowDepress: false, pressed: true, tooltip: "マウス操作", // check item options group: "draw", checked: true }); actions["nav"] = action; toolbarItems.push(action); action = new GeoExt.Action({ text: "ポリゴン", control: new OpenLayers.Control.DrawFeature( drawLayer, OpenLayers.Handler.Polygon ), map: map, // button options toggleGroup: "draw", allowDepress: false, tooltip: "ポリゴンの作成", // check item options group: "draw" }); actions["draw_poly"] = action; toolbarItems.push(action); action = new GeoExt.Action({ text: "ライン", control: new OpenLayers.Control.DrawFeature( drawLayer, OpenLayers.Handler.Path ), map: map, // button options toggleGroup: "draw", allowDepress: false, tooltip: "ラインの作成", // check item options group: "draw" }); actions["draw_line"] = action; toolbarItems.push(action); toolbarItems.push("-"); // SelectFeature control, a "toggle" control action = new GeoExt.Action({ text: "選択", control: new OpenLayers.Control.SelectFeature(drawLayer, { type: OpenLayers.Control.TYPE_TOGGLE, hover: true }), map: map, // button options enableToggle: true, tooltip: "フィーチャ選択" }); actions["select"] = action; toolbarItems.push(action); toolbarItems.push("-"); // Navigation history - two "button" controls ctrl = new OpenLayers.Control.NavigationHistory(); map.addControl(ctrl); action = new GeoExt.Action({ text: "前に戻る", control: ctrl.previous, disabled: true, tooltip: "前の表示範囲に戻る" }); actions["previous"] = action; toolbarItems.push(action); action = new GeoExt.Action({ text: "次に進む", control: ctrl.next, disabled: true, tooltip: "次の表示範囲に進む" }); actions["next"] = action; toolbarItems.push(action); toolbarItems.push("->"); // Reuse the GeoExt.Action objects created above // as menu items toolbarItems.push({ text: "menu", menu: new Ext.menu.Menu({ items: [ // ZoomToMaxExtent //actions["max_extent"], // Nav new Ext.menu.CheckItem(actions["nav"]), // Draw poly new Ext.menu.CheckItem(actions["draw_poly"]), // Draw line new Ext.menu.CheckItem(actions["draw_line"]), // Select control new Ext.menu.CheckItem(actions["select"]), // Navigation history control actions["previous"], actions["next"] ] }) }); mapPanel = new GeoExt.MapPanel({ renderTo: "mappanel", height: 480, width: 600, map: map, //初期の中心座標を指定(経緯度で入力して、内部的に真球メルカトル座標に変換して表示) center: new OpenLayers.LonLat(initCX,initCY).transform(projection4326,projection900913), zoom: 4, //電子国土地図の地理座標系 projection: projection900913, //表示の地理座標系 displayProjection: projection4326, //電子国土地図の最大解像度 maxResolution: maxResolution, //電子国土地図の最大範囲 maxExtent: maxExtent, //電子国土地図の表示制限範囲 restrictedExtent: restrictedExtent, //電子国土地図の単位 units: "m", //定義したメニューtoolbarの追加 tbar: toolbarItems, //定義した縮尺選択bbarの追加 bbar: [zoomSelector] }); });
次に、ブラウザーからhttp://localhost/test/GeoExt-toolbar.htmlとすれば、
toolbarメニューを操作して、ポリゴンやラインを作成などの操作ができます。
http://map.godo-tys.jp/GeoExt-toolbar.htmlにサンプルをおいておきます。
treeとviewportを付け加えたexample
次に、treeとviewportとmouse click eventを加えたものをサンプルとして作成します。
C:/ms4w/Apache/htdocs/testフォルダーに2つファイルを作成します。
-
GeoExt-tree.html
-
GeoExt-tree.js
GeoExt-tree.htmlのコード
<html> <head> <title>GeoExt Tree Legend</title> <script type="text/javascript" src="http://localhost/ext-3.4.0/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="http://localhost/ext-3.4.0/ext-all.js"></script> <link rel="stylesheet" type="text/css" href="http://localhost/ext-3.4.0/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="http://localhost/ext-3.4.0/examples/shared/examples.css" /> <script src="http://localhost/OpenLayers-2.12/OpenLayers.js"></script> <script type="text/javascript" src="http://localhost/GeoExt-1.1/script/GeoExt.js"></script> <script type="text/javascript" src="http://localhost/v4/webtis/webtis_v4.js" charset="UTF-8"></script> <link rel="stylesheet" href="http://localhost/v4/css/webtis.css" type="text/css"> <script src="http://maps.google.com/maps/api/js?v=3.9&sensor=false"></script> <script type="text/javascript" src="GeoExt-tree.js"></script> <style type="text/css"> .legend { padding-left: 18px; } .x-tree-node-el { border-bottom: 1px solid #ddd; padding-bottom: 3px; } .x-tree-ec-icon { width: 3px; } .gx-tree-layer-icon { display: none; } </style> </head> <body> <div id="desc"> <h1 id="title">GeoExt 電子国土地図 Tree Legend</h1> <p id="shortdesc"> GeoExt Legend Tree </p> <p>この例では、ツリー内のレイヤノードに凡例を追加する方法を示します。</p> </div> </body> </html>
GeoExt-toolbar.jsのコード
/** api: example[tree-legend] * Tree Legend * ----------- * Render layer nodes with legends. */ //初期の経度 var initCX = 139.4; //初期の緯度 var initCY = 35.4; //真球メルカトル投影 var projection900913 = new OpenLayers.Projection("EPSG:900913"); //等経緯度投影を定義 var projection4326 = new OpenLayers.Projection("EPSG:4326"); //真球メルカトル投影のときの最大範囲(単位はm) var maxExtent = new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508); //真球メルカトル投影のときの最大範囲に範囲を制限 var restrictedExtent = maxExtent.clone(); //真球メルカトル投影のときの最大解像度 var maxResolution = 156543.0339; var mapPanel, popup; // custom layer node UI class var LayerNodeUI = Ext.extend( GeoExt.tree.LayerNodeUI, new GeoExt.tree.TreeNodeUIEventMixin() ); Ext.onReady(function() { //Popup windowの定義 function addToPopup(loc) { // create the popup if it doesn't exist if (!popup) { popup = new GeoExt.Popup({ title: "Popup", width: 200, maximizable: true, collapsible: true, map: mapPanel.map, anchored: true, listeners: { close: function() { // closing a popup destroys it, but our reference is truthy popup = null; } } }); } // add some content to the popup (this can be any Ext component) popup.add({ xtype: "box", autoEl: { html: "You clicked on (" + loc.lon.toFixed(2) + ", " + loc.lat.toFixed(2) + ")" } }); // reset the popup's location loc.transform(projection4326, projection900913); popup.location = loc; popup.doLayout(); // since the popup is anchored, calling show will move popup to this location popup.show(); } var control = new OpenLayers.Control.Click({ trigger: function(evt) { var loc = mapPanel.map.getLonLatFromViewPortPx(evt.xy); loc.transform(projection900913, projection4326); addToPopup(loc); } }); // 電子国土地図の設定 var map = new OpenLayers.Map('map', { controls: [ //new OpenLayers.Control.Attribution(), new OpenLayers.Control.Navigation({mouseWheelOptions: {interval: 50}}), new OpenLayers.Control.KeyboardDefaults(), //new OpenLayers.Control.PanZoomBar(), //new OpenLayers.Control.LayerSwitcher(), new OpenLayers.Control.MousePosition(), new OpenLayers.Control.ScaleLine(), new OpenLayers.Control.PanPanel(), new OpenLayers.Control.ZoomPanel() //new OpenLayers.Control.OverviewMap() ], allOverlays: true, projection: projection900913, maxResolution: maxResolution, maxExtent: maxExtent, units: 'm', displayProjection: projection4326 }); //電子国土の定義 var webtisLayer = new webtis.Layer.BaseMap("電子国土"); // GeoJSONファイルを読み込んでVectorLayerを作成 var vectorLayer = new OpenLayers.Layer.Vector("GeoJSON", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: "http://localhost/test/data/kanagawk.json", format: new OpenLayers.Format.GeoJSON() }) }); mapPanel = new GeoExt.MapPanel({ region: "center", zoom: 6, map: map, //初期の中心座標を指定(経緯度で入力して、内部的に真球メルカトル座標に変換して表示) center: new OpenLayers.LonLat(initCX,initCY).transform(projection4326,projection900913), zoom: 4, //電子国土地図の地理座標系 projection: projection900913, //表示の地理座標系 displayProjection: projection4326, //電子国土地図の最大解像度 maxResolution: maxResolution, //電子国土地図の最大範囲 maxExtent: maxExtent, //電子国土地図の表示制限範囲 restrictedExtent: restrictedExtent, //電子国土地図の単位 units: "m", //Layerの追加 layers: [webtisLayer, vectorLayer] }); mapPanel.map.addControl(control); control.activate(); var tree = new Ext.tree.TreePanel({ region: "east", title: "Layers", width: 250, autoScroll: true, enableDD: true, // apply the tree node component plugin to layer nodes plugins: [{ ptype: "gx_treenodecomponent" }], loader: { applyLoader: false, uiProviders: { "custom_ui": LayerNodeUI } }, root: { nodeType: "gx_layercontainer", loader: { baseAttrs: { uiProvider: "custom_ui" }, createNode: function(attr) { // add a WMS legend to each node created attr.component = { xtype: "gx_wmslegend", layerRecord: mapPanel.layers.getByLayer(attr.layer), showTitle: false, // custom class for css positioning // see tree-legend.html cls: "legend" } return GeoExt.tree.LayerLoader.prototype.createNode.call(this, attr); } } }, rootVisible: false, lines: false }); //ViewPortの定義 new Ext.Viewport({ layout: "fit", hideBorders: true, items: { layout: "border", items: [ mapPanel, tree, { contentEl: desc, region: "west", width: 250, bodyStyle: {padding: "5px"} } ] } }); }); // simple control to handle user clicks on the map OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { defaultHandlerOptions: { single: true, double: false, pixelTolerance: 0, stopSingle: true }, initialize: function(options) { this.handlerOptions = OpenLayers.Util.extend( options && options.handlerOptions || {}, this.defaultHandlerOptions ); OpenLayers.Control.prototype.initialize.apply( this, arguments ); this.handler = new OpenLayers.Handler.Click( this, { click: this.trigger }, this.handlerOptions ); }, CLASS_NAME: "OpenLayers.Control.Click" });
次に、ブラウザーからhttp://localhost/test/GeoExt-tree.htmlとすれば、
が表示されます。 いろいろとマウスで操作してみてください。
とりあえず、OK。
http://map.godo-tys.jp/GeoExt-tree.htmlにサンプルをおいておきます。
最後に
GeoJSONデータを作成すれば、Overlayすることが簡単にできます。また、kmlやgml、GeoRSSも可能です。
これらのデータは、ESRI仕様のShape fileであれば、ogr2ogrコマンドで簡単にformat変換することができます。
使い方については、月の杜工房gdal/ogrの小技集が非常に参考になります。
vb.net版も作成中ですが。。。 いかんせん情報がないです。 最悪はdosコマンドをGUIくらいしかできないかもですね。
GeoExtで地図の操作性が非常に良くなります。もう少し手を加えてWEB-GISアプリケーションを作成してみます。
GeoExtのHPをしっかりと読んで、使いこなせるようにならねば。。。
「OpenlayersとGeoExtで電子国土地図を使ってみる。」は後2回ほどで終了する予定です。
なにか、こんなことはできないなどなりましたら、問い合わせからメールにてお願いします。
おまけ
DBFの編集ソフトを作成してみました。
GISエンジンはMapWinGISを使っています。
ベクターに登録も行っています。
また、株式会社森林再生システムと共同開発でExcelGISも作成しておりますので、覗いてみてください。
最近のコメント