qwc2
Version:
QGIS Web Client
94 lines • 17.3 kB
JavaScript
function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _iterableToArrayLimit(r,l){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,i,u,a=[],f=!0,o=!1;try{if(i=(t=t.call(r)).next,0===l){if(Object(t)!==t)return;f=!1}else for(;!(f=(e=i.call(t)).done)&&(a.push(e.value),a.length!==l);f=!0);}catch(r){o=!0,n=r}finally{try{if(!f&&null!=t["return"]&&(u=t["return"](),Object(u)!==u))return}finally{if(o)throw n}}return a}}function _arrayWithHoles(r){if(Array.isArray(r))return r}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,o)}return t}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}/**
* Copyright 2017-2024 Sourcepole AG
* 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.
*//**
* NOTE: This sample editing interface is designed to work with the counterpart at
* https://github.com/qwc-services/qwc-data-service
*/import axios from"axios";import isEmpty from"lodash.isempty";import ConfigUtils from"./ConfigUtils";import{computeExpressionFields}from"./EditingUtils";import LocaleUtils from"./LocaleUtils";var EditingInterface={buildErrMsg:function buildErrMsg(err){var message=LocaleUtils.tr("editing.commitfailed");if(err.response&&err.response.data&&err.response.data.message){message=err.response.data.message;if(!isEmpty(err.response.data.geometry_errors)){message+=":\n";message+=err.response.data.geometry_errors.map(function(entry){var entrymsg=" - "+entry.reason;if(entry.location){entrymsg+=" at "+entry.location}return entrymsg})}if(!isEmpty(err.response.data.data_errors)){message+=":\n - "+err.response.data.data_errors.join("\n - ")}if(!isEmpty(err.response.data.validation_errors)){message+=":\n - "+err.response.data.validation_errors.join("\n - ")}if(!isEmpty(err.response.data.attachment_errors)){message+=":\n - "+err.response.data.attachment_errors.join("\n - ")}}else if(err.response&&err.response.statusText){message+=": "+err.response.statusText}return message},/**
* Gets features at the specified map position.
*
* @param editConfig The edit config of the dataset to query features from
* @param mapPos The [x, y] map position
* @param mapCrs The CRS of the map, as an EPSG code
* @param mapScale The scale denominator, used to compute the pick tolerance
* @param dpi The screen dpi, used to compute the pick tolerance
* @param callback Callback invoked with the picked features, taking `{features: [...]}` on success and `null` on failure
* @param filter An optional feature attribute filter expression
* @param filterGeom An optional filter geometry
*/getFeature:function getFeature(editConfig,mapPos,mapCrs,mapScale,dpi,callback){var filter=arguments.length>6&&arguments[6]!==undefined?arguments[6]:null;var filterGeom=arguments.length>7&&arguments[7]!==undefined?arguments[7]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/";// 10px tolerance
var tol=10/dpi*0.0254*mapScale;var bbox=mapPos[0]-tol+","+(mapPos[1]-tol)+","+(mapPos[0]+tol)+","+(mapPos[1]+tol);var params={bbox:bbox,crs:mapCrs,filter:filter?JSON.stringify(filter):undefined,filter_geom:filterGeom?JSON.stringify(_objectSpread(_objectSpread({},filterGeom),{},{crs:{type:"name",properties:{name:mapCrs}}})):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){var _response$data;if(!isEmpty(response===null||response===void 0||(_response$data=response.data)===null||_response$data===void 0?void 0:_response$data.features)){var version=+new Date;var promises=response.data.features.map(function(feature){return new Promise(function(resolve){computeExpressionFields(editConfig,feature,EditingInterface,mapCrs,function(newfeature){return resolve(_objectSpread(_objectSpread({},newfeature),{},{__version__:version}))})})});Promise.all(promises).then(function(features){return callback({features:features})})}else{callback(null)}})["catch"](function(){callback(null)})},/**
* Queries a feature by id
*
* @param editConfig The edit config of the dataset to query the feature from
* @param featureId The feature id
* @param mapCrs The CRS of the map, as an EPSG code
* @param callback Callback invoked with the picked feature, taking `{<feature>}` on success and `null` on failure
*/getFeatureById:function getFeatureById(editConfig,featureId,mapCrs,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/"+featureId;var params={crs:mapCrs};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){computeExpressionFields(editConfig,response.data,EditingInterface,mapCrs,function(newfeature){return callback(_objectSpread(_objectSpread({},newfeature),{},{__version__:+new Date}))})})["catch"](function(){callback(null)})},/**
* Gets the dataset features
*
* @param editConfig The edit config of the dataset to query features from
* @param mapCrs The CRS of the map, as an EPSG code
* @param callback Callback invoked with the picked features, taking `{features: [...]}` on success and `null` on failure
* @param filter An optional feature attribute filter expression
* @param filterGeom An optional filter geometry
*/getFeatures:function getFeatures(editConfig,mapCrs,callback){var bbox=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var filter=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var filterGeom=arguments.length>5&&arguments[5]!==undefined?arguments[5]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/";var params={crs:mapCrs,bbox:bbox?bbox.join(","):undefined,filter:filter?JSON.stringify(filter):undefined,filter_geom:filterGeom?JSON.stringify(_objectSpread(_objectSpread({},filterGeom),{},{crs:{type:"name",properties:{name:mapCrs}}})):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){var _response$data2;if(!isEmpty(response===null||response===void 0||(_response$data2=response.data)===null||_response$data2===void 0?void 0:_response$data2.features)){var version=+new Date;var promises=response.data.features.map(function(feature){return new Promise(function(resolve){computeExpressionFields(editConfig,feature,EditingInterface,mapCrs,function(newfeature){return resolve(_objectSpread(_objectSpread({},newfeature),{},{__version__:version}))})})});Promise.all(promises).then(function(features){return callback({features:features})})}else{callback(null)}})["catch"](function(){return callback(null)})},/**
* Query the extent of the dataset features
* @param editConfig The edit config of the dataset to query features from
* @param mapCrs The CRS of the map, as an EPSG code
* @param callback Callback invoked with the feature extent, taking `{bbox: [xmin, ymin, xmax, ymax]}` on success and `null` on failure
* @param filter An optional feature attribute filter expression
* @param filterGeom An optional filter geometry
*/getExtent:function getExtent(editConfig,mapCrs,callback){var filter=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var filterGeom=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/extent";var params={crs:mapCrs,filter:filter?JSON.stringify(filter):undefined,filter_geom:filterGeom?JSON.stringify(_objectSpread(_objectSpread({},filterGeom),{},{crs:{type:"name",properties:{name:mapCrs}}})):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){callback(response.data)})["catch"](function(){callback(null)})},/**
* Adds a feature to the dataset
* @param editConfig The edit config of the dataset to add the feature to
* @param mapCrs The CRS of the map, as an EPSG code
* @param featureData A FormData instance, with:
* - A 'feature' entry containing the GeoJSON serialized feature
* - Zero or more 'file:' prefixed file upload entries
* - Zero or more 'relfile:' prefixed file upload entries
* - Optionally a 'g-recaptcha-response' entry with the captcha response
* @param callback Callback invoked with the added feature, taking `(true, {<feature>}` on success and `(false, <Error Message>}` on failure
*/addFeatureMultipart:function addFeatureMultipart(editConfig,mapCrs,featureData,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/multipart";var headers={"Content-Type":"multipart/form-data","Accept-Language":LocaleUtils.lang()};axios.post(requestUrl,featureData,{headers:headers}).then(function(response){computeExpressionFields(editConfig,response.data,EditingInterface,mapCrs,function(newfeature){return callback(true,_objectSpread(_objectSpread({},newfeature),{},{__version__:+new Date}))})})["catch"](function(err){callback(false,EditingInterface.buildErrMsg(err))})},/**
* Edits a feature of the dataset
* @param editConfig The edit config of the edited dataset
* @param mapCrs The CRS of the map, as an EPSG code
* @param featureId The ID of the edited feature
* @param featureData A FormData instance, with:
* - A 'feature' entry containing the GeoJSON serialized feature
* - Zero or more 'file:' prefixed file upload entries
* - Zero or more 'relfile:' prefixed file upload entries
* - Optionally a 'g-recaptcha-response' entry with the captcha response
* @param callback Callback invoked with the edited feature, taking `(true, {<feature>}` on success and `(false, <Error Message>}` on failure
*/editFeatureMultipart:function editFeatureMultipart(editConfig,mapCrs,featureId,featureData,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/multipart/"+featureId;var headers={"Content-Type":"multipart/form-data","Accept-Language":LocaleUtils.lang()};axios.put(requestUrl,featureData,{headers:headers}).then(function(response){computeExpressionFields(editConfig,response.data,EditingInterface,mapCrs,function(newfeature){return callback(true,_objectSpread(_objectSpread({},newfeature),{},{__version__:+new Date}))})})["catch"](function(err){callback(false,EditingInterface.buildErrMsg(err))})},/*
layerId: The edit layer id
featureId: The id of the feature to delete
callback: function(success, result), if success = true, result is null, if success = false, result is an error message
recaptchaResponse: Optional, captcha challenge response
*//**
* Deletes a feature from the dataset
* @param editConfig The edit config of the dataset from which to delete the feature
* @param featureId The ID of the edited feature
* @param callback Callback invoked with the id of the deleted feature, taking `(true, <feature_id>` on success and `(false, <Error Message>}` on failure
* @param recaptchaResponse Optional captcha challenge response
*/deleteFeature:function deleteFeature(editConfig,featureId,callback){var recaptchaResponse=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var req=editServiceUrl+"/"+editConfig.editDataset+"/"+featureId;var headers={"Accept-Language":LocaleUtils.lang()};var data={};if(recaptchaResponse){data["g-recaptcha-response"]=recaptchaResponse}axios["delete"](req,{headers:headers,data:data}).then(function(){callback(true,featureId)})["catch"](function(err){callback(false,EditingInterface.buildErrMsg(err))})},/**
* Queries relation values of a feature
* @param editConfig The edit config of the feature dataset
* @param featureId The feature ID
* @param mapCrs The CRS of the map, as an EPSG code
* @param tables Comma separated string of relation table names
* @param editConfigs The theme editConfig block, containing all theme dataset edit configs
* @param callback Callback invoked with the relation values, taking `{<tablename>: {<relation_values>}}` on success and `{}` on failure
*/getRelations:function getRelations(editConfig,featureId,mapCrs,tables,editConfigs,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var req=editServiceUrl+"/"+editConfig.editDataset+"/"+featureId+"/relations";var params={tables:tables,crs:mapCrs};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(req,{headers:headers,params:params}).then(function(response){Promise.all(Object.entries(response.data).map(function(_ref){var _ref2=_slicedToArray(_ref,2),reldataset=_ref2[0],relvalues=_ref2[1];return new Promise(function(resolveTable){Promise.all(relvalues.features.map(function(feature){return new Promise(function(resolveFeature){var relEditConfig=Object.values(editConfigs).find(function(entry){return entry.editDataset===reldataset});computeExpressionFields(relEditConfig,feature,EditingInterface,mapCrs,resolveFeature)})})).then(function(newfeatures){return resolveTable([reldataset,_objectSpread(_objectSpread({},relvalues),{},{features:newfeatures})])})})})).then(function(entries){return callback(Object.fromEntries(entries))})})["catch"](function(){return callback({})})},/**
* Query key-value-pairs of a key-value-relation
* @param keyvalues The keyval string `<keyvaldataset>:<keyfield>:<valuefield>`
* @param callback Callback invoked with the key-value pairs, taking `{keyvalues: {<keyvaldataset>: [{key: <key>, value: <value>}]}}` on success and `{}` on failure
* @param filter An optional filter expression, as `[[["<name>", "<op>", <value>],"and|or",["<name>","<op>",<value>],...]]` (one filter expr per keyvalue entry)
*/getKeyValues:function getKeyValues(keyvalues,callback){var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var req=editServiceUrl+"/"+"keyvals?tables="+keyvalues;var params={filter:filter?JSON.stringify(filter):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(req,{headers:headers,params:params}).then(function(response){callback(response.data)})["catch"](function(){return callback({})})},/**
* Resolve an attachment value to a full URL
*
* @param dataset The dataset name
* @param fileValue The attachment value
*/resolveAttachmentUrl:function resolveAttachmentUrl(dataset,fileValue){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");return editServiceUrl+"/"+dataset+"/attachment?file="+encodeURIComponent(fileValue)}};export default EditingInterface;