aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/c_api.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso19111/c_api.cpp')
-rw-r--r--src/iso19111/c_api.cpp127
1 files changed, 116 insertions, 11 deletions
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index d5f299c2..13152662 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -662,7 +662,8 @@ PJ *proj_create_from_database(PJ_CONTEXT *ctx, const char *auth_name,
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
-static const char *get_unit_category(UnitOfMeasure::Type type) {
+static const char *get_unit_category(const std::string &unit_name,
+ UnitOfMeasure::Type type) {
const char *ret = nullptr;
switch (type) {
case UnitOfMeasure::Type::UNKNOWN:
@@ -672,19 +673,26 @@ static const char *get_unit_category(UnitOfMeasure::Type type) {
ret = "none";
break;
case UnitOfMeasure::Type::ANGULAR:
- ret = "angular";
+ ret = unit_name.find(" per ") != std::string::npos ? "angular_per_time"
+ : "angular";
break;
case UnitOfMeasure::Type::LINEAR:
- ret = "linear";
+ ret = unit_name.find(" per ") != std::string::npos ? "linear_per_time"
+ : "linear";
break;
case UnitOfMeasure::Type::SCALE:
- ret = "scale";
+ ret = unit_name.find(" per year") != std::string::npos ||
+ unit_name.find(" per second") != std::string::npos
+ ? "scale_per_time"
+ : "scale";
break;
case UnitOfMeasure::Type::TIME:
ret = "time";
break;
case UnitOfMeasure::Type::PARAMETRIC:
- ret = "parametric";
+ ret = unit_name.find(" per ") != std::string::npos
+ ? "parametric_per_time"
+ : "parametric";
break;
}
return ret;
@@ -704,8 +712,9 @@ static const char *get_unit_category(UnitOfMeasure::Type type) {
* @param out_conv_factor Pointer to a value to store the conversion
* factor of the prime meridian longitude unit to radian. or NULL
* @param out_category Pointer to a string value to store the parameter name. or
- * NULL. This value might be "unknown", "none", "linear", "angular", "scale",
- * "time" or "parametric";
+ * NULL. This value might be "unknown", "none", "linear", "linear_per_time",
+ * "angular", "angular_per_time", "scale", "scale_per_time", "time",
+ * "parametric" or "parametric_per_time"
* @return TRUE in case of success
*/
int proj_uom_get_info_from_database(PJ_CONTEXT *ctx, const char *auth_name,
@@ -726,7 +735,7 @@ int proj_uom_get_info_from_database(PJ_CONTEXT *ctx, const char *auth_name,
*out_conv_factor = obj->conversionToSI();
}
if (out_category) {
- *out_category = get_unit_category(obj->type());
+ *out_category = get_unit_category(obj->name(), obj->type());
}
ctx->cpp_context->autoCloseDbIfNeeded();
return true;
@@ -2585,6 +2594,100 @@ void proj_crs_info_list_destroy(PROJ_CRS_INFO **list) {
// ---------------------------------------------------------------------------
+/** \brief Enumerate units from the database, taking into account various
+ * criteria.
+ *
+ * The returned object is an array of PROJ_UNIT_INFO* pointers, whose last
+ * entry is NULL. This array should be freed with proj_unit_list_destroy()
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param auth_name Authority name, used to restrict the search.
+ * Or NULL for all authorities.
+ * @param category Filter by category, if this parameter is not NULL. Category
+ * is one of "linear", "linear_per_time", "angular", "angular_per_time",
+ * "scale", "scale_per_time" or "time"
+ * @param allow_deprecated whether we should return deprecated objects as well.
+ * @param out_result_count Output parameter pointing to an integer to receive
+ * the size of the result list. Might be NULL
+ * @return an array of PROJ_UNIT_INFO* pointers to be freed with
+ * proj_unit_list_destroy(), or NULL in case of error.
+ *
+ * @since 7.1
+ */
+PROJ_UNIT_INFO **proj_get_units_from_database(PJ_CONTEXT *ctx,
+ const char *auth_name,
+ const char *category,
+ int allow_deprecated,
+ int *out_result_count) {
+ SANITIZE_CTX(ctx);
+ PROJ_UNIT_INFO **ret = nullptr;
+ int i = 0;
+ try {
+ auto factory = AuthorityFactory::create(getDBcontext(ctx),
+ auth_name ? auth_name : "");
+ auto list = factory->getUnitList();
+ ret = new PROJ_UNIT_INFO *[list.size() + 1];
+ for (const auto &info : list) {
+ if (category && info.category != category) {
+ continue;
+ }
+ if (!allow_deprecated && info.deprecated) {
+ continue;
+ }
+ ret[i] = new PROJ_UNIT_INFO;
+ ret[i]->auth_name = pj_strdup(info.authName.c_str());
+ ret[i]->code = pj_strdup(info.code.c_str());
+ ret[i]->name = pj_strdup(info.name.c_str());
+ ret[i]->category = pj_strdup(info.category.c_str());
+ ret[i]->conv_factor = info.convFactor;
+ ret[i]->proj_short_name =
+ info.projShortName.empty()
+ ? nullptr
+ : pj_strdup(info.projShortName.c_str());
+ ret[i]->deprecated = info.deprecated;
+ i++;
+ }
+ ret[i] = nullptr;
+ if (out_result_count)
+ *out_result_count = i;
+ ctx->cpp_context->autoCloseDbIfNeeded();
+ return ret;
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ if (ret) {
+ ret[i + 1] = nullptr;
+ proj_unit_list_destroy(ret);
+ }
+ if (out_result_count)
+ *out_result_count = 0;
+ }
+ ctx->cpp_context->autoCloseDbIfNeeded();
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Destroy the result returned by
+ * proj_get_units_from_database().
+ *
+ * @since 7.1
+ */
+void proj_unit_list_destroy(PROJ_UNIT_INFO **list) {
+ if (list) {
+ for (int i = 0; list[i] != nullptr; i++) {
+ pj_dalloc(list[i]->auth_name);
+ pj_dalloc(list[i]->code);
+ pj_dalloc(list[i]->name);
+ pj_dalloc(list[i]->category);
+ pj_dalloc(list[i]->proj_short_name);
+ delete list[i];
+ }
+ delete[] list;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Return the Conversion of a DerivedCRS (such as a ProjectedCRS),
* or the Transformation from the baseCRS to the hubCRS of a BoundCRS
*
@@ -6749,8 +6852,9 @@ int proj_coordoperation_get_param_index(PJ_CONTEXT *ctx,
* unit code. or NULL
* @param out_unit_category Pointer to a string value to store the parameter
* name. or
- * NULL. This value might be "unknown", "none", "linear", "angular", "scale",
- * "time" or "parametric";
+ * NULL. This value might be "unknown", "none", "linear", "linear_per_time",
+ * "angular", "angular_per_time", "scale", "scale_per_time", "time",
+ * "parametric" or "parametric_per_time"
* @return TRUE in case of success.
*/
@@ -6852,7 +6956,8 @@ int proj_coordoperation_get_param(
*out_unit_code = unit.code().c_str();
}
if (out_unit_category) {
- *out_unit_category = get_unit_category(unit.type());
+ *out_unit_category =
+ get_unit_category(unit.name(), unit.type());
}
}
}