Skip to content

Commit

Permalink
Merge pull request #96 from IGNF/patch_gpu
Browse files Browse the repository at this point in the history
Maj patch Gpu en attendant Geoplateforme
  • Loading branch information
MFrangi authored Feb 8, 2024
2 parents 778ad48 + a13ed49 commit 3f7c038
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 2 deletions.
111 changes: 111 additions & 0 deletions lib/ClientGpu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const httpClient = require('./httpClient');

var buildGpuFilter = require('./buildGpuFilter');


/**
* @classdesc
* WFS access client for the geoportal
* @constructor
*/
var ClientGpu = function (options) {
// should be removed to allow user/password?
this.url = options.url || 'https://wxs-gpu.mongeoportail.ign.fr/externe/{apiKey}/wfs/v';
this.apiKey = options.apiKey || null;
this.headers = options.headers || {};
/* allows to use WFS with different naming convention */
this.defaultGeomFieldName = options.defaultGeomFieldName || 'the_geom';
this.defaultCRS = options.defaultCRS || 'urn:ogc:def:crs:EPSG::4326';
};

/**
* Get WFS URL
*/
ClientGpu.prototype.getUrl = function () {
return this.url.replace('{apiKey}', this.apiKey);
};

/**
* @private
* @returns {Object}
*/
ClientGpu.prototype.getDefaultParams = function () {
return {
service: 'WFS',
version: '2.0.0'
};
};

/**
* @private
* @returns {Object}
*/
ClientGpu.prototype.getDefaultHeaders = function () {
return this.headers;
};

/**
* Get features for a given type
*
* @param {string} typeName - name of type
* @param {object} params - define cumulative filters (bbox, geom) and to manage the pagination
* @param {number} [params._start=0] index of the first result (STARTINDEX on the WFS)
* @param {number} [params._limit] maximum number of result (COUNT on the WFS)
* @param {array} [params._propertyNames] restrict a GetFeature request by properties
* @param {object} [params.geom] search geometry intersecting the resulting features.
* @param {object} [params.bbox] search bbox intersecting the resulting features.
* @param {string} [defaultGeomFieldName="the_geom"] name of the geometry column by default
* @param {string} [defaultCRS="urn:ogc:def:crs:EPSG::4326"] default data CRS (required in cql_filter)
*
* @return {Promise}
*/
ClientGpu.prototype.getFeatures = function (typeName, params) {
params = params || {};

var headers = this.getDefaultHeaders();
headers['Accept'] = 'application/json';

/*
* GetFeature params
*/
var queryParams = this.getDefaultParams();
queryParams['request'] = 'GetFeature';
queryParams['typename'] = typeName;
queryParams['outputFormat'] = 'application/json';
queryParams['srsName'] = 'CRS:84';
if (typeof params._limit !== 'undefined') {
queryParams['count'] = params._limit;
}
if (typeof params._start !== 'undefined') {
queryParams['startIndex'] = params._start;
}

if (typeof params._propertyNames !== 'undefined') {
queryParams['propertyName'] = params._propertyNames.join();
}
/*
* bbox and attribute filter as POST parameter
*/
var cql_filter = buildGpuFilter(params,this.defaultGeomFieldName,this.defaultCRS);
var body = (cql_filter !== null) ? 'cql_filter=' + encodeURI(cql_filter) : '';
return httpClient.post(this.getUrl(), body, {
params: queryParams,
headers: headers,
responseType: 'text',
transformResponse: function (body) {
try {
return JSON.parse(body);
} catch (err) {
// forward xml errors
throw {
'type': 'error',
'message': body
};
}
}
}).then(function (response) {
return response.data;
});
};

module.exports = ClientGpu;
90 changes: 90 additions & 0 deletions lib/buildGpuFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const WKT = require('@terraformer/wkt');
var flip = require('@turf/flip');

const proj4 = require('proj4');
proj4.defs('EPSG:4326','+proj=longlat +datum=WGS84 +no_defs');
proj4.defs('EPSG:2154','+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
proj4.defs('EPSG:3857','+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs');

const defaultCRS = 'urn:ogc:def:crs:EPSG::4326';
const meta = require('@turf/meta');
/*
* WARNING: Despite the use of WGS84, you need to do a flip on the coordinates
*/

/**
* Convert a bbox on array with 4 values
*/
function parseBoundingBox(bbox){
if ( typeof bbox !== 'string' ){
return bbox;
}
return bbox.replace(/'/g, '').split(',');
}

/**
* Convert a bbox in cql_filter fragment
*/
function bboxToFilter(bbox){
bbox = parseBoundingBox(bbox);
var xmin = bbox[1];
var ymin = bbox[0];
var xmax = bbox[3];
var ymax = bbox[2];
return 'BBOX(the_geom,'+xmin+','+ymin+','+xmax+','+ymax+')' ;
}

/**
* Build cql_filter parameter for GeoServer according to user params.
*
* @param {object} params
* @param {object} [params.geom] search geometry intersecting the resulting features.
* @param {object} [params.bbox] search bbox intersecting the resulting features.
* @param {string} [geomFieldName="the_geom"] name of the geometry column by default
* @param {string} [geomDefaultCRS=defaultCRS="urn:ogc:def:crs:EPSG::4326"] default data CRS (required in cql_filter)
* @returns {string}
*/
function buildGpuFilter(params, geomFieldName,geomDefaultCRS) {
geomFieldName = geomFieldName || 'the_geom';
geomDefaultCRS = geomDefaultCRS || defaultCRS;

var parts = [];
for (var name in params) {
// ignore _limit, _start, etc.
if (name.charAt(0) === '_') {
continue;
}

if (name == 'bbox') {
parts.push(bboxToFilter(params['bbox'], geomFieldName));
} else if (name == 'geom') {
var geom = params[name];
if (typeof geom !== 'object') {
geom = JSON.parse(geom);
}
if(geomDefaultCRS != defaultCRS) {
const input = geom;

const transform = proj4('EPSG:4326',geomDefaultCRS);

meta.coordEach(input,function(c){
let newC = transform.forward(c);
c[0] = newC[0];
c[1] = newC[1];
});
geom=input;
}
var wkt = WKT.geojsonToWKT(flip(geom));
parts.push('INTERSECTS( the_geom' + ',' + wkt + ')');
} else {
parts.push(name + '=\'' + params[name] + '\'');
}
}
if (parts.length === 0) {
return null;
}
return parts.join(' and ');
}


module.exports=buildGpuFilter;
4 changes: 2 additions & 2 deletions middlewares/gpuWfsClient.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const GeoportalWfsClient = require('geoportal-wfs-client');
const GeoportalWfsClientGpu = require('../lib/ClientGpu.js');

/*
* middleware pour la création du client geoportail
Expand All @@ -11,7 +11,7 @@ module.exports = function(req, res, next) {
referer = req.headers.referer ;
}

req.gpuWfsClient = new GeoportalWfsClient({
req.gpuWfsClient = new GeoportalWfsClientGpu({
'apiKey': '39wtxmgtn23okfbbs1al2lz3',
'url' : 'https://wxs-gpu.mongeoportail.ign.fr/externe/{apiKey}/wfs/v',
'headers':{
Expand Down

0 comments on commit 3f7c038

Please sign in to comment.