diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-07-02 10:47:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-02 10:47:33 +0200 |
| commit | 3ae09c3ba164728e200a3b930b72ed5fc24ef6ee (patch) | |
| tree | 72ae697f3fa40cb573db91629c8ad30ab657f03c /src | |
| parent | fb8228a938df79416329956164c76dae2023b0be (diff) | |
| parent | 74932008096b3135317d8c45cb9c9fabb5ab8c6b (diff) | |
| download | PROJ-3ae09c3ba164728e200a3b930b72ed5fc24ef6ee.tar.gz PROJ-3ae09c3ba164728e200a3b930b72ed5fc24ef6ee.zip | |
Merge pull request #1537 from rouault/add_scope_remarks_for_coordinate_operation
Database: import scope/remarks for coordinate operation and add C API
Diffstat (limited to 'src')
| -rw-r--r-- | src/iso19111/c_api.cpp | 117 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 5 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 55 | ||||
| -rw-r--r-- | src/proj.h | 11 |
4 files changed, 178 insertions, 10 deletions
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 1e3a331c..7a77ccfb 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1085,13 +1085,32 @@ const char *proj_get_name(const PJ *obj) { if (!desc.has_value()) { return nullptr; } - // The object will still be alived after the function call. + // The object will still be alive after the function call. // cppcheck-suppress stlcstr return desc->c_str(); } // --------------------------------------------------------------------------- +/** \brief Get the remarks of an object. + * + * The lifetime of the returned string is the same as the input obj parameter. + * + * @param obj Object (must not be NULL) + * @return a string, or NULL in case of error. + */ +const char *proj_get_remarks(const PJ *obj) { + assert(obj); + if (!obj->iso_obj) { + return nullptr; + } + // The object will still be alive after the function call. + // cppcheck-suppress stlcstr + return obj->iso_obj->remarks().c_str(); +} + +// --------------------------------------------------------------------------- + /** \brief Get the authority name / codespace of an identifier of an object. * * The lifetime of the returned string is the same as the input obj parameter. @@ -1113,7 +1132,7 @@ const char *proj_get_id_auth_name(const PJ *obj, int index) { if (!codeSpace.has_value()) { return nullptr; } - // The object will still be alived after the function call. + // The object will still be alive after the function call. // cppcheck-suppress stlcstr return codeSpace->c_str(); } @@ -1295,8 +1314,43 @@ const char *proj_as_proj_string(PJ_CONTEXT *ctx, const PJ *obj, // --------------------------------------------------------------------------- +/** \brief Get the scope of an object. + * + * In case of multiple usages, this will be the one of first usage. + * + * The lifetime of the returned string is the same as the input obj parameter. + * + * @param obj Object (must not be NULL) + * @return a string, or NULL in case of error or missing scope. + */ +const char *proj_get_scope(const PJ *obj) { + assert(obj); + if (!obj->iso_obj) { + return nullptr; + } + auto objectUsage = dynamic_cast<const ObjectUsage *>(obj->iso_obj.get()); + if (!objectUsage) { + return nullptr; + } + const auto &domains = objectUsage->domains(); + if (domains.empty()) { + return nullptr; + } + const auto &scope = domains[0]->scope(); + if (!scope.has_value()) { + return nullptr; + } + // The object will still be alive after the function call. + // cppcheck-suppress stlcstr + return scope->c_str(); +} + +// --------------------------------------------------------------------------- + /** \brief Return the area of use of an object. * + * In case of multiple usages, this will be the one of first usage. + * * @param ctx PROJ context, or NULL for default context * @param obj Object (must not be NULL) * @param out_west_lon_degree Pointer to a double to receive the west longitude @@ -6922,3 +6976,62 @@ PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ *obj) { return nullptr; } } + +// --------------------------------------------------------------------------- + +/** \brief Returns the number of steps of a concatenated operation. + * + * The input object must be a concatenated operation. + * + * @param ctx PROJ context, or NULL for default context + * @param concatoperation Concatenated operation (must not be NULL) + * @return the number of steps, or 0 in case of error. + */ +int proj_concatoperation_get_step_count(PJ_CONTEXT *ctx, + const PJ *concatoperation) { + SANITIZE_CTX(ctx); + assert(concatoperation); + auto l_co = dynamic_cast<const ConcatenatedOperation *>( + concatoperation->iso_obj.get()); + if (!l_co) { + proj_log_error(ctx, __FUNCTION__, + "Object is not a ConcatenatedOperation"); + return false; + } + return static_cast<int>(l_co->operations().size()); +} +// --------------------------------------------------------------------------- + +/** \brief Returns a step of a concatenated operation. + * + * The input object must be a concatenated operation. + * + * The returned object must be unreferenced with proj_destroy() after + * use. + * It should be used by at most one thread at a time. + * + * @param ctx PROJ context, or NULL for default context + * @param concatoperation Concatenated operation (must not be NULL) + * @param i_step Index of the step to extract. Between 0 and + * proj_concatoperation_get_step_count()-1 + * @return Object that must be unreferenced with proj_destroy(), or NULL + * in case of error. + */ +PJ *proj_concatoperation_get_step(PJ_CONTEXT *ctx, const PJ *concatoperation, + int i_step) { + SANITIZE_CTX(ctx); + assert(concatoperation); + auto l_co = dynamic_cast<const ConcatenatedOperation *>( + concatoperation->iso_obj.get()); + if (!l_co) { + proj_log_error(ctx, __FUNCTION__, + "Object is not a ConcatenatedOperation"); + return nullptr; + } + const auto &steps = l_co->operations(); + if (i_step < 0 || static_cast<size_t>(i_step) >= steps.size()) { + proj_log_error(ctx, __FUNCTION__, "Invalid step index"); + return nullptr; + } + return pj_obj_create(ctx, steps[i_step]); +} diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 1982e234..7f3a2137 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -7342,6 +7342,11 @@ createPropertiesForInverse(const CoordinateOperation *op, bool derivedFrom, map.set(common::IdentifiedObject::NAME_KEY, name); } + const std::string &remarks = op->remarks(); + if (!remarks.empty()) { + map.set(common::IdentifiedObject::REMARKS_KEY, remarks); + } + addModifiedIdentifier(map, op, true, derivedFrom); return map; diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 4515188a..1f40f1f0 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1222,6 +1222,13 @@ struct AuthorityFactory::Private { const std::string &area_of_use_auth_name, const std::string &area_of_use_code); + util::PropertyMap createProperties(const std::string &code, + const std::string &name, bool deprecated, + const std::string &remarks, + const std::string &scope, + const std::string &area_of_use_auth_name, + const std::string &area_of_use_code); + SQLResultSet run(const std::string &sql, const ListOfParams ¶meters = ListOfParams()); @@ -1307,6 +1314,26 @@ util::PropertyMap AuthorityFactory::Private::createProperties( // --------------------------------------------------------------------------- +util::PropertyMap AuthorityFactory::Private::createProperties( + const std::string &code, const std::string &name, bool deprecated, + const std::string &remarks, const std::string &scope, + const std::string &area_of_use_auth_name, + const std::string &area_of_use_code) { + auto props = createProperties(code, name, deprecated, + area_of_use_auth_name.empty() + ? nullptr + : createFactory(area_of_use_auth_name) + ->createExtent(area_of_use_code) + .as_nullable()); + if (!remarks.empty()) + props.set(common::IdentifiedObject::REMARKS_KEY, remarks); + if (!scope.empty()) + props.set(common::ObjectUsage::SCOPE_KEY, scope); + return props; +} + +// --------------------------------------------------------------------------- + bool AuthorityFactory::Private::rejectOpDueToMissingGrid( const operation::CoordinateOperationNNPtr &op, bool discardIfMissingGrid) { if (discardIfMissingGrid) { @@ -2604,7 +2631,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( if (type == "helmert_transformation") { auto res = d->runWithCodeParam( - "SELECT name, method_auth_name, method_code, method_name, " + "SELECT name, description, scope, " + "method_auth_name, method_code, method_name, " "source_crs_auth_name, source_crs_code, target_crs_auth_name, " "target_crs_code, area_of_use_auth_name, area_of_use_code, " "accuracy, tx, ty, tz, translation_uom_auth_name, " @@ -2629,6 +2657,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &row = res.front(); size_t idx = 0; const auto &name = row[idx++]; + const auto &description = row[idx++]; + const auto &scope = row[idx++]; const auto &method_auth_name = row[idx++]; const auto &method_code = row[idx++]; const auto &method_name = row[idx++]; @@ -2817,7 +2847,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( } auto props = - d->createProperties(code, name, deprecated, + d->createProperties(code, name, deprecated, description, scope, area_of_use_auth_name, area_of_use_code); if (!operation_version.empty()) { props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, @@ -2846,7 +2876,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( if (type == "grid_transformation") { auto res = d->runWithCodeParam( - "SELECT name, method_auth_name, method_code, method_name, " + "SELECT name, description, scope, " + "method_auth_name, method_code, method_name, " "source_crs_auth_name, source_crs_code, target_crs_auth_name, " "target_crs_code, area_of_use_auth_name, area_of_use_code, " "accuracy, grid_param_auth_name, grid_param_code, grid_param_name, " @@ -2866,6 +2897,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &row = res.front(); size_t idx = 0; const auto &name = row[idx++]; + const auto &description = row[idx++]; + const auto &scope = row[idx++]; const auto &method_auth_name = row[idx++]; const auto &method_code = row[idx++]; const auto &method_name = row[idx++]; @@ -2930,7 +2963,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( } auto props = - d->createProperties(code, name, deprecated, + d->createProperties(code, name, deprecated, description, scope, area_of_use_auth_name, area_of_use_code); if (!operation_version.empty()) { props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, @@ -2964,7 +2997,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( std::ostringstream buffer; buffer.imbue(std::locale::classic()); buffer - << "SELECT name, method_auth_name, method_code, method_name, " + << "SELECT name, description, scope, " + "method_auth_name, method_code, method_name, " "source_crs_auth_name, source_crs_code, target_crs_auth_name, " "target_crs_code, area_of_use_auth_name, area_of_use_code, " "accuracy"; @@ -2990,6 +3024,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &row = res.front(); size_t idx = 0; const auto &name = row[idx++]; + const auto &description = row[idx++]; + const auto &scope = row[idx++]; const auto &method_auth_name = row[idx++]; const auto &method_code = row[idx++]; const auto &method_name = row[idx++]; @@ -3044,7 +3080,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( ->createCoordinateReferenceSystem(target_crs_code); auto props = - d->createProperties(code, name, deprecated, + d->createProperties(code, name, deprecated, description, scope, area_of_use_auth_name, area_of_use_code); if (!operation_version.empty()) { props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, @@ -3099,7 +3135,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( if (allowConcatenated && type == "concatenated_operation") { auto res = d->runWithCodeParam( - "SELECT name, source_crs_auth_name, source_crs_code, " + "SELECT name, description, scope, " + "source_crs_auth_name, source_crs_code, " "target_crs_auth_name, target_crs_code, " "area_of_use_auth_name, area_of_use_code, accuracy, " "step1_auth_name, step1_code, step2_auth_name, step2_code, " @@ -3115,6 +3152,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &row = res.front(); size_t idx = 0; const auto &name = row[idx++]; + const auto &description = row[idx++]; + const auto &scope = row[idx++]; const auto &source_crs_auth_name = row[idx++]; const auto &source_crs_code = row[idx++]; const auto &target_crs_auth_name = row[idx++]; @@ -3160,7 +3199,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( operations); auto props = - d->createProperties(code, name, deprecated, + d->createProperties(code, name, deprecated, description, scope, area_of_use_auth_name, area_of_use_code); if (!operation_version.empty()) { props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, @@ -826,6 +826,10 @@ const char PROJ_DLL* proj_get_id_auth_name(const PJ *obj, int index); const char PROJ_DLL* proj_get_id_code(const PJ *obj, int index); +const char PROJ_DLL* proj_get_remarks(const PJ *obj); + +const char PROJ_DLL* proj_get_scope(const PJ *obj); + int PROJ_DLL proj_get_area_of_use(PJ_CONTEXT *ctx, const PJ *obj, double* out_west_lon_degree, @@ -1060,6 +1064,13 @@ int PROJ_DLL proj_coordoperation_get_towgs84_values(PJ_CONTEXT *ctx, int value_count, int emit_error_if_incompatible); +int PROJ_DLL proj_concatoperation_get_step_count(PJ_CONTEXT *ctx, + const PJ *concatoperation); + +PJ PROJ_DLL *proj_concatoperation_get_step(PJ_CONTEXT *ctx, + const PJ *concatoperation, + int i_step); + /**@}*/ #ifdef __cplusplus |
