/** * @module ol/geom/LinearRing */ import {closestSquaredDistanceXY} from '../extent.js'; import GeometryLayout from './GeometryLayout.js'; import GeometryType from './GeometryType.js'; import SimpleGeometry from './SimpleGeometry.js'; import {linearRing as linearRingArea} from './flat/area.js'; import {assignClosestPoint, maxSquaredDelta} from './flat/closest.js'; import {deflateCoordinates} from './flat/deflate.js'; import {inflateCoordinates} from './flat/inflate.js'; import {douglasPeucker} from './flat/simplify.js'; /** * @classdesc * Linear ring geometry. Only used as part of polygon; cannot be rendered * on its own. * * @api */ class LinearRing extends SimpleGeometry { /** * @param {Array|Array} coordinates Coordinates. * For internal use, flat coordinates in combination with `opt_layout` are also accepted. * @param {GeometryLayout=} opt_layout Layout. */ constructor(coordinates, opt_layout) { super(); /** * @private * @type {number} */ this.maxDelta_ = -1; /** * @private * @type {number} */ this.maxDeltaRevision_ = -1; if (opt_layout !== undefined && !Array.isArray(coordinates[0])) { this.setFlatCoordinates(opt_layout, /** @type {Array} */ (coordinates)); } else { this.setCoordinates(/** @type {Array} */ (coordinates), opt_layout); } } /** * Make a complete copy of the geometry. * @return {!LinearRing} Clone. * @override * @api */ clone() { return new LinearRing(this.flatCoordinates.slice(), this.layout); } /** * @inheritDoc */ closestPointXY(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; } if (this.maxDeltaRevision_ != this.getRevision()) { this.maxDelta_ = Math.sqrt(maxSquaredDelta( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0)); this.maxDeltaRevision_ = this.getRevision(); } return assignClosestPoint( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance); } /** * Return the area of the linear ring on projected plane. * @return {number} Area (on projected plane). * @api */ getArea() { return linearRingArea(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride); } /** * Return the coordinates of the linear ring. * @return {Array} Coordinates. * @override * @api */ getCoordinates() { return inflateCoordinates( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride); } /** * @inheritDoc */ getSimplifiedGeometryInternal(squaredTolerance) { const simplifiedFlatCoordinates = []; simplifiedFlatCoordinates.length = douglasPeucker( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0); return new LinearRing(simplifiedFlatCoordinates, GeometryLayout.XY); } /** * @inheritDoc * @api */ getType() { return GeometryType.LINEAR_RING; } /** * @inheritDoc */ intersectsExtent(extent) { return false; } /** * Set the coordinates of the linear ring. * @param {!Array} coordinates Coordinates. * @param {GeometryLayout=} opt_layout Layout. * @override * @api */ setCoordinates(coordinates, opt_layout) { this.setLayout(opt_layout, coordinates, 1); if (!this.flatCoordinates) { this.flatCoordinates = []; } this.flatCoordinates.length = deflateCoordinates( this.flatCoordinates, 0, coordinates, this.stride); this.changed(); } } export default LinearRing;