Destroyed Vector Editing (markdown)

Tim Schaub
2017-09-25 23:28:53 -07:00
parent 1d47869a6f
commit 74817fb524
-91
@@ -1,91 +0,0 @@
**Outdated!**
Assumptions:
* User created vector layers may have many thousands of features. During editing, it will be more efficient to frequently re-render a sketch layer with a subset of features involved in editing.
* Users will want to edit features associated with raster layers (e.g. a WMS layer with an associated WFS feature type, or a XYZ layer paired with a RESTful feature service).
* A single control may work on touch and non-touch devices, but the optimal touch editing workflow will likely require a dedicated control.
## Controls
### `ol.control.Select`
When active, this control allows users to select features by clicking or dragging (select in a box). Should allow addition to the current selection (shift-click, shift-drag), removal from the current selection (alt-click, alt-drag), and clearing of the current selection (click or drag outside a feature). Selected features are (generally) rendered with a different style than unselected features.
The control should be configurable with an array of layers. The control should create an anchor/button element for toggling activation.
#### Implementation
When activated, the control creates a new vector layer. This layer should have a property (e.g. `temp`) that indicates that it is temporary (so it will not be shown in things like a layer switcher).
When the user clicks or drags, the control calls `readFeatures` on all configured layers' sources (see below for `readFeatures` discussion). The provided callbacks will be called with selected features (per layer).
For configured vector layers with selected features, the control calls `setRenderIntent('hidden', features)`. This signals to the layer that it should be re-rendered without the selected features.
All selected features are then added to the sketch layer (created by the control), and the control calls `setRenderIntent('selected', features)`. When the user unselects features, the control removes selected features from the sketch layer and calls `setRenderIntent('default', features)` on the original layer.
### `ol.control.Edit`
The edit control has all of the behavior described above for the select control. In addition it allows for the modification and deletion of existing features and the creation of new features.
In addition to the activation toggle, the control should create anchor/button elements for setting insert point, insert line, insert polygon, or delete feature mode. The control should also create elements for cancel (undo) and save. The user should be able to configure which of the insert modes are supported.
#### Implementation
The edit control extends the select control. When selected features are added to the sketch layer, new features are created for each vertex in each selected feature and added with `setRenderIntent('hidden', features)`. An additional point feature is created (to support vertex insertion) and added with `setRenderIntent('hidden', [feature])`.
**Update Mode**
The default for the control is update mode. On mouse devices, with each mouse move, vertices near the pointer are found and rendered with `setRenderIntent('temporary', features)` (after first setting all to 'hidden'). When the pointer approaches an edge, a "ghost" vertex should be rendered along the edge. (We need to decide on the rendering intent - maybe `'future'`? It is also important that the ghost vertex not be rendered too close to any other vertex to clearly separate vertex insertion from vertex modification).
Dragging a temporary vertex edits the associated feature's geometry. Mouse down on a ghost vertex inserts the vertex (at the mouse position, which may be different than the rendered position). The user should be able to delete a vertex by hovering and pressing a key (e.g. `d`).
**Insert Point, Line, and Polygon Modes**
When the control is in insert mode, a vertex is rendered under the pointer (`'temporary'` intent). Click creates a new geometry. For lines and polygons, new vertex creation continues with each click and double-click finishes the feature. When a feature is complete, the control changes back to update mode. Since this might be annoying for inserting large numbers of features, there could be an option for insert mode to be sticky. If insert mode is sticky, the user has to "unpress" the insert anchor/button (alternatively there could be yet another button created for update mode, but it would be nice to avoid this).
**Delete Mode**
In delete mode, a click deletes a feature. A cautious default behavior would be to have the control return to update mode after deleting a feature. As above, there could be a sticky delete. But this requires another action to unstick.
**Cancel/Save**
To complete editing, the user clicks on the cancel or save button. The cancel button removes all features from the sketch layer and calls `setRenderIntent('default', features)` with the originally selected features (NEEDS DISCUSSION: this suggests that `setRenderIntent` either a) work with feature id, b) interpret undefined as second arg to mean all features, c) be handled in some other way). The cancel operation essentially undoes all edits that have not been saved.
When the user clicks the save button, this persists all changes. It should be possible to configure the control with a `beforeSave` function. This function would take a callback that, when called, would trigger a save. This would allow an application to do something like get a commit message from the user, do just-in-time authentication, or anything else async. To save, the control calls `writeFeatures` on the source (name up for discussion, see below for more). The `writeFeatures` method takes a callback. If the call to the callback indicates success, the control calls `setRenderIntent('default', features)` with originally selected features (more discussion needed here, see above.
## Sources
If all sources (raster and vector) could have `readFeatures` and `writeFeatures` methods, this would support editing across multiple layer types with the same editing control. This needs more discussion.
```js
/**
* Read features.
* @param {Object} options Options for reading (e.g. coordinate, bbox)
* @param {function(Error, Array.<ol.Feature>)} callback Called with an error on
* failure. Called with null and an array of features on success.
*/
ol.source.Source.readFeatures = function(options, callback) {
// default implementation
setTimeout(function() {
callback(null, []);
}, 0);
};
/**
* Write features.
* @param {Object} transaction Transaction object with insert, update, and
* delete properties. The delete property value is an array of fid. Others
* are arrays of features. The transaction object might have additional
* metadata (e.g. message).
* @param {function(Error, opt_inserts)} callback Called with an error on
* failure. Called with null as first arg on success. If the transaction
* included inserts, the second arg will be an array of fid.
*/
ol.source.Source.writeFeatures = function(transaction, callback) {
// default implementation
setTimeout(function() {
callback(new Error('writeFeatures method is not supported by this source'));
}, 0);
};
```