Rewritten WKT reader/writer (#411)

This commit is contained in:
Björn Harrtell 2020-07-24 13:29:46 +02:00 committed by GitHub
parent 63c107f459
commit b44ef4a38b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 843 additions and 359 deletions

View File

@ -2,7 +2,7 @@ module.exports = {
presets: [
['@babel/env', {
targets: {
node: ['10']
node: '10'
}
}]
]

View File

@ -2,6 +2,7 @@ import Long from './Long'
export default function Double() { }
Double.NaN = NaN
Double.isNaN = n => Number.isNaN(n)
Double.isInfinite = n => !Number.isFinite(n)
Double.MAX_VALUE = Number.MAX_VALUE

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@ import { expect } from 'chai'
import GeometryFactory from 'org/locationtech/jts/geom/GeometryFactory'
import PrecisionModel from 'org/locationtech/jts/geom/PrecisionModel'
import WKTReader from 'org/locationtech/jts/io/WKTReader'
import WKTWriter from 'org/locationtech/jts/io/WKTWriter'
import 'org/locationtech/jts/monkey'
import BufferResultMatcher from '../BufferResultMatcher'
@ -13,7 +14,7 @@ import BufferResultMatcher from '../BufferResultMatcher'
/**
* @return GeometryFactory with PrecisionModel from test XML (undefined if no such info in XML)
*/
function createGeometryFactory (precisionModelInfo) {
function createGeometryFactory(precisionModelInfo) {
if (precisionModelInfo.length === 1) {
const type = precisionModelInfo.attr('type')
if (type !== 'FLOATING') {
@ -27,29 +28,35 @@ function createGeometryFactory (precisionModelInfo) {
}
}
function fail (r, e, i) {
throw new Error(`\nResult: ${r}\nExpected: ${e}\nInput: ${i}`)
}
/**
* Translate JTS XML testcase document to Mocha suites
*/
export default function (doc, title) {
export default function(doc, title) {
const cases = $('case', doc)
const geometryFactory = createGeometryFactory($('precisionModel', doc))
const reader = new WKTReader(geometryFactory)
const writer = new WKTWriter(geometryFactory)
function fail(r, e, i) {
const rt = r ? writer.write(r) : 'undefined'
throw new Error(`\nResult: ${rt}\nExpected: ${e}\nInput: ${i}`)
}
/**
* Translate JTS XML "test" to a Jasmine test spec
*/
const generateSpec = function (a, b, opname, arg2, arg3, expected) {
const generateSpec = function(a, b, opname, arg2, arg3, expected) {
// fix opnames to real methods where needed
if (opname === 'convexhull') opname = 'convexHull'
else if (opname === 'getboundary') opname = 'getBoundary'
else if (opname === 'symdifference') opname = 'symDifference'
it('Executing ' + opname + ' on test geometry', function () {
const inputs = ' Input geometry A: ' + a + (b ? ' B: ' + b : '')
it('Executing ' + opname + ' on test geometry', function() {
const at = writer.write(a)
const bt = b ? writer.write(b) : 'undefined'
const inputs = ' Input geometry A: ' + at + ' B: ' + bt
var result
@ -99,7 +106,7 @@ export default function (doc, title) {
result.normalize()
expectedGeometry.normalize()
if (!result.equalsExact(expectedGeometry)) {
fail(result, expected, inputs)
fail(result, writer.write(expectedGeometry), inputs)
} else {
expect(true).to.be.true
}

View File

@ -0,0 +1,23 @@
import expect from 'expect.js'
import WKTParser from 'org/locationtech/jts/io/WKTParser'
const parser = new WKTParser()
describe('WKTParser', function() {
function roundtrip(wkt) {
const expected = wkt
const g = parser.read(expected)
const actual = parser.write(g)
expect(expected).to.equal(actual)
}
it('roundtrips', function() {
roundtrip('POINT EMPTY')
roundtrip('POINT (30 10)')
roundtrip('LINESTRING (30 10, 10 30, 40 40)')
roundtrip('POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))')
roundtrip('POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))')
roundtrip('MULTIPOINT ((10 40), (40 30), (20 20), (30 10))')
})
})

View File

@ -1,11 +1,23 @@
// import expect from 'expect.js'
import expect from 'expect.js'
import WKTReader from 'org/locationtech/jts/io/WKTReader'
const reader = new WKTReader()
describe('WKTReader', function () {
it('should be able to read a Polygon', function () {
describe('WKTReader', function() {
it('should be able to read a Polygon', function() {
reader.read('POLYGON((57.722165171745836 14.202919006347656,57.71909404549173 14.21055793762207,57.71753546383143 14.212703704833984,57.71675614783365 14.212446212768555,57.715655908448745 14.212532043457031,57.71382210182487 14.21030044555664,57.71244668589343 14.20832633972168,57.71354702281898 14.205236434936523,57.712584229838065 14.202919006347656,57.71515162088769 14.201374053955078,57.71528915455559 14.196224212646484,57.71758130542645 14.192447662353516,57.72065256003978 14.196138381958008,57.72092758505232 14.199399948120117,57.72207350010876 14.201288223266602,57.722165171745836 14.202919006347656))')
})
it('should be able to read a 3D Point', function() {
const p = reader.read('POINT Z (1 1 1)')
const c = p.getCoordinate()
expect(c.x).to.equal(1)
expect(c.y).to.equal(1)
expect(c.z).to.equal(1)
})
it('should be able to read a MultiPolygon', function() {
reader.read('MULTIPOLYGON (((20 0, 20 80, 100 80, 200 80, 200 0, 20 0)), ((100 80, 80 120, 120 120, 100 80)))')
})
})

View File

@ -2,8 +2,8 @@ import expect from 'expect.js'
import WKTWriter from 'org/locationtech/jts/io/WKTWriter'
describe('WKTWriter', function () {
it('should be able to create a LINESTRING from two points', function () {
describe('WKTWriter', function() {
it('should be able to create a LINESTRING from two points', function() {
const p0 = { x: 10.0, y: 20.0 }
const p1 = { x: 30.0, y: 40.0 }
const p2 = { x: 10.123, y: 20.234 }

View File

@ -7,9 +7,9 @@ import LengthIndexedLine from 'org/locationtech/jts/linearref/LengthIndexedLine'
const reader = new WKTReader()
const writer = new WKTWriter()
describe('LengthIndexedLine', function () {
describe('indexOf', function () {
it('should be able to calc start and end indexOf', function () {
describe('LengthIndexedLine', function() {
describe('indexOf', function() {
it('should be able to calc start and end indexOf', function() {
const linestring = reader.read('LINESTRING(1 1,2 2)')
const lengthIndexedLine = new LengthIndexedLine(linestring)
const indexOfStart = lengthIndexedLine.indexOf(new Coordinate(1, 1))
@ -20,13 +20,13 @@ describe('LengthIndexedLine', function () {
expect(indexOfEnd).to.eql(1.4142135623730951)
})
it('should be able to calc start and end indexOf', function () {
it('should be able to calc start and end indexOf', function() {
const linestring = reader.read('LINESTRING(1 1,2 2)')
const lengthIndexedLine = new LengthIndexedLine(linestring)
const part1 = lengthIndexedLine.extractLine(0, 0.7071067811865476)
const part2 = lengthIndexedLine.extractLine(0.7071067811865476, 1.4142135623730951)
expect(writer.write(part1)).to.eql('LINESTRING(1 1,1.5 1.5)')
expect(writer.write(part2)).to.eql('LINESTRING(1.5 1.5,2 2)')
expect(writer.write(part1)).to.eql('LINESTRING (1 1, 1.5 1.5)')
expect(writer.write(part2)).to.eql('LINESTRING (1.5 1.5, 2 2)')
})
})
})

View File

@ -4,8 +4,8 @@ import WKTReader from 'org/locationtech/jts/io/WKTReader'
import WKTWriter from 'org/locationtech/jts/io/WKTWriter'
import LineMerger from 'org/locationtech/jts/operation/linemerge/LineMerger'
describe('LineMerger', function () {
it('#373', function () {
describe('LineMerger', function() {
it('#373', function() {
const reader = new WKTReader()
const ls1 = reader.read('LINESTRING(0 0, 1 1)')
const ls2 = reader.read('LINESTRING(1 1, 2 2)')
@ -17,6 +17,6 @@ describe('LineMerger', function () {
const mergedLineString = mergedLineStrings.get(0)
const writer = new WKTWriter()
const result = writer.write(mergedLineString)
expect(result).to.equal('LINESTRING(0 0,1 1,2 2)')
expect(result).to.equal('LINESTRING (0 0, 1 1, 2 2)')
})
})

View File

@ -4,6 +4,9 @@ import Coordinate from 'org/locationtech/jts/geom/Coordinate'
import GeometryFactory from 'org/locationtech/jts/geom/GeometryFactory'
import OverlayOp from 'org/locationtech/jts/operation/overlay/OverlayOp'
import RelateOp from 'org/locationtech/jts/operation/relate/RelateOp'
import PrecisionModel from 'org/locationtech/jts/geom/PrecisionModel'
import WKTReader from 'org/locationtech/jts/io/WKTReader'
import WKTWriter from 'org/locationtech/jts/io/WKTWriter'
describe('OverlayOp', function () {
it('intersection between GCs', function () {
@ -16,4 +19,15 @@ describe('OverlayOp', function () {
expect(RelateOp.equalsTopo(intersection, p1)).to.be(true)
})
it('specific case', function() {
const factory = new GeometryFactory(new PrecisionModel(1))
const reader = new WKTReader(factory)
const writer = new WKTWriter(factory)
const a = reader.read('LINESTRING (240 190, 120 120)')
const b = reader.read('POLYGON ((110 240, 50 80, 240 70, 110 240))')
const r = OverlayOp.intersection(a, b)
const rt = writer.write(r)
expect('LINESTRING (177 153, 120 120)').to.equal(rt)
})
})

View File

@ -4,8 +4,6 @@ import GeometryFactory from 'org/locationtech/jts/geom/GeometryFactory'
import DelaunayTriangulationBuilder from 'org/locationtech/jts/triangulate/DelaunayTriangulationBuilder'
import WKTReader from 'org/locationtech/jts/io/WKTReader'
describe('DelauneyTriangulationBuilder', function () {
var geomFact = new GeometryFactory()
var reader = new WKTReader()
@ -16,26 +14,25 @@ describe('DelauneyTriangulationBuilder', function () {
builder.setSites(sites)
var result = null
if (computeTriangles) {
if (computeTriangles)
result = builder.getTriangles(geomFact)
} else {
else
result = builder.getEdges(geomFact)
}
return result
}
var runDelaunayEdges = function (sitesWKT) {
var runDelaunayEdges = function(sitesWKT) {
return runDelaunay(sitesWKT, false)
}
it('can be constructed', function () {
it('can be constructed', function() {
var builder = new DelaunayTriangulationBuilder()
expect(builder).to.be.an(DelaunayTriangulationBuilder)
})
it('can build from multipoints', function () {
var wkt = 'MULTIPOINT ((10 10 1), (10 20 2), (20 20 3))'
it('can build from multipoints', function() {
var wkt = 'MULTIPOINT Z ((10 10 1), (10 20 2), (20 20 3))'
var expected = reader.read('MULTILINESTRING ((10 20, 20 20), (10 10, 10 20), (10 10, 20 20))')
var result = runDelaunayEdges(wkt)
expect(result.equalsExact(expected)).to.be.ok()