aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/io.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-10-30 16:56:41 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-10-30 17:49:39 +0100
commit9095cf6fa351b5e6208cec811b86eb3d958c6f06 (patch)
tree771aed528565271f68509090396e6ed4555802dc /src/iso19111/io.cpp
parentfc769bbd9a4fb61e96e500788d24d1d12019a4d0 (diff)
downloadPROJ-9095cf6fa351b5e6208cec811b86eb3d958c6f06.tar.gz
PROJ-9095cf6fa351b5e6208cec811b86eb3d958c6f06.zip
createFromWkt(): be tolerant to missing scale_factor parameter (fixes #1700)
This is invalid WKT, but GDAL 2.4 used to accept it and make a reasonable use of it... Currently we default it to 0 which is non sensical. Better use 1 as GDAL 2.4 did, and emit a warning. Other fix: proj_create_from_wkt() was documented to operate by default in non-strict validation mode, but it was actually in strict mode. So do as documented.
Diffstat (limited to 'src/iso19111/io.cpp')
-rw-r--r--src/iso19111/io.cpp55
1 files changed, 54 insertions, 1 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index fc66b6c9..50ad5a87 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -3476,6 +3476,14 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
}
propertiesMethod.set(IdentifiedObject::NAME_KEY, projectionName);
+ std::vector<bool> foundParameters;
+ if (mapping) {
+ size_t countParams = 0;
+ while (mapping->params[countParams] != nullptr) {
+ ++countParams;
+ }
+ foundParameters.resize(countParams);
+ }
for (const auto &childNode : projCRSNode->GP()->children()) {
if (ci_equal(childNode->GP()->value(), WKTConstants::PARAMETER)) {
const auto &childNodeChildren = childNode->GP()->children();
@@ -3496,11 +3504,18 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
continue;
}
}
- const auto *paramMapping =
+ auto *paramMapping =
mapping ? getMappingFromWKT1(mapping, parameterName) : nullptr;
if (mapping &&
mapping->epsg_code == EPSG_CODE_METHOD_MERCATOR_VARIANT_B &&
ci_equal(parameterName, "latitude_of_origin")) {
+ for (size_t idx = 0; mapping->params[idx] != nullptr; ++idx) {
+ if (mapping->params[idx]->epsg_code ==
+ EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN) {
+ foundParameters[idx] = true;
+ break;
+ }
+ }
parameterName = EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN;
propertiesParameter.set(
Identifier::CODE_KEY,
@@ -3508,6 +3523,12 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
propertiesParameter.set(Identifier::CODESPACE_KEY,
Identifier::EPSG);
} else if (paramMapping) {
+ for (size_t idx = 0; mapping->params[idx] != nullptr; ++idx) {
+ if (mapping->params[idx] == paramMapping) {
+ foundParameters[idx] = true;
+ break;
+ }
+ }
parameterName = paramMapping->wkt2_name;
if (paramMapping->epsg_code != 0) {
propertiesParameter.set(Identifier::CODE_KEY,
@@ -3531,6 +3552,38 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
}
}
+ // Add back important parameters that should normally be present, but
+ // are sometimes missing. Currently we only deal with Scale factor at
+ // natural origin. This is to avoid a default value of 0 to slip in later.
+ // But such WKT should be considered invalid.
+ if (mapping) {
+ for (size_t idx = 0; mapping->params[idx] != nullptr; ++idx) {
+ if (!foundParameters[idx] &&
+ mapping->params[idx]->epsg_code ==
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN) {
+
+ emitRecoverableWarning(
+ "The WKT string lacks a value "
+ "for " EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN
+ ". Default it to 1.");
+
+ PropertyMap propertiesParameter;
+ propertiesParameter.set(
+ Identifier::CODE_KEY,
+ EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN);
+ propertiesParameter.set(Identifier::CODESPACE_KEY,
+ Identifier::EPSG);
+ propertiesParameter.set(
+ IdentifiedObject::NAME_KEY,
+ EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN);
+ parameters.push_back(
+ OperationParameter::create(propertiesParameter));
+ values.push_back(ParameterValue::create(
+ Measure(1.0, UnitOfMeasure::SCALE_UNITY)));
+ }
+ }
+ }
+
return Conversion::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"),
propertiesMethod, parameters, values)