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

OpenLayersAPI は、ドキュメントが懇切丁寧とは言えないところは残念ですが、全般的にセンスが良いところがよいところだと思います。

サーバから送られるベクトルデータの形式として、当面 GeoRSS, GeoJSON 及び WKT を考慮していこうと考えています。実際に実働するシステムでこれらを使っていくことで、それぞれの得失が明らかになっていきます*1

*1:逆に言えば、実際に使わない限りは得失は明らかにならないのではないのではないでしょうか。