2014年2月20日木曜日

36 - GeoEXT を使用した WFS-T 12 - 選択したレイヤの編集 3

36-12-3 選択したレイヤのフィーチャと属性の編集
選択したレイヤのフィーチャの作成(draw)と編集(modify, delete)と、属性の編集ができるようにします。
3.2. Editing Features and Their Attributes(http://workshops.boundlessgeo.com/geoext/wfs/editing.html)の「Bonus Task」を参考に、一部を修正します。

---
function reconfigure(store, url) {
 var fields = [], columns = [], geometryName, geometryType;
 // regular expression to detect the geometry column
 var geomRegex = /gml:(Multi)?(Point|Line|Polygon|Surface|Geometry).*/;
 // mapping of xml schema data types to Ext JS data types
 var types = {
  "xsd:int": "int",
  "xsd:short": "int",
  "xsd:long": "int",
  "xsd:string": "string",
  "xsd:dateTime": "string",
  "xsd:double": "float",
  "xsd:decimal": "float",
  "Line": "Path",
  "Surface": "Polygon"
 };
 store.each(function(rec) {
  var type = rec.get("type");
  var name = rec.get("name");
  var match = geomRegex.exec(type);
  if (match) {
   // we found the geometry column
   geometryName = name;
   // Geometry type for the sketch handler:
   // match[2] is "Point", "Line", "Polygon", "Surface" or "Geometry"
   geometryType = types[match[2]] || match[2]; // 追加
  } else {
   // we have an attribute column
   fields.push({
    name: name,
    type: types[type]
   });
   columns.push({
    xtype: types[type] == "string" ?
     "gridcolumn" :
     "numbercolumn",
      dataIndex: name,
      header: name,
// ここから追加
      // textfield editor for strings, numberfield for others
      editor: {
       xtype: types[type] == "string" ?
        "textfield" :
        "numberfield"
      }
// ここまで
     });
    }
   });
   app.featureGrid.reconfigure(new GeoExt.data.FeatureStore({
    autoLoad: true,
    proxy: new GeoExt.data.ProtocolProxy({
     protocol: new OpenLayers.Protocol.WFS({
      url: url,
      version: "1.1.0",
      featureType: rawAttributeData.featureTypes[0].typeName,
      featureNS: rawAttributeData.targetNamespace,
//    srsName: "EPSG:4326",
      srsName: "EPSG:2451",
      geometryName: geometryName,
      maxFeatures: 250
     })
    }),
    fields: fields
   }), new Ext.grid.ColumnModel(columns));
   app.featureGrid.store.bind(vectorLayer);
   app.featureGrid.getSelectionModel().bind(vectorLayer);
// ここから追加
   // Set the correct sketch handler according to the geometryType
   drawControl.handler = new OpenLayers.Handler[geometryType](
    drawControl, drawControl.callbacks, drawControl.handlerOptions
   );
// ここまで
  }
  function setLayer(model, node) {
   if(!node || node.layer instanceof OpenLayers.Layer.Vector) {
    return;
   }
   vectorLayer.removeAllFeatures();
   app.featureGrid.reconfigure(
    new Ext.data.Store(),
    new Ext.grid.ColumnModel([])
   );
   var layer = node.layer;
   var url = layer.url.split("?")[0]; // the base url without params
   var schema = new GeoExt.data.AttributeStore({
    url: url,
    // request specific params
    baseParams: {
     "SERVICE": "WFS",
     "REQUEST": "DescribeFeatureType",
     "VERSION": "1.1.0",
     "TYPENAME": layer.params.LAYERS
    },
    autoLoad: true,
    listeners: {
     "load": function(store) {
       app.featureGrid.setTitle(layer.name);
       reconfigure(store, url);
     }
    }
   });
  }
  Ext.onReady(function() {
   app.tree.getSelectionModel().on(
    "selectionchange", setLayer
   );
  });

 </script>
---

参考 HTML ファイル

36 - GeoEXT を使用した WFS-T 12 - 選択したレイヤの編集 2

36-12-2 選択したレイヤの属性の表示
3.1. Creating a Synchronized Grid and Map View of WFS Features(http://workshops.boundlessgeo.com/geoext/wfs/grid.html)の「Bonus Task」をコピーして貼り付け、一部を修正します。

---
// ここから追加
 var rawAttributeData;
 var read = OpenLayers.Format.WFSDescribeFeatureType.prototype.read;
 OpenLayers.Format.WFSDescribeFeatureType.prototype.read = function() {
  rawAttributeData = read.apply(this, arguments);
  return rawAttributeData;
 };
 function reconfigure(store, url) {
  var fields = [], columns = [], geometryName, geometryType;
  // regular expression to detect the geometry column
  var geomRegex = /gml:(Multi)?(Point|Line|Polygon|Surface|Geometry).*/;
  var types = {
   // mapping of xml schema data types to Ext JS data types
   "xsd:int": "int",
   "xsd:short": "int",
   "xsd:long": "int",
   "xsd:string": "string",
   "xsd:dateTime": "string",
   "xsd:double": "float",
   "xsd:decimal": "float",
   // mapping of geometry types
   "Line": "Path",
   "Surface": "Polygon"
  };
  store.each(function(rec) {
   var type = rec.get("type");
   var name = rec.get("name");
   var match = geomRegex.exec(type);
   if (match) {
    // we found the geometry column
    geometryName = name;
   } else {
    // we have an attribute column
    fields.push({
     name: name,
     type: types[type]
    });
    columns.push({
     xtype: types[type] == "string" ?
      "gridcolumn" :
      "numbercolumn",
     dataIndex: name,
     header: name
    });
   }
  });
  app.featureGrid.reconfigure(new GeoExt.data.FeatureStore({
   autoLoad: true,
   proxy: new GeoExt.data.ProtocolProxy({
    protocol: new OpenLayers.Protocol.WFS({
     url: url,
     version: "1.1.0",
     featureType: rawAttributeData.featureTypes[0].typeName,
     featureNS: rawAttributeData.targetNamespace,
//   srsName: "EPSG:4326",
     srsName: "EPSG:2451",
     geometryName: geometryName,
     maxFeatures: 250
    })
   }),
   fields: fields
  }), new Ext.grid.ColumnModel(columns));
  app.featureGrid.store.bind(vectorLayer);
  app.featureGrid.getSelectionModel().bind(vectorLayer);
 }
function setLayer(model, node) {
  if(!node || node.layer instanceof OpenLayers.Layer.Vector) {
   return;
  }
  vectorLayer.removeAllFeatures();
  app.featureGrid.reconfigure(
   new Ext.data.Store(),
   new Ext.grid.ColumnModel([])
  );
  var layer = node.layer;
  var url = layer.url.split("?")[0]; // the base url without params
  var schema = new GeoExt.data.AttributeStore({
   url: url,
   // request specific params
   baseParams: {
    "SERVICE": "WFS",
    "REQUEST": "DescribeFeatureType",
    "VERSION": "1.1.0",
    "TYPENAME": layer.params.LAYERS
   },
   autoLoad: true,
   listeners: {
    "load": function(store) {
     app.featureGrid.setTitle(layer.name);
     reconfigure(store, url);
    }
   }
  });
 }
 Ext.onReady(function() {
  app.tree.getSelectionModel().on(
   "selectionchange", setLayer
  );
 });
// ここまで
</script>
---

レイヤの属性の中で、「name」が表示されません。コード中に使用されている「name」に影響されているのかもしれません。属性の「name」を「term」に変更したら表示されるようになりました。

nippon_bmi=> ALTER TABLE akiruno_polygon RENAME name to term;
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_line RENAME name to term;
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_point RENAME name to term;
ALTER TABLE


GeoServer で akiruno_polygon akiruno_line akiruno_point レイヤの「Feature Type Details」を確認します。表示されないときは「Reload feature type」をクリックします。

36 - GeoEXT を使用した WFS-T 12 - 選択したレイヤの編集 1

36-12-1 akiruno_point と akiruno_line に 属性を追加
Developing OGC Compliant Web Applications with GeoExt の
3.1. Creating a Synchronized Grid and Map View of WFS Features(http://workshops.boundlessgeo.com/geoext/wfs/grid.html)と3.2. Editing Features and Their Attributes(http://workshops.boundlessgeo.com/geoext/wfs/editing.html)の「Bonus Task」を参考に、「Add to Map」で追加したレイヤを tree で選択して編集します。
「ol017-nippon_bmi_akiruno_pgis.html」をコピーして名前を付けて(「ol017bonus-nippon_bmi_akiruno_pgis.html」など)使います。

最初に、akiruno_point と akiruno_line に akiruno_polygon と同じように属性を追加します。

既存の属性
fid
the_geom
追加の属性
id  charactor varying(32)
name  charactor varying(32)
address  charactor varying(32)
createdate  charactor varying(32)
lastupdate  charactor varying(32)
category1  charactor varying(32)
category2  charactor varying(32)
category3  charactor varying(32)

user@debian7-vmw:~$ psql nippon_bmi
psql (9.1.11)
"help" でヘルプを表示します.
nippon_bmi=> ALTER TABLE akiruno_point ADD COLUMN id varchar(32);
---
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_line ADD COLUMN id varchar(32);
---

nippon_bmi=> \d akiruno_point
                                 テーブル "public.akiruno_point"
   カラム   |          型           |                           修飾語                           
------------+-----------------------+-------------------------------------------------------------
 fid        | integer               | not null default nextval('akiruno_point_fid_seq'::regclass)
 the_geom   | geometry              | 
 id         | character varying(32) | 
 name       | character varying(32) | 
 address    | character varying(32) | 
 createdate | character varying(32) | 
 lastupdate | character varying(32) | 
 category1  | character varying(32) | 
 category2  | character varying(32) | 
 category3  | character varying(32) | 

インデックス:
    "akiruno_point_pkey" PRIMARY KEY, btree (fid)
    "spatial_akiruno_point_the_geom" gist (the_geom)
CHECK 制約:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTIPOINT'::text OR the_geom IS NULL)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 2451)

(END):q


nippon_bmi=> \d akiruno_line
                                 テーブル "public.akiruno_line"
   カラム   |          型           |                           修飾語                           
------------+-----------------------+------------------------------------------------------------
 fid        | integer               | not null default nextval('akiruno_line_fid_seq'::regclass)
 the_geom   | geometry              | 
 id         | character varying(32) | 
 name       | character varying(32) | 
 address    | character varying(32) | 
 createdate | character varying(32) | 
 lastupdate | character varying(32) | 
 category1  | character varying(32) | 
 category2  | character varying(32) | 
 category3  | character varying(32) | 

インデックス:
    "akiruno_line_pkey" PRIMARY KEY, btree (fid)
    "spatial_akiruno_line_the_geom" gist (the_geom)
CHECK 制約:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTILINESTRING'::text OR the_geom IS NULL)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 2451)

(END):q


GeoServer で akiruno_point と akiruno_line レイヤの「Feature Type Details」を確認します。表示されないときは「Reload feature type」をクリックします。

仮の属性の値を追加します。

nippon_bmi=> SELECT fid, id, name, createdate, lastupdate, category1, category2, category3 from akiruno_point;
 fid | id | name | createdate | lastupdate | category1 | category2 | category3 
-----+----+------+------------+------------+-----------+-----------+-----------
   2 |    |      |            |            |           |           | 
(1 行)

nippon_bmi=> UPDATE akiruno_point SET id = 'a', name = '点2', address = 'aki', createdate = '2014-2-14', lastupdate = '2014-2-14', category1 = 'c1', category2 = 'c2', category3 = 'c3' where fid = 2;
UPDATE 1
nippon_bmi=> SELECT fid, id, name, address, createdate, lastupdate, category1, category2, category3 from akiruno_line;
 fid | id | name | address | createdate | lastupdate | category1 | category2 | category3 
-----+----+------+---------+------------+------------+-----------+-----------+-----------
   3 |    |      |         |            |            |           |           | 

(1 行)
(stdin):q

nippon_bmi=> UPDATE akiruno_line SET id = 'a', name = '線2', address = 'aki', createdate = '2014-2-14', lastupdate = '2014-2-14', category1 = 'c1', category2 = 'c2', category3 = 'c3' where fid = 3;
UPDATE 1

36 - GeoEXT を使用した WFS-T 11 - 編集したフィーチャの保存

36-11 編集したフィーチャの保存Developing OGC Compliant Web Applications with GeoExt の
3.3. Committing Feature Modifications Over WFS-T(http://workshops.boundlessgeo.com/geoext/wfs/wfst.html)を参考に WFS レイヤの編集したフィーチャを保存します。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。
akiruno_kukaku レイヤでは新規に作成したフィーチャが保存できなかったので、前回使用した akiruno_polygon レイヤに設定しました。

akiruno_polygon レイヤの属性を追加します。
既存の属性
fid
the_geom
追加の属性
id  charactor varying(32)
name  charactor varying(32)
address  charactor varying(32)
createdate  charactor varying(32)
lastupdate  charactor varying(32)
category1  charactor varying(32)
category2  charactor varying(32)
category3  charactor varying(32)

user@debian7-vmw:~$ psql nippon_bmi
psql (9.1.11)
"help" でヘルプを表示します.
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN id varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN name varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN address varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN createdate varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN lastupdate varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN category1 varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN category2 varchar(32);
ALTER TABLE
nippon_bmi=> ALTER TABLE akiruno_polygon ADD COLUMN category3 varchar(32);
ALTER TABLE
nippon_bmi=> \d akiruno_polygon
                                 テーブル "public.akiruno_polygon"
   カラム   |          型           |                            修飾語                             
------------+-----------------------+---------------------------------------------------------------
 fid        | integer               | not null default nextval('akiruno_polygon_fid_seq'::regclass)
 the_geom   | geometry              | 
 id         | character varying(32) | 
 name       | character varying(32) | 
 location   | character varying(32) | 
 createdate | character varying(32) | 
 lastupdate | character varying(32) | 
 category1  | character varying(32) | 
 category2  | character varying(32) | 
 category3  | character varying(32) | 

インデックス:
    "akiruno_polygon_pkey" PRIMARY KEY, btree (fid)
    "spatial_akiruno_polygon_the_geom" gist (the_geom)
CHECK 制約:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 2451)

(stdin):q


GeoServer で akiruno_polygon レイヤの「Feature Type Details」を確認します。表示されないときは「Reload feature type」をクリックします。
(属性の保存ができるように列を操作したので、順序が違います。詳細は後で説明します。)

コードの修正

---
items.push({
 xtype: "editorgrid",
 ref: "featureGrid",
 title: "Feature Table",
 region: "south",
 height: 150,
 sm: new GeoExt.grid.FeatureSelectionModel(),
 store: new GeoExt.data.FeatureStore({
  fields: [
// ここから修正
   {name: "fid", type: "int"},
   {name: "id", type: "string"},
   {name: "name", type: "string"},
   {name: "address", type: "string"},
   {name: "category1", type: "string"},
   {name: "category2", type: "string"},
   {name: "category3", type: "string"},
   {name: "createdate", type: "string"},
   {name: "lastupdate", type: "string"}
// ここまで
  ],
  proxy: new GeoExt.data.ProtocolProxy({
   protocol: new OpenLayers.Protocol.WFS({
    url: "/geoserver/ows",
     version: "1.1.0",
     featureType: "akiruno_polygon",
     featureNS: "http://www.myhome.net/npn",
     srsName: "EPSG:2451",
     geometryName: "the_geom", // 追加
     schema: "http://192.168.1.200/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=npn:akiruno_polygon" // 追加
   })
  }),
  autoLoad: true
 }),
 columns: [
// ここから修正
  {header: "fid", dataIndex: "fid"},
  {header: "id", dataIndex: "id", sortable : true, editor: {xtype: "textfield"}}, // editor: {xtype: "textfield"} 追加
  {header: "name", dataIndex: "name", sortable : true, editor: {xtype: "textfield"}},
  {header: "address", dataIndex: "address", sortable : true, editor: {xtype: "textfield"}},
  {header: "category1", dataIndex: "category1", sortable : true, editor: {xtype: "textfield"}},
  {header: "category2", dataIndex: "category2", sortable : true, editor: {xtype: "textfield"}},
  {header: "category3", dataIndex: "category3", sortable : true, editor: {xtype: "textfield"}},
  {header: "createdate", dataIndex: "createdate", sortable : true, editor: {xtype: "textfield"}},
  {header: "lastupdate", dataIndex: "lastupdate", sortable : true, editor: {xtype: "textfield"}}
// ここまで
 ],
bbar: []
});
---
Ext.onReady(function() {
 var bbar = app.featureGrid.getBottomToolbar();
 bbar.add([{
  text: "Delete",
  handler: function() {
// ここから追加
   app.featureGrid.store.featureFilter = new OpenLayers.Filter({
    evaluate: function(feature) {
     return feature.state != OpenLayers.State.DELETE;
    }
   });
// ここまで
   app.featureGrid.getSelectionModel().each(function(rec) {
    var feature = rec.getFeature();
    modifyControl.unselectFeature(feature);
    vectorLayer.removeFeatures([feature]);
// ここから追加
    if (feature.state != OpenLayers.State.INSERT) {
     feature.state = OpenLayers.State.DELETE;
     vectorLayer.addFeatures([feature]);
    }
// ここまで
   });
  }
 }, new GeoExt.Action({
    control: drawControl,
    text: "Create",
    enableToggle: true
 })
// ここから追加
  , {
  text: "Save",
  handler: function() {
   app.featureGrid.store.proxy.protocol.commit(
    vectorLayer.features, {
     callback: function() {
     var layers = app.mapPanel.map.layers;
     for (var i=layers.length-1; i>=0; --i) {
      layers[i].redraw(true);
     }
      app.featureGrid.store.reload();
     }
    });
  }
// ここまで
 }]);
 bbar.doLayout();
});
---

1)属性(attribution)を追加した後、WFS フィーチャが表示できなくなりました。
Firebug の「ネット」タブの「POST」に「Failed to get property: gid」が表示されていました。
「Geographic Information Systems Stack Exchange」の「“Failed to get property: gid” error in geoserver sql view」(http://gis.stackexchange.com/questions/83791/failed-to-get-property-gid-error-in-geoserver-sql-view)を参考に、原因を探しました。
結局、GeoServer のログに 「"aki" はジオメトリではない」という意味の記述がありました。
"aki" は、追加した属性の「location」の値です。カラム名が「location」の値は、ジオメトリと判断されてしまうようです。
それで、カラム名の「location」を「address」に変更したら、WFS フィーチャが表示されるようになりました。
このサイトのコードの「new OpenLayers.Protocol.WFS」には、「geometryName」がありませんでしたが、「schema」と共に、追加しました。

---
  proxy: new GeoExt.data.ProtocolProxy({
   protocol: new OpenLayers.Protocol.WFS({
    url: "/geoserver/ows",
     version: "1.1.0",
     featureType: "akiruno_polygon",
     featureNS: "http://www.myhome.net/npn",
     srsName: "EPSG:2451",
     geometryName: "the_geom", // 追加
     schema: "http://192.168.1.200/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=npn:akiruno_polygon" // 追加
   })
  }),
---

2)属性の「createdate」と「lastupdate」は日付ですが、EXTJS の「editor: {xtype: "datefield"}」を使用すると追加できない(PostgresQL の型との関係だと思われます)ので、"textfield" にしました。

参考 HTML ファイル
ol017-nippon_bmi_akiruno_pgis.html

36 - GeoEXT を使用した WFS-T 10 - フィーチャとその属性の編集

36-10 フィーチャとその属性の編集
Developing OGC Compliant Web Applications with GeoExt の
3.2. Editing Features and Their Attributes(http://workshops.boundlessgeo.com/geoext/wfs/editing.html)を参考に WFS レイヤのフィーチャと属性を編集できるようにします。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。

---
items.push({
 xtype: "editorgrid", // 修正
 ref: "featureGrid",
 title: "Feature Table",
 region: "south",
 height: 150,
 sm: new GeoExt.grid.FeatureSelectionModel(),
 store: new GeoExt.data.FeatureStore({
  fields: [
   {name: "gid", type: "int"},
   {name: "id", type: "string"},
   {name: "orggilvl", type: "string"},
   {name: "orgmdid", type: "string"}, 
   {name: "category", type: "string"},
   {name: "flag", type: "string"},
   {name: "type", type: "string"},
   {name: "name", type: "string"},
   {name: "code", type: "string"}
  ],
  proxy: new GeoExt.data.ProtocolProxy({
   protocol: new OpenLayers.Protocol.WFS({
    url: "/geoserver/ows",
    version: "1.1.0",
    featureType: "akiruno_kukaku",
    featureNS: "http://www.myhome.net/npn",
    srsName: "EPSG:2451"
   }),
  })
  autoLoad: true
 }),
 columns: [
  {header: "gid", dataIndex: "gid"},
  {header: "id", dataIndex: "id", editor: {xtype: "textfield"}}, // editor: {xtype: "textfield"} 追加
  {header: "orggilvl", dataIndex: "orggilvl", editor: {xtype: "textfield"}},
  {header: "orgmdid", dataIndex: "orgmdid", editor: {xtype: "textfield"}},
  {header: "category", dataIndex: "category", editor: {xtype: "textfield"}},
  {header: "flag", dataIndex: "flag", editor: {xtype: "textfield"}},
  {header: "type", dataIndex: "type", editor: {xtype: "textfield"}},
  {header: "name", dataIndex: "name", editor: {xtype: "textfield"}},
  {header: "code", dataIndex: "code", editor: {xtype: "textfield"}}
 ],
 bbar: []
});
var vectorLayer = new OpenLayers.Layer.Vector("Editable features");
Ext.onReady(function() {
 app.mapPanel.map.addLayer(vectorLayer);
 app.featureGrid.store.bind(vectorLayer);
 app.featureGrid.getSelectionModel().bind(vectorLayer);
});
// コントロールの追加
var modifyControl = new OpenLayers.Control.ModifyFeature(
 vectorLayer, {autoActivate: true}
);
var drawControl = new OpenLayers.Control.DrawFeature(
 vectorLayer,
 OpenLayers.Handler.Polygon,
 {handlerOptions: {multi: true}}
);
controls.push(modifyControl, drawControl);
// グリッドが1行だけ選択されていることを確認
Ext.onReady(function() {
 var sm = app.featureGrid.getSelectionModel();
 sm.unbind();
 sm.bind(modifyControl.selectControl);
 sm.on("beforerowselect", function() { sm.clearSelections(); });
});
// "Delete" と "Create" ボタン追加
Ext.onReady(function() {
 var bbar = app.featureGrid.getBottomToolbar();
 bbar.add([{
  text: "Delete",
  handler: function() {
   app.featureGrid.getSelectionModel().each(function(rec) {
    var feature = rec.getFeature();
    modifyControl.unselectFeature(feature);
    vectorLayer.removeFeatures([feature]);
   });
  }
 }, new GeoExt.Action({
  control: drawControl,
  text: "Create",
  enableToggle: true
 })]);
 bbar.doLayout();
});

</script>
---

36 - GeoEXT を使用した WFS-T 9 - WFS レイヤの表示

36-9 WFS レイヤの表示
Developing OGC Compliant Web Applications with GeoExt の
3.1. Creating a Synchronized Grid and Map View of WFS Features(http://workshops.boundlessgeo.com/geoext/wfs/grid.html)を参考に WFS レイヤを表示します。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。

属性の一部を表示するようにしました。

user@debian7-vmw:~$ psql nippon_bmi
psql (9.1.11)
"help" でヘルプを表示します.
                                 テーブル "public.akiruno_kukaku"
  カラム   |          型           |                            修飾語                            
-----------+-----------------------+--------------------------------------------------------------
 gid       | integer               | not null default nextval('akiruno_kukaku_gid_seq'::regclass)
 id        | character varying(6)  | 
 uuid      | character varying(28) | 
 presences | double precision      | 
 presencef | double precision      | 
 finished  | double precision      | 
 orggilvl  | character varying(4)  | 
 orgmdid   | character varying(7)  | 
 category  | character varying(4)  | 
 flag      | character varying(4)  | 
 type      | character varying(16) | 
 name      | character varying(12) | 
 code      | character varying(5)  | 
 the_geom  | geometry              | 
インデックス:
    "akiruno_kukaku_pkey" PRIMARY KEY, btree (gid)
CHECK 制約:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = (-1))

nippon_bmi=> SELECT gid, id, uuid, orggilvl, orgmdid, category, flag, type, name, code from akiruno_kukaku where gid = '1';
 gid |  id  |             uuid             | orggilvl | orgmdid | category | flag |       type       |    name    | code  
-----+------+------------------------------+----------+---------+----------+------+------------------+------------+-------
   1 | K4_1 | fgoid:10-00200-11-6572-94188 | 2500     |         | 表示     | 既存 | 郡市・東京都の区 | あきる野市 | 13228
(1 行)
---
// ここから追加
items.push({
 xtype: "grid",
 ref: "featureGrid",
 title: "Feature Table",
 region: "south",
 height: 150,
 sm: new GeoExt.grid.FeatureSelectionModel(),
 store: new GeoExt.data.FeatureStore({
  fields: [
   {name: "gid", type: "int"},
   {name: "id", type: "string"},
   {name: "orggilvl", type: "string"},
   {name: "orgmdid", type: "string"}, 
   {name: "category", type: "string"},
   {name: "flag", type: "string"},
   {name: "type", type: "string"},
   {name: "name", type: "string"},
   {name: "code", type: "string"}
  ],
  proxy: new GeoExt.data.ProtocolProxy({
   protocol: new OpenLayers.Protocol.WFS({
    url: "/geoserver/ows",
    version: "1.1.0",
    featureType: "akiruno_kukaku",
    featureNS: "http://www.myhome.net/npn",
    srsName: "EPSG:2451"
   }),
  })
  autoLoad: true
 }),
 columns: [
  {header: "gid", dataIndex: "gid"},
  {header: "id", dataIndex: "id"},
  {header: "orggilvl", dataIndex: "orggilvl"},
  {header: "orgmdid", dataIndex: "orgmdid"},
  {header: "category", dataIndex: "category"},
  {header: "flag", dataIndex: "flag"},
  {header: "type", dataIndex: "type"},
  {header: "name", dataIndex: "name"},
  {header: "code", dataIndex: "code"}
 ],
 bbar: []
});
var vectorLayer = new OpenLayers.Layer.Vector("Editable features");
Ext.onReady(function() {
 app.mapPanel.map.addLayer(vectorLayer);
 app.featureGrid.store.bind(vectorLayer);
 app.featureGrid.getSelectionModel().bind(vectorLayer);
});
// ここまで
</script>
---

36 - GeoEXT を使用した WFS-T 8 - GeoServer ドメイン表示の変更

36-8 GeoServer ドメイン表示の変更
「36-4 Grid の表示」でも「GeoExt.data.WMSCapabilitiesStore」の url の設定が出来ませんでした。ここでも同じ設定をするので、GISTutor の Configuring GeoServer Proxy for Public and Remote Data Access(http://www.gistutor.com/geoserver/21-intermediate-geoserver-tutorials/38-configuring-geoserver-proxy-for-public-and-remote-data-access.html)を参考に、 Apache の設定を修正してみます。

proxy モジュールを有効にします。
確認するには mod-enabled を見てみます。

root@debian7-vmw:~# ls /etc/apache2/mods-enabled/
alias.conf            authz_user.load  dir.load          php5.load
alias.load            autoindex.conf   env.load          reqtimeout.conf
auth_basic.load       autoindex.load   mime.conf         reqtimeout.load
authn_file.load       cgi.load         mime.load         setenvif.conf
authz_default.load    deflate.conf     negotiation.conf  setenvif.load
authz_groupfile.load  deflate.load     negotiation.load  status.conf
authz_host.load       dir.conf         php5.conf         status.load


proxy と proxy_http モジュールを有効にします。

root@debian7-vmw:~# a2enmod proxy
Enabling module proxy.
To activate the new configuration, you need to run:
  service apache2 restart
root@debian7-vmw:~# a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Enabling module proxy_http.
To activate the new configuration, you need to run:
  service apache2 restart


proxy.conf を修正します。

root@debian7-vmw:~# vim /etc/apache2/mods-available/proxy.conf

---
ProxyRequests Off
# Remember to turn the next line off if you are proxying to a NameVirtualHost
ProxyPreserveHost On
<Proxy *>
        Order deny,allow
        #Deny from all
        Allow from all
</Proxy>
# ProxyPass for Geoserver
ProxyPass /geoserver http://localhost:8080/geoserver
ProxyPassReverse /geoserver http://localhost:8080/geoserver

</IfModule>


Apache を再起動します。

root@debian7-vmw:~# /etc/init.d/apache2 restart
[ ok ] Restarting web server: apache2 ... waiting ...

36 - GeoEXT を使用した WFS-T 7 - WMS GetFeatureInfo Popup

36-7 WMS GetFeatureInfo Popup
Developing OGC Compliant Web Applications with GeoExt の
2.4. Explore Map Features with a WMS GetFeatureInfo Popup(http://workshops.boundlessgeo.com/geoext/stores/getfeatureinfo.html)を参考に WMS レイヤの属性をポップアップ表示します。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。

---
<link rel="stylesheet" type="text/css" href="GeoExt/resources/css/geoext-all-debug.css" />
<link rel="stylesheet" type="text/css" href="GeoExt/resources/css/popup.css"><!-- 追加 -->
<script type="text/javascript" src="GeoExt/lib/GeoExt.js"></script>
<script type="text/javascript">
 OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url="; // 追加
---
// ここから追加
 items.push({
  xtype: "gx_legendpanel",
  region: "east",
  width: 200,
  autoScroll: true,
  padding: 5
 });
  controls.push(new OpenLayers.Control.WMSGetFeatureInfo({
  autoActivate: true,
  infoFormat: "application/vnd.ogc.gml",
  maxFeatures: 3,
  eventListeners: {
   "getfeatureinfo": function(e) {
    var items = [];
    Ext.each(e.features, function(feature) {
     items.push({
      xtype: "propertygrid",
      title: feature.fid,
      source: feature.attributes
     });
    });
    new GeoExt.Popup({
     title: "Feature Info",
     width: 200,
     height: 200,
     layout: "accordion",
     map: app.mapPanel,
     location: e.xy,
     items: items
    }).show();
   }
  }
 }));

// ここまで
</script>
---

36 - GeoEXT を使用した WFS-T 6 - 凡例の表示

36-6 凡例の表示
Developing OGC Compliant Web Applications with GeoExt の
2.3. Adding a Legend Using WMS GetLegendGraphic(http://workshops.boundlessgeo.com/geoext/stores/legend.html)を参考に WMS レイヤの凡例を表示します。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。

---
// ここから追加
 items.push({
  xtype: "gx_legendpanel",
  region: "east",
  width: 200,
  autoScroll: true,
  padding: 5
 });
// ここまで
</script>
---

36 - GeoEXT を使用した WFS-T 5 - Tree の表示

36-5 Tree の表示
Developing OGC Compliant Web Applications with GeoExt の
2.2. Adding a Tree View to Manage the Map Panel’s Layers(http://workshops.boundlessgeo.com/geoext/stores/tree.html)を参考に WMS レイヤ表示操作を Tree でします。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。

---
// ここから追加
 items.push({
  xtype: "treepanel",
  ref: "tree",
  region: "west",
  width: 200,
  autoScroll: true,
  enableDD: true,
  root: new GeoExt.tree.LayerContainer({
   expanded: true
  }),
  bbar: [{
   text: "Remove from Map",
   handler: function() {
    var node = app.tree.getSelectionModel().getSelectedNode();
    if (node && node.layer instanceof OpenLayers.Layer.WMS) {
     app.mapPanel.map.removeLayer(node.layer);
    }
   }
  }]
 });

// ここまで
</script>
---

36 - GeoEXT を使用した WFS-T 4 - Grid の表示

36-4 Grid の表示
Developing OGC Compliant Web Applications with GeoExt の
2.1. Creating a Grid View of WMS Capabilities(http://workshops.boundlessgeo.com/geoext/stores/capabilities.html)を参考に WMS レイヤ一覧を Grid で表示します。
続けて「ol017-nippon_bmi_akiruno_pgis.html」を使います。

最初、GeServer の WMS レイヤのリストが表示されませんでした。

store: new GeoExt.data.WMSCapabilitiesStore({

の url に

"http://192.168.1.200:8080/geoserver/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1&TILED=true"

など、試しましたが表示されなかったので、Web ブラウザのアドレスバーに上記アドレスを入力して、ダウンロードしたファイルを読み込みました。

---
// ここから追加
 items.push({
  xtype: "grid",
  ref: "capsGrid", // makes the grid available as app.capsGrid
  title: "Available Layers",
  region: "north",
  height: 150,
  viewConfig: {forceFit: true},
  store: new GeoExt.data.WMSCapabilitiesStore({
   url: "getcapabilities_1.1.1.xml", 下記の url では表示できませんでした
//     url: "/geoserver/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1&TILED=true",
//     url: "http://192.168.1.200:8080/geoserver/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1&TILED=true",
   autoLoad: true
  }),
  columns: [
   {header: "Name", dataIndex: "name", sortable: true},
   {header: "Title", dataIndex: "title", sortable: true},
   {header: "Abstract", dataIndex: "abstract"}
  ],
  bbar: [{
   text: "Add to Map",
   handler: function() {
    app.capsGrid.getSelectionModel().each(function(record) {
     var clone = record.clone();
     clone.getLayer().mergeNewParams({
      format: "image/png",
      transparent: true
     });
     app.mapPanel.layers.add(clone);
     app.mapPanel.map.zoomToExtent(
      OpenLayers.Bounds.fromArray(clone.get("llbbox"))
      );
    });
   }
  }]
 });
// ここまで
</script>
---


レイヤを追加すると倍率が変わってしまいました。
(元の倍率に戻すボタン{地球儀?}をクリックします。)

akiruno_kidou レイヤを追加

36 - GeoEXT を使用した WFS-T 3 - HTML ファイルの作成

36-3 HTML ファイルの作成
Developing OGC Compliant Web Applications with GeoExt の 1.1. Creating a Map Window ページ(http://workshops.boundlessgeo.com/geoext/basics/map.html)を参考に HTML ファイルを準備します。
1. GeoExt Basics(http://workshops.boundlessgeo.com/geoext/basics/index.html#geoext-basics)を参考に GeoEXT で地図を表示します。

a 「App Exploler」ペインの「ol009-nippon_bmi_akiruno_pgis.html」を右クリックし「コピー」をクリックします。








b 「App Exploler」ペイン上で右クリックし「貼り付け」をクリックします。









c 「名前の競合」ウィンドウで「ol017-nippon_bmi_akiruno_pgis.html」と入力し「OK」ボタンをクリックします。



d 「App Exploler」ペインの「ol017-nippon_bmi_akiruno_pgis.html」をダブルクリックして開きます。
e 次のように内容の一部をコピーして「ol017-nippon_bmi_akiruno_pgis.html」に貼り付け、修正します。
(29-2 で追加したところは削除します。)

---
<!-- ここから追加 -->
  <link rel="stylesheet" type="text/css" href="ext-3.4.1/resources/css/ext-all.css" />
  <script type="text/javascript" src="ext-3.4.1/adapter/ext/ext-base.js"></script>
  <script type="text/javascript" src="ext-3.4.1/ext-all.js"></script>
  <link rel="stylesheet" type="text/css" href="GeoExt/resources/css/geoext-all-debug.css" />
  <script type="text/javascript" src="GeoExt/lib/GeoExt.js"></script>
<!-- ここまで -->
  <script type="text/javascript">
//   var map, layer0, layer1, layer2, layer3, layer4; 削除
/*
 ここからコードはほとんど書き換えます。
 Map 表示用のコードを利用して修正します。
*/
   Ext.BLANK_IMAGE_URL = "ext-3.4.1/resources/images/default/s.gif";

   var app, items = [], controls = [];
   Ext.onReady(function() {
    app = new Ext.Viewport({
     layout: "border",
     items: items
    });
   });
   items.push({
    xtype: "gx_mappanel",
    ref: "mapPanel",
    region: "center",
    map: {
//     numZoomLevels: 19,
     controls: controls,
     projection: new OpenLayers.Projection("EPSG:2451"),
     displayProjection: new OpenLayers.Projection("EPSG:4326"),
     maxResolution: 'auto',
     units: 'meters',
     maxExtent: new OpenLayers.Bounds(-63100,-34500,-45400,-24200)
    },
/*
    extent: OpenLayers.Bounds.fromArray([
      -122.911, 42.291,
      -122.787, 42.398
    ]),
*/
/*
    layers: [new OpenLayers.Layer.WMS(
     "Medford",
     "/geoserver/wms",
     {layers: "medford"},
     {isBaseLayer: false}
    )]
*/
// 表示順に並べ換える
    layers: [
     new OpenLayers.Layer.WMS( "Tokyo Height WMS",
      "http://192.168.1.200:8080/geoserver/wms",
     {
      layers: 'npn:tokyo10m-epsg2451'
       },{
       isBaselayer: false
     }),
     new OpenLayers.Layer.WMS( "Tokyo Kuiki WMS",
      "http://192.168.1.200:8080/geoserver/wms",
      {
      layers: 'npn:tokyo_kuiki',
      transparent: true,
      format: 'image/png'
       },{
       isBaselayer: false
     }),
     new OpenLayers.Layer.WMS( "Akiruno Kukaku WMS",
      "http://192.168.1.200:8080/geoserver/wms",
     {
      layers: 'npn:akiruno_kukaku',
      transparent: true,
       format: 'image/png'
       },{
       isBaselayer: false
     }),
     new OpenLayers.Layer.WMS( "Akiruno Kenchiku WMS",
      "http://192.168.1.200:8080/geoserver/wms",
     {
      layers: 'npn:akiruno_kenchiku',
      transparent: true,
      format: 'image/png'
       },{
       isBaselayer: false
     }),
     new OpenLayers.Layer.WMS( "Tokyo Public Facilities WMS",
      "http://192.168.1.200:8080/geoserver/wms",
      {
      layers: 'npn:tokyo_pf',
      transparent: true,
      format: 'image/png'
       },{
       isBaselayer: false
     })
    ]
   });
   controls.push(
    new OpenLayers.Control.Navigation(),
    new OpenLayers.Control.Attribution(),
    new OpenLayers.Control.PanPanel(),
    new OpenLayers.Control.ZoomPanel(),
    new OpenLayers.Control.LayerSwitcher(),
    new OpenLayers.Control.MousePosition(),
    new OpenLayers.Control.ScaleLine()
   );
  </script>
 </head>
 <body>
 </body>
</html>



36 - GeoEXT を使用した WFS-T 2 - レイヤのスタイルの修正

36-2 GeoServer のレイヤの スタイルの修正
GeoServer のレイヤのスタイルを修正して名称などを表示します。

tokyo_kuiki と akiruno_kukaku レイヤのスタイルの SLD(Styled Layer Descriptor)ファイルを作成します。

kuiki.sld
<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
 <NamedLayer>
 <Name>kuiki green</Name>
  <UserStyle>
   <Name>kuiki green</Name>
   <Title>Kuiki green polygon</Title>
   <Abstract>Light green fill with grey outline</Abstract>
   <FeatureTypeStyle>
    <Rule>
     <PolygonSymbolizer>
       <!-- 面の色 -->
      <Fill>
       <CssParameter name="fill">#CCFFCC</CssParameter>
       <CssParameter name="fill-opacity">0.5</CssParameter>
      </Fill>
       <!-- 縁の色 -->
      <Stroke>
       <CssParameter name="strok">#999999</CssParameter>
       <CssParameter name="stroke-width">1</CssParameter>
      </Stroke>
     </PolygonSymbolizer>
     <TextSymbolizer>
    <!-- 名称 -->
      <Label>
       <!-- tokyo_kuiki レイヤの名称の属性 -->
       <ogc:PropertyName>n03_004</ogc:PropertyName>
      </Label>
       <!-- フォント -->
      <Font>
       <CssParameter name="font-size">12</CssParameter>
       <CssParameter name="font-color">#CCCCCC</CssParameter>
      </Font>
     </TextSymbolizer>
    </Rule>
   </FeatureTypeStyle>
  </UserStyle>
 </NamedLayer>
</StyledLayerDescriptor>


kukaku.sld
<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
 <NamedLayer>
 <Name>kukaku yellow</Name>
  <UserStyle>
   <Name>kukaku yellow</Name>
   <Title>Kukaku yellow polygon</Title>
   <Abstract>Light yellow fill with grey outline</Abstract>
   <FeatureTypeStyle>
    <Rule>
     <PolygonSymbolizer>
      <Fill>
       <CssParameter name="fill">#FFFFCC</CssParameter>
       <CssParameter name="fill-opacity">1</CssParameter>
      </Fill>
      <Stroke>
       <CssParameter name="strok">#CCCCCC</CssParameter>
       <CssParameter name="stroke-width">1</CssParameter>
      </Stroke>
     </PolygonSymbolizer>
     <TextSymbolizer>
      <Label>
       <ogc:PropertyName>name</ogc:PropertyName>
      </Label>
      <Font>
       <CssParameter name="font-size">12</CssParameter>
       <CssParameter name="font-color">#CCCCCC</CssParameter>
      </Font>
     </TextSymbolizer>
    </Rule>
   </FeatureTypeStyle>
  </UserStyle>
 </NamedLayer>
</StyledLayerDescriptor>


akiruno_kenchiku レイヤは倍率が高くなったとき表示します。

kenchiku.sld

<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.0.0" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">
 <NamedLayer>
 <Name>kenchiku green</Name>
  <UserStyle>
   <Name>kenchiku green</Name>
   <Title>Kenchiku green polygon</Title>
   <Abstract>Green fill</Abstract>
   <FeatureTypeStyle>
    <Rule>
      <!-- 表示倍率 -->
     <MinScaleDenominator>500</MinScaleDenominator>
     <MaxScaleDenominator>10000</MaxScaleDenominator>
     <PolygonSymbolizer>
      <Fill>
       <CssParameter name="fill">#99CC99</CssParameter>
       <CssParameter name="fill-opacity">1</CssParameter>
      </Fill>
      <Stroke>
       <CssParameter name="stroke">#336633</CssParameter>
       <CssParameter name="stroke-width">1</CssParameter>
      </Stroke>
     </PolygonSymbolizer>
    </Rule>
   </FeatureTypeStyle>
  </UserStyle>
 </NamedLayer>
</StyledLayerDescriptor>


tokyo_pf レイヤは以前、作成した SLD ファイルを修正します。
倍率が高くなったとき表示して、名称を表示します。

tokyo_pf.sld
---
 <NamedLayer>
  <Name>Simple point</Name>
  <UserStyle>
   <Title>Tokyo Public Facility tokyo_pf: Simple point</Title>

   <FeatureTypeStyle>
    <Rule>
     <Name>Building: lightgreen</Name>
     <ogc:Filter>
      <ogc:PropertyIsEqualTo>
       <ogc:PropertyName>p02_002</ogc:PropertyName>
       <ogc:Literal>3</ogc:Literal>
      </ogc:PropertyIsEqualTo>
     </ogc:Filter>
      <!-- 表示倍率 追加 -->
     <MinScaleDenominator>500</MinScaleDenominator>
     <MaxScaleDenominator>10000</MaxScaleDenominator>
     <PointSymbolizer>
      <Graphic>
       <Mark>
        <WellKnownName>circle</WellKnownName>
        <Fill>
         <CssParameter name="fill">#99ff99</CssParameter>
        </Fill>
        <Stroke>
         <CssParameter name="stroke">#33ff33</CssParameter>
         <CssParameter name="stroke-width">2</CssParameter>
        </Stroke>
       </Mark>
       <Size>10</Size>
      </Graphic>
     </PointSymbolizer>
      <!-- 名称(ラベル) 追加 -->
     <TextSymbolizer>
      <Label>
       <ogc:PropertyName>p02_004</ogc:PropertyName>
      </Label>
      <Font>
       <CssParameter name="font-size">12</CssParameter>
       <CssParameter name="font-color">#CCCCCC</CssParameter>
      </Font>
       <!-- ポイントに対するラベルの位置 -->
      <LabelPlacement>
       <PointPlacement>
         <!-- ポイントとラベルの関わり -->
        <AnchorPoint>
          <!-- 水平方向(ラベルの中央) -->
         <AnchorPointX>0.5</AnchorPointX>
          <!-- 垂直方向(ラベルの底辺) -->
         <AnchorPointY>0.0</AnchorPointY>
        </AnchorPoint>
         <!-- ラベルのオフセット -->
        <Displacement>
          <!-- 水平方向 -->
         <DisplacementX>0</DisplacementX>
          <!-- 垂直方向(5ピクセル上) -->
         <DisplacementY>5</DisplacementY>
        </Displacement>
       </PointPlacement>
      </LabelPlacement>
     </TextSymbolizer>
    </Rule>
   </FeatureTypeStyle>
---

各 <FeatureTypeStyle> に同じ設定をします。

36 - GeoEXT を使用した WFS-T 1 - GeoEXT のインストール

36-1 GeoEXT のインストール

Developing OGC Compliant Web Applications with GeoExt
http://workshops.boundlessgeo.com/geoext/index.html

を参考に GeoEXT で WFS-T 機能を使用してみます。

GeoEXT ホームページ
http://geoext.org/

の Tutorial の GeoExt QuickStart ページ
http://geoext.org/tutorials/quickstart.html

の「Getting GeoEXT」の設定方法に従って、GeoEXT と EXTJS を準備します。

a ダウンロード
次のファイルをダウンロードしました。

GeoEXT:
Download GeoExt ページ
http://geoext.org/downloads.html

GeoExt 1.1 Sources + Full Build

EXT JS:
Download Sencha Ext JS
http://www.sencha.com/products/extjs/download/

Ext JS 3.4.1.1 GPLv3(Ext JS 4 ではありません。GeoExt Code Sprint – Spring 2012{http://boundlessgeo.com/2012/01/geoext-code-sprint-spring-2012/}を参照してください。フリーソフトですがライセンスについては確認してください。)

b インストール
ファイルを解凍して Eclipse の Workspace(私は openlayersTokyoproj)に移動します。

user@debian7-vmw:~$ cd ダウンロード
user@debian7-vmw:~/ダウンロード$ ls
---
GeoExt-1.1.zip
---
ext-3.4.1.1-gpl.zip
---
user@debian7-vmw:~/ダウンロード$ unzip GeoExt-1.1.zip
user@debian7-vmw:~/ダウンロード$ unzip ext-3.4.1.1-gpl.zip
(途中 「replace ...」と表示されたので 「A(ll)」と入力しました。)
user@debian7-vmw:~/ダウンロード$ mv GeoExt ../mapsite/openlayersTokyoproj/
user@debian7-vmw:~/ダウンロード$ mv ext-3.4.1 ../mapsite/openlayersTokyoproj/

2014年2月8日土曜日

35 - WFS-T(WFS Transaction) 4 - Point, Line, Polygon レイヤを設定

35-4 Point, Line, Polygon レイヤを設定
point と line、polygon は、別々のレイヤにして保存します。
GeoServer に新しいレイヤを作成します。レイヤは次のようにします。
(akiruno_polygon はすでに設定してあります。)

Layer(Type) Name  Default Style(WMS Setting)  attribute
akiruno_point     point                       Multi point
akiruno_line      line                        Multi lin
akiruno_polygon   polygon                     Multi polygon

次の設定は各レイヤ共通です。
Workspace  Store  Enabled?  Declare SRS
npn        bmi    cheked    EPSG:2451
Min X:  Min Y:  Max X:  Max Y: 
-63100  -34500  -45400  -24200


レイヤが複数になるとコントロール機能(drag や modify など)がうまく機能できませんでした。
drag, modyfy, delete コントロールのボタンを各レイヤ用に設定します。
「ol016-nippon_bmi_akiruno_pgis.html」 ファイルを続けて使います。
OpenLayers の Development Examples の「OpenLayers EditingToolbar Outside Viewport(http://openlayers.org/dev/examples/editingtoolbar-outside.html)」を参考にします。

akiruno_line と akiruno_poygon のレイヤを設定します。

---
var map, layer0, layer1, layer2, layer3, layer4, akirunoPoint, akirunoLine, akirunoPolygon, vectors;
// akirunoPoint, akirunoLine, akirunoPolygon 追加
var j, saveStrategy =[]; // 追加
---
// var saveStrategy = new OpenLayers.Strategy.Save(); // 削除
// ここから追加
 for(j = 0; j < 3; j++) {
  saveStrategy[j] = new OpenLayers.Strategy.Save();
 };
// ここまで
 akirunoPoint = new OpenLayers.Layer.Vector("Akiruno Point", {
  strategies: [new OpenLayers.Strategy.BBOX(), saveStrategy[0]],
  projection: new OpenLayers.Projection("EPSG:2451"),
protocol: new OpenLayers.Protocol.WFS({
   version: "1.1.0",
   srsName: "EPSG:2451",
   url: "http://192.168.1.200:8080/geoserver/wfs",
   featureNS :  "http://www.myhome.net/npn",
   featureType: "akiruno_point",
   geometryName: "the_geom",
   schema: "http://192.168.1.200:8080/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=npn:akiruno_point"
  })
 });
 akirunoLine = new OpenLayers.Layer.Vector("Akiruno Line", {
  strategies: [new OpenLayers.Strategy.BBOX(), saveStrategy[1]],
  projection: new OpenLayers.Projection("EPSG:2451"),
  protocol: new OpenLayers.Protocol.WFS({
   version: "1.1.0",
   srsName: "EPSG:2451",
   url: "http://192.168.1.200:8080/geoserver/wfs",
   featureNS :  "http://www.myhome.net/npn",
   featureType: "akiruno_line",
   geometryName: "the_geom",
   schema: "http://192.168.1.200:8080/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=npn:akiruno_line"
  })
 });
 akirunoPolygon = new OpenLayers.Layer.Vector("Akiruno Polygon", {
  strategies: [new OpenLayers.Strategy.BBOX(), saveStrategy[2]],
  projection: new OpenLayers.Projection("EPSG:2451"),
  protocol: new OpenLayers.Protocol.WFS({
   version: "1.1.0",
   srsName: "EPSG:2451",
   url: "http://192.168.1.200:8080/geoserver/wfs",
   featureNS :  "http://www.myhome.net/npn",
   featureType: "akiruno_polygon",
   geometryName: "the_geom",
   schema: "http://192.168.1.200:8080/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=npn:akiruno_polygon"
  })
 });
// ここまで
 map = new OpenLayers.Map('map', {
  projection: new OpenLayers.Projection("EPSG:2451"),
  displayProjection: new OpenLayers.Projection("EPSG:4326"),
maxResolution: 'auto',
  units: 'meters',
  maxExtent: new OpenLayers.Bounds(-63100,-34500,-45400,-24200),
  controls: [
   new OpenLayers.Control.PanZoom(),
   new OpenLayers.Control.LayerSwitcher(),
   new OpenLayers.Control.MousePosition()
  ]
 });
 map.addLayers([layer0, layer3, layer1, layer2, layer4, akirunoPoint, akirunoLine, akirunoPolygon]);
 // "vectors" を削除 "akiruno_point, akiruno_line, akiruno_polygon" を追加
 var container = document.getElementById("panel");
 // 追加 編集ボタンを地図の外に配置するため
 var panel = new OpenLayers.Control.Panel({ //追加
  displayClass: 'customEditingToolbar',
  allowDepress: true,
  div: container // 追加
 });
 vectors = [akirunoPoint, akirunoLine, akirunoPolygon]; //追加
 panelControl = [
  new OpenLayers.Control.Navigation(
  {
   title: "Navigation"
  }),

 new OpenLayers.Control.DrawFeature(
  vectors[0],
  OpenLayers.Handler.Point,
  {
   title: "Draw Point",
   displayClass: 'olControlDrawFeaturePoint',
   multi: true
 }),
 new OpenLayers.Control.DragFeature(
  vectors[0],
  {
   title: "Drag Feature",
   displayClass: 'olControlDragFeature'
 }),
 new DeleteFeature(
  vectors[0],
  {
   title: "Remove Feature",
   displayClass: "olControlDeleteFeature"
 }),
 new OpenLayers.Control.DrawFeature(
  vectors[1],
  OpenLayers.Handler.Path,
  {
   title: "Draw Line",
   displayClass: 'olControlDrawFeaturePath',
   multi: true
 }),
 new OpenLayers.Control.DragFeature(
  vectors[1],
  {
   title: "Drag Feature",
   displayClass: 'olControlDragFeature'
 }),
 new OpenLayers.Control.ModifyFeature(
  vectors[1],
  {
   title: "Modify Feature",
   displayClass: "olControlModifyFeature"
 }),
 new DeleteFeature(
  vectors[1],
  {
   title: "Remove Feature",
   displayClass: "olControlDeleteFeature"
 }),
 new OpenLayers.Control.DrawFeature(
  vectors[2],
  OpenLayers.Handler.Polygon,
  {
   title: "Draw Polygon",
   displayClass: 'olControlDrawFeaturePolygon',
   multi: true
 }),
 new OpenLayers.Control.DragFeature(
  vectors[2],
  {
   title: "Drag Feature",
   displayClass: 'olControlDragFeature'
 }),
 new OpenLayers.Control.ModifyFeature(
  vectors[2],
  {
   title: "Modify Feature",
   displayClass: "olControlModifyFeature"
 }),
 new DeleteFeature(
  vectors[2],
  {
   title: "Remove Feature",
   displayClass: "olControlDeleteFeature"
 }),

 new OpenLayers.Control.SelectFeature(
  vectors,
  {
   clickout: false, toggle: false,
   multiple: false, hover: false,
   toggleKey: "ctrlKey", // ctrl key removes from selection
   multipleKey: "shiftKey", // shift key adds to selection
   box: true,
   title: "Select Feature",
   displayClass: 'olControlSelectFeature'
 }),

 new OpenLayers.Control.Button({
  title: "Save Changes",
  trigger: function() {
   for(j = 0; j < 3; j++) {
    window.alert(j);
    saveStrategy[j].save();
   };
  },
  displayClass: "olControlSaveFeatures"
 })
]; 
// ここまで

panel.addControls(panelControl);
map.addControl(panel);

map.zoomToMaxExtent();
}
---

EditingToolbar を次の図のように、各レイヤごとにボタンを設定しました。


「background: -webkit-linear-gradient」は、対応していないブラウザがあります。

スタイルシートを次のように設定します。
<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <link rel="stylesheet" href="OpenLayers-2.13.1/theme/default/style.css" type="text/css">
  <link rel="stylesheet" href="OpenLayers-2.13.1/examples/style.css" type="text/css">
  <style>
   .customEditingToolbar {
    float: left;
    right: 0px;
    height: 30px;
    background: -webkit-linear-gradient(left, #ffffff 0px, #ffffff 35px, #ccffcc 35px, #ccffcc 138px, #ffcccc 138px, #ffcccc 275px, #ccccff 275px, #ccccff 409px, #ffffff 409px, #ffffff);
   }
   .customEditingToolbar div {
    float: left;
    margin: 5px;
    width: 24px;
    height: 24px;
   }
   .pointpanel
   {
    position: absolute;
    left: 53px;
    background-color: #ccffcc;
    width: 104px;
   }
   .linepanel
   {
    position: absolute;
    left: 157px;
    background-color: #ffcccc;
    width: 137px;
   }
   .polygonpanel
   {
    position: absolute;
    left: 294px;
    background-color: #ccccff;
    width: 134px;
   }
---
 <body onload="init()">
  <h1 id="title">WMS Example BMI Akiruno PGIS2</h1>

  <div id="tags">
   wms, layer, singletile
  </div>
  <p id="shortdesc">
   Shows the basic use of openlayers using a WMS layer
  </p>
  <div class="pointpanel">point</div><div class="linepanel">line</div><div class="polygonpanel">polygon</div><br />
  <div id="panel" class="customEditingToolbar"> </div>
  <br /><br />
  <div id="map" class="smallmap"> </div>
  <div id="docs">
   <p>This is an example of how to add an WMS layer to the OpenLayers
      window. The images are tiled in this instance. If you wanted to not use
      a tiled WMS, "singleTile" option to true like shown in this example.</p>
  </div>
 </body>
</html>
 
参考 HTML ファイル 
ol016-nippon_bmi_akiruno_pgis.html



35 - WFS-T(WFS Transaction) 3 - HTML ファイルを作成

35-3 HTML ファイルを作成
HTML ファイルを準備します。

a 「App Exploler」ペインの「ol015-nippon_bmi_akiruno_pgis.html」を右クリックし「コピー」をクリックします。








b 「App Exploler」ペイン上で右クリックし「貼り付け」をクリックします。









c 「名前の競合」ウィンドウで「ol016-nippon_bmi_akiruno_pgis.html」と入力し「OK」ボタンをクリックします。



d 「App Exploler」ペインの「ol016-nippon_bmi_akiruno_pgis.html」をダブルクリックして開きます。
e Development Examples の「WFS Transaction Example(http://openlayers.org/dev/examples/wfs-protocol- transaction.html)」サイトの「wfs-protocol-transactions.js source」リンクをクリックしてコードを表示します。
f 次のように内容の一部をコピーして「ol016-nippon_bmi_akiruno_pgis.html」に貼り付け、修正します。

---
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url="; // 追加

function init(){
---
 var saveStrategy = new OpenLayers.Strategy.Save(); // 追加
// ここから修正
 vectors = new OpenLayers.Layer.Vector("Akiruno Polygon", {
  strategies: [new OpenLayers.Strategy.BBOX(), saveStrategy],
  projection: new OpenLayers.Projection("EPSG:2451"),
  protocol: new OpenLayers.Protocol.WFS({
   version: "1.1.0",
   srsName: "EPSG:2451",
   url: "http://192.168.1.200:8080/geoserver/wfs",
   featureNS :  "http://www.myhome.net/npn",
   featureType: "akiruno_polygon",
   geometryName: "the_geom",
   schema: "http://192.168.1.200:8080/geoserver/wfs/DescribeFeatureType?version=1.1.0&typename=npn:akiruno_polygon"
  })
 }); 
// ここまで
 map = new OpenLayers.Map('map', {
---
 panelControl = [
  new OpenLayers.Control.Navigation(
  {
   title: "Navigation"
  }),
/* ここから削除
  new OpenLayers.Control.DrawFeature(
   vectors,
   OpenLayers.Handler.Point,
   {
    title: "Draw Point",
    displayClass: 'olControlDrawFeaturePoint',
    multi: true
  }),
  new OpenLayers.Control.DrawFeature(
   vectors,
   OpenLayers.Handler.Path,
   {
    title: "Draw Line",
    displayClass: 'olControlDrawFeaturePath',
    multi: true
  }),
ここまで */
  new OpenLayers.Control.DrawFeature(
   vectors,
   OpenLayers.Handler.Polygon,
   {
    title: "Draw Polygon",
    displayClass: 'olControlDrawFeaturePolygon',
    multi: true
  }),
---
// ここから追加
  new OpenLayers.Control.Button({
   title: "Save Changes",
   trigger: function() {
    saveStrategy.save();
   },
   displayClass: "olControlSaveFeatures"
  })
 ];
// ここまで
 panel.addControls(panelControl);
 map.addControl(panel);

 map.zoomToMaxExtent();
}
---


user@debian7-vmw:~$ psql nippon_bmi
psql (9.1.11)
"help" でヘルプを表示します.
nippon_bmi=> \dt
                 リレーションの一覧
 スキーマ |        名前         |    型    | 所有者 
----------+---------------------+----------+--------

 public   | akiruno_polygon     | テーブル | user
(21 行)
(stdin):q
nippon_bmi=> \d akiruno_polygon
                          テーブル "public.akiruno_polygon"
  カラム  |    型    |                        修飾語                         
----------+----------+-------------------------------------------------------
 fid      | integer  | not null default nextval('akiruno_polygon_fid_seq'::regclass)
 the_geom | geometry | 
インデックス:
    "akiruno_polygon_pkey" PRIMARY KEY, btree (fid)
    "spatial_akiruno_polygon_the_geom" gist (the_geom)
CHECK 制約:
    "enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
    "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL)
    "enforce_srid_the_geom" CHECK (st_srid(the_geom) = 2451)
(stdin):q
nippon_bmi=> select * from akiruno_polygon;
 fid |                                                                         
             the_geom                                                          
                           
-----+--------------------------------------------------------------------------
--------------------------------------------------------------------------------
----------------------------
   1 | 0106000020930900000100000001030000000100000004000000C57FFEFE122FEDC04F000
22C99F3DCC0C57FFEFEAA3DECC04F00022CF783DAC0C57FFEFEBA9CEBC04F00022CE425DDC0C57FF
EFE122FEDC04F00022C99F3DCC0
(1 行)