Hello All,
How to configure Edit Widget (Web AppBuilder 1.3v) to add a feature only if it falls in a particular boundary.
Please let me know how to achieve this by configuration or editing code.
Appreciate your support on this.
Regards,
Krish
Solved! Go to Solution.
Krish,
OK, I did a lot more testing this time with multiple geometry types and I found several issues that I have now addressed.
Here is the updated code:
I needed to add another require (for Point):
define([ 'dojo/_base/declare', 'dojo/_base/lang', 'dojo/_base/array', 'dojo/_base/html', 'dojo/i18n!esri/nls/jsapi', 'dojo/on', 'dijit/_WidgetsInTemplateMixin', 'jimu/BaseWidget', 'jimu/MapManager', 'jimu/LayerInfos/LayerInfos', 'esri/dijit/editing/Editor', 'esri/dijit/Popup', "esri/dijit/editing/TemplatePicker", "dijit/form/Button", "./utils", "esri/geometry/Extent", "esri/SpatialReference", "dojo/Deferred", "jimu/dijit/Message", "esri/geometry/Point" ], function(declare, lang, array, html, esriBundle, on, _WidgetsInTemplateMixin, BaseWidget, MapManager, LayerInfos, Editor, Popup, TemplatePicker, Button, editUtils, Extent, SpatialReference, Deferred, Message, Point) {
And here is the updated function:
_worksAfterCreate: function() { // add close button to atiInspector this._addButtonToInspector(); // resize editPopup this.editPopup.resize(500, 251); // update templatePicker for responsive. this.editor.templatePicker.update(); //just for BoxTheme setTimeout(lang.hitch(this, this._update), 900); // // reset default selectionSymbol that change by Editor dijit. // array.forEach(this.editor.settings.layerInfos, function(layerInfo) { // layerInfo.featureLayer.setSelectionSymbol(); // }, this); var poly, ext, j, mp, isOutside; this.editor.templatePicker.on('selection-change', lang.hitch(this,function(){ var selected = this.editor.templatePicker.getSelected(); if (selected) { if(this.selfeatureLayer !== selected.featureLayer){ if(this.selfeatureLayer && this.selfeatureLayer.myApplyEdits){ this.selfeatureLayer.applyEdits = this.selfeatureLayer.myApplyEdits; } this.selfeatureLayer = selected.featureLayer; // saving the default method for later use this.selfeatureLayer.myApplyEdits = this.selfeatureLayer.applyEdits; // override with dummy function this.selfeatureLayer.applyEdits = lang.hitch(this, function(adds, updates, deletes, callback, errback) { // create and returns Deferred to Editor still working var deferred = new Deferred(); // simulate async execution (.then() callback) setTimeout(lang.hitch(this, function() { if(adds && adds.length > 0){ if(adds[0].geometry.type !== "point"){ switch(adds[0].geometry.type){ case 'polyline': isOutside = false; var polyl = adds[0].geometry; for (var l = polyl.paths.length - 1; l >= 0; l--) { for (j = 0; j < polyl.paths.length; j++) { mp = polyl.getPoint(l, j); if(!this.myAlowedExtent.contains(mp)){ isOutside = true; break; } } } if(!isOutside){ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } else { this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } break; case 'polygon': isOutside = false; poly = adds[0].geometry; for (var i2 = poly.rings.length - 1; i2 >= 0; i2--) { for (var j1 = 0; j1 < poly.rings[i2].length; j1++) { mp = poly.getPoint(i2, j1); if(!this.myAlowedExtent.contains(mp)){ isOutside = true; break; } } // if(isOutside){ // break; // } } if(!isOutside){ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } else { this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } break; case 'extent': isOutside = false; ext = adds[0].geometry; var cext = [[ext.xmax, ext.ymax], [ext.xmax, ext.ymin], [ext.xmin, ext.ymin],[ext.xmin, ext.ymax]]; for (var e1 = 0; e1 < cext.length; e1++) { mp = new Point(cext[e1], ext.spatialReference); if(!this.myAlowedExtent.contains(mp)){ isOutside = true; break; } } if(!isOutside){ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } else { this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } break; } }else{ if(!this.myAlowedExtent.contains(adds[0].geometry)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } } }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } deferred.resolve(true); }), 100); return deferred; }); } } })); },
Krish,
Can you explain your desired workflow a little better?
Thanks for your response.
Please find the below screenshot for your reference:
As shown in above screenshot, user should be able to capture only in Area of Interest using Edit Widget.
When user tries to capture in Red Zone, user should get some warning message and shouldn't allow the user to capture in red zone.
Hope my question is clear now.
Please let me know how to achieve this by code or any configuration in Edit Widget. I'm using WAB 1.3.
Your support is much appreciated.!
Regards,
Krish
Krishna,
This took some work.
In the edit widgets Widget.js here are the modifications needed:
Add new requires and parameters (line 1, 18 - 21, 25):
/*global define, console, window, setTimeout*/ define([ 'dojo/_base/declare', 'dojo/_base/lang', 'dojo/_base/array', 'dojo/_base/html', 'dojo/i18n!esri/nls/jsapi', 'dojo/on', 'dijit/_WidgetsInTemplateMixin', 'jimu/BaseWidget', 'jimu/MapManager', 'jimu/LayerInfos/LayerInfos', 'esri/dijit/editing/Editor', 'esri/dijit/Popup', "esri/dijit/editing/TemplatePicker", "dijit/form/Button", "./utils", "esri/geometry/Extent", "esri/SpatialReference", "dojo/Deferred", "jimu/dijit/Message" ], function(declare, lang, array, html, esriBundle, on, _WidgetsInTemplateMixin, BaseWidget, MapManager, LayerInfos, Editor, Popup, TemplatePicker, Button, editUtils, Extent, SpatialReference, Deferred, Message) {
You need to add your allowed editing extent (I put this right above the _worksAfterCreate function):
myAlowedExtent: new Extent(-9575200,3981650,-9562900,3989570, new SpatialReference({ wkid:102100 })),
Next edit the _worksAfterCreate function (lines 14 - 46):
_worksAfterCreate: function() { // add close button to atiInspector this._addButtonToInspector(); // resize editPopup this.editPopup.resize(500, 251); // update templatePicker for responsive. this.editor.templatePicker.update(); //just for BoxTheme setTimeout(lang.hitch(this, this._update), 900); // // reset default selectionSymbol that change by Editor dijit. // array.forEach(this.editor.settings.layerInfos, function(layerInfo) { // layerInfo.featureLayer.setSelectionSymbol(); // }, this); this.editor.templatePicker.on('selection-change', lang.hitch(this,function(){ var selected = this.editor.templatePicker.getSelected(); if (selected) { if(this.selfeatureLayer !== selected.featureLayer){ this.selfeatureLayer = selected.featureLayer; // saving the default method for later use this.selfeatureLayer.myApplyEdits = this.selfeatureLayer.applyEdits; // override with dummy function this.selfeatureLayer.applyEdits = lang.hitch(this, function(adds, updates, deletes, callback, errback) { // create and returns Deferred to Editor still working var deferred = new Deferred(); // simulate async execution (.then() callback) setTimeout(lang.hitch(this, function() { if(adds && adds.length > 0){ if(!this.myAlowedExtent.contains(adds[0].geometry)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } deferred.resolve(true); }), 100); return deferred; }); } } })); },
Hi Robert,
Thanks for your time for helping me on this.
I have edited code as suggested and I have observed that Edit Widget is not allowing polygons to be added inside the extent and getting Message "Can Not Add Feature".
For myAlowedExtent, I have used as below..
Example:
new Polygon({"rings": [[[456891.299023729, 3314213.43369951],
[1106254.84054385, 3330754.54613897],
[1127994.04876981, 2910647.36018221],
[455355.318132059, 2895508.2708336],
[456891.299023729, 3314213.43369951]]], "spatialReference": { "wkid": 102100 }
}),
Please find the below screenshot which shows my AOI highlighted with Blue Color.
First it is allowing to add Point Feature inside the ring but when I'm trying to capture Polygon, I'm getting message "Can Not Add Feature". After this message, I'm unable to add Point Features also. Request you to review and suggest.
Thanks for your Support!!
Regards,
Krish
Krish,
I only tested with points. So it took some more code to handle other geometry types:
_worksAfterCreate: function() { // add close button to atiInspector this._addButtonToInspector(); // resize editPopup this.editPopup.resize(500, 251); // update templatePicker for responsive. this.editor.templatePicker.update(); //just for BoxTheme setTimeout(lang.hitch(this, this._update), 900); // // reset default selectionSymbol that change by Editor dijit. // array.forEach(this.editor.settings.layerInfos, function(layerInfo) { // layerInfo.featureLayer.setSelectionSymbol(); // }, this); var poly, ext, j, mp; this.editor.templatePicker.on('selection-change', lang.hitch(this,function(){ var selected = this.editor.templatePicker.getSelected(); if (selected) { if(this.selfeatureLayer !== selected.featureLayer){ this.selfeatureLayer = selected.featureLayer; // saving the default method for later use this.selfeatureLayer.myApplyEdits = this.selfeatureLayer.applyEdits; // override with dummy function this.selfeatureLayer.applyEdits = lang.hitch(this, function(adds, updates, deletes, callback, errback) { // create and returns Deferred to Editor still working var deferred = new Deferred(); // simulate async execution (.then() callback) setTimeout(lang.hitch(this, function() { if(adds && adds.length > 0){ if(adds[0].geometry.type !== "point"){ switch(adds[0].geometry.type){ case 'polyline': var polyl = adds[0].geometry; for (var l = polyl.paths.length - 1; l >= 0; l--) { for (j = 0; j < polyl.paths.length; j++) { mp = polyl.getPoint(l, j); if(!this.myAlowedExtent.contains(mp)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } } } this.selfeatureLayer.myApplyEdits(adds, updates, deletes); break; case 'polygon': poly = adds[0].geometry; for (var i2 = poly.rings.length - 1; i2 >= 0; i2--) { for (var j1 = 0; j1 < poly.rings[i2][1].length; j1++) { var mp2 = poly.getPoint(i2, j1); if(!this.myAlowedExtent.contains(mp2)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } } } this.selfeatureLayer.myApplyEdits(adds, updates, deletes); break; case 'extent': ext = adds[0].geometry; var cext = [[ext.xmax, ext.ymax], [ext.xmax, ext.ymin], [ext.xmin, ext.ymin],[ext.xmin, ext.ymax]]; for (var e1 = 0; e1 < cext.length; e1++) { var mp3 = new Point(cext[e1], ext.spatialReference); if(!this.myAlowedExtent.contains(mp3)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } } this.selfeatureLayer.myApplyEdits(adds, updates, deletes); break; } }else{ if(!this.myAlowedExtent.contains(adds[0].geometry)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } } }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } deferred.resolve(true); }), 100); return deferred; }); } } })); },
Hi Robert,
Thanks again for your time..
I have done the necessary changes as suggested by you. Now, Edit widget is allowing all types of geometry to be captured but have found two issues:
1. Edit Widget is unable to capture features when I switch from point to polygon and then to point. (After switching from point layer to polygon layer 3 times, Edit widget is unable to capture both point & polygon features).
2. When polygon drawn outside the extent, there is pop up but polygon is not getting deleted.
Request you to review and suggest how to proceed.
Regards,
Krish
Krish,
OK, I did a lot more testing this time with multiple geometry types and I found several issues that I have now addressed.
Here is the updated code:
I needed to add another require (for Point):
define([ 'dojo/_base/declare', 'dojo/_base/lang', 'dojo/_base/array', 'dojo/_base/html', 'dojo/i18n!esri/nls/jsapi', 'dojo/on', 'dijit/_WidgetsInTemplateMixin', 'jimu/BaseWidget', 'jimu/MapManager', 'jimu/LayerInfos/LayerInfos', 'esri/dijit/editing/Editor', 'esri/dijit/Popup', "esri/dijit/editing/TemplatePicker", "dijit/form/Button", "./utils", "esri/geometry/Extent", "esri/SpatialReference", "dojo/Deferred", "jimu/dijit/Message", "esri/geometry/Point" ], function(declare, lang, array, html, esriBundle, on, _WidgetsInTemplateMixin, BaseWidget, MapManager, LayerInfos, Editor, Popup, TemplatePicker, Button, editUtils, Extent, SpatialReference, Deferred, Message, Point) {
And here is the updated function:
_worksAfterCreate: function() { // add close button to atiInspector this._addButtonToInspector(); // resize editPopup this.editPopup.resize(500, 251); // update templatePicker for responsive. this.editor.templatePicker.update(); //just for BoxTheme setTimeout(lang.hitch(this, this._update), 900); // // reset default selectionSymbol that change by Editor dijit. // array.forEach(this.editor.settings.layerInfos, function(layerInfo) { // layerInfo.featureLayer.setSelectionSymbol(); // }, this); var poly, ext, j, mp, isOutside; this.editor.templatePicker.on('selection-change', lang.hitch(this,function(){ var selected = this.editor.templatePicker.getSelected(); if (selected) { if(this.selfeatureLayer !== selected.featureLayer){ if(this.selfeatureLayer && this.selfeatureLayer.myApplyEdits){ this.selfeatureLayer.applyEdits = this.selfeatureLayer.myApplyEdits; } this.selfeatureLayer = selected.featureLayer; // saving the default method for later use this.selfeatureLayer.myApplyEdits = this.selfeatureLayer.applyEdits; // override with dummy function this.selfeatureLayer.applyEdits = lang.hitch(this, function(adds, updates, deletes, callback, errback) { // create and returns Deferred to Editor still working var deferred = new Deferred(); // simulate async execution (.then() callback) setTimeout(lang.hitch(this, function() { if(adds && adds.length > 0){ if(adds[0].geometry.type !== "point"){ switch(adds[0].geometry.type){ case 'polyline': isOutside = false; var polyl = adds[0].geometry; for (var l = polyl.paths.length - 1; l >= 0; l--) { for (j = 0; j < polyl.paths.length; j++) { mp = polyl.getPoint(l, j); if(!this.myAlowedExtent.contains(mp)){ isOutside = true; break; } } } if(!isOutside){ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } else { this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } break; case 'polygon': isOutside = false; poly = adds[0].geometry; for (var i2 = poly.rings.length - 1; i2 >= 0; i2--) { for (var j1 = 0; j1 < poly.rings[i2].length; j1++) { mp = poly.getPoint(i2, j1); if(!this.myAlowedExtent.contains(mp)){ isOutside = true; break; } } // if(isOutside){ // break; // } } if(!isOutside){ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } else { this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } break; case 'extent': isOutside = false; ext = adds[0].geometry; var cext = [[ext.xmax, ext.ymax], [ext.xmax, ext.ymin], [ext.xmin, ext.ymin],[ext.xmin, ext.ymax]]; for (var e1 = 0; e1 < cext.length; e1++) { mp = new Point(cext[e1], ext.spatialReference); if(!this.myAlowedExtent.contains(mp)){ isOutside = true; break; } } if(!isOutside){ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } else { this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); } break; } }else{ if(!this.myAlowedExtent.contains(adds[0].geometry)){ this.selfeatureLayer.myApplyEdits(null, updates, deletes); new Message({ titleLabel: "Can Not Add Feature", message: "The feature you are trying to add is outside the allowed edit extent" }); }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } } }else{ this.selfeatureLayer.myApplyEdits(adds, updates, deletes); } deferred.resolve(true); }), 100); return deferred; }); } } })); },
Hi Robert,
Thanks a Million!!!!!!!
You are Genius..!
Regards,
Krish