OSGeo/PROJ

proj_list_db_units

Closed this issue · 8 comments

Currently there is proj_list_units for the old PROJ units. However, there is a WKT based set of units listed in: https://github.com/OSGeo/PROJ/blob/master/data/sql/unit_of_measure.sql

Thoughts on adding something like proj_list_db_units or proj_list_unit_of_measure ?

Thoughts on adding something like proj_list_db_units or proj_list_unit_of_measure ?

My thought is, that we shouldn't have two functions that does basically the same thing. Either we should re-wire proj_list_units() (and possibly other proj_list_* functions) or we should replace it with a proj_units() (or whatever name is suitable) that grabs the units from the DB. The last option would likely require a period with both functions available in the API and removal of proj_list_units() with PROJ 8.

@kbevers proj_list_units is used for exporting units to a PROJ string:

std::string UnitOfMeasure::exportToPROJString() const {
if (type() == Type::LINEAR) {
auto proj_units = proj_list_units();
for (int i = 0; proj_units[i].id != nullptr; i++) {
if (::fabs(proj_units[i].factor - conversionToSI()) <
1e-10 * conversionToSI()) {
return proj_units[i].id;
}
}
} else if (type() == Type::ANGULAR) {
auto proj_angular_units = proj_list_angular_units();
for (int i = 0; proj_angular_units[i].id != nullptr; i++) {
if (::fabs(proj_angular_units[i].factor - conversionToSI()) <
1e-10 * conversionToSI()) {
return proj_angular_units[i].id;
}
}
}
return std::string();
}

So, if you wanted to merge the two, this would also need to be accounted for.

I see a method called proj_get_authorities_from_database, maybe following that naming convention it could be called proj_get_units_from_database?

Also, I am thinking since proj_list_units is designed around PROJ strings it could be okay for both that and proj_get_units_from_database which is more designed for WKT/Spatial Reference strings to coexist if proper docstrings are added?

Another option would be to add the units in proj_list_units to the database under the PROJ authority and then proj_list_units could be removed without issue I think.

proj_get_units_from_database() + putting the historical PROJ units that have no EPSG correspondance would seem reasonable.

And gently tag proj_list_units() as being maybe retired some day, but not a big fan of doing so in PROJ 8. That would for example break SAGA: https://sources.debian.org/src/saga/7.3.0+dfsg-3/src/tools/projection/pj_proj4/crs_base.cpp (only use outside PROJ sources found by Debian source explorer)

proj_get_units_from_database() + putting the historical PROJ units that have no EPSG correspondance would seem reasonable.

This is also my preferred way forward.

And gently tag proj_list_units() as being maybe retired some day, but not a big fan of doing so in PROJ 8.

Deprecating it as soon as a proj_get_units_from_database() is in place would be ideal. With PROJ 8 it should be removed from the docs and removing the function altogether is a good excuse for having a PROJ 9 :-)

OK, this has coincidentally matched the needs from a customer, so I'm going to deal with that.

I'm considering the following API, similar to the one to get the list of CRS

-  PROJ_UNIT_INFO PROJ_DLL **proj_get_units_from_database(
                                      PJ_CONTEXT *ctx,
                                      const char *auth_name, // might be NULL, to get all units
                                      const char* category, // might be NULL
                                      int *out_result_count);

-  void PROJ_DLL proj_unit_list_destroy(PROJ_UNIT_INFO** list);

-   struct PROJ_UNIT_INFO
    {
       char* auth_name;
       char* code;
       char* name;
       double conv_factor;
       char* category; // "unknown", "none", "linear", "angular", "scale", "time" or "parametric"
       char* proj_name; // PROJ.4 nick, like "m", "ft", "us-ft", etc... might be NULL
    };

What will auth_name and code be for weird units only previously available through proj_list_units()? PROJ and consecutive numbers starting from 0?

What will auth_name and code be for weird units only previously available through proj_list_units()? PROJ and consecutive numbers starting from 0?

PROJ and probably the proj nick in upper case, like PROJ:DM