Merged
Conversation
Member
estebanzimanyi
commented
Apr 27, 2025
- Replicate PostGIS PROJ cache in MEOS
- Improve functions for spatial types
* Replicate PostGIS PROJ cache in MEOS * Improve functions for spatial types
mschoema
requested changes
Apr 27, 2025
Member
mschoema
left a comment
There was a problem hiding this comment.
I'm still going through the PR, but it will take a bit more time. These are the things I've already noticed.
Comment on lines
+223
to
+225
| install( | ||
| FILES "${CMAKE_SOURCE_DIR}/meos/src/geo/spatial_ref_sys.csv" | ||
| DESTINATION "${CMAKE_INSTALL_LIBDIR}") |
Member
There was a problem hiding this comment.
Not sure this should go to ${CMAKE_INSTALL_LIBDIR}. It should probably go into ${CMAKE_INSTALL_DATAROOTDIR} (/share). Either change this or open an issue related to this so we don't forget to change it later.
Comment on lines
+236
to
+238
| install( | ||
| FILES "${CMAKE_SOURCE_DIR}/meos/src/npoint/ways.csv" | ||
| DESTINATION "${CMAKE_INSTALL_LIBDIR}") |
Comment on lines
+337
to
+802
| /***************************************************************************** | ||
| * Validity macros | ||
| *****************************************************************************/ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a pointer is not null | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_NOT_NULL(ptr, ret) \ | ||
| do { if (! ensure_not_null((void *) (ptr))) return (ret); } while (0) | ||
| #else | ||
| #define VALIDATE_NOT_NULL(ptr, ret) \ | ||
| do { assert(ptr); } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /*****************************************************************************/ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a set is an integer set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_INTSET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_set_isof_type((set), T_INTSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_INTSET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert((set)->settype == T_INTSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a set is a big integer set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_BIGINTSET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_set_isof_type((set), T_BIGINTSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_BIGINTSET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert((set)->settype == T_BIGINTSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a set is a float set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_FLOATSET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_set_isof_type((set), T_FLOATSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_FLOATSET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert((set)->settype == T_FLOATSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a set is a text set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TEXTSET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_set_isof_type((set), T_TEXTSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TEXTSET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert((set)->settype == T_TEXTSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a set is a date set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_DATESET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_set_isof_type((set), T_DATESET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_DATESET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert((set)->settype == T_DATESET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a set is a timestamptz set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TSTZSET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_set_isof_type((set), T_TSTZSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TSTZSET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert((set)->settype == T_TSTZSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the span is a number span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_NUMSET(set, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (set)) || \ | ||
| ! ensure_numset_type((set)->settype) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_NUMSET(set, ret) \ | ||
| do { \ | ||
| assert(set); \ | ||
| assert(numset_type((set)->settype)); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /*****************************************************************************/ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span is an integer span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_INTSPAN(span, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (span)) || \ | ||
| ! ensure_span_isof_type((span), T_INTSPAN) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_INTSPAN(span, ret) \ | ||
| do { \ | ||
| assert(span); \ | ||
| assert((span)->spantype == T_INTSPAN); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span is a big integer span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_BIGINTSPAN(span, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (span)) || \ | ||
| ! ensure_span_isof_type((span), T_BIGINTSPAN) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_BIGINTSPAN(span, ret) \ | ||
| do { \ | ||
| assert(span); \ | ||
| assert((span)->spantype == T_BIGINTSPAN); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span is a float span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_FLOATSPAN(span, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (span)) || \ | ||
| ! ensure_span_isof_type((span), T_FLOATSPAN) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_FLOATSPAN(span, ret) \ | ||
| do { \ | ||
| assert(span); \ | ||
| assert((span)->spantype == T_FLOATSPAN); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span is a date span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_DATESPAN(span, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (span)) || \ | ||
| ! ensure_span_isof_type((span), T_DATESPAN) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_DATESPAN(span, ret) \ | ||
| do { \ | ||
| assert(span); \ | ||
| assert((span)->spantype == T_DATESPAN); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the span is a timestamptz span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TSTZSPAN(span, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (span)) || \ | ||
| ! ensure_span_isof_type((span), T_TSTZSPAN) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TSTZSPAN(span, ret) \ | ||
| do { \ | ||
| assert(span); \ | ||
| assert((span)->spantype == T_TSTZSPAN); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the span is a number span | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_NUMSPAN(span, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (span)) || \ | ||
| ! ensure_numspan_type((span)->spantype) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_NUMSPAN(span, ret) \ | ||
| do { \ | ||
| assert(span); \ | ||
| assert(numspan_type((span)->spantype)); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /*****************************************************************************/ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span set is an integer span set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_INTSPANSET(ss, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (ss)) || \ | ||
| ! ensure_spanset_isof_type((ss), T_INTSPANSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_INTSPANSET(ss, ret) \ | ||
| do { \ | ||
| assert(ss); \ | ||
| assert((ss)->spansettype == T_INTSPANSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span set is a big integer span set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_BIGINTSPANSET(ss, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (ss)) || \ | ||
| ! ensure_spanset_isof_type((ss), T_BIGINTSPANSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_BIGINTSPANSET(ss, ret) \ | ||
| do { \ | ||
| assert(ss); \ | ||
| assert((ss)->spansettype == T_BIGINTSPANSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span set is a float span set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_FLOATSPANSET(ss, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (ss)) || \ | ||
| ! ensure_spanset_isof_type((ss), T_FLOATSPANSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_FLOATSPANSET(ss, ret) \ | ||
| do { \ | ||
| assert(ss); \ | ||
| assert((ss)->spansettype == T_FLOATSPANSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that a span set is a date span set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_DATESPANSET(ss, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (ss)) || \ | ||
| ! ensure_spanset_isof_type((ss), T_DATESPANSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_DATESPANSET(ss, ret) \ | ||
| do { \ | ||
| assert(ss); \ | ||
| assert((ss)->spansettype == T_DATESPANSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the span set is a timestamptz span set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TSTZSPANSET(ss, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (ss)) || \ | ||
| ! ensure_spanset_isof_type(ss, T_TSTZSPANSET) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TSTZSPANSET(ss, ret) \ | ||
| do { \ | ||
| assert(ss); \ | ||
| assert((ss)->spansettype == T_TSTZSPANSET); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the span set is a number span set | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_NUMSPANSET(ss, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (ss)) || \ | ||
| ! ensure_numspanset_type((ss)->spansettype) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_NUMSPANSET(ss, ret) \ | ||
| do { \ | ||
| assert(ss); \ | ||
| assert(numspanset_type((ss)->spansettype)); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /*****************************************************************************/ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the temporal value is a temporal Boolean | ||
| * @note The macro works for the Temporal type and its subtypes TInstant, | ||
| * TSequence, and TSequenceSet | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TBOOL(temp, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (temp)) || \ | ||
| ! ensure_temporal_isof_type((Temporal *) (temp), T_TBOOL) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TBOOL(temp, ret) \ | ||
| do { \ | ||
| assert(temp); \ | ||
| assert(((Temporal *) (temp))->temptype == T_TBOOL); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the temporal value is a temporal integer | ||
| * @note The macro works for the Temporal type and its subtypes TInstant, | ||
| * TSequence, and TSequenceSet | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TINT(temp, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (temp)) || \ | ||
| ! ensure_temporal_isof_type((Temporal *) (temp), T_TINT) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TINT(temp, ret) \ | ||
| do { \ | ||
| assert(temp); \ | ||
| assert(((Temporal *) (temp))->temptype == T_TINT); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the temporal value is a temporal float | ||
| * @note The macro works for the Temporal type and its subtypes TInstant, | ||
| * TSequence, and TSequenceSet | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TFLOAT(temp, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (temp)) || \ | ||
| ! ensure_temporal_isof_type((Temporal *) (temp), T_TFLOAT) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TFLOAT(temp, ret) \ | ||
| do { \ | ||
| assert(temp); \ | ||
| assert(((Temporal *) (temp))->temptype == T_TFLOAT); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the temporal value is a temporal text | ||
| * @note The macro works for the Temporal type and its subtypes TInstant, | ||
| * TSequence, and TSequenceSet | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TTEXT(temp, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (temp)) || \ | ||
| ! ensure_temporal_isof_type((Temporal *) (temp), T_TTEXT) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TTEXT(temp, ret) \ | ||
| do { \ | ||
| assert(temp); \ | ||
| assert(((Temporal *) (temp))->temptype == T_TTEXT); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
||
| /** | ||
| * @brief Macro for ensuring that the temporal value is a temporal number | ||
| * @note The macro works for the Temporal type and its subtypes TInstant, | ||
| * TSequence, and TSequenceSet | ||
| */ | ||
| #if MEOS | ||
| #define VALIDATE_TNUMBER(temp, ret) \ | ||
| do { \ | ||
| if (! ensure_not_null((void *) (temp)) || \ | ||
| ! ensure_tnumber_type(((Temporal *) (temp))->temptype) ) \ | ||
| return (ret); \ | ||
| } while (0) | ||
| #else | ||
| #define VALIDATE_TNUMBER(temp, ret) \ | ||
| do { \ | ||
| assert(temp); \ | ||
| assert(tnumber_type(((Temporal *) (temp))->temptype)); \ | ||
| } while (0) | ||
| #endif /* MEOS */ | ||
|
|
Member
There was a problem hiding this comment.
I think this is a mistake, these macros are already in meos_internal.h
mschoema
requested changes
May 8, 2025
Comment on lines
+49
to
+114
| /* An entry in the PROJ SRS cache */ | ||
| typedef struct struct_PROJSRSCacheItem | ||
| { | ||
| int32_t srid_from; | ||
| int32_t srid_to; | ||
| uint64_t hits; | ||
| LWPROJ *projection; | ||
| } PROJSRSCacheItem; | ||
|
|
||
| /* PROJ 4 lookup transaction cache methods */ | ||
| #define PROJ_CACHE_ITEMS 128 | ||
|
|
||
| /** | ||
| * @brief The proj4 cache holds a fixed number of reprojection entries. | ||
| * In normal usage we don't expect it to have many entries, so we always | ||
| * linearly scanthe list. | ||
| * @note The structure removes the context field from PostGIS PROJSRSCache | ||
| */ | ||
| typedef struct struct_MEOSPROJSRSCache | ||
| { | ||
| PROJSRSCacheItem MEOSPROJSRSCache[PROJ_CACHE_ITEMS]; | ||
| uint32_t PROJSRSCacheCount; | ||
| } MEOSPROJSRSCache; | ||
|
|
||
| /** | ||
| * @brief PROJ 4 backend hash table initial hash size (since 16 is the default | ||
| * portal hash table size, and we would typically have 2 entries per portal | ||
| * then we shall use a default size of 256) | ||
| */ | ||
| #define PROJ_BACKEND_HASH_SIZE 256 | ||
|
|
||
| /* Global variable to hold the Proj object cache */ | ||
| MEOSPROJSRSCache *MEOS_PROJ_CACHE = NULL; | ||
|
|
||
| /** | ||
| * @brief Utility structure to get many potential string representations | ||
| * from spatial_ref_sys query | ||
| */ | ||
| typedef struct | ||
| { | ||
| char *authtext; /* auth_name:auth_srid */ | ||
| char *srtext; | ||
| char *proj4text; | ||
| } PjStrs; | ||
|
|
||
| /***************************************************************************** | ||
| * Definitions for reading the spatial_ref_sys.csv file | ||
| *****************************************************************************/ | ||
|
|
||
| #if MEOS | ||
| /* Maximum length in characters of a header record in the input CSV file */ | ||
| #define MAX_LENGTH_HEADER 1024 | ||
| /* Maximum length in characters of a geometry in the input data */ | ||
| #define MAX_LENGTH_SRS_RECORD 5120 | ||
| /* Location of the spatial_ref_sys.csv file */ | ||
| #define SPATIAL_REF_SYS_CSV "/usr/local/lib/spatial_ref_sys.csv" | ||
|
|
||
| typedef struct | ||
| { | ||
| char auth_name[256]; | ||
| int32_t auth_srid; | ||
| char proj4text[2048]; | ||
| char srtext[2048]; | ||
| } spatial_ref_sys_record; | ||
| #endif /* MEOS */ | ||
|
|
Member
There was a problem hiding this comment.
I think most of this should be in a header file.
mschoema
approved these changes
May 11, 2025
Member
mschoema
left a comment
There was a problem hiding this comment.
Requested changes will be included in next PR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.