From 2a8cc3d2f5e8d55944708717fc03b775afd21137 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 10 Jun 2022 18:17:02 +0200 Subject: [PATCH 1/2] Map multiple LineStringSegments to a one LineString --- src/ol/format/GML3.js | 13 ++++----- src/ol/format/GML32.js | 4 ++- test/browser/spec/ol/format/gml.test.js | 38 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/ol/format/GML3.js b/src/ol/format/GML3.js index e1d6a878d0..3cca0a2a47 100644 --- a/src/ol/format/GML3.js +++ b/src/ol/format/GML3.js @@ -13,6 +13,7 @@ import { XML_SCHEMA_INSTANCE_URI, createElementNS, getAllTextContent, + makeArrayExtender, makeArrayPusher, makeChildAppender, makeReplacer, @@ -189,13 +190,7 @@ class GML3 extends GMLBase { * @return {Array|undefined} flat coordinates. */ readSegment(node, objectStack) { - return pushParseAndPop( - [null], - this.SEGMENTS_PARSERS, - node, - objectStack, - this - ); + return pushParseAndPop([], this.SEGMENTS_PARSERS, node, objectStack, this); } /** @@ -1161,7 +1156,9 @@ GML3.prototype.PATCHES_PARSERS = { */ GML3.prototype.SEGMENTS_PARSERS = { 'http://www.opengis.net/gml': { - 'LineStringSegment': makeReplacer(GML3.prototype.readLineStringSegment), + 'LineStringSegment': makeArrayExtender( + GML3.prototype.readLineStringSegment + ), }, }; diff --git a/src/ol/format/GML32.js b/src/ol/format/GML32.js index 193d9b2378..6519564e99 100644 --- a/src/ol/format/GML32.js +++ b/src/ol/format/GML32.js @@ -169,7 +169,9 @@ GML32.prototype.PATCHES_PARSERS = { */ GML32.prototype.SEGMENTS_PARSERS = { 'http://www.opengis.net/gml/3.2': { - 'LineStringSegment': makeReplacer(GML3.prototype.readLineStringSegment), + 'LineStringSegment': makeArrayExtender( + GML3.prototype.readLineStringSegment + ), }, }; diff --git a/test/browser/spec/ol/format/gml.test.js b/test/browser/spec/ol/format/gml.test.js index 3c28d0c46e..d793d26be4 100644 --- a/test/browser/spec/ol/format/gml.test.js +++ b/test/browser/spec/ol/format/gml.test.js @@ -2252,6 +2252,44 @@ describe('ol.format.GML32', function () { const serialized = format.writeGeometryNode(g); expect(serialized.firstElementChild).to.xmleql(parse(text)); }); + + it('can read and write a curve geometry', function () { + const text = + '' + + ' ' + + ' ' + + ' 1 2 3 4' + + ' ' + + ' ' + + ' 5 6 7 8' + + ' ' + + ' ' + + ''; + const g = readGeometry(format, text); + expect(g).to.be.an(LineString); + expect(g.getCoordinates()).to.eql([ + [1, 2, 0], + [3, 4, 0], + [5, 6, 0], + [7, 8, 0], + ]); + format = new GML32({srsName: 'CRS:84', curve: true}); + const serialized = format.writeGeometryNode(g); + // Conversion back to GML is not lossless, because we don't know + // the mapping of original LineString segements to the OpenLayers + // LineString geometry's coordinates. + const expected = + '' + + ' ' + + ' ' + + ' 1 2 3 4 5 6 7 8' + + ' ' + + ' ' + + ''; + expect(serialized.firstElementChild).to.xmleql(parse(expected)); + }); }); describe('envelope', function () { From e86396059911f33af97f76192a69d84084ee7ada Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 10 Jun 2022 18:17:26 +0200 Subject: [PATCH 2/2] Support reading polygons with curve rings --- src/ol/format/GML3.js | 32 ++++++++++++++++++++++++ src/ol/format/GML32.js | 8 +++++- test/browser/spec/ol/format/gml.test.js | 33 +++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/ol/format/GML3.js b/src/ol/format/GML3.js index 3cca0a2a47..28ab6ee76f 100644 --- a/src/ol/format/GML3.js +++ b/src/ol/format/GML3.js @@ -134,6 +134,27 @@ class GML3 extends GMLBase { } } + /** + * @param {Element} node Node. + * @param {Array<*>} objectStack Object stack. + * @return {Array|undefined} Polygon. + */ + readFlatCurveRing(node, objectStack) { + /** @type {Array} */ + const lineStrings = pushParseAndPop( + [], + this.MULTICURVE_PARSERS, + node, + objectStack, + this + ); + const flatCoordinates = []; + for (let i = 0, ii = lineStrings.length; i < ii; ++i) { + extend(flatCoordinates, lineStrings[i].getFlatCoordinates()); + } + return flatCoordinates; + } + /** * @param {Element} node Node. * @param {Array<*>} objectStack Object stack. @@ -1162,6 +1183,17 @@ GML3.prototype.SEGMENTS_PARSERS = { }, }; +/** + * @const + * @type {Object>} + */ +GMLBase.prototype.RING_PARSERS = { + 'http://www.opengis.net/gml': { + 'LinearRing': makeReplacer(GMLBase.prototype.readFlatLinearRing), + 'Ring': makeReplacer(GML3.prototype.readFlatCurveRing), + }, +}; + /** * Encode an array of features in GML 3.1.1 Simple Features. * diff --git a/src/ol/format/GML32.js b/src/ol/format/GML32.js index 6519564e99..7063b538a6 100644 --- a/src/ol/format/GML32.js +++ b/src/ol/format/GML32.js @@ -4,7 +4,12 @@ import GML2 from './GML2.js'; import GML3 from './GML3.js'; import GMLBase from './GMLBase.js'; -import {makeArrayPusher, makeChildAppender, makeReplacer} from '../xml.js'; +import { + makeArrayExtender, + makeArrayPusher, + makeChildAppender, + makeReplacer, +} from '../xml.js'; import {writeStringTextNode} from '../format/xsd.js'; /** @@ -249,6 +254,7 @@ GML32.prototype.POLYGONMEMBER_PARSERS = { GML32.prototype.RING_PARSERS = { 'http://www.opengis.net/gml/3.2': { 'LinearRing': makeReplacer(GMLBase.prototype.readFlatLinearRing), + 'Ring': makeReplacer(GML32.prototype.readFlatCurveRing), }, }; diff --git a/test/browser/spec/ol/format/gml.test.js b/test/browser/spec/ol/format/gml.test.js index d793d26be4..efd4e7dcb9 100644 --- a/test/browser/spec/ol/format/gml.test.js +++ b/test/browser/spec/ol/format/gml.test.js @@ -2290,6 +2290,39 @@ describe('ol.format.GML32', function () { ''; expect(serialized.firstElementChild).to.xmleql(parse(expected)); }); + + it('can read a polygon with a ring of curves', function () { + const text = ` + + + + + + + + 1 2 3 4 + + + 5 6 7 8 + + + + + + + + `; + const g = readGeometry(format, text); + expect(g).to.be.an(Polygon); + expect(g.getCoordinates()).to.eql([ + [ + [1, 2, 0], + [3, 4, 0], + [5, 6, 0], + [7, 8, 0], + ], + ]); + }); }); describe('envelope', function () {