@mkerkstra/jsts-cjs
Version:
A CommonJS fork of JSTS: A JavaScript library of spatial predicates and functions for processing geometry
212 lines (194 loc) • 6.24 kB
JavaScript
import hasInterface from '../../../../hasInterface.js'
import Length from '../algorithm/Length.js'
import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException.js'
import GeometryComponentFilter from './GeometryComponentFilter.js'
import UnsupportedOperationException from '../../../../java/lang/UnsupportedOperationException.js'
import CoordinateArrays from './CoordinateArrays.js'
import Dimension from './Dimension.js'
import Envelope from './Envelope.js'
import Geometry from './Geometry.js'
import CoordinateFilter from './CoordinateFilter.js'
import Lineal from './Lineal.js'
import CoordinateSequences from './CoordinateSequences.js'
import GeometryFilter from './GeometryFilter.js'
import CoordinateSequenceFilter from './CoordinateSequenceFilter.js'
export default class LineString extends Geometry {
constructor() {
super()
LineString.constructor_.apply(this, arguments)
}
static constructor_() {
this._points = null
if (arguments.length === 0) {} else if (arguments.length === 2) {
const points = arguments[0], factory = arguments[1]
Geometry.constructor_.call(this, factory)
this.init(points)
}
}
computeEnvelopeInternal() {
if (this.isEmpty())
return new Envelope()
return this._points.expandEnvelope(new Envelope())
}
isRing() {
return this.isClosed() && CoordinateArrays.isRing(this.getCoordinates())
}
getCoordinates() {
return this._points.toCoordinateArray()
}
copyInternal() {
return new LineString(this._points.copy(), this._factory)
}
equalsExact() {
if (arguments.length === 2 && (typeof arguments[1] === 'number' && arguments[0] instanceof Geometry)) {
const other = arguments[0], tolerance = arguments[1]
if (!this.isEquivalentClass(other))
return false
const otherLineString = other
if (this._points.size() !== otherLineString._points.size())
return false
for (let i = 0; i < this._points.size(); i++)
if (!this.equal(this._points.getCoordinate(i), otherLineString._points.getCoordinate(i), tolerance))
return false
return true
} else {
return super.equalsExact.apply(this, arguments)
}
}
isClosed() {
if (this.isEmpty())
return false
return this.getCoordinateN(0).equals2D(this.getCoordinateN(this.getNumPoints() - 1))
}
reverseInternal() {
const seq = this._points.copy()
CoordinateSequences.reverse(seq)
return this.getFactory().createLineString(seq)
}
getEndPoint() {
if (this.isEmpty())
return null
return this.getPointN(this.getNumPoints() - 1)
}
getTypeCode() {
return Geometry.TYPECODE_LINESTRING
}
getDimension() {
return 1
}
getBoundary() {
throw new UnsupportedOperationException()
}
isEquivalentClass(other) {
return other instanceof LineString
}
getCoordinateSequence() {
return this._points
}
getPointN(n) {
return this.getFactory().createPoint(this._points.getCoordinate(n))
}
normalize() {
for (let i = 0; i < Math.trunc(this._points.size() / 2); i++) {
const j = this._points.size() - 1 - i
if (!this._points.getCoordinate(i).equals(this._points.getCoordinate(j))) {
if (this._points.getCoordinate(i).compareTo(this._points.getCoordinate(j)) > 0) {
const copy = this._points.copy()
CoordinateSequences.reverse(copy)
this._points = copy
}
return null
}
}
}
getCoordinate() {
if (this.isEmpty()) return null
return this._points.getCoordinate(0)
}
getBoundaryDimension() {
if (this.isClosed())
return Dimension.FALSE
return 0
}
getLength() {
return Length.ofLine(this._points)
}
getNumPoints() {
return this._points.size()
}
compareToSameClass() {
if (arguments.length === 1) {
const o = arguments[0]
const line = o
let i = 0
let j = 0
while (i < this._points.size() && j < line._points.size()) {
const comparison = this._points.getCoordinate(i).compareTo(line._points.getCoordinate(j))
if (comparison !== 0)
return comparison
i++
j++
}
if (i < this._points.size())
return 1
if (j < line._points.size())
return -1
return 0
} else if (arguments.length === 2) {
const o = arguments[0], comp = arguments[1]
const line = o
return comp.compare(this._points, line._points)
}
}
apply() {
if (hasInterface(arguments[0], CoordinateFilter)) {
const filter = arguments[0]
for (let i = 0; i < this._points.size(); i++)
filter.filter(this._points.getCoordinate(i))
} else if (hasInterface(arguments[0], CoordinateSequenceFilter)) {
const filter = arguments[0]
if (this._points.size() === 0) return null
for (let i = 0; i < this._points.size(); i++) {
filter.filter(this._points, i)
if (filter.isDone()) break
}
if (filter.isGeometryChanged()) this.geometryChanged()
} else if (hasInterface(arguments[0], GeometryFilter)) {
const filter = arguments[0]
filter.filter(this)
} else if (hasInterface(arguments[0], GeometryComponentFilter)) {
const filter = arguments[0]
filter.filter(this)
}
}
getCoordinateN(n) {
return this._points.getCoordinate(n)
}
getGeometryType() {
return Geometry.TYPENAME_LINESTRING
}
isEmpty() {
return this._points.size() === 0
}
init(points) {
if (points === null)
points = this.getFactory().getCoordinateSequenceFactory().create([])
if (points.size() === 1)
throw new IllegalArgumentException('Invalid number of points in LineString (found ' + points.size() + ' - must be 0 or >= 2)')
this._points = points
}
isCoordinate(pt) {
for (let i = 0; i < this._points.size(); i++)
if (this._points.getCoordinate(i).equals(pt))
return true
return false
}
getStartPoint() {
if (this.isEmpty())
return null
return this.getPointN(0)
}
get interfaces_() {
return [Lineal]
}
}