Skip to content

Commit aab4742

Browse files
committed
WKT ESRI: recognize Polar_Stereographic_Variant_A method name which is used in the official ESRI formulation of EPSG:5041 and EPSG:5042
1 parent 720e728 commit aab4742

File tree

4 files changed

+131
-7
lines changed

4 files changed

+131
-7
lines changed

scripts/build_esri_projection_mapping.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,15 @@
289289
- Scale_Factor: EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN
290290
- Latitude_Of_Origin: EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN
291291
292+
- Polar_Stereographic_Variant_A:
293+
WKT2_name: EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A
294+
Params:
295+
- False_Easting: EPSG_NAME_PARAMETER_FALSE_EASTING
296+
- False_Northing: EPSG_NAME_PARAMETER_FALSE_NORTHING
297+
- Central_Meridian: EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN
298+
- Scale_Factor: EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN
299+
- Latitude_Of_Origin: EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN
300+
292301
- Equidistant_Conic:
293302
WKT2_name: PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC
294303
Params:
@@ -740,7 +749,6 @@
740749
# Missing mappings
741750
742751
# Transverse_Mercator_NGA_2014: utm -- tricky mapping from Central_Meridian to zone
743-
# Polar_Stereographic_Variant_A: ups -- tricky mapping from Latitude_Of_Origin to "+south" when required
744752
# Transverse Mercator: alias for Transverse_Mercator, as seen in ESRI:102470 - ESRI:102489
745753
746754

src/iso19111/operation/conversion.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3085,6 +3085,19 @@ static void getESRIMethodNameAndParams(const Conversion *conv,
30853085
esriParams = paramsESRI_Rectified_Skew_Orthomorphic_Center;
30863086
esriMethodName = "Rectified_Skew_Orthomorphic_Center";
30873087
}
3088+
} else if (esriMapping->epsg_code ==
3089+
EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A) {
3090+
// Quite empiric, but looking at pe_list_projcs.csv, the only
3091+
// CRS that use Polar_Stereographic_Variant_A are EPSG:5041 and 5042
3092+
if (l_targetCRS &&
3093+
// EPSG:5041
3094+
(l_targetCRS->nameStr() == "WGS 84 / UPS North (E,N)" ||
3095+
// EPSG:5042
3096+
l_targetCRS->nameStr() == "WGS 84 / UPS South (E,N)")) {
3097+
esriMethodName = "Polar_Stereographic_Variant_A";
3098+
} else {
3099+
esriMethodName = "Stereographic";
3100+
}
30883101
} else if (esriMapping->epsg_code ==
30893102
EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B) {
30903103
if (conv->parameterValueNumericAsSI(

src/iso19111/operation/esriparammappings.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,19 @@ static const ESRIParamMapping paramsESRI_Stereographic[] = {
385385
EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, "0.0", false},
386386
{nullptr, nullptr, 0, "0.0", false}};
387387

388+
static const ESRIParamMapping paramsESRI_Polar_Stereographic_Variant_A[] = {
389+
{"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
390+
EPSG_CODE_PARAMETER_FALSE_EASTING, "0.0", false},
391+
{"False_Northing", EPSG_NAME_PARAMETER_FALSE_NORTHING,
392+
EPSG_CODE_PARAMETER_FALSE_NORTHING, "0.0", false},
393+
{"Central_Meridian", EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
394+
EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, "0.0", false},
395+
{"Scale_Factor", EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
396+
EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, "0.0", false},
397+
{"Latitude_Of_Origin", EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
398+
EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, "0.0", false},
399+
{nullptr, nullptr, 0, "0.0", false}};
400+
388401
static const ESRIParamMapping paramsESRI_Equidistant_Conic[] = {
389402
{"False_Easting", EPSG_NAME_PARAMETER_FALSE_EASTING,
390403
EPSG_CODE_PARAMETER_FALSE_EASTING, "0.0", false},
@@ -1033,6 +1046,10 @@ static const ESRIMethodMapping esriMappings[] = {
10331046
paramsESRI_Hotine_Oblique_Mercator_Two_Point_Natural_Origin},
10341047
{"Stereographic", PROJ_WKT2_NAME_METHOD_STEREOGRAPHIC, 0,
10351048
paramsESRI_Stereographic},
1049+
{"Polar_Stereographic_Variant_A",
1050+
EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
1051+
EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
1052+
paramsESRI_Polar_Stereographic_Variant_A},
10361053
{"Equidistant_Conic", PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC, 0,
10371054
paramsESRI_Equidistant_Conic},
10381055
{"Cassini", EPSG_NAME_METHOD_CASSINI_SOLDNER,

test/unit/test_io.cpp

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7307,6 +7307,7 @@ TEST(wkt_parse, wkt1_esri_normalize_unit) {
73077307
// ---------------------------------------------------------------------------
73087308

73097309
TEST(wkt_parse, wkt1_esri_ups_north) {
7310+
// EPSG:32661
73107311
auto wkt = "PROJCS[\"UPS_North\",GEOGCS[\"GCS_WGS_1984\","
73117312
"DATUM[\"D_WGS_1984\","
73127313
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
@@ -7319,9 +7320,8 @@ TEST(wkt_parse, wkt1_esri_ups_north) {
73197320
"PARAMETER[\"Latitude_Of_Origin\",90.0],"
73207321
"UNIT[\"Meter\",1.0]]";
73217322

7322-
auto obj = WKTParser()
7323-
.attachDatabaseContext(DatabaseContext::create())
7324-
.createFromWKT(wkt);
7323+
auto dbContext = DatabaseContext::create();
7324+
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
73257325
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
73267326
ASSERT_TRUE(crs != nullptr);
73277327

@@ -7334,11 +7334,18 @@ TEST(wkt_parse, wkt1_esri_ups_north) {
73347334
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
73357335
AxisDirection::SOUTH);
73367336
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");
7337+
7338+
EXPECT_EQ(
7339+
crs->exportToWKT(
7340+
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
7341+
.get()),
7342+
wkt);
73377343
}
73387344

73397345
// ---------------------------------------------------------------------------
73407346

73417347
TEST(wkt_parse, wkt1_esri_ups_south) {
7348+
// EPSG:32671
73427349
auto wkt = "PROJCS[\"UPS_South\",GEOGCS[\"GCS_WGS_1984\","
73437350
"DATUM[\"D_WGS_1984\","
73447351
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
@@ -7351,9 +7358,8 @@ TEST(wkt_parse, wkt1_esri_ups_south) {
73517358
"PARAMETER[\"Latitude_Of_Origin\",-90.0],"
73527359
"UNIT[\"Meter\",1.0]]";
73537360

7354-
auto obj = WKTParser()
7355-
.attachDatabaseContext(DatabaseContext::create())
7356-
.createFromWKT(wkt);
7361+
auto dbContext = DatabaseContext::create();
7362+
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
73577363
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
73587364
ASSERT_TRUE(crs != nullptr);
73597365

@@ -7366,6 +7372,86 @@ TEST(wkt_parse, wkt1_esri_ups_south) {
73667372
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
73677373
AxisDirection::NORTH);
73687374
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");
7375+
7376+
EXPECT_EQ(
7377+
crs->exportToWKT(
7378+
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
7379+
.get()),
7380+
wkt);
7381+
}
7382+
7383+
// ---------------------------------------------------------------------------
7384+
7385+
TEST(wkt_parse, wkt1_esri_wgs_1984_ups_north_E_N) {
7386+
// EPSG:5041
7387+
auto wkt = "PROJCS[\"WGS_1984_UPS_North_(E-N)\","
7388+
"GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\","
7389+
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
7390+
"PRIMEM[\"Greenwich\",0.0],"
7391+
"UNIT[\"Degree\",0.0174532925199433]],"
7392+
"PROJECTION[\"Polar_Stereographic_Variant_A\"],"
7393+
"PARAMETER[\"False_Easting\",2000000.0],"
7394+
"PARAMETER[\"False_Northing\",2000000.0],"
7395+
"PARAMETER[\"Central_Meridian\",0.0],"
7396+
"PARAMETER[\"Scale_Factor\",0.994],"
7397+
"PARAMETER[\"Latitude_Of_Origin\",90.0],"
7398+
"UNIT[\"Meter\",1.0]]";
7399+
7400+
auto dbContext = DatabaseContext::create();
7401+
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
7402+
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
7403+
ASSERT_TRUE(crs != nullptr);
7404+
7405+
EXPECT_EQ(crs->nameStr(), "WGS 84 / UPS North (E,N)");
7406+
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->direction(),
7407+
AxisDirection::SOUTH);
7408+
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->abbreviation(), "E");
7409+
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
7410+
AxisDirection::SOUTH);
7411+
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");
7412+
7413+
EXPECT_EQ(
7414+
crs->exportToWKT(
7415+
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
7416+
.get()),
7417+
wkt);
7418+
}
7419+
7420+
// ---------------------------------------------------------------------------
7421+
7422+
TEST(wkt_parse, wkt1_esri_wgs_1984_ups_south_E_N) {
7423+
// EPSG:5042
7424+
auto wkt = "PROJCS[\"WGS_1984_UPS_South_(E-N)\","
7425+
"GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\","
7426+
"SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],"
7427+
"PRIMEM[\"Greenwich\",0.0],"
7428+
"UNIT[\"Degree\",0.0174532925199433]],"
7429+
"PROJECTION[\"Polar_Stereographic_Variant_A\"],"
7430+
"PARAMETER[\"False_Easting\",2000000.0],"
7431+
"PARAMETER[\"False_Northing\",2000000.0],"
7432+
"PARAMETER[\"Central_Meridian\",0.0],"
7433+
"PARAMETER[\"Scale_Factor\",0.994],"
7434+
"PARAMETER[\"Latitude_Of_Origin\",-90.0],"
7435+
"UNIT[\"Meter\",1.0]]";
7436+
7437+
auto dbContext = DatabaseContext::create();
7438+
auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt);
7439+
auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
7440+
ASSERT_TRUE(crs != nullptr);
7441+
7442+
EXPECT_EQ(crs->nameStr(), "WGS 84 / UPS South (E,N)");
7443+
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->direction(),
7444+
AxisDirection::NORTH);
7445+
EXPECT_EQ(crs->coordinateSystem()->axisList()[0]->abbreviation(), "E");
7446+
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->direction(),
7447+
AxisDirection::NORTH);
7448+
EXPECT_EQ(crs->coordinateSystem()->axisList()[1]->abbreviation(), "N");
7449+
7450+
EXPECT_EQ(
7451+
crs->exportToWKT(
7452+
WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
7453+
.get()),
7454+
wkt);
73697455
}
73707456

73717457
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)