diff --git a/src/ol/format/EsriJSON.js b/src/ol/format/EsriJSON.js index 03b25d30b4..5563aad817 100644 --- a/src/ol/format/EsriJSON.js +++ b/src/ol/format/EsriJSON.js @@ -4,7 +4,7 @@ import Feature from '../Feature.js'; import {assert} from '../asserts.js'; import {containsExtent} from '../extent.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import JSONFeature from './JSONFeature.js'; import GeometryLayout from '../geom/GeometryLayout.js'; import GeometryType from '../geom/GeometryType.js'; @@ -263,9 +263,7 @@ function readGeometry(object, opt_options) { } } const geometryReader = GEOMETRY_READERS[type]; - return ( - /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometryReader(object), false, opt_options)) - ); + return transformGeometryWithOptions(geometryReader(object), false, opt_options); } @@ -563,8 +561,7 @@ function writeMultiPolygonGeometry(geometry, opt_options) { */ function writeGeometry(geometry, opt_options) { const geometryWriter = GEOMETRY_WRITERS[geometry.getType()]; - return geometryWriter(/** @type {import("../geom/Geometry.js").default} */( - transformWithOptions(geometry, true, opt_options)), opt_options); + return geometryWriter(transformGeometryWithOptions(geometry, true, opt_options), opt_options); } diff --git a/src/ol/format/Feature.js b/src/ol/format/Feature.js index e439e887af..1cba700b0e 100644 --- a/src/ol/format/Feature.js +++ b/src/ol/format/Feature.js @@ -214,39 +214,24 @@ class FeatureFormat { export default FeatureFormat; /** - * @param {import("../geom/Geometry.js").default|import("../extent.js").Extent} geometry Geometry. + * @param {import("../geom/Geometry.js").default} geometry Geometry. * @param {boolean} write Set to true for writing, false for reading. * @param {(WriteOptions|ReadOptions)=} opt_options Options. - * @return {import("../geom/Geometry.js").default|import("../extent.js").Extent} Transformed geometry. + * @return {import("../geom/Geometry.js").default} Transformed geometry. */ -export function transformWithOptions(geometry, write, opt_options) { - const featureProjection = opt_options ? - getProjection(opt_options.featureProjection) : null; - const dataProjection = opt_options ? - getProjection(opt_options.dataProjection) : null; - /** - * @type {import("../geom/Geometry.js").default|import("../extent.js").Extent} - */ +export function transformGeometryWithOptions(geometry, write, opt_options) { + const featureProjection = opt_options ? getProjection(opt_options.featureProjection) : null; + const dataProjection = opt_options ? getProjection(opt_options.dataProjection) : null; + let transformed; - if (featureProjection && dataProjection && - !equivalentProjection(featureProjection, dataProjection)) { - if (Array.isArray(geometry)) { - // FIXME this is necessary because GML treats extents - // as geometries - transformed = transformExtent( - geometry, - dataProjection, - featureProjection); - } else { - transformed = (write ? /** @type {import("../geom/Geometry").default} */ (geometry).clone() : geometry).transform( - write ? featureProjection : dataProjection, - write ? dataProjection : featureProjection); - } + if (featureProjection && dataProjection && !equivalentProjection(featureProjection, dataProjection)) { + transformed = (write ? geometry.clone() : geometry).transform( + write ? featureProjection : dataProjection, + write ? dataProjection : featureProjection); } else { transformed = geometry; } - if (write && opt_options && /** @type {WriteOptions} */ (opt_options).decimals !== undefined && - !Array.isArray(transformed)) { + if (write && opt_options && /** @type {WriteOptions} */ (opt_options).decimals !== undefined) { const power = Math.pow(10, /** @type {WriteOptions} */ (opt_options).decimals); // if decimals option on write, round each coordinate appropriately /** @@ -260,9 +245,26 @@ export function transformWithOptions(geometry, write, opt_options) { return coordinates; }; if (transformed === geometry) { - transformed = /** @type {import("../geom/Geometry").default} */ (geometry).clone(); + transformed = geometry.clone(); } transformed.applyTransform(transform); } return transformed; } + + +/** + * @param {import("../extent.js").Extent} extent Extent. + * @param {ReadOptions=} opt_options Read options. + * @return {import("../extent.js").Extent} Transformed extent. + */ +export function transformExtentWithOptions(extent, opt_options) { + const featureProjection = opt_options ? getProjection(opt_options.featureProjection) : null; + const dataProjection = opt_options ? getProjection(opt_options.dataProjection) : null; + + if (featureProjection && dataProjection && !equivalentProjection(featureProjection, dataProjection)) { + return transformExtent(extent, dataProjection, featureProjection); + } else { + return extent; + } +} diff --git a/src/ol/format/GML2.js b/src/ol/format/GML2.js index 1b2a7930e8..596ff706bd 100644 --- a/src/ol/format/GML2.js +++ b/src/ol/format/GML2.js @@ -2,11 +2,11 @@ * @module ol/format/GML2 */ import {createOrUpdate} from '../extent.js'; -import {transformWithOptions} from './Feature.js'; +import {transformExtentWithOptions, transformGeometryWithOptions} from './Feature.js'; import GMLBase, {GMLNS} from './GMLBase.js'; import {writeStringTextNode} from './xsd.js'; import {assign} from '../obj.js'; -import {get as getProjection, transformExtent} from '../proj.js'; +import {get as getProjection} from '../proj.js'; import {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender, makeReplacer, makeSimpleNodeFactory, OBJECT_PROPERTY_NODE_FACTORY, pushParseAndPop, pushSerializeAndPop} from '../xml.js'; @@ -287,14 +287,9 @@ class GML2 extends GMLBase { item['node'] = node; let value; if (Array.isArray(geometry)) { - if (context.dataProjection) { - value = transformExtent( - geometry, context.featureProjection, context.dataProjection); - } else { - value = geometry; - } + value = transformExtentWithOptions(/** @type {import("../extent.js").Extent} */ (geometry), context); } else { - value = transformWithOptions(/** @type {import("../geom/Geometry.js").default} */ (geometry), true, context); + value = transformGeometryWithOptions(/** @type {import("../geom/Geometry.js").default} */ (geometry), true, context); } pushSerializeAndPop(/** @type {import("../xml.js").NodeStackItem} */ (item), this.GEOMETRY_SERIALIZERS_, diff --git a/src/ol/format/GML3.js b/src/ol/format/GML3.js index 71e35a2b03..e6fd12d07d 100644 --- a/src/ol/format/GML3.js +++ b/src/ol/format/GML3.js @@ -3,7 +3,7 @@ */ import {extend} from '../array.js'; import {createOrUpdate} from '../extent.js'; -import {transformWithOptions} from './Feature.js'; +import {transformExtentWithOptions, transformGeometryWithOptions} from './Feature.js'; import GMLBase, {GMLNS} from './GMLBase.js'; import {readNonNegativeIntegerString, writeStringTextNode} from './xsd.js'; import GeometryLayout from '../geom/GeometryLayout.js'; @@ -12,7 +12,7 @@ import MultiLineString from '../geom/MultiLineString.js'; import MultiPolygon from '../geom/MultiPolygon.js'; import Polygon from '../geom/Polygon.js'; import {assign} from '../obj.js'; -import {get as getProjection, transformExtent} from '../proj.js'; +import {get as getProjection} from '../proj.js'; import {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender, makeReplacer, makeSimpleNodeFactory, OBJECT_PROPERTY_NODE_FACTORY, parseNode, pushParseAndPop, pushSerializeAndPop, XML_SCHEMA_INSTANCE_URI} from '../xml.js'; @@ -733,14 +733,9 @@ class GML3 extends GMLBase { item['node'] = node; let value; if (Array.isArray(geometry)) { - if (context.dataProjection) { - value = transformExtent( - geometry, context.featureProjection, context.dataProjection); - } else { - value = geometry; - } + value = transformExtentWithOptions(/** @type {import("../extent.js").Extent} */ (geometry), context); } else { - value = transformWithOptions(/** @type {import("../geom/Geometry.js").default} */ (geometry), true, context); + value = transformGeometryWithOptions(/** @type {import("../geom/Geometry.js").default} */ (geometry), true, context); } pushSerializeAndPop(/** @type {import("../xml.js").NodeStackItem} */ (item), this.GEOMETRY_SERIALIZERS_, diff --git a/src/ol/format/GMLBase.js b/src/ol/format/GMLBase.js index 410c09c2f6..64fb5cb289 100644 --- a/src/ol/format/GMLBase.js +++ b/src/ol/format/GMLBase.js @@ -6,7 +6,7 @@ // envelopes/extents, only geometries! import {extend} from '../array.js'; import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions, transformExtentWithOptions} from './Feature.js'; import XMLFeature from './XMLFeature.js'; import GeometryLayout from '../geom/GeometryLayout.js'; import LineString from '../geom/LineString.js'; @@ -216,18 +216,19 @@ class GMLBase extends XMLFeature { /** * @param {Element} node Node. * @param {Array<*>} objectStack Object stack. - * @return {import("../geom/Geometry.js").default|undefined} Geometry. + * @return {import("../geom/Geometry.js").default|import("../extent.js").Extent|undefined} Geometry. */ readGeometryElement(node, objectStack) { const context = /** @type {Object} */ (objectStack[0]); context['srsName'] = node.firstElementChild.getAttribute('srsName'); context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension'); - /** @type {import("../geom/Geometry.js").default} */ const geometry = pushParseAndPop(null, this.GEOMETRY_PARSERS, node, objectStack, this); if (geometry) { - return ( - /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, false, context)) - ); + if (Array.isArray(geometry)) { + return transformExtentWithOptions(/** @type {import("../extent.js").Extent} */ (geometry), context); + } else { + return transformGeometryWithOptions(/** @type {import("../geom/Geometry.js").default} */ (geometry), false, context); + } } else { return undefined; } diff --git a/src/ol/format/GPX.js b/src/ol/format/GPX.js index 5d3ba4988e..0b4b8bb807 100644 --- a/src/ol/format/GPX.js +++ b/src/ol/format/GPX.js @@ -3,7 +3,7 @@ */ import Feature from '../Feature.js'; import {includes} from '../array.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import XMLFeature from './XMLFeature.js'; import {readString, readDecimal, readNonNegativeInteger, readDateTime, writeStringTextNode, writeNonNegativeIntegerTextNode, writeDecimalTextNode, writeDateTimeTextNode} from './xsd.js'; import GeometryLayout from '../geom/GeometryLayout.js'; @@ -649,7 +649,7 @@ function readRte(node, objectStack) { delete values['layoutOptions']; const layout = applyLayoutOptions(layoutOptions, flatCoordinates); const geometry = new LineString(flatCoordinates, layout); - transformWithOptions(geometry, false, options); + transformGeometryWithOptions(geometry, false, options); const feature = new Feature(geometry); feature.setProperties(values); return feature; @@ -680,7 +680,7 @@ function readTrk(node, objectStack) { delete values['layoutOptions']; const layout = applyLayoutOptions(layoutOptions, flatCoordinates, ends); const geometry = new MultiLineString(flatCoordinates, layout, ends); - transformWithOptions(geometry, false, options); + transformGeometryWithOptions(geometry, false, options); const feature = new Feature(geometry); feature.setProperties(values); return feature; @@ -702,7 +702,7 @@ function readWpt(node, objectStack) { const coordinates = appendCoordinate([], layoutOptions, node, values); const layout = applyLayoutOptions(layoutOptions, coordinates); const geometry = new Point(coordinates, layout); - transformWithOptions(geometry, false, options); + transformGeometryWithOptions(geometry, false, options); const feature = new Feature(geometry); feature.setProperties(values); return feature; @@ -784,7 +784,7 @@ function writeRte(node, feature, objectStack) { context['properties'] = properties; const geometry = feature.getGeometry(); if (geometry.getType() == GeometryType.LINE_STRING) { - const lineString = /** @type {LineString} */ (transformWithOptions(geometry, true, options)); + const lineString = /** @type {LineString} */ (transformGeometryWithOptions(geometry, true, options)); context['geometryLayout'] = lineString.getLayout(); properties['rtept'] = lineString.getCoordinates(); } @@ -810,7 +810,7 @@ function writeTrk(node, feature, objectStack) { context['properties'] = properties; const geometry = feature.getGeometry(); if (geometry.getType() == GeometryType.MULTI_LINE_STRING) { - const multiLineString = /** @type {MultiLineString} */ (transformWithOptions(geometry, true, options)); + const multiLineString = /** @type {MultiLineString} */ (transformGeometryWithOptions(geometry, true, options)); properties['trkseg'] = multiLineString.getLineStrings(); } const parentNode = objectStack[objectStack.length - 1].node; @@ -849,7 +849,7 @@ function writeWpt(node, feature, objectStack) { context['properties'] = feature.getProperties(); const geometry = feature.getGeometry(); if (geometry.getType() == GeometryType.POINT) { - const point = /** @type {Point} */ (transformWithOptions(geometry, true, options)); + const point = /** @type {Point} */ (transformGeometryWithOptions(geometry, true, options)); context['geometryLayout'] = point.getLayout(); writeWptType(node, point.getCoordinates(), objectStack); } diff --git a/src/ol/format/GeoJSON.js b/src/ol/format/GeoJSON.js index c73cb17b95..8b05f7780d 100644 --- a/src/ol/format/GeoJSON.js +++ b/src/ol/format/GeoJSON.js @@ -4,7 +4,7 @@ import {assert} from '../asserts.js'; import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import JSONFeature from './JSONFeature.js'; import GeometryCollection from '../geom/GeometryCollection.js'; import LineString from '../geom/LineString.js'; @@ -293,7 +293,7 @@ function readGeometry(object, opt_options) { throw new Error('Unsupported GeoJSON type: ' + object.type); } } - return /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, false, opt_options)); + return transformGeometryWithOptions(geometry, false, opt_options); } @@ -375,7 +375,7 @@ function readPolygonGeometry(object) { * @return {GeoJSONGeometry} GeoJSON geometry. */ function writeGeometry(geometry, opt_options) { - geometry = /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, true, opt_options)); + geometry = transformGeometryWithOptions(geometry, true, opt_options); const type = geometry.getType(); /** @type {GeoJSONGeometry} */ diff --git a/src/ol/format/IGC.js b/src/ol/format/IGC.js index 17c2f6accf..3c173d12cb 100644 --- a/src/ol/format/IGC.js +++ b/src/ol/format/IGC.js @@ -2,7 +2,7 @@ * @module ol/format/IGC */ import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import TextFeature from './TextFeature.js'; import GeometryLayout from '../geom/GeometryLayout.js'; import LineString from '../geom/LineString.js'; @@ -158,7 +158,7 @@ class IGC extends TextFeature { } const layout = altitudeMode == IGCZ.NONE ? GeometryLayout.XYM : GeometryLayout.XYZM; const lineString = new LineString(flatCoordinates, layout); - const feature = new Feature(transformWithOptions(lineString, false, opt_options)); + const feature = new Feature(transformGeometryWithOptions(lineString, false, opt_options)); feature.setProperties(properties); return feature; } diff --git a/src/ol/format/KML.js b/src/ol/format/KML.js index 672d7f267e..49e0b8c3e1 100644 --- a/src/ol/format/KML.js +++ b/src/ol/format/KML.js @@ -5,7 +5,7 @@ import Feature from '../Feature.js'; import {extend, includes} from '../array.js'; import {assert} from '../asserts.js'; import {asArray} from '../color.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import XMLFeature from './XMLFeature.js'; import {readDecimal, readBoolean, readString, writeStringTextNode, writeCDATASection, writeDecimalTextNode, writeBooleanTextNode} from './xsd.js'; import GeometryCollection from '../geom/GeometryCollection.js'; @@ -500,7 +500,7 @@ class KML extends XMLFeature { const geometry = object['geometry']; if (geometry) { - transformWithOptions(geometry, false, options); + transformGeometryWithOptions(geometry, false, options); } feature.setGeometry(geometry); delete object['geometry']; @@ -2717,7 +2717,7 @@ function writePlacemark(node, feature, objectStack) { const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]); let geometry = feature.getGeometry(); if (geometry) { - geometry = /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, true, options)); + geometry = transformGeometryWithOptions(geometry, true, options); } pushSerializeAndPop(context, PLACEMARK_SERIALIZERS, GEOMETRY_NODE_FACTORY, [geometry], objectStack); diff --git a/src/ol/format/MVT.js b/src/ol/format/MVT.js index 6977299acf..8a47aad0b7 100644 --- a/src/ol/format/MVT.js +++ b/src/ol/format/MVT.js @@ -5,7 +5,7 @@ import {assert} from '../asserts.js'; import PBF from 'pbf'; -import FeatureFormat, {transformWithOptions} from './Feature.js'; +import FeatureFormat, {transformGeometryWithOptions} from './Feature.js'; import FormatType from './FormatType.js'; import GeometryLayout from '../geom/GeometryLayout.js'; import GeometryType from '../geom/GeometryType.js'; @@ -214,8 +214,7 @@ class MVT extends FeatureFormat { if (this.geometryName_) { feature.setGeometryName(this.geometryName_); } - const geometry = /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geom, false, - this.adaptOptions(opt_options))); + const geometry = transformGeometryWithOptions(geom, false, this.adaptOptions(opt_options)); feature.setGeometry(geometry); feature.setId(id); feature.setProperties(values); diff --git a/src/ol/format/OSMXML.js b/src/ol/format/OSMXML.js index 7ffe0bf6b0..050ad80b2e 100644 --- a/src/ol/format/OSMXML.js +++ b/src/ol/format/OSMXML.js @@ -4,7 +4,7 @@ // FIXME add typedef for stack state objects import {extend} from '../array.js'; import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import XMLFeature from './XMLFeature.js'; import GeometryLayout from '../geom/GeometryLayout.js'; import LineString from '../geom/LineString.js'; @@ -88,7 +88,7 @@ class OSMXML extends XMLFeature { } else { geometry = new LineString(flatCoordinates, GeometryLayout.XY); } - transformWithOptions(geometry, false, options); + transformGeometryWithOptions(geometry, false, options); const feature = new Feature(geometry); feature.setId(values.id); feature.setProperties(values.tags); @@ -134,7 +134,7 @@ function readNode(node, objectStack) { }, NODE_PARSERS, node, objectStack); if (!isEmpty(values.tags)) { const geometry = new Point(coordinates); - transformWithOptions(geometry, false, options); + transformGeometryWithOptions(geometry, false, options); const feature = new Feature(geometry); feature.setId(id); feature.setProperties(values.tags); diff --git a/src/ol/format/Polyline.js b/src/ol/format/Polyline.js index e92c3defc4..d28f2c4e2f 100644 --- a/src/ol/format/Polyline.js +++ b/src/ol/format/Polyline.js @@ -3,7 +3,7 @@ */ import {assert} from '../asserts.js'; import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import TextFeature from './TextFeature.js'; import GeometryLayout from '../geom/GeometryLayout.js'; import LineString from '../geom/LineString.js'; @@ -89,14 +89,9 @@ class Polyline extends TextFeature { const flatCoordinates = decodeDeltas(text, stride, this.factor_); flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates); const coordinates = inflateCoordinates(flatCoordinates, 0, flatCoordinates.length, stride); + const lineString = new LineString(coordinates, this.geometryLayout_); - return ( - /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions( - new LineString(coordinates, this.geometryLayout_), - false, - this.adaptOptions(opt_options) - )) - ); + return transformGeometryWithOptions(lineString, false, this.adaptOptions(opt_options)); } /** @@ -124,7 +119,7 @@ class Polyline extends TextFeature { */ writeGeometryText(geometry, opt_options) { geometry = /** @type {LineString} */ - (transformWithOptions(geometry, true, this.adaptOptions(opt_options))); + (transformGeometryWithOptions(geometry, true, this.adaptOptions(opt_options))); const flatCoordinates = geometry.getFlatCoordinates(); const stride = geometry.getStride(); flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates); diff --git a/src/ol/format/TopoJSON.js b/src/ol/format/TopoJSON.js index d5f2bb2e9f..d86701e589 100644 --- a/src/ol/format/TopoJSON.js +++ b/src/ol/format/TopoJSON.js @@ -2,7 +2,7 @@ * @module ol/format/TopoJSON */ import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import JSONFeature from './JSONFeature.js'; import LineString from '../geom/LineString.js'; import MultiLineString from '../geom/MultiLineString.js'; @@ -338,8 +338,7 @@ function readFeatureFromGeometry(object, arcs, scale, translate, property, name, geometry = geometryReader(object, arcs); } const feature = new Feature(); - feature.setGeometry(/** @type {import("../geom/Geometry.js").default} */ ( - transformWithOptions(geometry, false, opt_options))); + feature.setGeometry(transformGeometryWithOptions(geometry, false, opt_options)); if (object.id !== undefined) { feature.setId(object.id); } diff --git a/src/ol/format/WKT.js b/src/ol/format/WKT.js index 284dadeef0..ae5b9ed10f 100644 --- a/src/ol/format/WKT.js +++ b/src/ol/format/WKT.js @@ -2,7 +2,7 @@ * @module ol/format/WKT */ import Feature from '../Feature.js'; -import {transformWithOptions} from './Feature.js'; +import {transformGeometryWithOptions} from './Feature.js'; import TextFeature from './TextFeature.js'; import GeometryCollection from '../geom/GeometryCollection.js'; import GeometryType from '../geom/GeometryType.js'; @@ -682,9 +682,7 @@ class WKT extends TextFeature { readGeometryFromText(text, opt_options) { const geometry = this.parse_(text); if (geometry) { - return ( - /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, false, opt_options)) - ); + return transformGeometryWithOptions(geometry, false, opt_options); } else { return null; } @@ -721,7 +719,7 @@ class WKT extends TextFeature { */ writeGeometryText(geometry, opt_options) { return encode(/** @type {import("../geom/Geometry.js").default} */ ( - transformWithOptions(geometry, true, opt_options))); + transformGeometryWithOptions(geometry, true, opt_options))); } }