Skip to content

Commit

Permalink
projinfo completion: also suggest appropriate vertical CRS
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Jan 7, 2025
1 parent 4552703 commit d887cad
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
103 changes: 103 additions & 0 deletions src/apps/projinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,109 @@ static void suggestCompletion(const std::vector<std::string> &args) {
break;
}
}

// If the input was ``projinfo "NAD83(HARN) / California Albers +``,
// then check if "NAD83(HARN) / California Albers" is a known horizontal
// CRS, and if so, suggest relevant potential vertical CRS.
const auto posSpacePlus = lastArg.find(" +");
if (first && posSpacePlus != std::string::npos) {
const std::string candidateHorizCRSName =
lastArg.substr(0, posSpacePlus);
auto factory = AuthorityFactory::create(dbContext, std::string());
#ifdef DEBUG_COMPLETION
fprintf(stderr, "candidateHorizCRSName='%s'\n",
candidateHorizCRSName.c_str());
#endif
const auto candidateHorizCRS = factory->createObjectsFromName(
candidateHorizCRSName,
{AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS,
AuthorityFactory::ObjectType::PROJECTED_CRS},
/* approximateMatch = */ true,
/* limitResultCount = */ 2);
if (!candidateHorizCRS.empty()) {
const auto &domains = dynamic_cast<const ObjectUsage *>(
candidateHorizCRS.front().get())
->domains();
if (domains.size() == 1) {
const auto &domain = domains[0]->domainOfValidity();
if (domain && domain->geographicElements().size() == 1) {
const auto bbox =
dynamic_cast<const GeographicBoundingBox *>(
domain->geographicElements()[0].get());
if (bbox) {
std::string vertCRSAuthName;
const auto &codeSpace = candidateHorizCRS.front()
->identifiers()
.front()
->codeSpace();
if (codeSpace.has_value())
vertCRSAuthName = *codeSpace;
auto factoryVertCRS = AuthorityFactory::create(
dbContext, vertCRSAuthName);
const auto list = factoryVertCRS->getCRSInfoList();
std::string horizAreaOfUse;
if (domain->description().has_value()) {
horizAreaOfUse = *(domain->description());
const auto posDash = horizAreaOfUse.find(" -");
if (posDash != std::string::npos)
horizAreaOfUse.resize(posDash);
}
for (size_t attempt = 0; first && attempt < 2;
++attempt) {
for (const auto &info : list) {
if (!info.deprecated && info.bbox_valid &&
info.type ==
AuthorityFactory::ObjectType::
VERTICAL_CRS &&
!starts_with(info.name,
"EPSG example")) {
std::string vertAreaOfUse =
info.areaName;
const auto posDash =
vertAreaOfUse.find(" -");
if (posDash != std::string::npos)
vertAreaOfUse.resize(posDash);
bool ok = false;
if (attempt == 0 &&
!horizAreaOfUse.empty()) {
ok =
horizAreaOfUse == vertAreaOfUse;
} else if (attempt == 1 &&
vertAreaOfUse == "World.") {
// auto vertCrsBbox =
// GeographicBoundingBox::create(info.west_lon_degree,
// info.south_lat_degree,
// info.east_lon_degree,
// info.north_lat_degree); if(
// bbox->intersects(vertCrsBbox))
{ ok = true; }
}
if (ok) {
if (!first)
printf(" ");
first = false;
#ifdef DEBUG_COMPLETION
fprintf(stderr, "'%s'\n",
replaceAll(info.name, " ",
"\\ ")
.c_str());
#endif
printf("%s", replaceAll(info.name,
" ", "\\ ")
.c_str());
}
}
}
if (!first) {
printf("\n");
}
}
}
}
}
}
}

} catch (const std::exception &) {
}
}
Expand Down
6 changes: 6 additions & 0 deletions test/cli/test_projinfo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1922,3 +1922,9 @@ tests:
- args: completion projinfo "\"RGF93" v1 "/"
out: |
Lambert-93 CC42 CC43 CC44 CC45 CC46 CC47 CC48 CC49 CC50 Lambert-93\ +\ NGF-IGN69\ height Lambert-93\ +\ NGF-IGN78\ height
- args: completion projinfo "\"NAD83(HARN) / California Albers" "+"
out: |
NGVD29\ height\ (ftUS) NAVD88\ depth\ (ftUS) NGVD29\ depth\ (ftUS) NAVD88\ height\ (ftUS) NGVD29\ height\ (m) MSL\ height\ (ftUS) MSL\ depth\ (ftUS) NAVD88\ height\ (ft)
- args: completion projinfo "\"Mauritania 1999" "/" UTM zone 29N "+"
out: |
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 comments on commit d887cad

Please sign in to comment.