OpenLayers のベクトル編集機能を試す
OpenLayers のベクトル編集機能を試してみました。
内容
このエントリは、d:id:hfu:20090407 の続きというところもあって、アパッチを使わない流儀でいきます。d:id:hfu:20090407 と違う点は、Rack ではなくてその上に乗っている Sinatra を使うようになったことと、finds.jp さんの基盤地図情報25000 WMSを使うようになったことです。
OpenLayers で基盤地図情報 25000 WMS を表示して、ベクトルレイヤとして適当な GeoRSS レイヤと WKT レイヤをつけた上で、WKT レイヤを編集可能にするサーバプログラムは、次のようになりました。
require 'rubygems' require 'sinatra' get '/' do content_type "text/html" haml <<-EOS !!! XML %html %head %script{:src => 'http://openlayers.org/dev/OpenLayers.js'} %script{:src => 'http://www.google.com/jsapi'} :javascript var map, layer, mf, sf, df; google.load('jquery', '1.3.1'); google.load('jqueryui', '1.5.3'); function init() { // initialize an OpenLayers map map = new OpenLayers.Map('map', { controls: [ new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.LayerSwitcher(), new OpenLayers.Control.Permalink(), new OpenLayers.Control.MousePosition(), new OpenLayers.Control.KeyboardDefaults(), new OpenLayers.Control.Attribution()], maxResolutions: 'auto' }); map.addLayer(new OpenLayers.Layer.WMS('fgd25000', 'http://www.finds.jp/ws/kiban25000gwc.cgi?', {layers: 'kiban25000:AllT', format: 'image/png'})); map.addLayer(new OpenLayers.Layer.WMS('placenames', 'http://www.finds.jp/ws/pnwms.cgi?', {layers: 'PrefName,MncplName,AzaName', format: 'image/png', isBaseLayer: false}, {isBaseLayer: false})); map.setCenter(new OpenLayers.LonLat(135, 35), 14); // add a GeoRSS layer map.addLayer(new OpenLayers.Layer.GeoRSS('georss', '/georss')); // add a WKT layer var wkt_layer = new OpenLayers.Layer.Vector('wkt'); var wkt_parser = new OpenLayers.Format.WKT(); var feature = wkt_parser.read('POINT (135 35)'); wkt_layer.addFeatures(feature); // add an editing toolbar for the WKT layer var et = new OpenLayers.Control.EditingToolbar(wkt_layer); map.addControl(et); // add editing features for the WKT layer, which need to be activated mf = new OpenLayers.Control.ModifyFeature(wkt_layer); sf = new OpenLayers.Control.SelectFeature(wkt_layer); df = new OpenLayers.Control.DragFeature(wkt_layer); map.addControl(mf); map.addControl(sf); map.addControl(df); map.addLayer(wkt_layer); //$('#radios').draggable(); //$('#map').draggable(); //map.addLayer(new OpenLayers.Layer.GeoJSON(...)); } %body{:onload => 'init();'} %div{:id => 'map', :style => 'width: 640px; height: 480px; border: 4px solid #ccc;'} %div{:id => 'radios', :style => 'position: absolute;'} %input{:type => 'radio', :name => 'mode', :value => 'default', :checked => 'checked', :onclick => 'mf.deactivate(); sf.deactivate(); df.deactivate();'} Default %input{:type => 'radio', :name => 'mode', :value => 'mf', :onclick => 'mf.activate(); sf.deactivate(); df.deactivate();'} Modify Feature %input{:type => 'radio', :name => 'mode', :value => 'sf', :onclick => 'mf.deactivate(); sf.activate(); df.deactivate();'} Select Feature %input{:type => 'radio', :name => 'mode', :value => 'df', :onclick => 'mf.deactivate(); sf.deactivate(); df.activate();'} Drag Feature EOS end get '/wkt' do content_type "text/plain" end get '/geojson' do conten_type "text/javascript" end get '/georss' do content_type "application/rss+xml" haml <<-EOS !!!XML %feed{:xmlns => 'http://www.w3.org/2005/Atom', :'xmlns:georss' => 'http://www.georss.org/georss'} %title GeoRSS example %subtitle to investigate to what extent GeoRSS sucks %updated 2009-12-29 %id ab4at3qrfda %entry %title GeoRSS point entry %id age3243 %updated 2009-12-29 %summary ok, that's good. %georss:point 35 135 EOS end
OpenLayers の API は、ドキュメントが懇切丁寧とは言えないところは残念ですが、全般的にセンスが良いところがよいところだと思います。
サーバから送られるベクトルデータの形式として、当面 GeoRSS, GeoJSON 及び WKT を考慮していこうと考えています。実際に実働するシステムでこれらを使っていくことで、それぞれの得失が明らかになっていきます*1。
*1:逆に言えば、実際に使わない限りは得失は明らかにならないのではないのではないでしょうか。