Skip to content

Commit d887cad

Browse files
committed
projinfo completion: also suggest appropriate vertical CRS
1 parent 4552703 commit d887cad

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/apps/projinfo.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,109 @@ static void suggestCompletion(const std::vector<std::string> &args) {
12781278
break;
12791279
}
12801280
}
1281+
1282+
// If the input was ``projinfo "NAD83(HARN) / California Albers +``,
1283+
// then check if "NAD83(HARN) / California Albers" is a known horizontal
1284+
// CRS, and if so, suggest relevant potential vertical CRS.
1285+
const auto posSpacePlus = lastArg.find(" +");
1286+
if (first && posSpacePlus != std::string::npos) {
1287+
const std::string candidateHorizCRSName =
1288+
lastArg.substr(0, posSpacePlus);
1289+
auto factory = AuthorityFactory::create(dbContext, std::string());
1290+
#ifdef DEBUG_COMPLETION
1291+
fprintf(stderr, "candidateHorizCRSName='%s'\n",
1292+
candidateHorizCRSName.c_str());
1293+
#endif
1294+
const auto candidateHorizCRS = factory->createObjectsFromName(
1295+
candidateHorizCRSName,
1296+
{AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS,
1297+
AuthorityFactory::ObjectType::PROJECTED_CRS},
1298+
/* approximateMatch = */ true,
1299+
/* limitResultCount = */ 2);
1300+
if (!candidateHorizCRS.empty()) {
1301+
const auto &domains = dynamic_cast<const ObjectUsage *>(
1302+
candidateHorizCRS.front().get())
1303+
->domains();
1304+
if (domains.size() == 1) {
1305+
const auto &domain = domains[0]->domainOfValidity();
1306+
if (domain && domain->geographicElements().size() == 1) {
1307+
const auto bbox =
1308+
dynamic_cast<const GeographicBoundingBox *>(
1309+
domain->geographicElements()[0].get());
1310+
if (bbox) {
1311+
std::string vertCRSAuthName;
1312+
const auto &codeSpace = candidateHorizCRS.front()
1313+
->identifiers()
1314+
.front()
1315+
->codeSpace();
1316+
if (codeSpace.has_value())
1317+
vertCRSAuthName = *codeSpace;
1318+
auto factoryVertCRS = AuthorityFactory::create(
1319+
dbContext, vertCRSAuthName);
1320+
const auto list = factoryVertCRS->getCRSInfoList();
1321+
std::string horizAreaOfUse;
1322+
if (domain->description().has_value()) {
1323+
horizAreaOfUse = *(domain->description());
1324+
const auto posDash = horizAreaOfUse.find(" -");
1325+
if (posDash != std::string::npos)
1326+
horizAreaOfUse.resize(posDash);
1327+
}
1328+
for (size_t attempt = 0; first && attempt < 2;
1329+
++attempt) {
1330+
for (const auto &info : list) {
1331+
if (!info.deprecated && info.bbox_valid &&
1332+
info.type ==
1333+
AuthorityFactory::ObjectType::
1334+
VERTICAL_CRS &&
1335+
!starts_with(info.name,
1336+
"EPSG example")) {
1337+
std::string vertAreaOfUse =
1338+
info.areaName;
1339+
const auto posDash =
1340+
vertAreaOfUse.find(" -");
1341+
if (posDash != std::string::npos)
1342+
vertAreaOfUse.resize(posDash);
1343+
bool ok = false;
1344+
if (attempt == 0 &&
1345+
!horizAreaOfUse.empty()) {
1346+
ok =
1347+
horizAreaOfUse == vertAreaOfUse;
1348+
} else if (attempt == 1 &&
1349+
vertAreaOfUse == "World.") {
1350+
// auto vertCrsBbox =
1351+
// GeographicBoundingBox::create(info.west_lon_degree,
1352+
// info.south_lat_degree,
1353+
// info.east_lon_degree,
1354+
// info.north_lat_degree); if(
1355+
// bbox->intersects(vertCrsBbox))
1356+
{ ok = true; }
1357+
}
1358+
if (ok) {
1359+
if (!first)
1360+
printf(" ");
1361+
first = false;
1362+
#ifdef DEBUG_COMPLETION
1363+
fprintf(stderr, "'%s'\n",
1364+
replaceAll(info.name, " ",
1365+
"\\ ")
1366+
.c_str());
1367+
#endif
1368+
printf("%s", replaceAll(info.name,
1369+
" ", "\\ ")
1370+
.c_str());
1371+
}
1372+
}
1373+
}
1374+
if (!first) {
1375+
printf("\n");
1376+
}
1377+
}
1378+
}
1379+
}
1380+
}
1381+
}
1382+
}
1383+
12811384
} catch (const std::exception &) {
12821385
}
12831386
}

test/cli/test_projinfo.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,3 +1922,9 @@ tests:
19221922
- args: completion projinfo "\"RGF93" v1 "/"
19231923
out: |
19241924
Lambert-93 CC42 CC43 CC44 CC45 CC46 CC47 CC48 CC49 CC50 Lambert-93\ +\ NGF-IGN69\ height Lambert-93\ +\ NGF-IGN78\ height
1925+
- args: completion projinfo "\"NAD83(HARN) / California Albers" "+"
1926+
out: |
1927+
NGVD29\ height\ (ftUS) NAVD88\ depth\ (ftUS) NGVD29\ depth\ (ftUS) NAVD88\ height\ (ftUS) NGVD29\ height\ (m) MSL\ height\ (ftUS) MSL\ depth\ (ftUS) NAVD88\ height\ (ft)
1928+
- args: completion projinfo "\"Mauritania 1999" "/" UTM zone 29N "+"
1929+
out: |
1930+
EGM2008\ height MSL\ height MSL\ depth EGM96\ height EGM84\ height Instantaneous\ Water\ Level\ height Instantaneous\ Water\ Level\ depth LAT\ depth LLWLT\ depth ISLW\ depth MLLWS\ depth MLWS\ depth MLLW\ depth MLW\ depth MHW\ height MHHW\ height MHWS\ height HHWLT\ height HAT\ height Low\ Water\ depth High\ Water\ height MSL\ height\ (ft) MSL\ depth\ (ft)

0 commit comments

Comments
 (0)