Merge pull request #10340 from mike-000/patch-7

Draw circles and custom geometry in user coordinates
This commit is contained in:
Andreas Hocevar
2019-12-11 10:07:12 +01:00
committed by GitHub
2 changed files with 188 additions and 23 deletions

View File

@@ -24,6 +24,7 @@ import InteractionProperty from './Property.js';
import VectorLayer from '../layer/Vector.js';
import VectorSource from '../source/Vector.js';
import {createEditingStyle} from '../style/Style.js';
import {fromUserCoordinate, getUserProjection} from '../proj.js';
/**
@@ -104,11 +105,12 @@ import {createEditingStyle} from '../style/Style.js';
/**
* Function that takes an array of coordinates and an optional existing geometry as
* arguments, and returns a geometry. The optional existing geometry is the
* geometry that is returned when the function is called without a second
* argument.
* @typedef {function(!SketchCoordType, import("../geom/SimpleGeometry.js").default=):
* Function that takes an array of coordinates and an optional existing geometry
* and a projection as arguments, and returns a geometry. The optional existing
* geometry is the geometry that is returned when the function is called without
* a second argument.
* @typedef {function(!SketchCoordType, import("../geom/SimpleGeometry.js").default=,
* import("../proj/Projection.js").default):
* import("../geom/SimpleGeometry.js").default} GeometryFunction
*/
@@ -296,14 +298,20 @@ class Draw extends PointerInteraction {
/**
* @param {!LineCoordType} coordinates The coordinates.
* @param {import("../geom/SimpleGeometry.js").default=} opt_geometry Optional geometry.
* @param {import("../proj/Projection.js").default} projection The view projection.
* @return {import("../geom/SimpleGeometry.js").default} A geometry.
*/
geometryFunction = function(coordinates, opt_geometry) {
geometryFunction = function(coordinates, opt_geometry, projection) {
const circle = opt_geometry ? /** @type {Circle} */ (opt_geometry) :
new Circle([NaN, NaN]);
const center = fromUserCoordinate(coordinates[0], projection);
const squaredLength = squaredCoordinateDistance(
coordinates[0], coordinates[1]);
circle.setCenterAndRadius(coordinates[0], Math.sqrt(squaredLength));
center, fromUserCoordinate(coordinates[1], projection));
circle.setCenterAndRadius(center, Math.sqrt(squaredLength));
const userProjection = getUserProjection();
if (userProjection) {
circle.transform(projection, userProjection);
}
return circle;
};
} else {
@@ -319,9 +327,10 @@ class Draw extends PointerInteraction {
/**
* @param {!LineCoordType} coordinates The coordinates.
* @param {import("../geom/SimpleGeometry.js").default=} opt_geometry Optional geometry.
* @param {import("../proj/Projection.js").default} projection The view projection.
* @return {import("../geom/SimpleGeometry.js").default} A geometry.
*/
geometryFunction = function(coordinates, opt_geometry) {
geometryFunction = function(coordinates, opt_geometry, projection) {
let geometry = opt_geometry;
if (geometry) {
if (mode === Mode.POLYGON) {
@@ -675,6 +684,7 @@ class Draw extends PointerInteraction {
*/
startDrawing_(event) {
const start = event.coordinate;
const projection = event.map.getView().getProjection();
this.finishCoordinate_ = start;
if (this.mode_ === Mode.POINT) {
this.sketchCoords_ = start.slice();
@@ -688,7 +698,7 @@ class Draw extends PointerInteraction {
this.sketchLine_ = new Feature(
new LineString(this.sketchLineCoords_));
}
const geometry = this.geometryFunction_(this.sketchCoords_);
const geometry = this.geometryFunction_(this.sketchCoords_, undefined, projection);
this.sketchFeature_ = new Feature();
if (this.geometryName_) {
this.sketchFeature_.setGeometryName(this.geometryName_);
@@ -706,6 +716,7 @@ class Draw extends PointerInteraction {
modifyDrawing_(event) {
let coordinate = event.coordinate;
const geometry = this.sketchFeature_.getGeometry();
const projection = event.map.getView().getProjection();
let coordinates, last;
if (this.mode_ === Mode.POINT) {
last = this.sketchCoords_;
@@ -722,7 +733,7 @@ class Draw extends PointerInteraction {
}
last[0] = coordinate[0];
last[1] = coordinate[1];
this.geometryFunction_(/** @type {!LineCoordType} */ (this.sketchCoords_), geometry);
this.geometryFunction_(/** @type {!LineCoordType} */ (this.sketchCoords_), geometry, projection);
if (this.sketchPoint_) {
const sketchPointGeom = this.sketchPoint_.getGeometry();
sketchPointGeom.setCoordinates(coordinate);
@@ -759,6 +770,7 @@ class Draw extends PointerInteraction {
addToDrawing_(event) {
const coordinate = event.coordinate;
const geometry = this.sketchFeature_.getGeometry();
const projection = event.map.getView().getProjection();
let done;
let coordinates;
if (this.mode_ === Mode.LINE_STRING) {
@@ -772,7 +784,7 @@ class Draw extends PointerInteraction {
}
}
coordinates.push(coordinate.slice());
this.geometryFunction_(coordinates, geometry);
this.geometryFunction_(coordinates, geometry, projection);
} else if (this.mode_ === Mode.POLYGON) {
coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0];
if (coordinates.length >= this.maxPoints_) {
@@ -786,7 +798,7 @@ class Draw extends PointerInteraction {
if (done) {
this.finishCoordinate_ = coordinates[0];
}
this.geometryFunction_(this.sketchCoords_, geometry);
this.geometryFunction_(this.sketchCoords_, geometry, projection);
}
this.updateSketchFeatures_();
if (done) {
@@ -803,13 +815,14 @@ class Draw extends PointerInteraction {
return;
}
const geometry = this.sketchFeature_.getGeometry();
const projection = this.getMap().getView().getProjection();
let coordinates;
/** @type {LineString} */
let sketchLineGeom;
if (this.mode_ === Mode.LINE_STRING) {
coordinates = /** @type {LineCoordType} */ (this.sketchCoords_);
coordinates.splice(-2, 1);
this.geometryFunction_(coordinates, geometry);
this.geometryFunction_(coordinates, geometry, projection);
if (coordinates.length >= 2) {
this.finishCoordinate_ = coordinates[coordinates.length - 2].slice();
}
@@ -818,7 +831,7 @@ class Draw extends PointerInteraction {
coordinates.splice(-2, 1);
sketchLineGeom = this.sketchLine_.getGeometry();
sketchLineGeom.setCoordinates(coordinates);
this.geometryFunction_(this.sketchCoords_, geometry);
this.geometryFunction_(this.sketchCoords_, geometry, projection);
}
if (coordinates.length === 0) {
@@ -841,14 +854,15 @@ class Draw extends PointerInteraction {
}
let coordinates = this.sketchCoords_;
const geometry = sketchFeature.getGeometry();
const projection = this.getMap().getView().getProjection();
if (this.mode_ === Mode.LINE_STRING) {
// remove the redundant last point
coordinates.pop();
this.geometryFunction_(coordinates, geometry);
this.geometryFunction_(coordinates, geometry, projection);
} else if (this.mode_ === Mode.POLYGON) {
// remove the redundant last point in ring
/** @type {PolyCoordType} */ (coordinates)[0].pop();
this.geometryFunction_(coordinates, geometry);
this.geometryFunction_(coordinates, geometry, projection);
coordinates = geometry.getCoordinates();
}
@@ -966,9 +980,9 @@ function getDefaultStyleFunction() {
* @api
*/
export function createRegularPolygon(opt_sides, opt_angle) {
return function(coordinates, opt_geometry) {
const center = /** @type {LineCoordType} */ (coordinates)[0];
const end = /** @type {LineCoordType} */ (coordinates)[1];
return function(coordinates, opt_geometry, projection) {
const center = fromUserCoordinate(/** @type {LineCoordType} */ (coordinates)[0], projection);
const end = fromUserCoordinate(/** @type {LineCoordType} */ (coordinates)[1], projection);
const radius = Math.sqrt(
squaredCoordinateDistance(center, end));
const geometry = opt_geometry ? /** @type {Polygon} */ (opt_geometry) :
@@ -980,6 +994,10 @@ export function createRegularPolygon(opt_sides, opt_angle) {
angle = Math.atan(y / x) - (x < 0 ? Math.PI : 0);
}
makeRegular(geometry, center, radius, angle);
const userProjection = getUserProjection();
if (userProjection) {
geometry.transform(projection, userProjection);
}
return geometry;
};
}
@@ -994,8 +1012,10 @@ export function createRegularPolygon(opt_sides, opt_angle) {
*/
export function createBox() {
return (
function(coordinates, opt_geometry) {
const extent = boundingExtent(/** @type {LineCoordType} */ (coordinates));
function(coordinates, opt_geometry, projection) {
const extent = boundingExtent(/** @type {LineCoordType} */ (coordinates).map(function(coordinate) {
return fromUserCoordinate(coordinate, projection);
}));
const boxCoordinates = [[
getBottomLeft(extent),
getBottomRight(extent),
@@ -1009,6 +1029,10 @@ export function createBox() {
} else {
geometry = new Polygon(boxCoordinates);
}
const userProjection = getUserProjection();
if (userProjection) {
geometry.transform(projection, userProjection);
}
return geometry;
}
);