aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-11-28 19:51:49 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-11-29 00:39:06 +0100
commitff7f5da97563f697fd70eeb161dbebe24b39e8d2 (patch)
treea936d6bf846f99f41a195453055768e1ef74dfc6
parent492763fec2bb4fa9c0c52b906feda0a2a96d866c (diff)
downloadPROJ-ff7f5da97563f697fd70eeb161dbebe24b39e8d2.tar.gz
PROJ-ff7f5da97563f697fd70eeb161dbebe24b39e8d2.zip
importFromWKT: check we have a valid unit where we need one
-rw-r--r--src/io.cpp36
-rw-r--r--test/unit/test_io.cpp112
2 files changed, 99 insertions, 49 deletions
diff --git a/src/io.cpp b/src/io.cpp
index 7a0a7435..749b3e14 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -1166,6 +1166,7 @@ struct WKTParser::Private {
MeridianNNPtr buildMeridian(const WKTNodeNNPtr &node);
CoordinateSystemAxisNNPtr buildAxis(const WKTNodeNNPtr &node,
const UnitOfMeasure &unitIn,
+ const UnitOfMeasure::Type &unitType,
bool isGeocentric,
int expectedOrderNum);
@@ -2039,10 +2040,17 @@ MeridianNNPtr WKTParser::Private::buildMeridian(const WKTNodeNNPtr &node) {
// ---------------------------------------------------------------------------
+PROJ_NO_RETURN static void ThrowParsingExceptionMissingUNIT() {
+ throw ParsingException("buildCS: missing UNIT");
+}
+
+// ---------------------------------------------------------------------------
+
CoordinateSystemAxisNNPtr
WKTParser::Private::buildAxis(const WKTNodeNNPtr &node,
- const UnitOfMeasure &unitIn, bool isGeocentric,
- int expectedOrderNum) {
+ const UnitOfMeasure &unitIn,
+ const UnitOfMeasure::Type &unitType,
+ bool isGeocentric, int expectedOrderNum) {
const auto *nodeP = node->GP();
const auto &children = nodeP->children();
if (children.size() < 2) {
@@ -2128,7 +2136,8 @@ WKTParser::Private::buildAxis(const WKTNodeNNPtr &node,
abbreviation = AxisAbbreviation::Y;
direction = &AxisDirection::GEOCENTRIC_Y;
} else if (isGeocentric && axisName == AxisName::Geocentric_Z &&
- dirString == AxisDirectionWKT1::NORTH.toString()) {
+ (dirString == AxisDirectionWKT1::NORTH.toString() ||
+ dirString == AxisDirectionWKT1::OTHER.toString())) {
abbreviation = AxisAbbreviation::Z;
direction = &AxisDirection::GEOCENTRIC_Z;
} else if (dirString == AxisDirectionWKT1::OTHER.toString()) {
@@ -2146,6 +2155,11 @@ WKTParser::Private::buildAxis(const WKTNodeNNPtr &node,
// If no unit in the AXIS node, use the one potentially coming from
// the CS.
unit = unitIn;
+ if (unit == UnitOfMeasure::NONE &&
+ unitType != UnitOfMeasure::Type::NONE &&
+ unitType != UnitOfMeasure::Type::TIME) {
+ ThrowParsingExceptionMissingUNIT();
+ }
}
auto &meridianNode = nodeP->lookForChild(WKTConstants::MERIDIAN);
@@ -2165,10 +2179,6 @@ PROJ_NO_RETURN static void ThrowParsingException(const std::string &msg) {
throw ParsingException(msg);
}
-PROJ_NO_RETURN static void ThrowParsingExceptionMissingUNIT() {
- throw ParsingException("buildCS: missing UNIT");
-}
-
static ParsingException
buildParsingExceptionInvalidAxisCount(const std::string &csType) {
return ParsingException(
@@ -2331,8 +2341,7 @@ WKTParser::Private::buildCS(const WKTNodeNNPtr &node, /* maybe null */
"and number of AXIS are inconsistent");
}
- UnitOfMeasure unit = buildUnitInSubNode(
- parentNode,
+ const auto unitType =
ci_equal(csType, "ellipsoidal")
? UnitOfMeasure::Type::ANGULAR
: ci_equal(csType, "ordinal")
@@ -2347,13 +2356,14 @@ WKTParser::Private::buildCS(const WKTNodeNNPtr &node, /* maybe null */
ci_equal(csType, "TemporalCount") ||
ci_equal(csType, "TemporalMeasure"))
? UnitOfMeasure::Type::TIME
- : UnitOfMeasure::Type::UNKNOWN);
+ : UnitOfMeasure::Type::UNKNOWN;
+ UnitOfMeasure unit = buildUnitInSubNode(parentNode, unitType);
std::vector<CoordinateSystemAxisNNPtr> axisList;
for (int i = 0; i < axisCount; i++) {
axisList.emplace_back(
buildAxis(parentNode->GP()->lookForChild(WKTConstants::AXIS, i),
- unit, isGeocentric, i + 1));
+ unit, unitType, isGeocentric, i + 1));
};
const PropertyMap &csMap = emptyPropertyMap;
@@ -3173,11 +3183,11 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
projCRSNode->countChildrenOfName(WKTConstants::AXIS) == 2 &&
&buildAxis(
projCRSNode->GP()->lookForChild(WKTConstants::AXIS, 0),
- defaultLinearUnit, false,
+ defaultLinearUnit, UnitOfMeasure::Type::LINEAR, false,
1)->direction() == &AxisDirection::SOUTH &&
&buildAxis(
projCRSNode->GP()->lookForChild(WKTConstants::AXIS, 1),
- defaultLinearUnit, false,
+ defaultLinearUnit, UnitOfMeasure::Type::LINEAR, false,
2)->direction() == &AxisDirection::WEST) {
mapping = getMapping(EPSG_CODE_METHOD_KROVAK);
}
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index a2a865ad..fa0305cc 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -768,6 +768,28 @@ TEST(wkt_parse, wkt1_geocentric) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_geocentric_with_z_OTHER) {
+ auto wkt = "GEOCCS[\"WGS 84 (geocentric)\",\n"
+ " DATUM[\"WGS_1984\",\n"
+ " SPHEROID[\"WGS 84\",6378137,298.257223563,\n"
+ " AUTHORITY[\"EPSG\",\"7030\"]],\n"
+ " AUTHORITY[\"EPSG\",\"6326\"]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " AUTHORITY[\"EPSG\",\"8901\"]],\n"
+ " UNIT[\"metre\",1,\n"
+ " AUTHORITY[\"EPSG\",9001]],\n"
+ " AXIS[\"Geocentric X\",OTHER],\n"
+ " AXIS[\"Geocentric Y\",OTHER],\n"
+ " AXIS[\"Geocentric Z\",OTHER],\n"
+ " AUTHORITY[\"EPSG\",\"4328\"]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ checkGeocentric(crs);
+}
+
+// ---------------------------------------------------------------------------
+
static void checkProjected(ProjectedCRSPtr crs, bool checkEPSGCodes = true) {
EXPECT_EQ(crs->nameStr(), "WGS 84 / UTM zone 31N");
ASSERT_EQ(crs->identifiers().size(), 1);
@@ -2641,9 +2663,10 @@ TEST(wkt_parse, LOCAL_CS_short) {
// ---------------------------------------------------------------------------
-TEST(wkt_parse, LOCAL_CS_long_one_aix) {
+TEST(wkt_parse, LOCAL_CS_long_one_axis) {
auto wkt = "LOCAL_CS[\"Engineering CRS\",\n"
" LOCAL_DATUM[\"Engineering datum\",12345],\n"
+ " UNIT[\"meter\",1],\n"
" AXIS[\"height\",up]]";
auto obj = WKTParser().createFromWKT(wkt);
@@ -2661,6 +2684,7 @@ TEST(wkt_parse, LOCAL_CS_long_one_aix) {
TEST(wkt_parse, LOCAL_CS_long_two_axis) {
auto wkt = "LOCAL_CS[\"Engineering CRS\",\n"
" LOCAL_DATUM[\"Engineering datum\",12345],\n"
+ " UNIT[\"meter\",1],\n"
" AXIS[\"Easting\",EAST],\n"
" AXIS[\"Northing\",NORTH]]";
@@ -4139,7 +4163,7 @@ TEST(wkt_parse, invalid_GEOGCS) {
TEST(wkt_parse, invalid_UNIT) {
std::string startWKT("GEODCRS[\"x\",DATUM[\"x\",SPHEROID[\"x\",1,0.5]],CS["
"ellipsoidal,2],AXIS[\"latitude\",north],AXIS["
- "\"longitude\",east,");
+ "\"longitude\",east],");
EXPECT_NO_THROW(WKTParser().createFromWKT(
startWKT + "UNIT[\"degree\",0.0174532925199433]]]"));
@@ -4228,31 +4252,35 @@ TEST(wkt_parse, invalid_CS_of_GEODCRS) {
// CS: OK
EXPECT_NO_THROW(WKTParser().createFromWKT(
startWKT + ",CS[ellipsoidal,2],AXIS[\"latitude\",north],AXIS["
- "\"longitude\",east]]"));
+ "\"longitude\",east],UNIT[\"degree\",0.0174532925199433]]"));
// CS: Cartesian with 2 axis unexpected
- EXPECT_THROW(WKTParser().createFromWKT(startWKT +
- ",CS[Cartesian,2],AXIS[\"latitude\","
- "north],AXIS[\"longitude\",east]]"),
+ EXPECT_THROW(WKTParser().createFromWKT(
+ startWKT + ",CS[Cartesian,2],AXIS[\"latitude\","
+ "north],AXIS[\"longitude\",east],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// CS: missing axis
EXPECT_THROW(WKTParser().createFromWKT(
- startWKT + ",CS[ellipsoidal,2],AXIS[\"latitude\",north]]"),
+ startWKT + ",CS[ellipsoidal,2],AXIS[\"latitude\",north],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// not enough children in AXIS
EXPECT_THROW(
WKTParser().createFromWKT(
startWKT +
- ",CS[ellipsoidal,2],AXIS[\"latitude\",north],AXIS[\"longitude\"]]"),
+ ",CS[ellipsoidal,2],AXIS[\"latitude\",north],AXIS[\"longitude\"],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// not enough children in ORDER
EXPECT_THROW(WKTParser().createFromWKT(
startWKT +
",CS[ellipsoidal,2],AXIS[\"latitude\",north,ORDER[]],AXIS["
- "\"longitude\",east]]"),
+ "\"longitude\",east],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// invalid value in ORDER
@@ -4260,7 +4288,7 @@ TEST(wkt_parse, invalid_CS_of_GEODCRS) {
WKTParser().createFromWKT(
startWKT +
",CS[ellipsoidal,2],AXIS[\"latitude\",north,ORDER[\"x\"]],AXIS["
- "\"longitude\",east]]"),
+ "\"longitude\",east],UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// unexpected ORDER value
@@ -4268,7 +4296,7 @@ TEST(wkt_parse, invalid_CS_of_GEODCRS) {
WKTParser().createFromWKT(
startWKT +
",CS[ellipsoidal,2],AXIS[\"latitude\",north,ORDER[2]],AXIS["
- "\"longitude\",east]]"),
+ "\"longitude\",east],UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// Invalid CS type
@@ -4794,7 +4822,8 @@ TEST(wkt_parse, invalid_DerivedGeographicCRS) {
" METHOD[\"bar\"]],\n"
" CS[ellipsoidal,2],\n"
" AXIS[\"latitude\",north],\n"
- " AXIS[\"longitude\",east]]"));
+ " AXIS[\"longitude\",east],\n"
+ " UNIT[\"degree\",0.0174532925199433]]"));
// Missing DERIVINGCONVERSION
EXPECT_THROW(
@@ -4805,7 +4834,8 @@ TEST(wkt_parse, invalid_DerivedGeographicCRS) {
" ELLIPSOID[\"WGS 84\",6378137,298.257223563]]],\n"
" CS[ellipsoidal,2],\n"
" AXIS[\"latitude\",north],\n"
- " AXIS[\"longitude\",east]]"),
+ " AXIS[\"longitude\",east],\n"
+ " UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// Missing CS
@@ -4982,18 +5012,20 @@ TEST(wkt_parse, invalid_LOCAL_CS) {
TEST(wkt_parse, invalid_ParametricCRS) {
- EXPECT_NO_THROW(
- WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
- " PDATUM[\"name\"],\n"
- " CS[parametric,1],\n"
- " AXIS[\"time (T)\",future]]"));
+ EXPECT_NO_THROW(WKTParser().createFromWKT(
+ "PARAMETRICCRS[\"name\",\n"
+ " PDATUM[\"name\"],\n"
+ " CS[parametric,1],\n"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]]"));
// Missing PDATUM
- EXPECT_THROW(
- WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
- " CS[parametric,1],\n"
- " AXIS[\"time (T)\",future]]"),
- ParsingException);
+ EXPECT_THROW(WKTParser().createFromWKT(
+ "PARAMETRICCRS[\"name\",\n"
+ " CS[parametric,1],\n"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]]"),
+ ParsingException);
// Missing CS
EXPECT_THROW(WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
@@ -5001,13 +5033,15 @@ TEST(wkt_parse, invalid_ParametricCRS) {
ParsingException);
// Invalid number of axis for CS
- EXPECT_THROW(
- WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
- " PDATUM[\"name\"],\n"
- " CS[parametric,2],\n"
- " AXIS[\"time (T)\",future],\n"
- " AXIS[\"time (T)\",future]]"),
- ParsingException);
+ EXPECT_THROW(WKTParser().createFromWKT(
+ "PARAMETRICCRS[\"name\",\n"
+ " PDATUM[\"name\"],\n"
+ " CS[parametric,2],\n"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]]"),
+ ParsingException);
// Invalid CS type
EXPECT_THROW(
@@ -5034,7 +5068,8 @@ TEST(wkt_parse, invalid_DERIVEDPROJCRS) {
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[Cartesian,2],\n"
" AXIS[\"(E)\",east],\n"
- " AXIS[\"(N)\",north]]"));
+ " AXIS[\"(N)\",north],\n"
+ " UNIT[\"metre\",1]]"));
EXPECT_THROW(
WKTParser().createFromWKT("DERIVEDPROJCRS[\"derived projectedCRS\",\n"
@@ -5042,7 +5077,8 @@ TEST(wkt_parse, invalid_DERIVEDPROJCRS) {
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[Cartesian,2],\n"
" AXIS[\"(E)\",east],\n"
- " AXIS[\"(N)\",north]]"),
+ " AXIS[\"(N)\",north],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
// Missing DERIVINGCONVERSION
@@ -5058,7 +5094,8 @@ TEST(wkt_parse, invalid_DERIVEDPROJCRS) {
" METHOD[\"PROJ unimplemented\"]]],\n"
" CS[Cartesian,2],\n"
" AXIS[\"(E)\",east],\n"
- " AXIS[\"(N)\",north]]"),
+ " AXIS[\"(N)\",north],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
// Missing CS
@@ -5087,7 +5124,8 @@ TEST(wkt_parse, invalid_DerivedVerticalCRS) {
" DERIVINGCONVERSION[\"unnamed\",\n"
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[vertical,1],\n"
- " AXIS[\"gravity-related height (H)\",up]]"));
+ " AXIS[\"gravity-related height (H)\",up],\n"
+ " UNIT[\"metre\",1]]"));
// Missing DERIVINGCONVERSION
EXPECT_THROW(WKTParser().createFromWKT(
@@ -5095,7 +5133,8 @@ TEST(wkt_parse, invalid_DerivedVerticalCRS) {
" BASEVERTCRS[\"ODN height\",\n"
" VDATUM[\"Ordnance Datum Newlyn\"]],\n"
" CS[vertical,1],\n"
- " AXIS[\"gravity-related height (H)\",up]]"),
+ " AXIS[\"gravity-related height (H)\",up],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
// Missing CS
@@ -5115,7 +5154,8 @@ TEST(wkt_parse, invalid_DerivedVerticalCRS) {
" DERIVINGCONVERSION[\"unnamed\",\n"
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[parametric,1],\n"
- " AXIS[\"gravity-related height (H)\",up]]"),
+ " AXIS[\"gravity-related height (H)\",up],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
}