| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- import BufferParameters from './BufferParameters'
- import Geometry from '../../geom/Geometry'
- import BufferBuilder from './BufferBuilder'
- import ScaledNoder from '../../noding/ScaledNoder'
- import TopologyException from '../../geom/TopologyException'
- import MathUtil from '../../math/MathUtil'
- import PrecisionModel from '../../geom/PrecisionModel'
- import RuntimeException from '../../../../../java/lang/RuntimeException'
- import MCIndexSnapRounder from '../../noding/snapround/MCIndexSnapRounder'
- export default class BufferOp {
- constructor() {
- BufferOp.constructor_.apply(this, arguments)
- }
- static constructor_() {
- this._argGeom = null
- this._distance = null
- this._bufParams = new BufferParameters()
- this._resultGeometry = null
- this._saveException = null
- if (arguments.length === 1) {
- const g = arguments[0]
- this._argGeom = g
- } else if (arguments.length === 2) {
- const g = arguments[0], bufParams = arguments[1]
- this._argGeom = g
- this._bufParams = bufParams
- }
- }
- static bufferOp() {
- if (arguments.length === 2) {
- const g = arguments[0], distance = arguments[1]
- const gBuf = new BufferOp(g)
- const geomBuf = gBuf.getResultGeometry(distance)
- return geomBuf
- } else if (arguments.length === 3) {
- if (Number.isInteger(arguments[2]) && (arguments[0] instanceof Geometry && typeof arguments[1] === 'number')) {
- const g = arguments[0], distance = arguments[1], quadrantSegments = arguments[2]
- const bufOp = new BufferOp(g)
- bufOp.setQuadrantSegments(quadrantSegments)
- const geomBuf = bufOp.getResultGeometry(distance)
- return geomBuf
- } else if (arguments[2] instanceof BufferParameters && (arguments[0] instanceof Geometry && typeof arguments[1] === 'number')) {
- const g = arguments[0], distance = arguments[1], params = arguments[2]
- const bufOp = new BufferOp(g, params)
- const geomBuf = bufOp.getResultGeometry(distance)
- return geomBuf
- }
- } else if (arguments.length === 4) {
- const g = arguments[0], distance = arguments[1], quadrantSegments = arguments[2], endCapStyle = arguments[3]
- const bufOp = new BufferOp(g)
- bufOp.setQuadrantSegments(quadrantSegments)
- bufOp.setEndCapStyle(endCapStyle)
- const geomBuf = bufOp.getResultGeometry(distance)
- return geomBuf
- }
- }
- static precisionScaleFactor(g, distance, maxPrecisionDigits) {
- const env = g.getEnvelopeInternal()
- const envMax = MathUtil.max(Math.abs(env.getMaxX()), Math.abs(env.getMaxY()), Math.abs(env.getMinX()), Math.abs(env.getMinY()))
- const expandByDistance = distance > 0.0 ? distance : 0.0
- const bufEnvMax = envMax + 2 * expandByDistance
- const bufEnvPrecisionDigits = Math.trunc(Math.log(bufEnvMax) / Math.log(10) + 1.0)
- const minUnitLog10 = maxPrecisionDigits - bufEnvPrecisionDigits
- const scaleFactor = Math.pow(10.0, minUnitLog10)
- return scaleFactor
- }
- bufferFixedPrecision(fixedPM) {
- const noder = new ScaledNoder(new MCIndexSnapRounder(new PrecisionModel(1.0)), fixedPM.getScale())
- const bufBuilder = new BufferBuilder(this._bufParams)
- bufBuilder.setWorkingPrecisionModel(fixedPM)
- bufBuilder.setNoder(noder)
- this._resultGeometry = bufBuilder.buffer(this._argGeom, this._distance)
- }
- bufferReducedPrecision() {
- if (arguments.length === 0) {
- for (let precDigits = BufferOp.MAX_PRECISION_DIGITS; precDigits >= 0; precDigits--) {
- try {
- this.bufferReducedPrecision(precDigits)
- } catch (ex) {
- if (ex instanceof TopologyException)
- this._saveException = ex
- else throw ex
- } finally {}
- if (this._resultGeometry !== null) return null
- }
- throw this._saveException
- } else if (arguments.length === 1) {
- const precisionDigits = arguments[0]
- const sizeBasedScaleFactor = BufferOp.precisionScaleFactor(this._argGeom, this._distance, precisionDigits)
- const fixedPM = new PrecisionModel(sizeBasedScaleFactor)
- this.bufferFixedPrecision(fixedPM)
- }
- }
- computeGeometry() {
- this.bufferOriginalPrecision()
- if (this._resultGeometry !== null) return null
- const argPM = this._argGeom.getFactory().getPrecisionModel()
- if (argPM.getType() === PrecisionModel.FIXED) this.bufferFixedPrecision(argPM); else this.bufferReducedPrecision()
- }
- setQuadrantSegments(quadrantSegments) {
- this._bufParams.setQuadrantSegments(quadrantSegments)
- }
- bufferOriginalPrecision() {
- try {
- const bufBuilder = new BufferBuilder(this._bufParams)
- this._resultGeometry = bufBuilder.buffer(this._argGeom, this._distance)
- } catch (ex) {
- if (ex instanceof RuntimeException)
- this._saveException = ex
- else throw ex
- } finally {}
- }
- getResultGeometry(distance) {
- this._distance = distance
- this.computeGeometry()
- return this._resultGeometry
- }
- setEndCapStyle(endCapStyle) {
- this._bufParams.setEndCapStyle(endCapStyle)
- }
- }
- BufferOp.CAP_ROUND = BufferParameters.CAP_ROUND
- BufferOp.CAP_BUTT = BufferParameters.CAP_FLAT
- BufferOp.CAP_FLAT = BufferParameters.CAP_FLAT
- BufferOp.CAP_SQUARE = BufferParameters.CAP_SQUARE
- BufferOp.MAX_PRECISION_DIGITS = 12
|