Skip to content

Commit

Permalink
added request builder for WFST (#1927)
Browse files Browse the repository at this point in the history
  • Loading branch information
offtherailz authored Jun 13, 2017
1 parent 84c1823 commit 4e3c106
Show file tree
Hide file tree
Showing 13 changed files with 268 additions and 18 deletions.
2 changes: 1 addition & 1 deletion web/client/test-resources/wfst/delete/museam_1_1_0.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/WFS-transaction.xsd" xmlns:tiger="http://www.census.gov"><wfs:Delete typeName="tiger:poi"><ogc:Filter><ogc:FeatureId fid="poi.1"/></ogc:Filter></wfs:Delete></wfs:Transaction>
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs" xmlns:tiger="http://www.census.gov"><wfs:Delete typeName="tiger:poi"><ogc:Filter><ogc:FeatureId fid="poi.1"/></ogc:Filter></wfs:Delete></wfs:Transaction>
2 changes: 1 addition & 1 deletion web/client/test-resources/wfst/insert/Wyoming_1_1_0.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/WFS-transaction.xsd" xmlns:topp="http://www.openplans.org/topp"><wfs:Insert><topp:states><topp:STATE_NAME>Wyoming</topp:STATE_NAME><topp:STATE_FIPS>56</topp:STATE_FIPS><topp:SUB_REGION>Mtn</topp:SUB_REGION><topp:STATE_ABBR>WY</topp:STATE_ABBR><topp:LAND_KM>251500.801</topp:LAND_KM><topp:WATER_KM>1848.149</topp:WATER_KM><topp:PERSONS>453588</topp:PERSONS><topp:FAMILIES>119825</topp:FAMILIES><topp:HOUSHOLD>168839</topp:HOUSHOLD><topp:MALE>227007</topp:MALE><topp:FEMALE>226581</topp:FEMALE><topp:WORKERS>164561</topp:WORKERS><topp:DRVALONE>153679</topp:DRVALONE><topp:CARPOOL>28109</topp:CARPOOL><topp:PUBTRANS>2963</topp:PUBTRANS><topp:EMPLOYED>207868</topp:EMPLOYED><topp:UNEMPLOY>13112</topp:UNEMPLOY><topp:SERVICE>71419</topp:SERVICE><topp:MANUAL>29157</topp:MANUAL><topp:P_MALE>0.5</topp:P_MALE><topp:P_FEMALE>0.5</topp:P_FEMALE><topp:SAMP_POP>83202</topp:SAMP_POP><topp:the_geom><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon srsName="EPSG:4326"><gml:exterior><gml:LinearRing><gml:posList>-104.053108 41.698246 -104.054993 41.564247 -104.053505 41.388107 -104.051201 41.003227 -104.933968 40.994305 -105.278259 40.996365 -106.202896 41.000111 -106.328545 41.001316 -106.864838 40.998489 -107.303436 41.000168 -107.918037 41.00341 -109.047638 40.998474 -110.001457 40.997646 -110.062477 40.99794 -111.050285 40.996635 -111.050911 41.25848 -111.050323 41.578648 -111.047951 41.996265 -111.046028 42.503323 -111.048447 43.019962 -111.04673 43.284813 -111.045998 43.515606 -111.049629 43.982632 -111.050789 44.473396 -111.050842 44.664562 -111.05265 44.995766 -110.428894 44.992348 -110.392006 44.998688 -109.994789 45.002853 -109.798653 44.99958 -108.624573 44.997643 -108.258568 45.00016 -107.893715 44.999813 -106.258644 44.996174 -106.020576 44.997227 -105.084465 44.999832 -105.04126 45.001091 -104.059349 44.997349 -104.058975 44.574368 -104.060547 44.181843 -104.059242 44.145844 -104.05899 43.852928 -104.057426 43.503738 -104.05867 43.47916 -104.05571 43.003094 -104.055725 42.614704 -104.053009 41.999851 -104.053108 41.698246</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom></topp:states></wfs:Insert></wfs:Transaction>
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp"><wfs:Insert><topp:states><topp:STATE_NAME>Wyoming</topp:STATE_NAME><topp:STATE_FIPS>56</topp:STATE_FIPS><topp:SUB_REGION>Mtn</topp:SUB_REGION><topp:STATE_ABBR>WY</topp:STATE_ABBR><topp:LAND_KM>251500.801</topp:LAND_KM><topp:WATER_KM>1848.149</topp:WATER_KM><topp:PERSONS>453588</topp:PERSONS><topp:FAMILIES>119825</topp:FAMILIES><topp:HOUSHOLD>168839</topp:HOUSHOLD><topp:MALE>227007</topp:MALE><topp:FEMALE>226581</topp:FEMALE><topp:WORKERS>164561</topp:WORKERS><topp:DRVALONE>153679</topp:DRVALONE><topp:CARPOOL>28109</topp:CARPOOL><topp:PUBTRANS>2963</topp:PUBTRANS><topp:EMPLOYED>207868</topp:EMPLOYED><topp:UNEMPLOY>13112</topp:UNEMPLOY><topp:SERVICE>71419</topp:SERVICE><topp:MANUAL>29157</topp:MANUAL><topp:P_MALE>0.5</topp:P_MALE><topp:P_FEMALE>0.5</topp:P_FEMALE><topp:SAMP_POP>83202</topp:SAMP_POP><topp:the_geom><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon srsName="EPSG:4326"><gml:exterior><gml:LinearRing><gml:posList>-104.053108 41.698246 -104.054993 41.564247 -104.053505 41.388107 -104.051201 41.003227 -104.933968 40.994305 -105.278259 40.996365 -106.202896 41.000111 -106.328545 41.001316 -106.864838 40.998489 -107.303436 41.000168 -107.918037 41.00341 -109.047638 40.998474 -110.001457 40.997646 -110.062477 40.99794 -111.050285 40.996635 -111.050911 41.25848 -111.050323 41.578648 -111.047951 41.996265 -111.046028 42.503323 -111.048447 43.019962 -111.04673 43.284813 -111.045998 43.515606 -111.049629 43.982632 -111.050789 44.473396 -111.050842 44.664562 -111.05265 44.995766 -110.428894 44.992348 -110.392006 44.998688 -109.994789 45.002853 -109.798653 44.99958 -108.624573 44.997643 -108.258568 45.00016 -107.893715 44.999813 -106.258644 44.996174 -106.020576 44.997227 -105.084465 44.999832 -105.04126 45.001091 -104.059349 44.997349 -104.058975 44.574368 -104.060547 44.181843 -104.059242 44.145844 -104.05899 43.852928 -104.057426 43.503738 -104.05867 43.47916 -104.05571 43.003094 -104.055725 42.614704 -104.053009 41.999851 -104.053108 41.698246</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom></topp:states></wfs:Insert></wfs:Transaction>
2 changes: 1 addition & 1 deletion web/client/test-resources/wfst/insert/museam_1_1_0.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/WFS-transaction.xsd" xmlns:tiger="http://www.census.gov"><wfs:Insert><tiger:poi><tiger:NAME>museam</tiger:NAME><tiger:THUMBNAIL>pics/22037827-Ti.jpg</tiger:THUMBNAIL><tiger:MAINPAGE>pics/22037827-L.jpg</tiger:MAINPAGE><tiger:the_geom><gml:Point srsDimension="2" srsName="EPSG:4326"><gml:pos>-74.0104611 40.70758763</gml:pos></gml:Point></tiger:the_geom></tiger:poi></wfs:Insert></wfs:Transaction>
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs" xmlns:tiger="http://www.census.gov"><wfs:Insert><tiger:poi><tiger:NAME>museam</tiger:NAME><tiger:THUMBNAIL>pics/22037827-Ti.jpg</tiger:THUMBNAIL><tiger:MAINPAGE>pics/22037827-L.jpg</tiger:MAINPAGE><tiger:the_geom><gml:Point srsDimension="2" srsName="EPSG:4326"><gml:pos>-74.0104611 40.70758763</gml:pos></gml:Point></tiger:the_geom></tiger:poi></wfs:Insert></wfs:Transaction>
2 changes: 1 addition & 1 deletion web/client/test-resources/wfst/update/museam_1_1_0.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/WFS-transaction.xsd" xmlns:tiger="http://www.census.gov"><wfs:Update typeName="tiger:poi"><wfs:Property><wfs:Name>NAME</wfs:Name><wfs:Value>newName</wfs:Value></wfs:Property><ogc:Filter><ogc:FeatureId fid="poi.7"/></ogc:Filter></wfs:Update></wfs:Transaction>
<wfs:Transaction service="WFS" version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs" xmlns:tiger="http://www.census.gov"><wfs:Update typeName="tiger:poi"><wfs:Property><wfs:Name>NAME</wfs:Name><wfs:Value>newName</wfs:Value></wfs:Property><ogc:Filter><ogc:FeatureId fid="poi.7"/></ogc:Filter></wfs:Update></wfs:Transaction>
81 changes: 81 additions & 0 deletions web/client/utils/ogc/WFST/RequestBuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

const {get} = require('lodash');
const {insert, feature, attribute} = require('./insert');
const {transaction} = require('./transaction');
const {deleteFeaturesByFilter, deleteFeature} = require('./delete');
const {update, propertyChange} = require('./update');
const {getPropertyDesciptor, getValue, findGeometryProperty, featureTypeSchema} = require("../WFS/base");
const wfsRequestBuilder = require('../WFS/RequestBuilder');


const WFSVersionNotSupportedException = function(wfsVersion) {
this.version = wfsVersion;
};
const getTypeName = dft => get(dft, "featureTypes[0].typeName");
const getFullQualifiedTypeName = dft => dft.targetPrefix ? `${dft.targetPrefix}:${getTypeName(dft)}` : getTypeName(dft);
const getGeometryName = (f, describe) => f.geometry_name || findGeometryProperty(describe).name;
/**
* RequestBuilder for WFS-T. Returns the proper method to create request bodies
* @augments utils.WFS.RequestBuilder
* @param {object} describe the describeFeatureType object, json format
* @param {object} [options] by default wfsVersion="1.1.0" wfsNS="wfs"
* @return {object} the RequestBuilder for WFS-T
*/
module.exports = function(describe, {wfsVersion = "1.1.0", wfsNS="wfs", ...other} = {}) {
if (wfsVersion !== "1.1.0") {
throw new WFSVersionNotSupportedException(wfsVersion);
}
const toFeature = (f) => feature( describe.targetPrefix, getTypeName(describe), Object.keys(f.properties || [])
.filter(k => getPropertyDesciptor(k, describe))
.map((key) => attribute(describe.targetPrefix, key, getValue(f.properties[key], key, describe)))
.concat(attribute(describe.targetPrefix, getGeometryName(f, describe), getValue(f.geometry, getGeometryName(f, describe), describe) ))
);
const toFeatures = (f) => f.features ? f.features.map(toFeature) : toFeature(f);
return {
...wfsRequestBuilder({...other, wfsVersion, wfsNS}),
/**
* Create an Insert request body for the given features
* @param {array|object} features The features to insert
* @return {string} the request body
*/
insert: (features) => insert(wfsNS,
Array.isArray(features) ? features.map(toFeature) : toFeatures(features)
),
/**
* Create a delete request body for the given features
* @param {array|string} filter The filter to use for delete
* @return {string} the request body of the request
*/
deleteByFilter: (filter) => deleteFeaturesByFilter(wfsNS, filter, getFullQualifiedTypeName(describe)),
/**
* Create a delete request for a specific feature using the Id of the feature. It requires the feature id is unique
* @param {object} f the feature
* @return {string} the body of the request
*/
deleteFeature: (f) => deleteFeature(wfsNS, f, getFullQualifiedTypeName(describe)),
/**
* Wraps the given content into an update
* @param {string} content the property changes and filter to use
* @return {string} the body of the request
*/
update: update.bind(null, wfsNS, getFullQualifiedTypeName(describe)),
/**
* Create a property change entry
* @type {[type]}
*/
propertyChange: propertyChange.bind(null, wfsNS),
/**
* Wraps the given content into a tranaction object
* @param {[type]} content [description]
* @return {[type]} [description]
*/
transaction: (content) => transaction(content, featureTypeSchema(describe), wfsVersion, wfsNS)
};
};
59 changes: 59 additions & 0 deletions web/client/utils/ogc/WFST/__tests__/WFST-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

const expect = require('expect');
const requestBuilder = require('../RequestBuilder');
const {fidFilter} = require('../../Filter/filter');
const {featureTypeSchema} = require('../../WFS/base');
const describeStates = require('json-loader!../../../../test-resources/wfs/describe-states.json');
const describePois = require('json-loader!../../../../test-resources/wfs/describe-pois.json');
const wyoming = require('json-loader!../../../../test-resources/wfs/Wyoming.json');
const museam = require('json-loader!../../../../test-resources/wfs/museam.json');
const expectedInsertWyoming = require('raw-loader!../../../../test-resources/wfst/insert/Wyoming_1_1_0.xml');
const expectedInsertmuseam = require('raw-loader!../../../../test-resources/wfst/insert/museam_1_1_0.xml');
const expectedDelete = require('raw-loader!../../../../test-resources/wfst/delete/museam_1_1_0.xml');
const expectedUpdate = require('raw-loader!../../../../test-resources/wfst/update/museam_1_1_0.xml');
describe('Test WFS-T request bodies generation', () => {
it('WFS-T insert', () => {
const {insert} = requestBuilder(describeStates);
const result = insert(wyoming, describeStates);
expect(result).toExist();
});
it('WFS-T transaction with insert polygon', () => {
const {insert, transaction} = requestBuilder(describeStates);
const result = transaction(insert(wyoming));
expect(result).toExist();
expect(result + '\n').toEqual(expectedInsertWyoming);
});

it('WFS-T transaction with insert point', () => {
const {insert, transaction} = requestBuilder(describePois);
const result = transaction([insert(museam)]);
expect(result).toExist();
expect(result + '\n').toEqual(expectedInsertmuseam);
});

it('WFS-T transaction with delete', () => {
const {deleteFeature, transaction} = requestBuilder(describePois);
const result = transaction([deleteFeature(museam)], featureTypeSchema(describePois));
expect(result).toExist();
expect(result + '\n').toEqual(expectedDelete);
});

it('WFS-T transaction with update', () => {
const {update, propertyChange, transaction} = requestBuilder(describePois);
const result = transaction(
update(
[propertyChange("NAME", "newName"), fidFilter("ogc", "poi.7")])
,
featureTypeSchema(describePois));
expect(result).toExist();
expect(result + '\n').toEqual(expectedUpdate);
});

});
26 changes: 26 additions & 0 deletions web/client/utils/ogc/WFST/delete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/


const {fidFilter} = require('../Filter/base');
/**
* Generate WFS delete features
* @function
* @param {string} content The content of the delete request, e.g. the filter to use
* @param {object} describeFeatureType describeFeatureType object
* @return {string} the XML for the update
*/
const deleteFeaturesByFilter = (ns, content, typeName) =>
`<${ns}:Delete typeName="${typeName}">${content}</${ns}:Delete>`;
const deleteById = (ns, fid, typeName) => deleteFeaturesByFilter(ns, fidFilter("ogc", fid), typeName);
const deleteFeature = (ns, feature, typeName) => deleteById(ns, feature.features && feature.features.length === 1 ? feature.features[0].id : feature.id, typeName);
module.exports = {
deleteFeaturesByFilter,
deleteById,
deleteFeature
};
21 changes: 20 additions & 1 deletion web/client/utils/ogc/WFST/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
module.exports = require("./v1_1_0");
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
const {transaction} = require('./transaction');
const {insert} = require('./insert');
// const {update, property} = require('./update');
const {deleteFeature, deleteFeaturesByFilter, deleteById} = require('./delete');
module.exports = {
insert,
// update,
// property,
deleteFeature,
deleteFeaturesByFilter,
deleteById,
transaction
};
18 changes: 18 additions & 0 deletions web/client/utils/ogc/WFST/insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

const optNameSpaceTag = (ns, key, content) => `<${ns ? ns + ":" + key : key}>${Array.isArray(content) ? content.join("") : content}</${ns ? ns + ":" + key : key}>`;
const attribute = optNameSpaceTag;
const feature = optNameSpaceTag;
const insert = (ns, content) => `<${ns}:Insert>${Array.isArray(content) ? content.join("") : content}</${ns}:Insert>`;

module.exports = {
insert,
feature,
attribute
};
23 changes: 23 additions & 0 deletions web/client/utils/ogc/WFST/transaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/


const transaction = (operations, schemaLocation, {wfsNS = "wfs", wfsVersion = "1.1.0"} = {}) => `<${wfsNS}:Transaction `
+ 'service="WFS" '
+ `version="${wfsVersion}" `
+ `xmlns:${wfsNS}="http://www.opengis.net/wfs" `
+ 'xmlns:gml="http://www.opengis.net/gml" '
+ 'xmlns:ogc="http://www.opengis.net/ogc" '
+ 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
+ 'xsi:schemaLocation="http://www.opengis.net/wfs" '
+ `${schemaLocation}>`
+ `${Array.isArray(operations) ? operations.join("") : operations}`
+ `</${wfsNS}:Transaction>`;
module.exports = {
transaction
};
25 changes: 25 additions & 0 deletions web/client/utils/ogc/WFST/update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

const propertyChange = (ns, propName, value) => `<${ns}:Property>`
+ `<${ns}:Name>${propName}</${ns}:Name>`
+ `<${ns}:Value>${value}</${ns}:Value>`
+ `</${ns}:Property>`;

/**
* Generate update XML.
* @function
* @param {string} content the properties to update and/or features to use (inXML)
* @param {object} describeFeatureType describeFeatureType object
* @return {string} the XML for the update
*/
const update = (wfsNs, typeName, content) => `<${wfsNs}:Update typeName="${typeName}">${Array.isArray(content) ? content.join("") : content}</wfs:Update>`;
module.exports = {
update,
propertyChange
};
Loading

0 comments on commit 4e3c106

Please sign in to comment.