Rework transformWithOptions

Create one function per input/output type: `transformGeometryWithOptions` and `transformExtentWithOptions`.
This commit is contained in:
Frederic Junod
2018-12-12 13:58:03 +01:00
parent b546eafeae
commit d838de32b7
14 changed files with 76 additions and 95 deletions

View File

@@ -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);
}

View File

@@ -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.
*/
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}
* @return {import("../geom/Geometry.js").default} Transformed geometry.
*/
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(
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;
}
}

View File

@@ -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);
value = transformExtentWithOptions(/** @type {import("../extent.js").Extent} */ (geometry), context);
} else {
value = geometry;
}
} 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_,

View File

@@ -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);
value = transformExtentWithOptions(/** @type {import("../extent.js").Extent} */ (geometry), context);
} else {
value = geometry;
}
} 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_,

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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} */

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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)));
}
}