Skip to content

Commit

Permalink
Merge dc666ad into 67c49f2
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed May 9, 2023
2 parents 67c49f2 + dc666ad commit 49d0c53
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 17 deletions.
10 changes: 9 additions & 1 deletion scripts/build_esri_projection_mapping.py
Expand Up @@ -289,6 +289,15 @@
- Scale_Factor: EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN
- Latitude_Of_Origin: EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN
- Polar_Stereographic_Variant_A:
WKT2_name: EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A
Params:
- False_Easting: EPSG_NAME_PARAMETER_FALSE_EASTING
- False_Northing: EPSG_NAME_PARAMETER_FALSE_NORTHING
- Central_Meridian: EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN
- Scale_Factor: EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN
- Latitude_Of_Origin: EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN
- Equidistant_Conic:
WKT2_name: PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC
Params:
Expand Down Expand Up @@ -740,7 +749,6 @@
# Missing mappings
# Transverse_Mercator_NGA_2014: utm -- tricky mapping from Central_Meridian to zone
# Polar_Stereographic_Variant_A: ups -- tricky mapping from Latitude_Of_Origin to "+south" when required
# Transverse Mercator: alias for Transverse_Mercator, as seen in ESRI:102470 - ESRI:102489
Expand Down
10 changes: 1 addition & 9 deletions src/iso19111/io.cpp
Expand Up @@ -4388,15 +4388,7 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {

const std::string projCRSName = stripQuotes(nodeP->children()[0]);
if (esriStyle_ && dbContext_) {
// It is likely that the ESRI definition of EPSG:32661 (UPS North) &
// EPSG:32761 (UPS South) uses the easting-northing order, instead
// of the EPSG northing-easting order
// so don't substitute names to avoid confusion.
if (projCRSName == "UPS_North") {
props.set(IdentifiedObject::NAME_KEY, "WGS 84 / UPS North (E,N)");
} else if (projCRSName == "UPS_South") {
props.set(IdentifiedObject::NAME_KEY, "WGS 84 / UPS South (E,N)");
} else if (cartesianCS) {
if (cartesianCS) {
std::string outTableName;
std::string authNameFromAlias;
std::string codeFromAlias;
Expand Down
13 changes: 13 additions & 0 deletions src/iso19111/operation/conversion.cpp
Expand Up @@ -3085,6 +3085,19 @@ static void getESRIMethodNameAndParams(const Conversion *conv,
esriParams = paramsESRI_Rectified_Skew_Orthomorphic_Center;
esriMethodName = "Rectified_Skew_Orthomorphic_Center";
}
} else if (esriMapping->epsg_code ==
EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A) {
// Quite empiric, but looking at pe_list_projcs.csv, the only
// CRS that use Polar_Stereographic_Variant_A are EPSG:5041 and 5042
if (l_targetCRS &&
// EPSG:5041
(l_targetCRS->nameStr() == "WGS 84 / UPS North (E,N)" ||
// EPSG:5042
l_targetCRS->nameStr() == "WGS 84 / UPS South (E,N)")) {
esriMethodName = "Polar_Stereographic_Variant_A";
} else {
esriMethodName = "Stereographic";
}
} else if (esriMapping->epsg_code ==
EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B) {
if (conv->parameterValueNumericAsSI(
Expand Down
17 changes: 17 additions & 0 deletions src/iso19111/operation/esriparammappings.cpp
Expand Up @@ -385,6 +385,19 @@ static const ESRIParamMapping paramsESRI_Stereographic[] = {
EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, "0.0", false},
{nullptr, nullptr, 0, "0.0", false}};

static const ESRIParamMapping paramsESRI_Polar_Stereographic_Variant_A[] = {
{"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
EPSG_CODE_PARAMETER_FALSE_EASTING, "0.0", false},
{"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
EPSG_CODE_PARAMETER_FALSE_NORTHING, "0.0", false},
{"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, "0.0", false},
{"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, "0.0", false},
{"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, "0.0", false},
{nullptr, nullptr, 0, "0.0", false}};

static const ESRIParamMapping paramsESRI_Equidistant_Conic[] = {
{"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
EPSG_CODE_PARAMETER_FALSE_EASTING, "0.0", false},
Expand Down Expand Up @@ -1033,6 +1046,10 @@ static const ESRIMethodMapping esriMappings[] = {
paramsESRI_Hotine_Oblique_Mercator_Two_Point_Natural_Origin},
{"Stereographic", PROJ_WKT2_NAME_METHOD_STEREOGRAPHIC, 0,
paramsESRI_Stereographic},
{"Polar_Stereographic_Variant_A",
EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
paramsESRI_Polar_Stereographic_Variant_A},
{"Equidistant_Conic", PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC, 0,
paramsESRI_Equidistant_Conic},
{"Cassini", EPSG_NAME_METHOD_CASSINI_SOLDNER,
Expand Down
104 changes: 97 additions & 7 deletions test/unit/test_io.cpp
Expand Up @@ -7307,6 +7307,7 @@ TEST(wkt_parse, wkt1_esri_normalize_unit) {
// ---------------------------------------------------------------------------

TEST(wkt_parse, wkt1_esri_ups_north) {
// EPSG:32661
auto wkt = "PROJCS[\"UPS_North\",GEOGCS[\"GCS_WGS_1984\","
"DATUM[\"D_WGS_1984\","
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
Expand All @@ -7319,24 +7320,32 @@ TEST(wkt_parse, wkt1_esri_ups_north) {
"PARAMETER[\"Latitude_Of_Origin\",90.0],"
"UNIT[\"Meter\",1.0]]";

auto obj = WKTParser()
.attachDatabaseContext(DatabaseContext::create())
.createFromWKT(wkt);
auto dbContext = DatabaseContext::create();
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
ASSERT_TRUE(crs != nullptr);

EXPECT_EQ(crs->nameStr(), "WGS 84 / UPS North (E,N)");
EXPECT_EQ(crs->nameStr(), "WGS 84 / UPS North (N,E)");
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->direction(),
AxisDirection::SOUTH);
// Yes, inconsistency between the name (coming from EPSG) and the fact
// that with ESRI CRS, we always output E, N axis order
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->abbreviation(), "E");
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
AxisDirection::SOUTH);
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");

EXPECT_EQ(
crs->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
.get()),
wkt);
}

// ---------------------------------------------------------------------------

TEST(wkt_parse, wkt1_esri_ups_south) {
// EPSG:32671
auto wkt = "PROJCS[\"UPS_South\",GEOGCS[\"GCS_WGS_1984\","
"DATUM[\"D_WGS_1984\","
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
Expand All @@ -7349,9 +7358,84 @@ TEST(wkt_parse, wkt1_esri_ups_south) {
"PARAMETER[\"Latitude_Of_Origin\",-90.0],"
"UNIT[\"Meter\",1.0]]";

auto obj = WKTParser()
.attachDatabaseContext(DatabaseContext::create())
.createFromWKT(wkt);
auto dbContext = DatabaseContext::create();
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
ASSERT_TRUE(crs != nullptr);

EXPECT_EQ(crs->nameStr(), "WGS 84 / UPS South (N,E)");
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->direction(),
AxisDirection::NORTH);
// Yes, inconsistency between the name (coming from EPSG) and the fact
// that with ESRI CRS, we always output E, N axis order
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->abbreviation(), "E");
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
AxisDirection::NORTH);
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");

EXPECT_EQ(
crs->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
.get()),
wkt);
}

// ---------------------------------------------------------------------------

TEST(wkt_parse, wkt1_esri_wgs_1984_ups_north_E_N) {
// EPSG:5041
auto wkt = "PROJCS[\"WGS_1984_UPS_North_(E-N)\","
"GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\","
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
"PRIMEM[\"Greenwich\",0.0],"
"UNIT[\"Degree\",0.0174532925199433]],"
"PROJECTION[\"Polar_Stereographic_Variant_A\"],"
"PARAMETER[\"False_Easting\",2000000.0],"
"PARAMETER[\"False_Northing\",2000000.0],"
"PARAMETER[\"Central_Meridian\",0.0],"
"PARAMETER[\"Scale_Factor\",0.994],"
"PARAMETER[\"Latitude_Of_Origin\",90.0],"
"UNIT[\"Meter\",1.0]]";

auto dbContext = DatabaseContext::create();
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
ASSERT_TRUE(crs != nullptr);

EXPECT_EQ(crs->nameStr(), "WGS 84 / UPS North (E,N)");
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->direction(),
AxisDirection::SOUTH);
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->abbreviation(), "E");
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
AxisDirection::SOUTH);
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");

EXPECT_EQ(
crs->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
.get()),
wkt);
}

// ---------------------------------------------------------------------------

TEST(wkt_parse, wkt1_esri_wgs_1984_ups_south_E_N) {
// EPSG:5042
auto wkt = "PROJCS[\"WGS_1984_UPS_South_(E-N)\","
"GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\","
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
"PRIMEM[\"Greenwich\",0.0],"
"UNIT[\"Degree\",0.0174532925199433]],"
"PROJECTION[\"Polar_Stereographic_Variant_A\"],"
"PARAMETER[\"False_Easting\",2000000.0],"
"PARAMETER[\"False_Northing\",2000000.0],"
"PARAMETER[\"Central_Meridian\",0.0],"
"PARAMETER[\"Scale_Factor\",0.994],"
"PARAMETER[\"Latitude_Of_Origin\",-90.0],"
"UNIT[\"Meter\",1.0]]";

auto dbContext = DatabaseContext::create();
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
ASSERT_TRUE(crs != nullptr);

Expand All @@ -7362,6 +7446,12 @@ TEST(wkt_parse, wkt1_esri_ups_south) {
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
AxisDirection::NORTH);
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");

EXPECT_EQ(
crs->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
.get()),
wkt);
}

// ---------------------------------------------------------------------------
Expand Down

0 comments on commit 49d0c53

Please sign in to comment.