Version 4 (modified by hayashi, 14 years ago) |
---|
OpenLayers を使用したWPSクライアントの構築
TOC(heading= )? 前へ | ワークショップ 目次 | 次へ
次のステップではOpenLayers mapから作成したOGR Servicesに関連付けます。こうすることで、選択したポリゴン上で単一または複数の幾何処理を行い、新規作成したジオメトリを表示することができます。
WMSのデータセットを表示する簡単なマップの作成
!OpenLayersはOSGeoLiveのデフォルトのディストリビューションにも含まれているため、便宜上これを使用します。好きなテキストエディタで /var/www/zoo-ogr.html を開き、次のHTMLをペーストしてください:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="EN" lang="EN"> <head> <meta content="text/html; charset=UTF-8" http-equiv="content-type"/> <title>ZOO WPS Client example</title> <style> #map{width:700px;height:600px;} </style> <link rel="stylesheet" href="/openlayers/theme/default/style.css" type="text/css" /> <script type="text/javascript" src="/openlayers/lib/OpenLayers.js"></script> </head> <body onload="init()"> <div id="map"></div> </body> </html>
次のJavaScript コードを<head>内の <script></script>} セクションに追加します。するとWMSとして日本の領域を表示するデータが設定されます。
var map, layer, select, hover, multi, control; var typename="regions"; var main_url="http://localhost/cgi-bin/mapserv?map=/var/www/wfs.map"; function init(){ map = new OpenLayers.Map('map', { controls: [ new OpenLayers.Control.PanZoom(), new OpenLayers.Control.Permalink(), new OpenLayers.Control.Navigation() ] }); layer = new OpenLayers.Layer.WMS(typename,main_url, { layers: 'regions', transparent: 'true', format: 'image/png' }, { isBaseLayer: true, visibility: true, buffer: 0, singleTile: true } ); map.addLayers([layer]); map.setCenter(new OpenLayers.LonLat(138,33.5),5); }
終了したらHTMLファイルをzoo-ogr.htmlとしてワークショップディレクトリに保存し、/var/www にコピーします。好きなウェブブラウザでリンク/var/www http://localhost/zoo-ogr.html. を開き、これを使って可視化してください。WMSレイヤーが選択されている、USAを中心とするマップを手に入れることができます。
WFSのデータレイヤー取得と選択コントロールの追加
WFSを通じて表示されているデータにアクセスする前に、先ずはこれから作成するいくつもの相互作用をすることを目的とするに新規ベクトルレイヤーを作成しなければなりません。init() 関数内に次のラインを追加します。 map.addLayers メソッドに新規作成したレイヤーを忘れず追加して下さい:
select = new OpenLayers.Layer.Vector("Selection", { styleMap: new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"]) }); hover = new OpenLayers.Layer.Vector("Hover"); multi = new OpenLayers.Layer.Vector("Multi", { styleMap: new OpenLayers.Style({ fillColor:"red", fillOpacity:0.4, strokeColor:"red", strokeOpacity:1, strokeWidth:2 }) }); map.addLayers([layer, select, hover, multi]);
次に、下記ようにポリゴンを選択する新規コントロールを作成することによってtデータにアクセスすることが可能になります。OpenLayers.Protocol.WFS.fromWMSLayer(layer)はジオメトリへのアクセスに使用され、そして選択の状況は表示され制御変数に追加されるということにご注意ください。
control = new OpenLayers.Control.GetFeature({ protocol: protocol, box: false, hover: false, multipleKey: "shiftKey", toggleKey: "ctrlKey" }); control.events.register("featureselected", this, function(e) { select.addFeatures([e.feature]); }); control.events.register("featureunselected", this, function(e) { select.removeFeatures([e.feature]); }); map.addControl(control); control.activate();
HTMファイルを再度保存して下さい。ポリゴン上でクリックすると選択することができます。選択されたポリゴンは青色で表示されます。
JavaScript から呼び出される単一ジオメトリサービス
これで全て設定できたので、!JavaScriptでOGR ZOO サービスを呼び出してみましょう。 init() 関数のあとに次の行を追加してください。一つのジオメトリ処理を呼び出します。fid 値として返された不要な空白を削除する特定の parseMapServerId 関数を使うことに気づくでしょう。
function parseMapServerId(){ var sf=arguments[0].split("."); return sf[0]+"."+sf[1].replace(/ /g,''); } function simpleProcessing(aProcess) { if (select.features.length == 0) return alert("No feature selected!"); if(multi.features.length>=1) multi.removeFeatures(multi.features); var url = '/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&'; if (aProcess == 'Buffer') { var dist = document.getElementById('bufferDist')?document.getElementById('bufferDist').value:'1'; if (isNaN(dist)) return alert("Distance is not a Number!"); url+='Identifier=Buffer&DataInputs=BufferDistance='+dist+'@datatype=interger;InputPolygon=Reference@xlink:href='; } else url += 'Identifier='+aProcess+'&DataInputs=InputPolygon=Reference@xlink:href='; var xlink = control.protocol.url +"&SERVICE=WFS&REQUEST=GetFeature&VERSION=1.0.0"; xlink += '&typename='+control.protocol.featurePrefix; xlink += ':'+control.protocol.featureType; xlink += '&SRS='+control.protocol.srsName; xlink += '&FeatureID='+parseMapServerId(select.features[0].fid); url += encodeURIComponent(xlink); url += '&RawDataOutput=Result@mimeType=application/json'; var request = new OpenLayers.Request.XMLHttpRequest(); request.open('GET',url,true); request.onreadystatechange = function() { if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) { var GeoJSON = new OpenLayers.Format.GeoJSON(); var features = GeoJSON.read(request.responseText); hover.removeFeatures(hover.features); hover.addFeatures(features); } } request.send(); }
次に、私たちがちょうど示した異なる処理を呼び出すには、いくつかの特定のボタンをHTMLに追加しなければなりません。<div id="map"></div>の前に次の行を書き込んでマップの上にそれらを追加します。
<div style="float: right;padding-left: 5px;"> <h3>Single geometry processing</h3> <ul> <li> <input type="button" onclick="simpleProcessing(this.value);" value="Buffer" /> <input id="bufferDist" value="1" /> </li> <li> <input type="button" onclick="simpleProcessing(this.value);" value="ConvexHull" /> </li> <li> <input type="button" onclick="simpleProcessing(this.value);" value="Boundary" /> </li> <li> <input type="button" onclick="simpleProcessing(this.value);" value="Centroid" /> </li> </ul> </div>
再びHTMLファイルを保存してください。これでボタンの一つをクリックして、ポリゴンを選択し、Buffer、ConvexHull、Boundary あるいは Centroidを起動できます。処理の結果はマップ上にGeoJSONレイヤーとしてオレンジ色で表示されます。
JavaScript から呼び出される複合ジオメトリサービス
同じテクニックを使って、複数のジオメトリ処理のために作られている関数を書き込むことができます。simpleProcessing() 関数のあとに次の行を追加してください。このような関数を作成する方法はセクション5のエクササイズで説明します。
function multiProcessing(aProcess) { if (select.features.length == 0 || hover.features.length == 0) return alert("No feature created!"); var url = '/cgi-bin/zoo_loader.cgi'; var xlink = control.protocol.url +"&SERVICE=WFS&REQUEST=GetFeature&VERSION=1.0.0"; xlink += '&typename='+control.protocol.featurePrefix; xlink += ':'+control.protocol.featureType; xlink += '&SRS='+control.protocol.srsName; xlink += '&FeatureID='+parseMapServerId(select.features[0].fid); var GeoJSON = new OpenLayers.Format.GeoJSON(); try { var params = '<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0/../wpsExecute_request.xsd">'; params += '<ows:Identifier>'+aProcess+'</ows:Identifier>'; params += '<wps:DataInputs>'; params += '<wps:Input>'; params += '<ows:Identifier>InputEntity1</ows:Identifier>'; params += '<wps:Reference xlink:href="'+xlink.replace(/&/gi,'&')+'"/>'; params += '</wps:Input>'; params += '<wps:Input>'; params += '<ows:Identifier>InputEntity2</ows:Identifier>'; params += '<wps:Data>'; params += '<wps:ComplexData mimeType="application/json"> '+GeoJSON.write(hover.features[0].geometry)+' </wps:ComplexData>'; params += '</wps:Data>'; params += '</wps:Input>'; params += '</wps:DataInputs>'; params += '<wps:ResponseForm>'; params += '<wps:RawDataOutput>'; params += '<ows:Identifier>Result</ows:Identifier>'; params += '</wps:RawDataOutput>'; params += '</wps:ResponseForm>'; params += '</wps:Execute>'; } catch(e) { alert(e); return false; } var request = new OpenLayers.Request.XMLHttpRequest(); request.open('POST',url,true); request.setRequestHeader('Content-Type','text/xml'); request.onreadystatechange = function() { if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) { var GeoJSON = new OpenLayers.Format.GeoJSON(); var features = GeoJSON.read(request.responseText); multi.removeFeatures(multi.features); multi.addFeatures(features); } } request.send(params); }
今回は、ZOO Kernelを呼び出すのにGETメソッドではなくXML POSTを使用していることに注意してください。GETメソッドを使用すると、リクエストの長さに基づくHTTP GETメソッド制限のためにエラーが表示されます。ジオメトリを表すJSONストリングの使用すると、リクエストは長くなります。
一度複数のジオメトリ処理を呼び出す関数を得ると、リクエストの呼び出しを消すためにいくつかボタンを追加しなければなりません。これは現在の zoo-ogr.html ファイルに追加するためのHTMLコードです:
<h3>Multiple geometries processing</h3> <ul> <li> <input type="button" onclick="multiProcessing(this.name);" value="Union"/> </li> <li> <input type="button" onclick="multiProcessing(this.name);" value="Difference"/> </li> <li> <input type="button" onclick="multiProcessing(this.value);" value="SymDifference"/> </li> <li> <input type="button" onclick="multiProcessing(this.name);" value="Intersection"/> </li> </ul>
ページをリロードしてください。すると、複数のジオメトリサービスを実行でき、次のスクリーンショットのように赤色で表示された結果を得ることができます:
同じ結果を得るには、Services Providerに何かが足りないように思われます … 複数のジオメトリサービスです! これは次のセクションで行います。
前へ | ワークショップ 目次 | 次へ