From 8a156921b9483d82693c7a9e426c629a941fcce1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 2 Dec 2021 17:18:13 +0100 Subject: Merge pull request #2966 from rouault/fix_2965 Cache result of proj_get_type() to help for performance of proj_factors() (fixes #2965) --- src/iso19111/c_api.cpp | 170 ++++++++++++++++++++++++++----------------------- src/proj_internal.h | 3 + 2 files changed, 92 insertions(+), 81 deletions(-) diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 70f589b3..eab23319 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1150,98 +1150,106 @@ PJ_TYPE proj_get_type(const PJ *obj) { if (!obj || !obj->iso_obj) { return PJ_TYPE_UNKNOWN; } - auto ptr = obj->iso_obj.get(); - if (dynamic_cast(ptr)) { - return PJ_TYPE_ELLIPSOID; - } + if (obj->type != PJ_TYPE_UNKNOWN) + return obj->type; - if (dynamic_cast(ptr)) { - return PJ_TYPE_PRIME_MERIDIAN; - } + const auto getType = [&obj]() { + auto ptr = obj->iso_obj.get(); + if (dynamic_cast(ptr)) { + return PJ_TYPE_ELLIPSOID; + } - if (dynamic_cast(ptr)) { - return PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_GEODETIC_REFERENCE_FRAME; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_VERTICAL_REFERENCE_FRAME; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_DATUM_ENSEMBLE; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_TEMPORAL_DATUM; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_ENGINEERING_DATUM; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_PARAMETRIC_DATUM; - } + if (dynamic_cast(ptr)) { + return PJ_TYPE_PRIME_MERIDIAN; + } - { - auto crs = dynamic_cast(ptr); - if (crs) { - if (crs->coordinateSystem()->axisList().size() == 2) { - return PJ_TYPE_GEOGRAPHIC_2D_CRS; - } else { - return PJ_TYPE_GEOGRAPHIC_3D_CRS; + if (dynamic_cast(ptr)) { + return PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_GEODETIC_REFERENCE_FRAME; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_VERTICAL_REFERENCE_FRAME; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_DATUM_ENSEMBLE; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_TEMPORAL_DATUM; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_ENGINEERING_DATUM; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_PARAMETRIC_DATUM; + } + + { + auto crs = dynamic_cast(ptr); + if (crs) { + if (crs->coordinateSystem()->axisList().size() == 2) { + return PJ_TYPE_GEOGRAPHIC_2D_CRS; + } else { + return PJ_TYPE_GEOGRAPHIC_3D_CRS; + } } } - } - { - auto crs = dynamic_cast(ptr); - if (crs) { - if (crs->isGeocentric()) { - return PJ_TYPE_GEOCENTRIC_CRS; - } else { - return PJ_TYPE_GEODETIC_CRS; + { + auto crs = dynamic_cast(ptr); + if (crs) { + if (crs->isGeocentric()) { + return PJ_TYPE_GEOCENTRIC_CRS; + } else { + return PJ_TYPE_GEODETIC_CRS; + } } } - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_VERTICAL_CRS; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_PROJECTED_CRS; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_COMPOUND_CRS; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_TEMPORAL_CRS; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_ENGINEERING_CRS; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_BOUND_CRS; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_OTHER_CRS; - } + if (dynamic_cast(ptr)) { + return PJ_TYPE_VERTICAL_CRS; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_PROJECTED_CRS; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_COMPOUND_CRS; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_TEMPORAL_CRS; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_ENGINEERING_CRS; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_BOUND_CRS; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_OTHER_CRS; + } - if (dynamic_cast(ptr)) { - return PJ_TYPE_CONVERSION; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_TRANSFORMATION; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_CONCATENATED_OPERATION; - } - if (dynamic_cast(ptr)) { - return PJ_TYPE_OTHER_COORDINATE_OPERATION; - } + if (dynamic_cast(ptr)) { + return PJ_TYPE_CONVERSION; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_TRANSFORMATION; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_CONCATENATED_OPERATION; + } + if (dynamic_cast(ptr)) { + return PJ_TYPE_OTHER_COORDINATE_OPERATION; + } + + return PJ_TYPE_UNKNOWN; + }; - return PJ_TYPE_UNKNOWN; + obj->type = getType(); + return obj->type; } // --------------------------------------------------------------------------- diff --git a/src/proj_internal.h b/src/proj_internal.h index 6edb6aec..2b2fb959 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -573,6 +573,9 @@ struct PJconsts { mutable bool gridsNeededAsked = false; mutable std::vector gridsNeeded{}; + // cache pj_get_type() result to help for repeated calls to proj_factors() + mutable PJ_TYPE type = PJ_TYPE_UNKNOWN; + /************************************************************************************* proj_create_crs_to_crs() alternative coordinate operations **************************************************************************************/ -- cgit v1.2.3