// @require WFS_URL
if (!WFS_URL) throw "Missing WFS_URL"
var DBG = DBG || false
var httpFetch = window.fetch
// wfsFeature json format:
/*
{
$fieldName:
- string => field value
- array of objects => ref features as objects (wfsFeature)
- array of strings => ref features as xlink url
}
*/
function p5WFS_ParseFeatureFieldRecurse(tagNode) { // @returns object from xml element
var item = {}
var i = 0
for (i = 0; i < tagNode.children.length; i++) {
var fieldNode = tagNode.children[i]
if ('p5:links' === fieldNode.tagName) {
//
//
// "https://.../wfs-data.php/default_db/?SERVICE=WFS&VERSION=1.0.0&TYPENAME=default_db__x3A__BI_audit_KW_requested_person:BI_audit_KW_requested_person&REQUEST=GetFeature&backRefNS=default_db/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA&backRefPK=20&backRefField=default_db__x3A__BI_audit_KW_requested_person:BI_audit_KW_requested_person&startIndex=10"
//
for (var j = 0; j < fieldNode.children.length; j++) {
var p5LinkNode = fieldNode.children[j]
if ('p5:next' === p5LinkNode.tagName) {
var typeName = p5LinkNode.getAttribute('p5:typeName')
item[ typeName ].push( {
'type': 'next',
'@backRefNS': p5LinkNode.getAttribute('p5:backRefNS'),
'@backRefPK': p5LinkNode.getAttribute('p5:backRefPK'),
'@typeName': p5LinkNode.getAttribute('p5:typeName'),
'@startIndex': p5LinkNode.getAttribute('p5:startIndex'),
'value': p5LinkNode.textContent
} )
} else {
if (DBG) console.warn("Not implemented p5:links/" + p5LinkNode.tagName)
}
}
}
else if (!fieldNode.children.length) {
if (fieldNode.textContent) item[ fieldNode.localName ] = fieldNode.textContent
else {
var xlink = fieldNode.getAttribute('xlink:href')
if (xlink) {
if (!(fieldNode.tagName in item)) item[ fieldNode.tagName ] = []
item[ fieldNode.tagName ].push( xlink )
}
}
}
else {
if (!(fieldNode.tagName in item)) item[ fieldNode.tagName ] = []
item[ fieldNode.tagName ].push( p5WFS_ParseFeatureFieldRecurse(fieldNode) )
}
}
return item
}
function p5WFS_ParseFeatureMember(featureMember) { // @returns object from xml element
if (!featureMember) return null
if (!featureMember.children.length) return null
var featureNode = featureMember.children[0]
if (!featureNode) return null
if (!featureNode.children.length) return null
return p5WFS_ParseFeatureFieldRecurse(featureNode)
}
/**
* @usage
p5WFS_GetFeature('p5_default_db:CRM_PROCES', {
'featureID': 'CRM_PROCES.' + id,
}).then(function (features) {
// ...
}).catch(function (e) {
// ...
})
* @usage - expected one feature
p5WFS_GetFeature('p5_default_db:CRM_PROCES', {
'featureID': 'CRM_PROCES.' + id,
}).then(function (features) {
if (!features) throw "Nie odnaleziono rekordu id = " + id
if (!features.length) throw "Nie odnaleziono rekordu id = " + id
if (1 !== features.length) throw "Bład: API zwróciło za dużo rekordów"
return features[0]
console.log('fetched features', features)
}).then(function (feature) {
// ...
}).catch(function (e) {
// ...
})
* @usage - POST
p5WFS_GetFeature('p5_default_db:CRM_PROCES', {
// 'Filter': '' + "PARENT_ID" + '' + parent_id + '',
'sortBy': 'SORT_PRIO+A,ID',
'ogc:Filter': '' +
'' +
'' + "PARENT_ID" + '' + parent_id + '' +
'' +
''
}).then(function (features) {
...
*/
function p5WFS_GetFeature(typeName, query) { // @returns Promise
var postData = null
var link = WFS_URL + '?SERVICE=WFS&VERSION=1.0.0' +
'&REQUEST=GetFeature' +
'&TYPENAME=' + typeName +
'&SRSNAME=EPSG:3003'
;
if ('WFS_URL' in query && query['WFS_URL'].length) {
link = query['WFS_URL']
link += ( (-1 !== query['WFS_URL'].indexOf('?')) ? '&' : '?' )
link += 'SERVICE=WFS&VERSION=1.0.0'
link += '&REQUEST=GetFeature'
link += '&TYPENAME=' + typeName
link += '&SRSNAME=EPSG:3003'
}
// '&Filter=ID' + id + ''
var query = query || {}
if ('featureID' in query) link += '&featureID=' + query['featureID']
if ('Filter' in query && 'string' === typeof query['Filter']) {
var ogcFilter = ('' !== query['Filter'].substr(0, ''.length))
? '' + query['Filter'] + ''
: query['Filter']
;
link += '&Filter=' + ogcFilter
}
if ('ogc:Filter' in query && 'string' === typeof query['ogc:Filter']) {
var headerOgcFilter = ''
if ('' === query['ogc:Filter'].substr(0, ''.length)) {
postData = headerOgcFilter + '' + query['ogc:Filter'] + '' + ''
} else if ('' === query['ogc:Filter'].substr(0, ''.length)) {
postData = headerOgcFilter + query['ogc:Filter'] + ''
} else {
return Promise.reject(new Error('Wrong syntax ogc:Filter'))
}
}
if ('graphql:query' in query && 'string' === typeof query['graphql:query']) { // TODO: http://graphql.org/learn/queries/
link += '&outputFormat=json'
postData = query['graphql:query']
}
if ('sortBy' in query) link += '&sortBy=' + query['sortBy']
if ('maxFeatures' in query) link += '&maxFeatures=' + query['maxFeatures']
if ('count' in query) link += '&count=' + query['count']
if ('startIndex' in query) link += '&startIndex=' + query['startIndex']
if ('primaryKey' in query) link += '&primaryKey=' + query['primaryKey']
if ('resolveDepth' in query && !('resolve' in query)) return Promise.reject(new Error('ResolveDepth set but missing resolve="all"'))
if ('resolve' in query) link += '&resolve=' + query['resolve']
if ('resolveDepth' in query) link += '&resolveDepth=' + query['resolveDepth']
if ('xlink' in query) link += '&xlink=' + query['xlink'] // NOTE: replace '#' to '/'
if ('root' in query) link += '&root=' + query['root'] // NOTE: require admin perms (admin level 0)
if ('backRefNS' in query && 'backRefPK' in query && 'backRefField' in query) {
link += '&backRefNS=' + query['backRefNS']
link += '&backRefPK=' + query['backRefPK']
link += '&backRefField=' + query['backRefField']
}
if ('p5:next' in query) link = query['p5:next'];
var method = (postData) ? 'POST' : 'GET'
var wfsPromise = httpFetch(link, Object.assign({
method: method,
credentials: 'include',
}, ('POST' === method)
? {
body: postData
}
: {}
)).then(function (response) {
return response.text()
});
return _p5WFS_GetFeaturePromise(wfsPromise);
}
function p5WFS_GetFeatureFromXml(url) {
var wfsPromise = httpFetch(url, {
method: 'GET',
credentials: 'include',
}).then(function (response) {
return response.text()
});
return _p5WFS_GetFeaturePromise(wfsPromise);
}
function p5WFS_GetFeatureFromXmlString(xmlString) {
var wfsPromise = new Promise(function (resolve, reject) {
resolve(xmlString);
});
return _p5WFS_GetFeaturePromise(wfsPromise);
}
function _p5WFS_GetFeaturePromise(wfsPromise) {
return wfsPromise.then(function (responseText) {
return (new DOMParser()).parseFromString(responseText, "text/xml");
}).then(function (xmlResponse) {
if (!xmlResponse.children.length) throw "Missing response xml root element"
return xmlResponse.children[0]
}).then(function (xmlRoot) {
if ('html' === xmlRoot.localName) {
// console.log(xmlRoot) // html / body / parseerror / div
throw "Parse xml error"
}
if ('FeatureCollection' !== xmlRoot.localName) {
if ('ServiceExceptionReport' === xmlRoot.tagName) {
if (xmlRoot.children[0] && xmlRoot.children[0].textContent) throw xmlRoot.children[0].textContent
throw "WFS API Exception"
}
throw "Missing FeatureCollection as root element in wfs response"
}
var features = []
for (var i = 0; i < xmlRoot.children.length; i++) {
features.push(p5WFS_ParseFeatureMember(xmlRoot.children[i]))
}
return features.filter(function (item) { return !!item; })
})
}
module.exports = {
p5WFS_ParseFeatureMember: p5WFS_ParseFeatureMember,
p5WFS_ParseFeatureFieldRecurse: p5WFS_ParseFeatureFieldRecurse,
p5WFS_GetFeature: p5WFS_GetFeature,
p5WFS_GetFeatureFromXml: p5WFS_GetFeatureFromXml,
p5WFS_GetFeatureFromXmlString: p5WFS_GetFeatureFromXmlString,
}