qwc2
Version:
QGIS Web Client
625 lines (603 loc) • 32.8 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 _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 _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread 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 _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
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 _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, 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 2024 Stadtwerke München GmbH
* 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.
*/
import React from 'react';
import isEqual from 'lodash.isequal';
import ol from 'openlayers';
import PropTypes from 'prop-types';
import rotateCursor from '../resources/rotate.svg';
import FeatureStyles from '../utils/FeatureStyles';
import MapUtils from '../utils/MapUtils';
var PrintSelection = /*#__PURE__*/function (_React$Component) {
function PrintSelection(props) {
var _this$map$getView$get;
var _this;
_classCallCheck(this, PrintSelection);
_this = _callSuper(this, PrintSelection, [props]);
_defineProperty(_this, "setViewportCursor", function (ev) {
if (_this.isInteracting) {
return;
}
var overFeature = _this.map.getFeaturesAtPixel(ev.pixel, {
hitTolerance: 20,
layerFilter: function layerFilter(layer) {
return layer === _this.selectionLayer;
}
}).includes(_this.feature);
if (!overFeature) {
_this.map.getViewport().style.cursor = '';
return;
}
var sqdist = function sqdist(p, q) {
return (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]);
};
var getPixelFromCoordinate = MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);
var topright = getPixelFromCoordinate(_this.feature.getGeometry().getCoordinates()[0][0], false);
var bottomright = getPixelFromCoordinate(_this.feature.getGeometry().getCoordinates()[0][1], false);
var bottomleft = getPixelFromCoordinate(_this.feature.getGeometry().getCoordinates()[0][2], false);
var topleft = getPixelFromCoordinate(_this.feature.getGeometry().getCoordinates()[0][3], false);
if (sqdist(ev.pixel, topright) < 400) {
_this.map.getViewport().style.cursor = 'nesw-resize';
} else if (sqdist(ev.pixel, bottomright) < 400) {
_this.map.getViewport().style.cursor = "url(".concat(rotateCursor, ") 12 12, auto");
} else if (sqdist(ev.pixel, bottomleft) < 400) {
_this.map.getViewport().style.cursor = 'nesw-resize';
} else if (sqdist(ev.pixel, topleft) < 400) {
_this.map.getViewport().style.cursor = 'nwse-resize';
} else {
_this.map.getViewport().style.cursor = '';
}
});
_defineProperty(_this, "getGeometry", function () {
var modifyGeometry = _this.feature.get('modifyGeometry');
return modifyGeometry ? modifyGeometry.geometry : _this.feature.getGeometry();
});
_defineProperty(_this, "getBackgroundGeometry", function (feature) {
var background = feature.getGeometry().clone();
if (_this.feature !== null) {
var geom = _this.getGeometry().clone();
// ignore degenerate geometries
if (geom.getArea() === 0) {
return background;
}
// make the current selection transparent
background.appendLinearRing(geom.getLinearRing(0));
// add the origin to the selected tiles
var selected = ['0,0'].concat(_toConsumableArray(_this.props.printSeriesSelected));
// make the selected series transparent
_this.seriesGeometries.filter(_this.isPrintSeriesSelected).forEach(function (entry) {
// add the inner part of the tile
var clonedGeom = entry.geometry.clone();
clonedGeom.scale(1 - 2 * _this.props.printSeriesOverlap);
background.appendLinearRing(clonedGeom.getLinearRing(0));
// clone the original geometry and rotate it
var clonedGeomBase = entry.geometry.clone();
var center = ol.extent.getCenter(clonedGeomBase.getExtent());
clonedGeomBase.rotate(entry.rotation, center);
var extent = clonedGeomBase.getExtent();
// create the geometries for the overlapping borders
var clonedGeomLeft = clonedGeomBase.clone();
var centerLeft = [extent[0], 0.5 * (extent[1] + extent[3])];
clonedGeomLeft.scale(_this.props.printSeriesOverlap, 1 - 2 * _this.props.printSeriesOverlap, centerLeft);
clonedGeomLeft.rotate(-entry.rotation, center);
var clonedGeomRight = clonedGeomBase.clone();
var centerRight = [extent[2], 0.5 * (extent[1] + extent[3])];
clonedGeomRight.scale(_this.props.printSeriesOverlap, 1 - 2 * _this.props.printSeriesOverlap, centerRight);
clonedGeomRight.rotate(-entry.rotation, center);
var clonedGeomBottom = clonedGeomBase.clone();
var centerBottom = [0.5 * (extent[0] + extent[2]), extent[1]];
clonedGeomBottom.scale(1 - 2 * _this.props.printSeriesOverlap, _this.props.printSeriesOverlap, centerBottom);
clonedGeomBottom.rotate(-entry.rotation, center);
var clonedGeomTop = clonedGeomBase.clone();
var centerTop = [0.5 * (extent[0] + extent[2]), extent[3]];
clonedGeomTop.scale(1 - 2 * _this.props.printSeriesOverlap, _this.props.printSeriesOverlap, centerTop);
clonedGeomTop.rotate(-entry.rotation, center);
// create the geometries for the overlapping corners
var clonedGeomBottomLeft = clonedGeomBase.clone();
var bottomLeft = [extent[0], extent[1]];
clonedGeomBottomLeft.scale(_this.props.printSeriesOverlap, _this.props.printSeriesOverlap, bottomLeft);
clonedGeomBottomLeft.rotate(-entry.rotation, center);
var clonedGeomBottomRight = clonedGeomBase.clone();
var bottomRight = [extent[2], extent[1]];
clonedGeomBottomRight.scale(_this.props.printSeriesOverlap, _this.props.printSeriesOverlap, bottomRight);
clonedGeomBottomRight.rotate(-entry.rotation, center);
var clonedGeomTopLeft = clonedGeomBase.clone();
var topLeft = [extent[0], extent[3]];
clonedGeomTopLeft.scale(_this.props.printSeriesOverlap, _this.props.printSeriesOverlap, topLeft);
clonedGeomTopLeft.rotate(-entry.rotation, center);
var clonedGeomTopRight = clonedGeomBase.clone();
var topRight = [extent[2], extent[3]];
clonedGeomTopRight.scale(_this.props.printSeriesOverlap, _this.props.printSeriesOverlap, topRight);
clonedGeomTopRight.rotate(-entry.rotation, center);
// calculate the neighbours of the current tile
var topNeighbour = [entry.index[0] - 1, entry.index[1]].join(',');
var bottomNeighbour = [entry.index[0] + 1, entry.index[1]].join(',');
var leftNeighbour = [entry.index[0], entry.index[1] - 1].join(',');
var rightNeighbour = [entry.index[0], entry.index[1] + 1].join(',');
var topLeftNeighbour = [entry.index[0] - 1, entry.index[1] - 1].join(',');
var topRightNeighbour = [entry.index[0] - 1, entry.index[1] + 1].join(',');
var bottomLeftNeighbour = [entry.index[0] + 1, entry.index[1] - 1].join(',');
var bottomRightNeighbour = [entry.index[0] + 1, entry.index[1] + 1].join(',');
// Each tile is responsible to draw its border facing away from the origin.
// left border
if (!selected.includes(leftNeighbour) || entry.index[1] <= 0) {
background.appendLinearRing(clonedGeomLeft.getLinearRing(0));
}
// right border
if (!selected.includes(rightNeighbour) || entry.index[1] >= 0) {
background.appendLinearRing(clonedGeomRight.getLinearRing(0));
}
// top border
if (!selected.includes(topNeighbour) || entry.index[0] <= 0) {
background.appendLinearRing(clonedGeomTop.getLinearRing(0));
}
// bottom border
if (!selected.includes(bottomNeighbour) || entry.index[0] >= 0) {
background.appendLinearRing(clonedGeomBottom.getLinearRing(0));
}
// The corners are drawn by the tile facing away from the origin, and in counter-clockwise order.
// top-left corner
if (entry.index[0] <= 0 && entry.index[1] <= 0 || entry.index[0] <= 0 && !selected.includes(leftNeighbour) || entry.index[1] <= 0 && !selected.includes(topNeighbour) && !selected.includes(topLeftNeighbour) || !selected.includes(leftNeighbour) && !selected.includes(topNeighbour) && !selected.includes(topLeftNeighbour)) {
background.appendLinearRing(clonedGeomTopLeft.getLinearRing(0));
}
// top-right corner
if (entry.index[0] <= 0 && entry.index[1] >= 0 || entry.index[0] <= 0 && !selected.includes(rightNeighbour) || entry.index[1] >= 0 && !selected.includes(topNeighbour) && !selected.includes(topRightNeighbour) || !selected.includes(rightNeighbour) && !selected.includes(topNeighbour) && !selected.includes(topRightNeighbour)) {
background.appendLinearRing(clonedGeomTopRight.getLinearRing(0));
}
// bottom-left corner
if (entry.index[0] >= 0 && entry.index[1] <= 0 || entry.index[0] >= 0 && !selected.includes(leftNeighbour) || entry.index[1] <= 0 && !selected.includes(bottomNeighbour) && !selected.includes(bottomLeftNeighbour) || !selected.includes(leftNeighbour) && !selected.includes(bottomNeighbour) && !selected.includes(bottomLeftNeighbour)) {
background.appendLinearRing(clonedGeomBottomLeft.getLinearRing(0));
}
// bottom-right corner
if (entry.index[0] >= 0 && entry.index[1] >= 0 || entry.index[0] >= 0 && !selected.includes(rightNeighbour) || entry.index[1] >= 0 && !selected.includes(bottomNeighbour) && !selected.includes(bottomRightNeighbour) || !selected.includes(rightNeighbour) && !selected.includes(bottomNeighbour) && !selected.includes(bottomRightNeighbour)) {
background.appendLinearRing(clonedGeomBottomRight.getLinearRing(0));
}
});
}
return background;
});
_defineProperty(_this, "calculateSeriesGeometries", function () {
var featureGeometry = _this.getGeometry();
var coordinates = featureGeometry.getCoordinates()[0];
var dx1 = coordinates[1][0] - coordinates[2][0];
var dy1 = coordinates[1][1] - coordinates[2][1];
var dx2 = coordinates[2][0] - coordinates[3][0];
var dy2 = coordinates[2][1] - coordinates[3][1];
var rotation = -Math.atan2(dy1, dx1);
var gridSize = _this.props.printSeriesEnabled ? _this.props.printSeriesGridSize : 0;
var geometries = [];
for (var i = -gridSize; i <= gridSize; i++) {
for (var j = -gridSize; j <= gridSize; j++) {
var index = [i, j];
var geometry = featureGeometry.clone();
geometry.translate((1 - _this.props.printSeriesOverlap) * (j * dx1 + i * dx2), (1 - _this.props.printSeriesOverlap) * (j * dy1 + i * dy2));
geometries.push({
index: index,
geometry: geometry,
rotation: rotation
});
}
}
return geometries;
});
_defineProperty(_this, "layerStyle", function (feature) {
// background geometry with own styling
if (feature === _this.backgroundFeature) {
return FeatureStyles.printInteractionBackground({
geometryFunction: _this.getBackgroundGeometry
});
}
// draw series geometries with own styling
if (feature === _this.printSeriesFeature && _this.props.printSeriesEnabled) {
var styles = [];
var size = Math.min(_this.props.fixedFrame.width, _this.props.fixedFrame.height);
var radius = Math.min(_this.props.scale * size / _this.map.getView().getResolution() / 100000, 2);
_this.seriesGeometries.forEach(function (entry) {
// ignore the center geometry
if (!isEqual(entry.index, [0, 0])) {
styles.push(FeatureStyles.printInteractionSeries({
geometryFunction: entry.geometry
}));
styles.push.apply(styles, _toConsumableArray(FeatureStyles.printInteractionSeriesIcon({
geometryFunction: new ol.geom.Point(ol.extent.getCenter(entry.geometry.getExtent())),
rotation: entry.rotation,
radius: radius,
img: _this.isPrintSeriesSelected(entry) ? 'minus' : 'plus'
})));
}
});
return styles;
}
// main feature
if (feature === _this.feature) {
var _styles = [FeatureStyles.printInteraction({
geometryFunction: _this.getGeometry
})];
var coordinates = _this.getGeometry().getCoordinates()[0];
if (coordinates && _this.props.fixedFrame) {
if (_this.props.allowScaling) {
// vertices to scale the selection
_styles.push(FeatureStyles.printInteractionVertex({
geometryFunction: new ol.geom.MultiPoint(coordinates.slice(2))
}));
}
if (_this.props.allowScaling || _this.props.allowRotation) {
// vertices to scale or rotate the selection
_styles.push(FeatureStyles.printInteractionVertex({
geometryFunction: new ol.geom.MultiPoint(coordinates.slice(1, 2)),
fill: _this.props.allowRotation
}));
}
}
return _styles;
}
return null;
});
_defineProperty(_this, "scaleRotateStyle", function (feature) {
feature.get('features').forEach(function (modifyFeature) {
var modifyGeometry = modifyFeature.get('modifyGeometry');
if (modifyGeometry) {
var point = feature.getGeometry().getCoordinates();
// rotate only with vertex on bottom-right
var isRotationVertex = isEqual(point, modifyFeature.getGeometry().getCoordinates()[0][1]);
if (!modifyGeometry.point) {
// save the initial geometry and vertex position
modifyGeometry.point = point;
modifyGeometry.initialGeometry = modifyGeometry.geometry;
}
var center = ol.extent.getCenter(modifyGeometry.initialGeometry.getExtent());
var _this$calculateRotati = _this.calculateRotationScale(modifyGeometry.point, point, center),
_this$calculateRotati2 = _slicedToArray(_this$calculateRotati, 2),
rotation = _this$calculateRotati2[0],
scale = _this$calculateRotati2[1];
var geometry = modifyGeometry.initialGeometry.clone();
if (_this.props.allowRotation && isRotationVertex) {
geometry.rotate(rotation, center);
} else if (_this.props.allowScaling) {
geometry.scale(scale, undefined, center);
}
modifyGeometry.geometry = geometry;
}
});
return null;
});
_defineProperty(_this, "isPrintSeriesSelected", function (entry) {
return _this.props.printSeriesSelected.includes(entry.index.join(','));
});
_defineProperty(_this, "calculateExtents", function () {
_this.seriesGeometries = _this.calculateSeriesGeometries();
_this.selectionLayer.changed();
return _this.seriesGeometries.filter(function (entry) {
return isEqual(entry.index, [0, 0]) || _this.isPrintSeriesSelected(entry);
}).map(function (entry) {
var clonedGeom = entry.geometry.clone();
var center = ol.extent.getCenter(clonedGeom.getExtent());
clonedGeom.rotate(-_this.props.rotation * Math.PI / 180, center);
return clonedGeom.getExtent();
});
});
_defineProperty(_this, "geometryChanged", function () {
var geometry = _this.getGeometry();
var extent = geometry.getExtent();
var point = geometry.getCoordinates()[0][0];
var center = ol.extent.getCenter(extent);
// Update series geometries and obtain extents
var extents = _this.calculateExtents();
var rotation = 0;
var scale = null;
if (_this.initialWidth !== null && _this.initialHeight !== null) {
var initialPoint = [center[0] + 0.5 * _this.initialWidth, center[1] + 0.5 * _this.initialHeight];
var _this$calculateRotati3 = _this.calculateRotationScale(initialPoint, point, center),
_this$calculateRotati4 = _slicedToArray(_this$calculateRotati3, 2),
calcRotation = _this$calculateRotati4[0],
calcScale = _this$calculateRotati4[1];
var degree = (360 + calcRotation * 180 / Math.PI) % 360;
rotation = Math.round(degree * 10) / 10 % 360;
scale = Math.round(1000 * calcScale);
}
_this.props.geometryChanged(center, extents, rotation, scale);
});
_defineProperty(_this, "calculateRotationScale", function (p1, p2, center) {
var dx = p1[0] - center[0];
var dy = p1[1] - center[1];
var initialAngle = Math.atan2(dy, dx);
var initialRadius = Math.sqrt(dx * dx + dy * dy);
dx = p2[0] - center[0];
dy = p2[1] - center[1];
var currentAngle = Math.atan2(dy, dx);
var currentRadius = Math.sqrt(dx * dx + dy * dy);
return [currentAngle - initialAngle, currentRadius / initialRadius];
});
_this.map = MapUtils.getHook(MapUtils.GET_MAP);
// create a layer to draw on
_this.source = new ol.source.Vector();
_this.selectionLayer = new ol.layer.Vector({
source: _this.source,
zIndex: 1000000,
style: _this.layerStyle
});
// create a geometry for the background feature
var _extent = (_this$map$getView$get = _this.map.getView().getProjection().getExtent()) !== null && _this$map$getView$get !== void 0 ? _this$map$getView$get : [Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER];
var _geometry = ol.geom.polygonFromExtent(_extent);
_this.backgroundFeature = new ol.Feature(_geometry);
_this.source.addFeature(_this.backgroundFeature);
_this.printSeriesFeature = new ol.Feature(_geometry);
_this.source.addFeature(_this.printSeriesFeature);
_this.feature = null;
_this.initialWidth = null;
_this.initialHeight = null;
_this.seriesGeometries = [];
_this.translateInteraction = null;
_this.scaleRotateInteraction = null;
_this.selectPrintSeriesInteraction = null;
_this.drawInteraction = null;
_this.isInteracting = false;
return _this;
}
_inherits(PrintSelection, _React$Component);
return _createClass(PrintSelection, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
if (!isEqual(prevProps.fixedFrame, this.props.fixedFrame) || !isEqual(prevProps.center, this.props.center) || prevProps.rotation !== this.props.rotation || prevProps.scale !== this.props.scale) {
if (!this.isInteracting) {
this.recomputeFeature();
}
}
if (prevProps.printSeriesEnabled !== this.props.printSeriesEnabled || prevProps.printSeriesOverlap !== this.props.printSeriesOverlap || prevProps.printSeriesSelected !== this.props.printSeriesSelected) {
this.geometryChanged();
}
}
}, {
key: "recomputeFeature",
value: function recomputeFeature() {
// delete the old feature
if (this.feature !== null) {
// remove old feature
this.source.removeFeature(this.feature);
this.feature = null;
this.initialWidth = null;
this.initialHeight = null;
this.seriesGeometries = [];
}
// render the current feature if given a fixed frame
if (this.props.fixedFrame !== null) {
// calculate actual width and height
var _MapUtils$transformEx = MapUtils.transformExtent(this.map.getView().getProjection(), this.props.center, this.props.fixedFrame.width, this.props.fixedFrame.height),
width = _MapUtils$transformEx.width,
height = _MapUtils$transformEx.height;
// add rectangle
var x1 = this.props.center[0] + 0.5 * width;
var x2 = this.props.center[0] - 0.5 * width;
var y1 = this.props.center[1] + 0.5 * height;
var y2 = this.props.center[1] - 0.5 * height;
var geometry = new ol.geom.Polygon([[[x1, y1], [x1, y2], [x2, y2], [x2, y1], [x1, y1]]]);
// rotate and scale rectangle
if (this.props.rotation) {
geometry.rotate(this.props.rotation * Math.PI / 180, this.props.center);
}
if (this.props.scale) {
geometry.scale(this.props.scale / 1000, undefined, this.props.center);
}
// add feature to layer
this.feature = new ol.Feature(geometry);
this.feature.on('change', this.geometryChanged);
this.source.addFeature(this.feature);
// store initial width and height for future updates
this.initialWidth = width;
this.initialHeight = height;
// update geometry to new extent
this.geometryChanged();
}
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
this.map.on('pointermove', this.setViewportCursor);
this.map.addLayer(this.selectionLayer);
this.addInteractions();
this.recomputeFeature();
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.map.un('pointermove', this.setViewportCursor);
this.map.removeLayer(this.selectionLayer);
this.removeInteractions();
}
}, {
key: "addInteractions",
value: function addInteractions() {
var _this2 = this;
// move the selection
var translateCondition = function translateCondition(ev) {
return ol.events.condition.primaryAction(ev) && _this2.props.fixedFrame && _this2.props.allowTranslation;
};
this.translateInteraction = new ol.interaction.Translate({
condition: translateCondition,
// add condition to filter for correct cursor selection
filter: function filter(feature) {
return _this2.props.fixedFrame && _this2.props.allowTranslation && feature === _this2.feature;
},
layers: [this.selectionLayer]
});
this.translateInteraction.on('translatestart', function () {
_this2.isInteracting = true;
});
this.translateInteraction.on('translateend', function () {
_this2.isInteracting = false;
});
// scale and rotate the selection
var modifyCondition = function modifyCondition(ev) {
return ol.events.condition.primaryAction(ev) && _this2.props.fixedFrame && (_this2.props.allowScaling || _this2.props.allowRotation);
};
this.scaleRotateInteraction = new ol.interaction.Modify({
source: this.source,
condition: modifyCondition,
deleteCondition: ol.events.condition.never,
insertVertexCondition: ol.events.condition.never,
pixelTolerance: 20,
style: this.scaleRotateStyle
});
this.scaleRotateInteraction.on('modifystart', function (ev) {
_this2.isInteracting = true;
ev.features.forEach(function (feature) {
feature.set('modifyGeometry', {
geometry: feature.getGeometry().clone()
}, true);
});
});
this.scaleRotateInteraction.on('modifyend', function (ev) {
_this2.isInteracting = false;
ev.features.forEach(function (feature) {
var modifyGeometry = feature.get('modifyGeometry');
if (modifyGeometry) {
feature.setGeometry(modifyGeometry.geometry);
feature.unset('modifyGeometry', true);
}
});
_this2.recomputeFeature();
});
// select frames for printing a series
this.selectPrintSeriesInteraction = new ol.interaction.Select({
filter: function filter(feature) {
return feature === _this2.printSeriesFeature;
},
layers: [this.selectionLayer],
condition: ol.events.condition.click,
addCondition: ol.events.condition.always,
removeCondition: ol.events.condition.always,
style: null
});
this.selectPrintSeriesInteraction.on('select', function (ev) {
var coordinate = ev.mapBrowserEvent.coordinate;
var intersecting = _this2.seriesGeometries.find(function (entry) {
return !isEqual(entry.index, [0, 0]) && entry.geometry.intersectsCoordinate(coordinate);
});
if (intersecting) {
var selected = _this2.props.printSeriesSelected;
if (selected.includes(intersecting.index.join(','))) {
selected = selected.filter(function (index) {
return index !== intersecting.index.join(',');
});
} else {
selected = [].concat(_toConsumableArray(selected), [intersecting.index.join(',')]);
}
_this2.props.printSeriesChanged(selected);
}
});
// select a new area when no frame is given (only added when no fixed frame is given)
var drawCondition = function drawCondition(ev) {
return ol.events.condition.primaryAction(ev) && !_this2.props.fixedFrame;
};
this.drawInteraction = new ol.interaction.Draw({
source: this.source,
type: 'Circle',
style: FeatureStyles.printInteraction(),
geometryFunction: ol.interaction.createBox(),
condition: ol.events.condition.never,
freehandCondition: drawCondition
});
this.drawInteraction.on('drawstart', function (ev) {
_this2.isInteracting = true;
_this2.feature = ev.feature;
_this2.feature.on('change', _this2.geometryChanged);
});
this.drawInteraction.on('drawend', function () {
_this2.isInteracting = false;
_this2.geometryChanged();
});
// register interactions
this.map.addInteraction(this.translateInteraction);
this.map.addInteraction(this.scaleRotateInteraction);
this.map.addInteraction(this.selectPrintSeriesInteraction);
this.map.addInteraction(this.drawInteraction);
}
}, {
key: "removeInteractions",
value: function removeInteractions() {
if (this.translateInteraction !== null) {
this.map.removeInteraction(this.translateInteraction);
this.translateInteraction = null;
}
if (this.scaleRotateInteraction !== null) {
this.map.removeInteraction(this.scaleRotateInteraction);
this.scaleRotateInteraction = null;
}
if (this.selectPrintSeriesInteraction !== null) {
this.map.removeInteraction(this.selectPrintSeriesInteraction);
this.selectPrintSeriesInteraction = null;
}
if (this.drawInteraction !== null) {
this.map.removeInteraction(this.drawInteraction);
this.drawInteraction = null;
}
}
}, {
key: "render",
value: function render() {
return null;
}
}]);
}(React.Component);
_defineProperty(PrintSelection, "propTypes", {
allowRotation: PropTypes.bool,
allowScaling: PropTypes.bool,
allowTranslation: PropTypes.bool,
center: PropTypes.arrayOf(PropTypes.number),
fixedFrame: PropTypes.shape({
width: PropTypes.number,
// in meters
height: PropTypes.number // in meters
}),
geometryChanged: PropTypes.func,
printSeriesChanged: PropTypes.func,
printSeriesEnabled: PropTypes.bool,
printSeriesGridSize: PropTypes.number,
printSeriesOverlap: PropTypes.number,
printSeriesSelected: PropTypes.arrayOf(PropTypes.string),
rotation: PropTypes.number,
scale: PropTypes.number
});
_defineProperty(PrintSelection, "defaultProps", {
allowRotation: true,
allowScaling: true,
allowTranslation: true,
fixedFrame: null,
geometryChanged: function geometryChanged() {},
printSeriesChanged: function printSeriesChanged() {},
printSeriesEnabled: false,
printSeriesGridSize: 2,
printSeriesOverlap: 0,
printSeriesSelected: [],
rotation: 0,
scale: 1000
});
export { PrintSelection as default };