User coordinates during drawing

This commit is contained in:
Tim Schaub
2019-09-26 19:29:19 +02:00
parent e0d24d3af0
commit 3c7b129106
4 changed files with 53 additions and 19 deletions
+4
View File
@@ -9,3 +9,7 @@ docs: >
tags: "geographic" tags: "geographic"
--- ---
<div id="map" class="map"></div> <div id="map" class="map"></div>
<select id="mode">
<option value="modify">select a feature to modify</option>
<option value="draw">draw new features</option>
</select>
+35 -9
View File
@@ -1,17 +1,15 @@
import {Map, View} from '../src/ol/index.js'; import {Map, View} from '../src/ol/index.js';
import GeoJSON from '../src/ol/format/GeoJSON.js'; import GeoJSON from '../src/ol/format/GeoJSON.js';
import {Modify, Select} from '../src/ol/interaction.js'; import {Modify, Select, Draw} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js';
import {useGeographic} from '../src/ol/proj.js'; import {useGeographic} from '../src/ol/proj.js';
useGeographic(); useGeographic();
const vector = new VectorLayer({ const source = new VectorSource({
source: new VectorSource({ url: 'data/geojson/countries.geojson',
url: 'data/geojson/countries.geojson', format: new GeoJSON()
format: new GeoJSON()
})
}); });
const map = new Map({ const map = new Map({
@@ -20,7 +18,9 @@ const map = new Map({
new TileLayer({ new TileLayer({
source: new OSM() source: new OSM()
}), }),
vector new VectorLayer({
source: source
})
], ],
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
@@ -29,9 +29,35 @@ const map = new Map({
}); });
const select = new Select(); const select = new Select();
map.addInteraction(select);
const modify = new Modify({ const modify = new Modify({
features: select.getFeatures() features: select.getFeatures()
}); });
map.addInteraction(modify);
const draw = new Draw({
type: 'Polygon',
source: source
});
const mode = document.getElementById('mode');
function onChange() {
switch (mode.value) {
case 'draw': {
map.removeInteraction(modify);
map.removeInteraction(select);
map.addInteraction(draw);
break;
}
case 'modify': {
map.removeInteraction(draw);
map.addInteraction(select);
map.addInteraction(modify);
break;
}
default: {
// pass
}
}
}
mode.addEventListener('change', onChange);
onChange();
+3 -5
View File
@@ -417,8 +417,7 @@ class Draw extends PointerInteraction {
useSpatialIndex: false, useSpatialIndex: false,
wrapX: options.wrapX ? options.wrapX : false wrapX: options.wrapX ? options.wrapX : false
}), }),
style: options.style ? options.style : style: options.style ? options.style : getDefaultStyleFunction(),
getDefaultStyleFunction(),
updateWhileInteracting: true updateWhileInteracting: true
}); });
@@ -443,8 +442,7 @@ class Draw extends PointerInteraction {
if (options.freehand) { if (options.freehand) {
this.freehandCondition_ = always; this.freehandCondition_ = always;
} else { } else {
this.freehandCondition_ = options.freehandCondition ? this.freehandCondition_ = options.freehandCondition ? options.freehandCondition : shiftKeyOnly;
options.freehandCondition : shiftKeyOnly;
} }
this.addEventListener(getChangeEventType(InteractionProperty.ACTIVE), this.updateState_); this.addEventListener(getChangeEventType(InteractionProperty.ACTIVE), this.updateState_);
@@ -639,7 +637,7 @@ class Draw extends PointerInteraction {
const map = event.map; const map = event.map;
for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) { for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) {
const finishCoordinate = potentiallyFinishCoordinates[i]; const finishCoordinate = potentiallyFinishCoordinates[i];
const finishPixel = map.getPixelFromCoordinateInternal(finishCoordinate); const finishPixel = map.getPixelFromCoordinate(finishCoordinate);
const pixel = event.pixel; const pixel = event.pixel;
const dx = pixel[0] - finishPixel[0]; const dx = pixel[0] - finishPixel[0];
const dy = pixel[1] - finishPixel[1]; const dy = pixel[1] - finishPixel[1];
+11 -5
View File
@@ -20,7 +20,7 @@ import VectorSource from '../source/Vector.js';
import VectorEventType from '../source/VectorEventType.js'; import VectorEventType from '../source/VectorEventType.js';
import RBush from '../structs/RBush.js'; import RBush from '../structs/RBush.js';
import {createEditingStyle} from '../style/Style.js'; import {createEditingStyle} from '../style/Style.js';
import {fromUserExtent, toUserExtent} from '../proj.js'; import {fromUserExtent, toUserExtent, fromUserCoordinate, toUserCoordinate} from '../proj.js';
/** /**
@@ -38,6 +38,7 @@ const CIRCLE_CENTER_INDEX = 0;
const CIRCLE_CIRCUMFERENCE_INDEX = 1; const CIRCLE_CIRCUMFERENCE_INDEX = 1;
const tempExtent = [0, 0, 0, 0]; const tempExtent = [0, 0, 0, 0];
const tempSegment = [];
/** /**
* @enum {string} * @enum {string}
@@ -808,6 +809,7 @@ class Modify extends PointerInteraction {
this.modified_ = false; this.modified_ = false;
const vertexFeature = this.vertexFeature_; const vertexFeature = this.vertexFeature_;
if (vertexFeature) { if (vertexFeature) {
const projection = evt.map.getView().getProjection();
const insertVertices = []; const insertVertices = [];
const vertex = vertexFeature.getGeometry().getCoordinates(); const vertex = vertexFeature.getGeometry().getCoordinates();
const vertexExtent = boundingExtent([vertex]); const vertexExtent = boundingExtent([vertex]);
@@ -827,7 +829,7 @@ class Modify extends PointerInteraction {
} }
if (segmentDataMatch.geometry.getType() === GeometryType.CIRCLE && segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX) { if (segmentDataMatch.geometry.getType() === GeometryType.CIRCLE && segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX) {
const closestVertex = closestOnSegmentData(pixelCoordinate, segmentDataMatch); const closestVertex = closestOnSegmentData(pixelCoordinate, segmentDataMatch, projection);
if (coordinatesEqual(closestVertex, vertex) && !componentSegments[uid][0]) { if (coordinatesEqual(closestVertex, vertex) && !componentSegments[uid][0]) {
this.dragSegments_.push([segmentDataMatch, 0]); this.dragSegments_.push([segmentDataMatch, 0]);
componentSegments[uid][0] = segmentDataMatch; componentSegments[uid][0] = segmentDataMatch;
@@ -934,7 +936,7 @@ class Modify extends PointerInteraction {
nodes.sort(sortByDistance); nodes.sort(sortByDistance);
const node = nodes[0]; const node = nodes[0];
const closestSegment = node.segment; const closestSegment = node.segment;
let vertex = closestOnSegmentData(pixelCoordinate, node); let vertex = closestOnSegmentData(pixelCoordinate, node, projection);
const vertexPixel = map.getPixelFromCoordinate(vertex); const vertexPixel = map.getPixelFromCoordinate(vertex);
let dist = coordinateDistance(pixel, vertexPixel); let dist = coordinateDistance(pixel, vertexPixel);
if (dist <= this.pixelTolerance_) { if (dist <= this.pixelTolerance_) {
@@ -1259,15 +1261,19 @@ function pointDistanceToSegmentDataSquared(pointCoordinates, segmentData) {
* should be found. * should be found.
* @param {SegmentData} segmentData The object describing the line * @param {SegmentData} segmentData The object describing the line
* segment which should contain the closest point. * segment which should contain the closest point.
* @param {import("../proj/Projection.js").default} projection The view projection.
* @return {import("../coordinate.js").Coordinate} The point closest to the specified line segment. * @return {import("../coordinate.js").Coordinate} The point closest to the specified line segment.
*/ */
function closestOnSegmentData(pointCoordinates, segmentData) { function closestOnSegmentData(pointCoordinates, segmentData, projection) {
const geometry = segmentData.geometry; const geometry = segmentData.geometry;
if (geometry.getType() === GeometryType.CIRCLE && segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX) { if (geometry.getType() === GeometryType.CIRCLE && segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX) {
return geometry.getClosestPoint(pointCoordinates); return geometry.getClosestPoint(pointCoordinates);
} }
return closestOnSegment(pointCoordinates, segmentData.segment); const coordinate = fromUserCoordinate(pointCoordinates, projection);
tempSegment[0] = fromUserCoordinate(segmentData.segment[0], projection);
tempSegment[1] = fromUserCoordinate(segmentData.segment[1], projection);
return toUserCoordinate(closestOnSegment(coordinate, tempSegment), projection);
} }