Leafletでの空間データの編集

地図グラフィックWebフレームワークの開発にもかかわらず、ほとんどの場合、ベクター地理データの編集はデスクトップアプリケーションで行われています。 2015年の中庭では、ブラウザーでの編集に移ります。



OpenLayersやLeafletなど、Webマップをレンダリングするためのオープンライブラリがいくつかあります。 ずいぶん前に、私たちの選択はLeafletにかかっており、プロジェクトを実装するときにそれを積極的に使用し続けています。 ジオデータを編集するためにも、それを使用すると同時に、既存の空間データウェアハウスと統合することができます。



後者の目標を達成するために、GISサーバー(geoserver、mapserver)が通常使用されます。GISサーバーは、 標準に従って多数のさまざまなデータ形式を公開できます。 OGC 。 したがって、 WMSプロトコルは、完成したマップの視覚化機能に対応していますが、編集機能を意味するものではありません。そのため、データを変更できるWFSプロトコルを使用するのが妥当です。 WMSへのリクエストは、すでにレンダリングされたタイル(写真)、およびWFS(未加工情報)を返します。これらのタイルの背後にある「ソースコード」です。 Leafletは拡張モジュールをサポートしているため、完成したコンポーネントを検索したり、独自のコンポーネントを作成したりできます。 なぜなら Leaflet用の既製のモジュールを検索しても満足のいく結果が得られなかったため、独自の実装を開始しました。



leaflet.uservoice.comへのリクエストの統計によると、このモジュールが私たちだけでなく興味深いものであることは明らかです。



WFS-Tとその用途を説明することから始めましょう。



OGC Web Feature Service標準では、サーバークエリを使用して空間データをクエリおよび編集(「-T」の場合-トランザクション)することができます。CRUD関数は、GetFeature読み取りと残りのトランザクションクエリに分かれています。



クライアントとサーバーの相互作用には2つの方法を使用できます。1つ目はXMLおよびPOST要求を使用し、2つ目はキー/値のペアおよびGET要求を使用します。



次の形式のGETリクエストを使用してデータを取得できます。

%WFSServerURL%?Service = WFS&version = 1.0.0&request = GetFeature&typeName = osm_perm_region:perm_water_polygon&maxFeatures = 50&outputFormat = application / json、

サービス= WFS サービスの種類、常に同じ
バージョン= 1.0.0 WFS標準のバージョン。 現在、3つのバージョンがあります:1.0.0、1.1.0、2.0.0。 バージョン1.1.0を使用します。 2.0.0は、サーバー側のすべてのメーカーによって実装されているわけではありません
リクエスト= GetFeature リクエストタイプ
typeName = osm_perm_region:perm_water_polygon WFSサーバーによって公開されたデータのタイプ
maxFeature = 50 サーバーによって返されるオブジェクトの数
outputFormat = application / json サーバーによって返されるデータの形式。 標準によって規制されているデータ形式は1つだけ-GMLですが、一部の実装ではGML以外を使用できます。たとえば、ジオサーバーはgeoJsonにデータを送信できます


場合によっては、GET要求でキーと値のペアを使用してデータを作成、変更、削除することもできますが、XMLデータで%WFSServerURL%のPOST要求を実行すると、より多くのオプションが提供されます。

オブジェクトの変更の例:



作成
<wfs:Transaction service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd http://www.openplans.org/topp http://localhost:8080/geoserver/wfs/DescribeFeatureType?typename=topp:tasmania_roads"> <wfs:Insert> <topp:tasmania_roads> <topp:the_geom> <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> <gml:lineStringMember> <gml:LineString> <gml:coordinates decimal="." cs="," ts=" "> 494475.71056415,5433016.8189323 494982.70115662,5435041.95096618 </gml:coordinates> </gml:LineString> </gml:lineStringMember> </gml:MultiLineString> </topp:the_geom> <topp:TYPE>alley</topp:TYPE> </topp:tasmania_roads> </wfs:Insert> </wfs:Transaction>
      
      







更新する
 <wfs:Transaction service="WFS" version="1.0.0" xmlns:topp="http://www.openplans.org/topp" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"> <wfs:Update typeName="topp:tasmania_roads"> <wfs:Property> <wfs:Name>the_geom</wfs:Name> <wfs:Value> <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> <gml:lineStringMember> <gml:LineString> <gml:coordinates>500000,5450000,0 540000,5450000,0</gml:coordinates> </gml:LineString> </gml:lineStringMember> </gml:MultiLineString> </wfs:Value> </wfs:Property> <ogc:Filter> <ogc:FeatureId fid="tasmania_roads.1"/> </ogc:Filter> </wfs:Update> </wfs:Transaction>
      
      







削除する
 <wfs:Transaction service="WFS" version="1.0.0" xmlns:cdf="http://www.opengis.net/cite/data" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp"> <wfs:Delete typeName="topp:tasmania_roads"> <ogc:Filter> <ogc:PropertyIsEqualTo> <ogc:PropertyName>topp:TYPE</ogc:PropertyName> <ogc:Literal>alley</ogc:Literal> </ogc:PropertyIsEqualTo> </ogc:Filter> </wfs:Delete> </wfs:Transaction>
      
      







GMLは、空間データの記述に使用されます。 この形式では、デフォルトで、サーバーはデータを送信し(outputFormatフラグが設定されていない場合)、データが変更されたときにリクエストのみを受信します。 たとえば、GMLのポイント[0、0]は次のように表すことができます。



 <gml:Point srsName="http://www.opengis.net/def/crs/EPSG/0/4326"> <gml:pos srsDimension="2">0.0 0.0</gml:pos> </gml:Point>
      
      





フィルタは、データの削除と変更のリクエストを制限するために使用されます-これは、OGC標準のもう1つです。 最初は十分です-GmlObjectId、オブジェクトの更新と削除に使用されます。 将来的には、他のフィルターが必要になります。



ID = 1の例:



 <ogc:Filter> <ogc:GmlFeatureId gml:id=1/> </ogc:Filter>
      
      





リーフレットプラグインの作成



前述のように、Leafletには適切に設計されたモジュール式インフラストラクチャがあるため、これらのモジュールを作成できる必要があります。 プラグインの作成の概要、Leaflet WebサイトおよびILayerの実装例にあります 。 Habrに関する記事もいくつかあります。



独自のレイヤーを作成する必要があります。このレイヤーを読み込むと、サービスからデータを受信して​​描画します。 WFSを読み取るために、いくつかのプラグインが見つかりました。それらはすべてL.GeoJSONレイヤーから継承され、目的の形式ですぐにデータを読み取りました。 ただし、この標準では、サーバー側のメーカーがgeoJsonでデータを提供することを義務付けていません(この可能性はgeoserver'aでのみ見ました)。GML形式は必須です。 OpenLayersで読み取りが行われる方法を確認した後、そこからアイデアを取りました。読み取りに別のクラスを使用し、目的の形式を理解する方法を知っています。 L.GeoJSONと同様に、L.FeatureGroupから実装を継承しました。 GMLとGeoJSONを読み取る2つの形式が実装されました



データ検索



AJAXリクエストによって実行され、処理のために読み取りクラスに渡されます。ここでは、geoJson変換をマーカー\ポリゴン\ポリラインに渡し、リーフレット自体の腸に入れます。



 var layers = []; var geoJson = JSON.parse(response.rawData); for (var i = 0; i < geoJson.features.length; i++) { var layer = L.GeoJSON.geometryToLayer(geoJson.features[i], options.pointToLayer || null, options.coordsToLatLng, null); layer.feature = geoJson.features[i]; layers.push(layer); } return layers;
      
      





またはparsim GML-出力で同じマーカー\ポリゴン\ポリライン:



 var layers = []; var xmlDoc = L.XmlUtil.parseXml(rawData); var featureCollection = xmlDoc.documentElement; var featureMemberNodes = featureCollection.getElementsByTagNameNS(L.XmlUtil.namespaces.gml, 'featureMember'); for (var i = 0; i < featureMemberNodes.length; i++) { var feature = featureMemberNodes[i].firstChild; layers.push(this.processFeature(feature)); } var featureMembersNode = featureCollection.getElementsByTagNameNS(L.XmlUtil.namespaces.gml, 'featureMembers'); if (featureMembersNode.length > 0) { var features = featureMembersNode[0].childNodes; for (var j = 0; j < features.length; j++) { var node = features[j]; if (node.nodeType === document.ELEMENT_NODE) { layers.push(this.processFeature(node)); } } } return layers;
      
      





オブジェクトの編集



Leafletオブジェクト(leaflet.draw、Leaflet.Editable)を視覚的に編集するためのプラグインと対話して、行われた変更を記憶する関数が作成されます。 編集が完了したら、save()メソッドを呼び出して、変更のGML記述を作成する必要があります-「wfs:Transaction」要素、および変更されたオブジェクトごとに、対応するアクション(アクション):wfs:Insert、wfs:Update、wfs:Deleteその後、AJAXリクエストが実行されます。



Leaflet.Editableプラグインのイベントをサブスクライブする例:



 map.on('editable:created', function (e) { wfst.addLayer(e.layer); }); map.on('editable:editing', function (e) { wfst.editLayer(e.layer); }); map.on('editable:delete', function (e) { wfst.removeLayer(e.layer); });
      
      





各リーフレットプリミティブ(マーカー、ポリライン、ポリゴンなど)について、GMLジオメトリの説明に変換する関数が記述されています。たとえば、マーカーの場合は次のようになります。



 L.Marker.include({ toGml: function (crs) { var node = L.XmlUtil.createElementNS('gml:Point', {srsName: crs.code}); node.appendChild(L.GMLUtil.posNode(L.Util.project(crs, this.getLatLng()))); return node; } });
      
      





使用例



読み取り専用



 var map = L.map('map').setView([0, 0], 2); var boundaries = new L.WFS({ url: 'http://demo.opengeo.org/geoserver/ows', typeNS: 'topp', typeName: 'tasmania_state_boundaries', crs: L.CRS.EPSG4326, style: { color: 'blue', weight: 2 } }).addTo(map) .on('load', function () { map.fitBounds(boundaries); })
      
      





参照



編集中



 var wfst = new L.WFS.Transaction({ url: 'http://myserver/geoserver/ows', typeNS: 'myns', typeName: 'POIPOINT', style: { color: 'blue', weight: 2 } }).addTo(map).once('load', function () { map.fitBounds(wfst); wfst.enableEdit(); }); map.on('editable:created', function (e) { wfst.addLayer(e.layer); }); map.on('editable:editing', function (e) { wfst.editLayer(e.layer); }); L.easyButton('fa-save', function () { wfst.save(); }, 'Save changes');
      
      





参照



プラグイン開発計画



-Leaflet 0.8への移行(マルチクラスの内部が変更され、ポリゴンを含むポリラインにリングが追加されました)。

-WFSの異なるバージョンを使用する機能。

-OGC Filter Encoding標準の他のアイテムのサポート。



ソースと開発



このプロジェクトはGitHubにあります 。 自動化には、Gruntが使用されます。 テストには、多数のカルマ+モカ+チャイ+シノンが使用されます。 参加をご希望の方-ようこそ。



参照資料



  1. OGC規格: WMSWFSGMLフィルターエンコーディング
  2. ロシア語のいくつかの標準の説明-live.osgeo.org
  3. leaflet.wfs-tは見つかったリーフレットのwfstプラグインであり、マイナスは放棄され、アルファ版、連結、マーカーとポリゴンのみ、geojsonのみのクエリアセンブリ(xml)です。
  4. geoserver.orgは、WFSTをサポートするオープンGISサーバーの1つであり、デモデータが公開されています。



All Articles