package.geom.flat.interiorpoint.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ol Show documentation
Show all versions of ol Show documentation
OpenLayers mapping library
The newest version!
/**
* @module ol/geom/flat/interiorpoint
*/
import {ascending} from '../../array.js';
import {linearRingsContainsXY} from './contains.js';
/**
* Calculates a point that is likely to lie in the interior of the linear rings.
* Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.
* @param {Array} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array} ends Ends.
* @param {number} stride Stride.
* @param {Array} flatCenters Flat centers.
* @param {number} flatCentersOffset Flat center offset.
* @param {Array} [dest] Destination.
* @return {Array} Destination point as XYM coordinate, where M is the
* length of the horizontal intersection that the point belongs to.
*/
export function getInteriorPointOfArray(
flatCoordinates,
offset,
ends,
stride,
flatCenters,
flatCentersOffset,
dest,
) {
let i, ii, x, x1, x2, y1, y2;
const y = flatCenters[flatCentersOffset + 1];
/** @type {Array} */
const intersections = [];
// Calculate intersections with the horizontal line
for (let r = 0, rr = ends.length; r < rr; ++r) {
const end = ends[r];
x1 = flatCoordinates[end - stride];
y1 = flatCoordinates[end - stride + 1];
for (i = offset; i < end; i += stride) {
x2 = flatCoordinates[i];
y2 = flatCoordinates[i + 1];
if ((y <= y1 && y2 <= y) || (y1 <= y && y <= y2)) {
x = ((y - y1) / (y2 - y1)) * (x2 - x1) + x1;
intersections.push(x);
}
x1 = x2;
y1 = y2;
}
}
// Find the longest segment of the horizontal line that has its center point
// inside the linear ring.
let pointX = NaN;
let maxSegmentLength = -Infinity;
intersections.sort(ascending);
x1 = intersections[0];
for (i = 1, ii = intersections.length; i < ii; ++i) {
x2 = intersections[i];
const segmentLength = Math.abs(x2 - x1);
if (segmentLength > maxSegmentLength) {
x = (x1 + x2) / 2;
if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {
pointX = x;
maxSegmentLength = segmentLength;
}
}
x1 = x2;
}
if (isNaN(pointX)) {
// There is no horizontal line that has its center point inside the linear
// ring. Use the center of the the linear ring's extent.
pointX = flatCenters[flatCentersOffset];
}
if (dest) {
dest.push(pointX, y, maxSegmentLength);
return dest;
}
return [pointX, y, maxSegmentLength];
}
/**
* @param {Array} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array>} endss Endss.
* @param {number} stride Stride.
* @param {Array} flatCenters Flat centers.
* @return {Array} Interior points as XYM coordinates, where M is the
* length of the horizontal intersection that the point belongs to.
*/
export function getInteriorPointsOfMultiArray(
flatCoordinates,
offset,
endss,
stride,
flatCenters,
) {
/** @type {Array} */
let interiorPoints = [];
for (let i = 0, ii = endss.length; i < ii; ++i) {
const ends = endss[i];
interiorPoints = getInteriorPointOfArray(
flatCoordinates,
offset,
ends,
stride,
flatCenters,
2 * i,
interiorPoints,
);
offset = ends[ends.length - 1];
}
return interiorPoints;
}