From trac at osgeo.org Wed Oct 1 00:43:36 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 01 Oct 2025 07:43:36 -0000 Subject: [PostGIS] #5995: Add pg_upgrade testing in CI Message-ID: <046.4e51da8597e36490023f2d61394acc94@osgeo.org> #5995: Add pg_upgrade testing in CI --------------------------+--------------------------- Reporter: strk | Owner: robe Type: task | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: QA/buildbots | Version: master Keywords: pg_upgrade | --------------------------+--------------------------- At the moment we have no CI agent testing pg_upgrade. The OCI image used for Woodie testing already contains different PostgreSQL versions so would be usable for such test. Ideally we'd have a script to do the testing, so developers can also easily run the script locally, like utils/check_all_upgrades.sh (and possibly adding the new support in that same script) Known bug whose fix could be secured in this way: #5899 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 1 00:43:59 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 01 Oct 2025 07:43:59 -0000 Subject: [PostGIS] #5899: pg_upgrade fails restore geography because spatial_ref_sys does not exist In-Reply-To: <046.7db8fae173ff95d3422792441e5a0a68@osgeo.org> References: <046.7db8fae173ff95d3422792441e5a0a68@osgeo.org> Message-ID: <061.3bb7b927199431be80b4d1cc44a75889@osgeo.org> #5899: pg_upgrade fails restore geography because spatial_ref_sys does not exist ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.2.9 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by strk): jeevanchalke while a solution is still not available, could you consider integrating a reproducer of this issue in our existing test infrastructure ( #5995 ) -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 1 13:11:52 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 01 Oct 2025 20:11:52 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon (was: ST_Distance error on curvepolgyon) In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.87c5b076ff74bc98e50603f2b42ab6e7@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by pramsey): * summary: ST_Distance error on curvepolgyon => ST_Distance error on CurvePolygon -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 1 14:44:31 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 14:44:31 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-69-g34ee8312c Message-ID: <20251001214432.2ECF26DCA@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 34ee8312cdb01171ceb2895d0c4f6124f3e63913 (commit) via fba69e60f1fc636564afe16b6942a84f9c755a22 (commit) from a89de164624f1a9024d7912107cd9e6662f0cadb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 34ee8312cdb01171ceb2895d0c4f6124f3e63913 Author: Paul Ramsey Date: Wed Oct 1 14:14:27 2025 -0700 Ensure calloc called with count as first argument diff --git a/loader/dbfopen.c b/loader/dbfopen.c index 5611473f4..fa2df7f9a 100644 --- a/loader/dbfopen.c +++ b/loader/dbfopen.c @@ -1975,12 +1975,11 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) return FALSE; /* a simple malloc() would be enough, but calloc() helps clang static analyzer */ - panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields)); - pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * - psDBF->nFields)); + panFieldOffsetNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldSizeNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldDecimalsNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + pachFieldTypeNew = STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char))); + pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields)); if( panFieldOffsetNew == SHPLIB_NULLPTR || panFieldSizeNew == SHPLIB_NULLPTR || panFieldDecimalsNew == SHPLIB_NULLPTR || pachFieldTypeNew == SHPLIB_NULLPTR || diff --git a/loader/shpopen.c b/loader/shpopen.c index 3fe86874d..903e8a3c2 100644 --- a/loader/shpopen.c +++ b/loader/shpopen.c @@ -366,7 +366,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ - psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1)); + psSHP = STATIC_CAST(SHPHandle, calloc(1,sizeof(SHPInfo))); if( psSHP == SHPLIB_NULLPTR ) return SHPLIB_NULLPTR; @@ -1259,7 +1259,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, psObject->nParts = MAX(1,nParts); psObject->panPartStart = STATIC_CAST(int *, - calloc(sizeof(int), psObject->nParts)); + calloc(psObject->nParts, sizeof(int))); psObject->panPartType = STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts)); @@ -1288,13 +1288,13 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, { size_t nSize = sizeof(double) * nVertices; psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); if( padfX != SHPLIB_NULLPTR ) memcpy(psObject->padfX, padfX, nSize); if( padfY != SHPLIB_NULLPTR ) commit fba69e60f1fc636564afe16b6942a84f9c755a22 Author: Paul Ramsey Date: Wed Oct 1 14:04:33 2025 -0700 Compilation failure in CI, uninit variable nsolids diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c index 433c01a51..8aaa9445b 100644 --- a/liblwgeom/lwgeom_sfcgal.c +++ b/liblwgeom/lwgeom_sfcgal.c @@ -322,7 +322,7 @@ ptarray_to_SFCGAL(const POINTARRAY *pa, int type) LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid) { - uint32_t ngeoms, nshells, nsolids; + uint32_t ngeoms = 0, nshells = 0, nsolids = 0; uint32_t i, j, k; int want3d; ----------------------------------------------------------------------- Summary of changes: liblwgeom/lwgeom_sfcgal.c | 2 +- loader/dbfopen.c | 11 +++++------ loader/shpopen.c | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 1 15:22:53 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 15:22:53 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-9-gb212d84b6 Message-ID: <20251001222253.37AC97BDC@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via b212d84b694c61e2efb86bb9f2e2c0367e74a81c (commit) from 9161e94863560ddec2768e57a6ba3b4790c52a32 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b212d84b694c61e2efb86bb9f2e2c0367e74a81c Author: Paul Ramsey Date: Wed Oct 1 15:22:45 2025 -0700 Remove build warnings for latest compilers. diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c index 433c01a51..8aaa9445b 100644 --- a/liblwgeom/lwgeom_sfcgal.c +++ b/liblwgeom/lwgeom_sfcgal.c @@ -322,7 +322,7 @@ ptarray_to_SFCGAL(const POINTARRAY *pa, int type) LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid) { - uint32_t ngeoms, nshells, nsolids; + uint32_t ngeoms = 0, nshells = 0, nsolids = 0; uint32_t i, j, k; int want3d; diff --git a/loader/dbfopen.c b/loader/dbfopen.c index 32d11a0c2..c0418297b 100644 --- a/loader/dbfopen.c +++ b/loader/dbfopen.c @@ -1966,12 +1966,11 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) return FALSE; /* a simple malloc() would be enough, but calloc() helps clang static analyzer */ - panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields)); - pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * - psDBF->nFields)); + panFieldOffsetNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldSizeNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldDecimalsNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + pachFieldTypeNew = STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char))); + pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields)); /* shuffle fields definitions */ for(i=0; i < psDBF->nFields; i++) diff --git a/loader/shpopen.c b/loader/shpopen.c index 63d301e06..fd9523ea8 100644 --- a/loader/shpopen.c +++ b/loader/shpopen.c @@ -366,7 +366,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ - psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1)); + psSHP = STATIC_CAST(SHPHandle, calloc(1,sizeof(SHPInfo))); psSHP->bUpdated = FALSE; memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) ); @@ -1248,7 +1248,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, psObject->nParts = MAX(1,nParts); psObject->panPartStart = STATIC_CAST(int *, - calloc(sizeof(int), psObject->nParts)); + calloc(psObject->nParts, sizeof(int))); psObject->panPartType = STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts)); @@ -1277,13 +1277,13 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, { size_t nSize = sizeof(double) * nVertices; psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); if( padfX != SHPLIB_NULLPTR ) memcpy(psObject->padfX, padfX, nSize); if( padfY != SHPLIB_NULLPTR ) ----------------------------------------------------------------------- Summary of changes: liblwgeom/lwgeom_sfcgal.c | 2 +- loader/dbfopen.c | 11 +++++------ loader/shpopen.c | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 1 15:24:02 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 15:24:02 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-57-g686839214 Message-ID: <20251001222402.D02397BEB@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 686839214ba333ccd3f4eb816d9e9caeb79d93e2 (commit) from 50caad929fce9d57ff633da75e29575b692acaa0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 686839214ba333ccd3f4eb816d9e9caeb79d93e2 Author: Paul Ramsey Date: Wed Oct 1 15:23:57 2025 -0700 Remove build warnings for latest compilers. diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c index fcb1c8a0e..c9aa22349 100644 --- a/liblwgeom/lwgeom_sfcgal.c +++ b/liblwgeom/lwgeom_sfcgal.c @@ -328,7 +328,7 @@ ptarray_to_SFCGAL(const POINTARRAY *pa, int type) LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid) { - uint32_t ngeoms, nshells, nsolids; + uint32_t ngeoms = 0, nshells = 0, nsolids = 0; uint32_t i, j, k; int want3d; diff --git a/loader/dbfopen.c b/loader/dbfopen.c index 32d11a0c2..c0418297b 100644 --- a/loader/dbfopen.c +++ b/loader/dbfopen.c @@ -1966,12 +1966,11 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) return FALSE; /* a simple malloc() would be enough, but calloc() helps clang static analyzer */ - panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields)); - pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * - psDBF->nFields)); + panFieldOffsetNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldSizeNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldDecimalsNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + pachFieldTypeNew = STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char))); + pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields)); /* shuffle fields definitions */ for(i=0; i < psDBF->nFields; i++) diff --git a/loader/shpopen.c b/loader/shpopen.c index 4d12d2692..a00dc19cf 100644 --- a/loader/shpopen.c +++ b/loader/shpopen.c @@ -366,7 +366,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ - psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1)); + psSHP = STATIC_CAST(SHPHandle, calloc(1,sizeof(SHPInfo))); psSHP->bUpdated = FALSE; memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) ); @@ -1248,7 +1248,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, psObject->nParts = MAX(1,nParts); psObject->panPartStart = STATIC_CAST(int *, - calloc(sizeof(int), psObject->nParts)); + calloc(psObject->nParts, sizeof(int))); psObject->panPartType = STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts)); @@ -1277,13 +1277,13 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, { size_t nSize = sizeof(double) * nVertices; psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); if( padfX != SHPLIB_NULLPTR ) memcpy(psObject->padfX, padfX, nSize); if( padfY != SHPLIB_NULLPTR ) ----------------------------------------------------------------------- Summary of changes: liblwgeom/lwgeom_sfcgal.c | 2 +- loader/dbfopen.c | 11 +++++------ loader/shpopen.c | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 1 15:25:02 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 15:25:02 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-53-g567d074fb Message-ID: <20251001222502.CD4A977FD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via 567d074fb45efe85825cf32a7b63b74154ff0421 (commit) from 1dcce8754e7b9f266c00d194f07668e4a41a29d4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 567d074fb45efe85825cf32a7b63b74154ff0421 Author: Paul Ramsey Date: Wed Oct 1 15:24:58 2025 -0700 Remove build warnings for latest compilers. diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c index 27c944887..7bb9fd47b 100644 --- a/liblwgeom/lwgeom_sfcgal.c +++ b/liblwgeom/lwgeom_sfcgal.c @@ -304,7 +304,7 @@ ptarray_to_SFCGAL(const POINTARRAY *pa, int type) LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid) { - uint32_t ngeoms, nshells, nsolids; + uint32_t ngeoms = 0, nshells = 0, nsolids = 0; uint32_t i, j, k; int want3d; diff --git a/loader/dbfopen.c b/loader/dbfopen.c index 32d11a0c2..c0418297b 100644 --- a/loader/dbfopen.c +++ b/loader/dbfopen.c @@ -1966,12 +1966,11 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) return FALSE; /* a simple malloc() would be enough, but calloc() helps clang static analyzer */ - panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields)); - pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * - psDBF->nFields)); + panFieldOffsetNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldSizeNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldDecimalsNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + pachFieldTypeNew = STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char))); + pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields)); /* shuffle fields definitions */ for(i=0; i < psDBF->nFields; i++) diff --git a/loader/shpopen.c b/loader/shpopen.c index 4d12d2692..a00dc19cf 100644 --- a/loader/shpopen.c +++ b/loader/shpopen.c @@ -366,7 +366,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ - psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1)); + psSHP = STATIC_CAST(SHPHandle, calloc(1,sizeof(SHPInfo))); psSHP->bUpdated = FALSE; memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) ); @@ -1248,7 +1248,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, psObject->nParts = MAX(1,nParts); psObject->panPartStart = STATIC_CAST(int *, - calloc(sizeof(int), psObject->nParts)); + calloc(psObject->nParts, sizeof(int))); psObject->panPartType = STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts)); @@ -1277,13 +1277,13 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, { size_t nSize = sizeof(double) * nVertices; psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); if( padfX != SHPLIB_NULLPTR ) memcpy(psObject->padfX, padfX, nSize); if( padfY != SHPLIB_NULLPTR ) ----------------------------------------------------------------------- Summary of changes: liblwgeom/lwgeom_sfcgal.c | 2 +- loader/dbfopen.c | 11 +++++------ loader/shpopen.c | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 1 15:25:46 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 15:25:46 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.7-56-g5e99f2edf Message-ID: <20251001222547.237497CCC@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via 5e99f2edfaf388110d9d6873f4180266d7533607 (commit) from 2a326e9bc1739c60402e701a19fc9037b578b526 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5e99f2edfaf388110d9d6873f4180266d7533607 Author: Paul Ramsey Date: Wed Oct 1 15:25:42 2025 -0700 Remove build warnings for latest compilers. diff --git a/liblwgeom/lwgeom_sfcgal.c b/liblwgeom/lwgeom_sfcgal.c index 325c67ecd..123a37783 100644 --- a/liblwgeom/lwgeom_sfcgal.c +++ b/liblwgeom/lwgeom_sfcgal.c @@ -292,7 +292,7 @@ ptarray_to_SFCGAL(const POINTARRAY *pa, int type) LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid) { - uint32_t ngeoms, nshells, nsolids; + uint32_t ngeoms = 0, nshells = 0, nsolids = 0; uint32_t i, j, k; int want3d; diff --git a/loader/dbfopen.c b/loader/dbfopen.c index 32d11a0c2..c0418297b 100644 --- a/loader/dbfopen.c +++ b/loader/dbfopen.c @@ -1966,12 +1966,11 @@ DBFReorderFields( DBFHandle psDBF, int* panMap ) return FALSE; /* a simple malloc() would be enough, but calloc() helps clang static analyzer */ - panFieldOffsetNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldSizeNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - panFieldDecimalsNew = STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields)); - pachFieldTypeNew = STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields)); - pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * - psDBF->nFields)); + panFieldOffsetNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldSizeNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + panFieldDecimalsNew = STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int))); + pachFieldTypeNew = STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char))); + pszHeaderNew = STATIC_CAST(char*, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields)); /* shuffle fields definitions */ for(i=0; i < psDBF->nFields; i++) diff --git a/loader/shpopen.c b/loader/shpopen.c index 4d12d2692..a00dc19cf 100644 --- a/loader/shpopen.c +++ b/loader/shpopen.c @@ -366,7 +366,7 @@ SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks ) /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ - psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo),1)); + psSHP = STATIC_CAST(SHPHandle, calloc(1,sizeof(SHPInfo))); psSHP->bUpdated = FALSE; memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) ); @@ -1248,7 +1248,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, psObject->nParts = MAX(1,nParts); psObject->panPartStart = STATIC_CAST(int *, - calloc(sizeof(int), psObject->nParts)); + calloc(psObject->nParts, sizeof(int))); psObject->panPartType = STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts)); @@ -1277,13 +1277,13 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts, { size_t nSize = sizeof(double) * nVertices; psObject->padfX = STATIC_CAST(double *, padfX ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfY = STATIC_CAST(double *, padfY ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfZ = STATIC_CAST(double *, padfZ && bHasZ ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); psObject->padfM = STATIC_CAST(double *, padfM && bHasM ? malloc(nSize) : - calloc(sizeof(double),nVertices)); + calloc(nVertices, sizeof(double))); if( padfX != SHPLIB_NULLPTR ) memcpy(psObject->padfX, padfX, nSize); if( padfY != SHPLIB_NULLPTR ) ----------------------------------------------------------------------- Summary of changes: liblwgeom/lwgeom_sfcgal.c | 2 +- loader/dbfopen.c | 11 +++++------ loader/shpopen.c | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 1 15:26:37 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 15:26:37 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-70-g45af77d62 Message-ID: <20251001222638.139CA160183@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 45af77d62d20b37bc4ed47c75896013888082941 (commit) from 34ee8312cdb01171ceb2895d0c4f6124f3e63913 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 45af77d62d20b37bc4ed47c75896013888082941 Author: Paul Ramsey Date: Wed Oct 1 14:56:19 2025 -0700 Support pg19 change in VARATT_IS_* macros diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h index 102d84f35..6474de8c4 100644 --- a/libpgcommon/lwgeom_pg.h +++ b/libpgcommon/lwgeom_pg.h @@ -88,13 +88,23 @@ void pg_install_lwgeom_handlers(void); /* Argument handling macros */ #define PG_GETARG_GSERIALIZED_P(varno) ((GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(varno))) + #define PG_GETARG_GSERIALIZED_P_COPY(varno) ((GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(varno))) + #define PG_GSERIALIZED_DATUM_NEEDS_DETOAST(datum) \ (VARATT_IS_EXTENDED((datum)) || VARATT_IS_EXTERNAL((datum)) || VARATT_IS_COMPRESSED((datum))) + +#if POSTGIS_PGSQL_VERSION >= 190 +#define PG_GETARG_GSERIALIZED_HEADER(varno) \ + PG_GSERIALIZED_DATUM_NEEDS_DETOAST(DatumGetPointer(PG_GETARG_DATUM(varno))) \ + ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ + : ((GSERIALIZED *)(PG_GETARG_POINTER(varno))) +#else #define PG_GETARG_GSERIALIZED_HEADER(varno) \ PG_GSERIALIZED_DATUM_NEEDS_DETOAST(PG_GETARG_DATUM(varno)) \ ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ : ((GSERIALIZED *)(PG_GETARG_DATUM(varno))) +#endif /* Debugging macros */ #if POSTGIS_DEBUG_LEVEL > 0 ----------------------------------------------------------------------- Summary of changes: libpgcommon/lwgeom_pg.h | 10 ++++++++++ 1 file changed, 10 insertions(+) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 1 15:49:57 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 1 Oct 2025 15:49:57 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-75-gdc860997c Message-ID: <20251001224958.E8586160C66@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via dc860997c4d074ad8ca11e5f1c53aec7254d8ff0 (commit) via 791660030a5071bf6c56d43066728200de50be5e (commit) via 332bebf6c3eb13a5a0c1c3e3678d277919a20a7b (commit) via 063388ceda8d264cd1c1ed468c722ebbaf76c031 (commit) via 6e8b86bd9204e494e330b296156a0ddddf36cd50 (commit) from 45af77d62d20b37bc4ed47c75896013888082941 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dc860997c4d074ad8ca11e5f1c53aec7254d8ff0 Merge: 791660030 45af77d62 Author: Paul Ramsey Date: Wed Oct 1 15:32:36 2025 -0700 Merge branch 'master' into master-5989 commit 791660030a5071bf6c56d43066728200de50be5e Merge: 332bebf6c 34ee8312c Author: Paul Ramsey Date: Wed Oct 1 14:17:21 2025 -0700 Merge branch 'master' into master-5989 commit 332bebf6c3eb13a5a0c1c3e3678d277919a20a7b Author: Paul Ramsey Date: Wed Oct 1 13:57:10 2025 -0700 Quiet uninit warning maybe? diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 818d20523..507e2283d 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -962,7 +962,7 @@ ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on const POINT2D* p0 = getPoint2d_cp(pa, i-1); const POINT2D* p1 = getPoint2d_cp(pa, i); const POINT2D* p2 = getPoint2d_cp(pa, i+1); - POINT2D center; + POINT2D center = {0,0}; double radius, d; GBOX gbox; commit 063388ceda8d264cd1c1ed468c722ebbaf76c031 Author: Paul Ramsey Date: Wed Oct 1 13:50:48 2025 -0700 Match up types in comparison diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index b99f0db21..62e2a3586 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1622,7 +1622,7 @@ lw_dist2d_circle_intersections( * @return int The number of intersection points found (1 or 2). Returns 0 if * the centers are coincident or another error occurs. */ -static int +static uint32_t lw_dist2d_circle_circle_intersections( const POINT2D *cA, double rA, const POINT2D *cB, double rB, @@ -1741,7 +1741,7 @@ lw_dist2d_arc_arc( /* * Find the two points the circles intersect at. */ - int npoints = lw_dist2d_circle_circle_intersections( + uint32_t npoints = lw_dist2d_circle_circle_intersections( ¢er_A, radius_A, ¢er_B, radius_B, intersectionPts); commit 6e8b86bd9204e494e330b296156a0ddddf36cd50 Author: Paul Ramsey Date: Wed Oct 1 13:35:45 2025 -0700 Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 610b2a593..58e7cb4ba 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -222,6 +222,11 @@ static void test_mindistance2d_tolerance(void) DIST2DTEST( "CURVEPOLYGON(CIRCULARSTRING(7874821 8715927,8907663 8715927,8844683 7750316,7937800 7750316,7874821 8715927))", "POINT(5433865 8243495)", 2271704.2698450615, default_accepted_error); + + /* Ticket 5989 */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0, -1 5, 0 10), (0 10, -10 10, -10 0, 0 0)))", + "POINT(-0.5 5)", 0.5, default_accepted_error); } static void @@ -918,6 +923,25 @@ test_lw_dist2d_arc_arc(void) B2.x = 0 ; B2.y = 1; B3.x = 1 ; B3.y = 0; + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = 0; A1.y = .5; + A2.x = -0.3; A2.y = .5; + A3.x = 0; A3.y = .6; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + printf("%g\n", dl.distance); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.271798, 0.000001); + + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -0.5; A1.y = .5; + A2.x = -0.4; A2.y = .2; + A3.x = 0; A3.y = 0; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.292893, 0.000001); + /* Arc above the unit semicircle */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -1; A1.y = 3; @@ -954,6 +978,15 @@ test_lw_dist2d_arc_arc(void) CU_ASSERT_EQUAL( rv, LW_SUCCESS ); CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0, 0.000001); + /* Closed circle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -2.0; A1.y = -0.1; + A2.x = 1.5; A2.y = -0.1; + A3.x = -2.0; A3.y = -0.1; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.480742, 0.0001); + /* Concentric: and fully parallel */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -2.0; A1.y = 0.0; diff --git a/liblwgeom/cunit/cu_ptarray.c b/liblwgeom/cunit/cu_ptarray.c index a28da5cce..99c689ac2 100644 --- a/liblwgeom/cunit/cu_ptarray.c +++ b/liblwgeom/cunit/cu_ptarray.c @@ -433,14 +433,14 @@ static void test_ptarrayarc_contains_point() { /* int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) */ - LWLINE *lwline; + LWCIRCSTRING *lwcirc; POINTARRAY *pa; POINT2D pt; int rv; /*** Collection of semi-circles surrounding unit square ***/ - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); - pa = lwline->points; + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); + pa = lwcirc->points; /* Point in middle of square */ pt.x = 0; @@ -473,9 +473,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** Two-edge ring made up of semi-circles (really, a circle) ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); + pa = lwcirc->points; /* Point outside */ pt.x = -1.5; @@ -514,9 +514,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Two-edge ring, closed ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); + pa = lwcirc->points; /* Point to left of ring */ pt.x = 20; @@ -525,9 +525,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** One-edge ring, closed circle ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, -1 0)")); + pa = lwcirc->points; /* Point inside */ pt.x = 0; @@ -548,23 +548,23 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Overshort ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); //printf("%s\n", cu_error_msg); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_raycast_intersections called with even number of points"); /*** Unclosed ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, 2 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, 2 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called on unclosed ring", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_contains_point called on unclosed ring"); - lwline_free(lwline); + lwcircstring_free(lwcirc); } static void test_ptarray_scale() diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index e51062b00..04a3504e2 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -445,13 +445,15 @@ double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, PO int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2); int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); +int lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p); double lw_seg_length(const POINT2D *A1, const POINT2D *A2); double lw_arc_length(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring); int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); -int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); +int ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); +int ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt); int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt); diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index cb3727f15..a2cb2b037 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -90,7 +90,9 @@ lw_seg_length(const POINT2D *A1, const POINT2D *A2) int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3) { - return lw_segment_side(A1, A3, A2) == lw_segment_side(A1, A3, P); + int pt_side = lw_segment_side(A1, A3, P); + int arc_side = lw_segment_side(A1, A3, A2); + return pt_side == 0 || pt_side == arc_side; } /** @@ -104,6 +106,28 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) ((A1->y <= P->y && P->y < A2->y) || (A1->y >= P->y && P->y > A2->y)); } +int +lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +{ + // Check if the point is within the bounding box of the segment + if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || + p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) + { + return LW_FALSE; + } + + // Check for collinearity using the 2D cross-product. + // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) + double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); + + if (fabs(cross_product) < DBL_EPSILON) + { + return LW_TRUE; // Point is collinear and within the bounding box + } + + return LW_TRUE; +} + /** * Returns true if arc A is actually a point (all vertices are the same) . */ diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c index 90fee3560..1e0d5c2ee 100644 --- a/liblwgeom/lwcompound.c +++ b/liblwgeom/lwcompound.c @@ -184,63 +184,48 @@ int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) return LW_FAILURE; } +/* + * Use a ray-casting count to determine if the point + * is inside or outside of the compound curve. Ray-casting + * is run against each component of the overall arc, and + * the even/odd test run against the total of all components. + * Returns LW_INSIDE / LW_BOUNDARY / LW_OUTSIDE + */ int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { - uint32_t i; - LWLINE *lwline; - LWCIRCSTRING *lwcirc; - int wn = 0; - int winding_number = 0; - int result; + int intersections = 0; - for ( i = 0; i < comp->ngeoms; i++ ) + if (lwgeom_is_empty(lwcompound_as_lwgeom(comp))) + return LW_OUTSIDE; + + for (uint32_t j = 0; j < comp->ngeoms; j++) { - LWGEOM *lwgeom = comp->geoms[i]; - if ( lwgeom->type == LINETYPE ) + int on_boundary = LW_FALSE; + const LWGEOM *sub = comp->geoms[j]; + if (sub->type == LINETYPE) { - lwline = lwgeom_as_lwline(lwgeom); - if ( comp->ngeoms == 1 ) - { - return ptarray_contains_point(lwline->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); - } + LWLINE *lwline = lwgeom_as_lwline(sub); + intersections += ptarray_raycast_intersections(lwline->points, pt, &on_boundary); + } + else if (sub->type == CIRCSTRINGTYPE) + { + LWCIRCSTRING *lwcirc = lwgeom_as_lwcircstring(sub); + intersections += ptarrayarc_raycast_intersections(lwcirc->points, pt, &on_boundary); } else { - lwcirc = lwgeom_as_lwcircstring(lwgeom); - if ( ! lwcirc ) { - lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); - return 0; - } - if ( comp->ngeoms == 1 ) - { - return ptarrayarc_contains_point(lwcirc->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); - } + lwerror("%s: unsupported type %s", __func__, lwtype_name(sub->type)); } - - /* Propagate boundary condition */ - if ( result == LW_BOUNDARY ) + if (on_boundary) return LW_BOUNDARY; - - wn += winding_number; } - /* Outside */ - if (wn == 0) - return LW_OUTSIDE; - - /* Inside */ - return LW_INSIDE; + /* + * Odd number of intersections means inside. + * Even means outside. + */ + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } LWCOMPOUND * diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index bc240eb45..b99f0db21 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1540,37 +1540,156 @@ lw_dist2d_pt_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const P return LW_TRUE; } -/* Auxiliary function to calculate the distance between 2 concentric arcs*/ -int lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl); + + +/** + * @brief Calculates the intersection points of a circle and line. + * + * This function assumes the center and test point are distinct. + * Finds the line between the circle center and test point, and + * the two intersection points on the circle defined by that line. + * If those points fall within the provided arc (A1,A2,A3) then + * the points are added to the provided array (I) and the array + * length counter is incremented. + * + * @param A1 Point of arc + * @param A2 Point of arc + * @param A3 Point of arc + * @param center_A Center of arc A circle + * @param radius_A Radius of arc A circle + * @param P Point to use in calculating intersection line + * @param I [out] Pointer to an return value array + * @param ni [out] Pointer to return array size counter + * @return int + */ +static int +lw_dist2d_circle_intersections( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *center_A, + double radius_A, + const POINT2D *P, + POINT2D *I, + uint32_t *ni) +{ + POINT2D R; + + // If the test point is on the center of the other + // arc, some other point has to be closer, by definition. + if (p2d_same(center_A, P)) + return 0; + + // Calculate vector from the center to the pt + double dir_x = center_A->x - P->x; + double dir_y = center_A->y - P->y; + double dist = sqrt(dir_x * dir_x + dir_y * dir_y); + + // Normalize the direction vector to get a unit vector (length = 1) + double unit_x = dir_x / dist; + double unit_y = dir_y / dist; + + // Calculate the two intersection points on the circle + // Point 1: Move from center_A along the unit vector by distance radius_A + R.x = center_A->x + unit_x * radius_A; + R.y = center_A->y + unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + // Point 2: Move from center_A against the unit vector by distance radius_A + R.x = center_A->x - unit_x * radius_A; + R.y = center_A->y - unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + return 0; +} + + +/** + * @brief Calculates the intersection points of two overlapping circles. + * + * This function assumes the circles are known to intersect at one or two points. + * Specifically, the distance 'd' between their centers must satisfy: + * d < (rA + rB) and d > fabs(rA - rB) + * If these conditions are not met, the results are undefined. + * + * @param cA [in] Pointer to the center point of the first circle (A). + * @param rA [in] The radius of the first circle (A). + * @param cB [in] Pointer to the center point of the second circle (B). + * @param rB [in] The radius of the second circle (B). + * @param I [out] Pointer to an array of at least 2 POINT2D structs to store the results. + * I[0] will contain the first intersection point. + * If a second exists, it will be in I[1]. + * @return int The number of intersection points found (1 or 2). Returns 0 if + * the centers are coincident or another error occurs. + */ +static int +lw_dist2d_circle_circle_intersections( + const POINT2D *cA, double rA, + const POINT2D *cB, double rB, + POINT2D *I) +{ + // Vector from center A to center B + double dx = cB->x - cA->x; + double dy = cB->y - cA->y; + + // Distance between the centers + double d = sqrt(dx * dx + dy * dy); + + // 'a' is the distance from the center of circle A to the point P, + // which is the base of the right triangle formed by cA, P, and an intersection point. + double a = (rA * rA - rB * rB + d * d) / (2.0 * d); + + // 'h' is the height of that right triangle. + double h_squared = rA * rA - a * a; + + // Due to floating point errors, h_squared can be slightly negative. + // This happens when the circles are perfectly tangent. Clamp to 0. + if (h_squared < 0.0) + h_squared = 0.0; + + double h = sqrt(h_squared); + + // Find the coordinates of point P + double Px = cA->x + a * (dx / d); + double Py = cA->y + a * (dy / d); + + // The two intersection points are found by moving from P by a distance 'h' + // in directions perpendicular to the line connecting the centers. + // The perpendicular vector to (dx, dy) is (-dy, dx). + + // Intersection point 1 + I[0].x = Px - h * (dy / d); + I[0].y = Py + h * (dx / d); + + // If h is very close to 0, the circles are tangent and there's only one intersection point. + if (FP_IS_ZERO(h)) + return 1; + + // Intersection point 2 + I[1].x = Px + h * (dy / d); + I[1].y = Py - h * (dx / d); + + return 2; +} + int -lw_dist2d_arc_arc(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - DISTPTS *dl) +lw_dist2d_arc_arc( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, + DISTPTS *dl) { - POINT2D CA, CB; /* Center points of arcs A and B */ + POINT2D pts_A[16]; /* Points on A that might be the nearest */ + POINT2D pts_B[16]; /* Points on B that might be the nearest */ + uint32_t ai = 0, bi = 0; /* Number of points in pts_A and pts_B */ + POINT2D center_A, center_B; /* Center points of arcs A and B */ double radius_A, radius_B, d; /* Radii of arcs A and B */ - POINT2D D; /* Mid-point between the centers CA and CB */ - int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */ + int is_disjoint, is_overlapping, is_contained, is_same_center; + POINT2D intersectionPts[2]; if (dl->mode != DIST_MIN) lwerror("lw_dist2d_arc_arc only supports mindistance"); - /* TODO: Handle case where arc is closed circle (A1 = A3) */ - /* What if one or both of our "arcs" is actually a point? */ if (lw_arc_is_pt(B1, B2, B3) && lw_arc_is_pt(A1, A2, A3)) return lw_dist2d_pt_pt(B1, A1, dl); @@ -1580,8 +1699,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, return lw_dist2d_pt_arc(A1, B1, B2, B3, dl); /* Calculate centers and radii of circles. */ - radius_A = lw_arc_center(A1, A2, A3, &CA); - radius_B = lw_arc_center(B1, B2, B3, &CB); + radius_A = lw_arc_center(A1, A2, A3, ¢er_A); + radius_B = lw_arc_center(B1, B2, B3, ¢er_B); /* Two co-linear arcs?!? That's two segments. */ if (radius_A < 0 && radius_B < 0) @@ -1595,275 +1714,112 @@ lw_dist2d_arc_arc(const POINT2D *A1, if (radius_B < 0) return lw_dist2d_seg_arc(B1, B3, A1, A2, A3, dl); - /* Center-center distance */ - d = distance2d_pt_pt(&CA, &CB); + /* Circle relationships */ + d = distance2d_pt_pt(¢er_A, ¢er_B); + is_disjoint = (d > (radius_A + radius_B)); + is_contained = (d < fabs(radius_A - radius_B)); + is_same_center = p2d_same(¢er_A, ¢er_B); + is_overlapping = ! (is_disjoint || is_contained || is_same_center); - /* Concentric arcs */ - if (FP_EQUALS(d, 0.0)) - return lw_dist2d_arc_arc_concentric(A1, A2, A3, radius_A, B1, B2, B3, radius_B, &CA, dl); + /* + * Prime the array of potential closest points with the + * arc end points, which frequently participate in closest + * points. + */ + pts_A[ai++] = *A1; + pts_A[ai++] = *A3; + pts_B[bi++] = *B1; + pts_B[bi++] = *B3; - /* Make sure that arc "A" has the bigger radius */ - if (radius_B > radius_A) + /* + * Overlapping circles might have a zero distance + * case if the circle intersection points are inside both + * arcs. + */ + if (is_overlapping) { - const POINT2D *tmp; - POINT2D TP; /* Temporary point P */ - double td; - tmp = B1; - B1 = A1; - A1 = tmp; - tmp = B2; - B2 = A2; - A2 = tmp; - tmp = B3; - B3 = A3; - A3 = tmp; - TP = CB; - CB = CA; - CA = TP; - td = radius_B; - radius_B = radius_A; - radius_A = td; - } - - /* Circles touch at a point. Is that point within the arcs? */ - if (d == (radius_A + radius_B)) - { - D.x = CA.x + (CB.x - CA.x) * radius_A / d; - D.y = CA.y + (CB.y - CA.y) * radius_A / d; - - pt_in_arc_A = lw_pt_in_arc(&D, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&D, B1, B2, B3); - - /* Arcs do touch at D, return it */ - if (pt_in_arc_A && pt_in_arc_B) + /* + * Find the two points the circles intersect at. + */ + int npoints = lw_dist2d_circle_circle_intersections( + ¢er_A, radius_A, + ¢er_B, radius_B, + intersectionPts); + for (uint32_t i = 0; i < npoints; i++) { - lw_dist2d_distpts_set(dl, 0.0, &D, &D); - return LW_TRUE; + /* + * If an intersection point is contained in both + * arcs, that is a location of zero distance, so + * we are done calculating. + */ + if (lw_pt_in_arc(&intersectionPts[i], A1, A2, A3) && + lw_pt_in_arc(&intersectionPts[i], B1, B2, B3)) + { + lw_dist2d_distpts_set(dl, 0.0, &intersectionPts[i], &intersectionPts[i]); + return LW_TRUE; + } } } - /* Disjoint or contained circles don't intersect. Closest point may be on */ - /* the line joining CA to CB. */ - else if (d > (radius_A + radius_B) /* Disjoint */ || d < (radius_A - radius_B) /* Contained */) + + /* + * Join the circle centers and find the places that + * line intersects the circles. Where those places + * are in the arcs, they are potential sites of the + * closest points. + */ + if (is_disjoint || is_contained || is_overlapping) { - POINT2D XA, XB; /* Points where the line from CA to CB cross their circle bounds */ - - /* Calculate hypothetical nearest points, the places on the */ - /* two circles where the center-center line crosses. If both */ - /* arcs contain their hypothetical points, that's the crossing distance */ - XA.x = CA.x + (CB.x - CA.x) * radius_A / d; - XA.y = CA.y + (CB.y - CA.y) * radius_A / d; - XB.x = CB.x + (CA.x - CB.x) * radius_B / d; - XB.y = CB.y + (CA.y - CB.y) * radius_B / d; - - pt_in_arc_A = lw_pt_in_arc(&XA, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&XB, B1, B2, B3); - - /* If the nearest points are both within the arcs, that's our answer */ - /* the shortest distance is at the nearest points */ - if (pt_in_arc_A && pt_in_arc_B) + if (!is_same_center) { - return lw_dist2d_pt_pt(&XA, &XB, dl); - } - } - /* Circles cross at two points, are either of those points in both arcs? */ - /* http://paulbourke.net/geometry/2circle/ */ - else if (d < (radius_A + radius_B)) - { - POINT2D E, F; /* Points where circle(A) and circle(B) cross */ - /* Distance from CA to D */ - double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d); - /* Distance from D to E or F */ - double h = sqrt(radius_A * radius_A - a * a); + /* Add points on A that intersect line from center_A to center_B */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, ¢er_B, + pts_A, &ai); - /* Location of D */ - D.x = CA.x + (CB.x - CA.x) * a / d; - D.y = CA.y + (CB.y - CA.y) * a / d; - - /* Start from D and project h units perpendicular to CA-D to get E */ - E.x = D.x + (D.y - CA.y) * h / a; - E.y = D.y + (D.x - CA.x) * h / a; - - /* Crossing point E contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&E, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&E, B1, B2, B3); - - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &E, &E); - return LW_TRUE; + /* Add points on B that intersect line from center_B to center_A */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, ¢er_A, + pts_B, &bi); } - /* Start from D and project h units perpendicular to CA-D to get F */ - F.x = D.x - (D.y - CA.y) * h / a; - F.y = D.y - (D.x - CA.x) * h / a; + /* Add points on A that intersect line to B1 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B1, + pts_A, &ai); - /* Crossing point F contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&F, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&F, B1, B2, B3); + /* Add points on A that intersect line to B3 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B3, + pts_A, &ai); - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &F, &F); - return LW_TRUE; - } - } - else - { - lwerror("lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!"); - return LW_FALSE; + /* Add points on B that intersect line to A1 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A1, + pts_B, &bi); + + /* Add points on B that intersect line to A3 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A3, + pts_B, &bi); } - /* Closest point is in the arc A, but not in the arc B, so */ - /* one of the B end points must be the closest. */ - if (pt_in_arc_A && !pt_in_arc_B) - { - lw_dist2d_pt_arc(B1, A1, A2, A3, dl); - lw_dist2d_pt_arc(B3, A1, A2, A3, dl); - return LW_TRUE; - } - /* Closest point is in the arc B, but not in the arc A, so */ - /* one of the A end points must be the closest. */ - else if (pt_in_arc_B && !pt_in_arc_A) - { - lw_dist2d_pt_arc(A1, B1, B2, B3, dl); - lw_dist2d_pt_arc(A3, B1, B2, B3, dl); - return LW_TRUE; - } - /* Finally, one of the end-point to end-point combos is the closest. */ - else - { - lw_dist2d_pt_pt(A1, B1, dl); - lw_dist2d_pt_pt(A1, B3, dl); - lw_dist2d_pt_pt(A3, B1, dl); - lw_dist2d_pt_pt(A3, B3, dl); - return LW_TRUE; - } + /* + * Now just brute force check all pairs of participating + * points, to find the pair that is closest together. + */ + for (uint32_t i = 0; i < ai; i++) + for (uint32_t j = 0; j < bi; j++) + lw_dist2d_pt_pt(&pts_A[i], &pts_B[j], dl); return LW_TRUE; } -int -lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl) -{ - int seg_size; - double dist_sqr, shortest_sqr; - const POINT2D *P1; - const POINT2D *P2; - POINT2D proj; - - if (radius_A == radius_B) - { - /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */ - seg_size = lw_segment_side(A1, A3, A2); - if (seg_size == lw_segment_side(A1, A3, B1)) - { - lw_dist2d_distpts_set(dl, 0.0, B1, B1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(A1, A3, B3)) - { - lw_dist2d_distpts_set(dl, 0.0, B3, B3); - return LW_TRUE; - } - /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */ - seg_size = lw_segment_side(B1, B3, B2); - if (seg_size == lw_segment_side(B1, B3, A1)) - { - lw_dist2d_distpts_set(dl, 0.0, A1, A1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(B1, B3, A3)) - { - lw_dist2d_distpts_set(dl, 0.0, A3, A3); - return LW_TRUE; - } - } - else - { - /* Check if any projection of B ends are in A*/ - seg_size = lw_segment_side(A1, A3, A2); - - /* B1 */ - proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B; - - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B1); - return LW_TRUE; - } - /* B3 */ - proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B; - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B3); - return LW_TRUE; - } - - /* Now check projections of A in B */ - seg_size = lw_segment_side(B1, B3, B2); - - /* A1 */ - proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A1); - return LW_TRUE; - } - - /* A3 */ - proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A3); - return LW_TRUE; - } - } - - /* Check the shortest between the distances of the 4 ends */ - shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1); - P1 = A1; - P2 = B1; - - dist_sqr = distance2d_sqr_pt_pt(A1, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A1; - P2 = B3; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B1); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B1; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B3; - } - - lw_dist2d_distpts_set(dl, sqrt(shortest_sqr), P1, P2); - return LW_TRUE; -} /** Finds the shortest distance between two segments. diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index a1e790dee..818d20523 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -742,17 +742,285 @@ ptarray_is_closed_z(const POINTARRAY *in) } /** -* Return LW_INSIDE if the point is inside the POINTARRAY, -* LW_OUTSIDE if it is outside, and LW_BOUNDARY if it is on -* the boundary. -* LW_INSIDE == 1, LW_BOUNDARY == 0, LW_OUTSIDE == -1 -*/ + * The following is based on the "Fast Winding Number Inclusion of a Point + * in a Polygon" algorithm by Dan Sunday. + * http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number + * + * Return: + * - LW_INSIDE (1) if the point is inside the POINTARRAY + * - LW_BOUNDARY (0) if it is on the boundary. + * - LW_OUTSIDE (-1) if it is outside + */ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarray_contains_point_partial(pa, pt, LW_TRUE, NULL); + const POINT2D *seg1, *seg2; + int wn = 0; + + seg1 = getPoint2d_cp(pa, 0); + seg2 = getPoint2d_cp(pa, pa->npoints-1); + if (!p2d_same(seg1, seg2)) + lwerror("ptarray_contains_point called on unclosed ring"); + + for (uint32_t i = 1; i < pa->npoints; i++) + { + double side, ymin, ymax; + + seg2 = getPoint2d_cp(pa, i); + + /* Zero length segments are ignored. */ + if (p2d_same(seg1, seg2)) + { + seg1 = seg2; + continue; + } + + ymin = FP_MIN(seg1->y, seg2->y); + ymax = FP_MAX(seg1->y, seg2->y); + + /* Only test segments in our vertical range */ + if (pt->y > ymax || pt->y < ymin) + { + seg1 = seg2; + continue; + } + + side = lw_segment_side(seg1, seg2, pt); + + /* + * A point on the boundary of a ring is not contained. + * WAS: if (fabs(side) < 1e-12), see #852 + */ + if ((side == 0) && lw_pt_in_seg(pt, seg1, seg2)) + { + return LW_BOUNDARY; + } + + /* + * If the point is to the left of the line, and it's rising, + * then the line is to the right of the point and + * circling counter-clockwise, so increment. + */ + if ((side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y)) + { + wn++; + } + + /* + * If the point is to the right of the line, and it's falling, + * then the line is to the right of the point and circling + * clockwise, so decrement. + */ + else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) ) + { + wn--; + } + + seg1 = seg2; + } + + /* wn == 0 => Outside, wn != 0 => Inside */ + return wn == 0 ? LW_OUTSIDE : LW_INSIDE; } +int +ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + // A valid linestring must have at least 2 point + if (pa->npoints < 2) + lwerror("%s called on invalid linestring", __func__); + + int intersections = 0; + double px = p->x; + double py = p->y; + + // Iterate through each edge of the polygon + for (uint32_t i = 0; i < pa->npoints-1; ++i) + { + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + + /* Skip zero-length edges */ + if (p2d_same(p1, p2)) + continue; + + /* --- Step 1: Check if the point is ON the boundary edge --- */ + if (lw_pt_on_segment(p1, p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + /* --- Step 2: Perform the Ray Casting intersection test --- */ + + /* + * Check if the horizontal ray from p intersects the edge (p1, p2). + * This is the core condition for handling vertices correctly: + * - One vertex must be strictly above the ray (py < vertex.y) + * - The other must be on or below the ray (py >= vertex.y) + */ + if (((p1->y <= py) && (py < p2->y)) || ((p2->y <= py) && (py < p1->y))) + { + /* + * Calculate the x-coordinate where the edge intersects the ray's horizontal line. + * Formula: x = x1 + (y - y1) * (x2 - x1) / (y2 - y1) + */ + double x_intersection = p1->x + (py - p1->y) * (p2->x - p1->x) / (p2->y - p1->y); + + /* + * If the intersection point is to the right of our test point, + * it's a valid "crossing". + */ + if (x_intersection > px) + { + intersections++; + } + } + } + + return intersections; +} + + +/** + * @brief Calculates the intersection points of a circle and a horizontal line. + * + * The equation of a circle is (x - cx)^2 + (y - cy)^2 = r^2. + * The equation of the horizontal line is y = y_line. + * Substituting y_line into the circle equation gives: + * (x - cx)^2 = r^2 - (y_line - cy)^2 + * This function solves for x. + * + * @param center A pointer to the center point of the circle. + * @param radius The radius of the circle. + * @param ray The y-coordinate of the horizontal line. + * @param i0 A pointer to a POINT2D to store the first intersection point. + * @param i1 A pointer to a POINT2D to store the second intersection point. + * + * @return The number of intersection points found (0, 1, or 2). + */ +static int +circle_raycast_intersections(const POINT2D *center, double radius, double ray, POINT2D *i0, POINT2D *i1) +{ + // Calculate the vertical distance from the circle's center to the horizontal line. + double dy = ray - center->y; + + // If the absolute vertical distance is greater than the radius, there are no intersections. + if (fabs(dy) > radius) + return 0; + + // Use the Pythagorean theorem to find the horizontal distance (dx) from the + // center's x-coordinate to the intersection points. + // dx^2 + dy^2 = radius^2 => dx^2 = radius^2 - dy^2 + double dx_squared = radius * radius - dy * dy; + + // Case 1: One intersection (tangent) + // This occurs when the line just touches the top or bottom of the circle. + // dx_squared will be zero. We check against a small epsilon for floating-point safety. + if (FP_EQUALS(dx_squared, 0.0)) + { + i0->x = center->x; + i0->y = ray; + return 1; + } + + // Case 2: Two intersections + // The line cuts through the circle. + double dx = sqrt(dx_squared); + + // The first intersection point has the smaller x-value. + i0->x = center->x - dx; + i0->y = ray; + + // The second intersection point has the larger x-value. + i1->x = center->x + dx; + i1->y = ray; + + return 2; +} + + +int +ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + int intersections = 0; + double px = p->x; + double py = p->y; + + assert(on_boundary); + + // A valid circular arc must have at least 3 vertices (circle). + if (pa->npoints < 3) + lwerror("%s called on invalid circularstring", __func__); + + if (pa->npoints % 2 == 0) + lwerror("%s called with even number of points", __func__); + + // Iterate through each arc of the circularstring + for (uint32_t i = 1; i < pa->npoints-1; i +=2) + { + const POINT2D* p0 = getPoint2d_cp(pa, i-1); + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + POINT2D center; + double radius, d; + GBOX gbox; + + // Skip zero-length arc + if (lw_arc_is_pt(p0, p1, p2)) + continue; + + // --- Step 1: Check if the point is ON the boundary edge --- + if (p2d_same(p0, p) || p2d_same(p1, p) || p2d_same(p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // Calculate some important pieces + radius = lw_arc_center(p0, p1, p2, ¢er); + + d = distance2d_pt_pt(p, ¢er); + if (FP_EQUALS(d, radius) && lw_pt_in_arc(p, p0, p1, p2)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // --- Step 2: Perform the Ray Casting intersection test --- + + // Only process arcs that our ray crosses + lw_arc_calculate_gbox_cartesian_2d(p0, p1, p2, &gbox); + if ((gbox.ymin <= py) && (py < gbox.ymax)) + { + // Point of intersection on the circle that defines the arc + POINT2D i0, i1; + + // How many points of intersection are there + int iCount = circle_raycast_intersections(¢er, radius, py, &i0, &i1); + + // Nothing to see here + if (iCount == 0) + continue; + + // Cannot think of a case where a grazing is not a + // no-op + if (iCount == 1) + continue; + + // So we must have 2 intersections + // Only increment the counter for intersections to the right + // of the test point + if (i0.x > px && lw_pt_in_arc(&i0, p0, p1, p2)) + intersections++; + + if (i1.x > px && lw_pt_in_arc(&i1, p0, p1, p2)) + intersections++; + } + } + + return intersections; +} /* * The following is based on the "Fast Winding Number Inclusion of a Point @@ -765,8 +1033,7 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int wn = 0; uint32_t i; double side; - const POINT2D *seg1; - const POINT2D *seg2; + const POINT2D *seg1, *seg2; double ymin, ymax; seg1 = getPoint2d_cp(pa, 0); @@ -855,160 +1122,16 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarrayarc_contains_point_partial(pa, pt, LW_TRUE /* Check closed*/, NULL); -} + int on_boundary = LW_FALSE; + int intersections; + if (!ptarray_is_closed_2d(pa)) + lwerror("%s called on unclosed ring", __func__); -int -ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number) -{ - int wn = 0; - uint32_t i; - int side; - const POINT2D *seg1; - const POINT2D *seg2; - const POINT2D *seg3; - GBOX gbox; - - /* Check for not an arc ring (always have odd # of points) */ - if ( (pa->npoints % 2) == 0 ) - { - lwerror("ptarrayarc_contains_point called with even number of points"); - return LW_OUTSIDE; - } - - /* Check for not an arc ring (always have >= 3 points) */ - if ( pa->npoints < 3 ) - { - lwerror("ptarrayarc_contains_point called too-short pointarray"); - return LW_OUTSIDE; - } - - /* Check for unclosed case */ - seg1 = getPoint2d_cp(pa, 0); - seg3 = getPoint2d_cp(pa, pa->npoints-1); - if ( check_closed && ! p2d_same(seg1, seg3) ) - { - lwerror("ptarrayarc_contains_point called on unclosed ring"); - return LW_OUTSIDE; - } - /* OK, it's closed. Is it just one circle? */ - else if ( p2d_same(seg1, seg3) && pa->npoints == 3 ) - { - double radius, d; - POINT2D c; - seg2 = getPoint2d_cp(pa, 1); - - /* Wait, it's just a point, so it can't contain anything */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - return LW_OUTSIDE; - - /* See if the point is within the circle radius */ - radius = lw_arc_center(seg1, seg2, seg3, &c); - d = distance2d_pt_pt(pt, &c); - if ( FP_EQUALS(d, radius) ) - return LW_BOUNDARY; /* Boundary of circle */ - else if ( d < radius ) - return LW_INSIDE; /* Inside circle */ - else - return LW_OUTSIDE; /* Outside circle */ - } - else if ( p2d_same(seg1, pt) || p2d_same(seg3, pt) ) - { - return LW_BOUNDARY; /* Boundary case */ - } - - /* Start on the ring */ - seg1 = getPoint2d_cp(pa, 0); - for ( i=1; i < pa->npoints; i += 2 ) - { - seg2 = getPoint2d_cp(pa, i); - seg3 = getPoint2d_cp(pa, i+1); - - /* Catch an easy boundary case */ - if( p2d_same(seg3, pt) ) - return LW_BOUNDARY; - - /* Skip arcs that have no size */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - { - seg1 = seg3; - continue; - } - - /* Only test segments in our vertical range */ - lw_arc_calculate_gbox_cartesian_2d(seg1, seg2, seg3, &gbox); - if ( pt->y > gbox.ymax || pt->y < gbox.ymin ) - { - seg1 = seg3; - continue; - } - - /* Outside of horizontal range, and not between end points we also skip */ - if ( (pt->x > gbox.xmax || pt->x < gbox.xmin) && - (pt->y > FP_MAX(seg1->y, seg3->y) || pt->y < FP_MIN(seg1->y, seg3->y)) ) - { - seg1 = seg3; - continue; - } - - side = lw_arc_side(seg1, seg2, seg3, pt); - - /* On the boundary */ - if ( (side == 0) && lw_pt_in_arc(pt, seg1, seg2, seg3) ) - { - return LW_BOUNDARY; - } - - /* Going "up"! Point to left of arc. */ - if ( side < 0 && (seg1->y <= pt->y) && (pt->y < seg3->y) ) - { - wn++; - } - - /* Going "down"! */ - if ( side > 0 && (seg3->y <= pt->y) && (pt->y < seg1->y) ) - { - wn--; - } - - /* Inside the arc! */ - if ( pt->x <= gbox.xmax && pt->x >= gbox.xmin ) - { - POINT2D C; - double radius = lw_arc_center(seg1, seg2, seg3, &C); - double d = distance2d_pt_pt(pt, &C); - - /* On the boundary! */ - if ( d == radius ) - return LW_BOUNDARY; - - /* Within the arc! */ - if ( d < radius ) - { - /* Left side, increment winding number */ - if ( side < 0 ) - wn++; - /* Right side, decrement winding number */ - if ( side > 0 ) - wn--; - } - } - - seg1 = seg3; - } - - /* Sent out the winding number for calls that are building on this as a primitive */ - if ( winding_number ) - *winding_number = wn; - - /* Outside */ - if (wn == 0) - { - return LW_OUTSIDE; - } - - /* Inside */ - return LW_INSIDE; + intersections = ptarrayarc_raycast_intersections(pa, pt, &on_boundary); + if (on_boundary) + return LW_BOUNDARY; + else + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } /** ----------------------------------------------------------------------- Summary of changes: liblwgeom/cunit/cu_measures.c | 33 +++ liblwgeom/cunit/cu_ptarray.c | 42 ++-- liblwgeom/liblwgeom_internal.h | 4 +- liblwgeom/lwalgorithm.c | 26 ++- liblwgeom/lwcompound.c | 73 +++--- liblwgeom/measures.c | 508 +++++++++++++++++++---------------------- liblwgeom/ptarray.c | 415 +++++++++++++++++++++------------ 7 files changed, 612 insertions(+), 489 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 1 15:50:08 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 01 Oct 2025 22:50:08 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.10cb733cce8b86ff167773bfd0eb1d08@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"6e8b86bd9204e494e330b296156a0ddddf36cd50/git" 6e8b86b/git]: {{{#!CommitTicketReference repository="git" revision="6e8b86bd9204e494e330b296156a0ddddf36cd50" Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 2 08:56:21 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 08:56:21 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-10-gd3f3a8bf9 Message-ID: <20251002155621.9C2CF16B1F3@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via d3f3a8bf9e23c32beb28a04c490930fd82cba95d (commit) from b212d84b694c61e2efb86bb9f2e2c0367e74a81c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d3f3a8bf9e23c32beb28a04c490930fd82cba95d Author: Paul Ramsey Date: Thu Oct 2 08:56:08 2025 -0700 Pg19 build support diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h index 102d84f35..6474de8c4 100644 --- a/libpgcommon/lwgeom_pg.h +++ b/libpgcommon/lwgeom_pg.h @@ -88,13 +88,23 @@ void pg_install_lwgeom_handlers(void); /* Argument handling macros */ #define PG_GETARG_GSERIALIZED_P(varno) ((GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(varno))) + #define PG_GETARG_GSERIALIZED_P_COPY(varno) ((GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(varno))) + #define PG_GSERIALIZED_DATUM_NEEDS_DETOAST(datum) \ (VARATT_IS_EXTENDED((datum)) || VARATT_IS_EXTERNAL((datum)) || VARATT_IS_COMPRESSED((datum))) + +#if POSTGIS_PGSQL_VERSION >= 190 +#define PG_GETARG_GSERIALIZED_HEADER(varno) \ + PG_GSERIALIZED_DATUM_NEEDS_DETOAST(DatumGetPointer(PG_GETARG_DATUM(varno))) \ + ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ + : ((GSERIALIZED *)(PG_GETARG_POINTER(varno))) +#else #define PG_GETARG_GSERIALIZED_HEADER(varno) \ PG_GSERIALIZED_DATUM_NEEDS_DETOAST(PG_GETARG_DATUM(varno)) \ ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ : ((GSERIALIZED *)(PG_GETARG_DATUM(varno))) +#endif /* Debugging macros */ #if POSTGIS_DEBUG_LEVEL > 0 ----------------------------------------------------------------------- Summary of changes: libpgcommon/lwgeom_pg.h | 10 ++++++++++ 1 file changed, 10 insertions(+) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 09:44:21 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 09:44:21 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-58-gfad381ea7 Message-ID: <20251002164422.3197416BE19@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via fad381ea7594ac2162ee82e6bcb58dd82e1cf6d0 (commit) from 686839214ba333ccd3f4eb816d9e9caeb79d93e2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fad381ea7594ac2162ee82e6bcb58dd82e1cf6d0 Author: Paul Ramsey Date: Thu Oct 2 09:44:15 2025 -0700 Pg19 build support diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h index b05290bd2..e4b69f3a0 100644 --- a/libpgcommon/lwgeom_pg.h +++ b/libpgcommon/lwgeom_pg.h @@ -88,13 +88,23 @@ void pg_install_lwgeom_handlers(void); /* Argument handling macros */ #define PG_GETARG_GSERIALIZED_P(varno) ((GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(varno))) + #define PG_GETARG_GSERIALIZED_P_COPY(varno) ((GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(varno))) + #define PG_GSERIALIZED_DATUM_NEEDS_DETOAST(datum) \ (VARATT_IS_EXTENDED((datum)) || VARATT_IS_EXTERNAL((datum)) || VARATT_IS_COMPRESSED((datum))) + +#if POSTGIS_PGSQL_VERSION >= 190 +#define PG_GETARG_GSERIALIZED_HEADER(varno) \ + PG_GSERIALIZED_DATUM_NEEDS_DETOAST(DatumGetPointer(PG_GETARG_DATUM(varno))) \ + ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ + : ((GSERIALIZED *)(PG_GETARG_POINTER(varno))) +#else #define PG_GETARG_GSERIALIZED_HEADER(varno) \ PG_GSERIALIZED_DATUM_NEEDS_DETOAST(PG_GETARG_DATUM(varno)) \ ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ : ((GSERIALIZED *)(PG_GETARG_DATUM(varno))) +#endif /* Debugging macros */ #if POSTGIS_DEBUG_LEVEL > 0 ----------------------------------------------------------------------- Summary of changes: libpgcommon/lwgeom_pg.h | 10 ++++++++++ 1 file changed, 10 insertions(+) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 09:46:28 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 09:46:28 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-59-ge612c0ad8 Message-ID: <20251002164628.E4F4A16C018@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via e612c0ad859742b6bf0bd8af0567a577419adbfa (commit) from fad381ea7594ac2162ee82e6bcb58dd82e1cf6d0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e612c0ad859742b6bf0bd8af0567a577419adbfa Author: Paul Ramsey Date: Thu Oct 2 09:46:21 2025 -0700 Remove Cirrus-CI as constant source of CI failure due to Cirrus resource limits diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index c2490f510..000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,95 +0,0 @@ -task: - only_if: $CIRRUS_BRANCH =~ 'pull/.*' - name: FreeBSD - alias: test-freebsd - #env: - #MAKE_FLAGS: -j 8 - - install_script: - - sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf - - ASSUME_ALWAYS_YES=yes pkg bootstrap -f - - pkg install -y - autoconf - automake - bison - cunit - docbook - gdal - geos - gmake - iconv - json-c - libtool - libxml2 - libxslt - pcre - pkgconf - postgresql13-contrib - postgresql13-server - proj - protobuf-c - sfcgal - - projsync --system-directory --source-id us_noaa - - projsync --system-directory --source-id ch_swisstopo - - patch_script: - # will be removed - - find . -name "*.pl" | xargs sed -i -r 's|/usr/bin/perl|/usr/bin/env perl|' - build_script: - - ./autogen.sh - - ./configure PKG_CONFIG=/usr/local/bin/pkgconf CFLAGS="-isystem /usr/local/include -Wall -fno-omit-frame-pointer -Werror" LDFLAGS="-L/usr/local/lib" --with-libiconv-prefix=/usr/local --without-gui --with-topology --without-raster --with-sfcgal=/usr/local/bin/sfcgal-config --with-address-standardizer --with-protobuf - - service postgresql oneinitdb - - service postgresql onestart - - su postgres -c "createuser -s `whoami`" - - gmake || { service postgresql onestop; exit 1;} - - gmake check RUNTESTFLAGS="-v" || { service postgresql onestop; exit 1;} - - gmake install || { service postgresql onestop; exit 1;} - - gmake check RUNTESTFLAGS="-v --extension" || { service postgresql onestop; exit 1;} - - gmake check RUNTESTFLAGS="-v --extension --dumprestore" || { service postgresql onestop; exit 1;} - - service postgresql onestop - - freebsd_instance: - cpu: 8 - memory: 24g - matrix: - # - name: 14-CURRENT - # freebsd_instance: - # image_family: freebsd-14-0-snap - - name: 13.2-RELEASE - freebsd_instance: - image_family: freebsd-13-2 - -task: - name: macOS - alias: test-macos - test_script: - - brew update - - brew install - autoconf - automake - cunit - docbook - docbook-xsl - gdal - geos - gpp - json-c - libtool - pcre2 - pkg-config - postgresql at 14 - proj - sfcgal - - ./autogen.sh - - ./configure --without-gui --without-interrupt-tests --without-topology --without-raster --with-sfcgal --with-address-standardizer --without-protobuf --with-pgconfig=/opt/homebrew/opt/postgresql at 14/bin/pg_config - - brew services start postgresql at 14 - - postgres -V - - make -j8 || { brew services stop postgresql at 14; exit 1;} - - make -j8 check || { brew services stop postgresql at 14; exit 1;} - - brew services stop postgresql at 14 - - matrix: - macos_instance: - image: ghcr.io/cirruslabs/macos-ventura-base:latest - # macos_instance: - # image: ghcr.io/cirruslabs/macos-monterey-base:latest ----------------------------------------------------------------------- Summary of changes: .cirrus.yml | 95 ------------------------------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 .cirrus.yml hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 09:49:03 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 09:49:03 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-60-gacb45a0e7 Message-ID: <20251002164904.0B9E416BDB2@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via acb45a0e79760135209ef30ace18af7761a48e99 (commit) from e612c0ad859742b6bf0bd8af0567a577419adbfa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit acb45a0e79760135209ef30ace18af7761a48e99 Author: Paul Ramsey Date: Thu Oct 2 09:48:53 2025 -0700 Revert "Remove Cirrus-CI as constant source of CI failure due to Cirrus resource limits" This reverts commit e612c0ad859742b6bf0bd8af0567a577419adbfa. diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 000000000..c2490f510 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,95 @@ +task: + only_if: $CIRRUS_BRANCH =~ 'pull/.*' + name: FreeBSD + alias: test-freebsd + #env: + #MAKE_FLAGS: -j 8 + + install_script: + - sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf + - ASSUME_ALWAYS_YES=yes pkg bootstrap -f + - pkg install -y + autoconf + automake + bison + cunit + docbook + gdal + geos + gmake + iconv + json-c + libtool + libxml2 + libxslt + pcre + pkgconf + postgresql13-contrib + postgresql13-server + proj + protobuf-c + sfcgal + - projsync --system-directory --source-id us_noaa + - projsync --system-directory --source-id ch_swisstopo + + patch_script: + # will be removed + - find . -name "*.pl" | xargs sed -i -r 's|/usr/bin/perl|/usr/bin/env perl|' + build_script: + - ./autogen.sh + - ./configure PKG_CONFIG=/usr/local/bin/pkgconf CFLAGS="-isystem /usr/local/include -Wall -fno-omit-frame-pointer -Werror" LDFLAGS="-L/usr/local/lib" --with-libiconv-prefix=/usr/local --without-gui --with-topology --without-raster --with-sfcgal=/usr/local/bin/sfcgal-config --with-address-standardizer --with-protobuf + - service postgresql oneinitdb + - service postgresql onestart + - su postgres -c "createuser -s `whoami`" + - gmake || { service postgresql onestop; exit 1;} + - gmake check RUNTESTFLAGS="-v" || { service postgresql onestop; exit 1;} + - gmake install || { service postgresql onestop; exit 1;} + - gmake check RUNTESTFLAGS="-v --extension" || { service postgresql onestop; exit 1;} + - gmake check RUNTESTFLAGS="-v --extension --dumprestore" || { service postgresql onestop; exit 1;} + - service postgresql onestop + + freebsd_instance: + cpu: 8 + memory: 24g + matrix: + # - name: 14-CURRENT + # freebsd_instance: + # image_family: freebsd-14-0-snap + - name: 13.2-RELEASE + freebsd_instance: + image_family: freebsd-13-2 + +task: + name: macOS + alias: test-macos + test_script: + - brew update + - brew install + autoconf + automake + cunit + docbook + docbook-xsl + gdal + geos + gpp + json-c + libtool + pcre2 + pkg-config + postgresql at 14 + proj + sfcgal + - ./autogen.sh + - ./configure --without-gui --without-interrupt-tests --without-topology --without-raster --with-sfcgal --with-address-standardizer --without-protobuf --with-pgconfig=/opt/homebrew/opt/postgresql at 14/bin/pg_config + - brew services start postgresql at 14 + - postgres -V + - make -j8 || { brew services stop postgresql at 14; exit 1;} + - make -j8 check || { brew services stop postgresql at 14; exit 1;} + - brew services stop postgresql at 14 + + matrix: + macos_instance: + image: ghcr.io/cirruslabs/macos-ventura-base:latest + # macos_instance: + # image: ghcr.io/cirruslabs/macos-monterey-base:latest ----------------------------------------------------------------------- Summary of changes: .cirrus.yml | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .cirrus.yml hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 09:50:52 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 09:50:52 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-61-g0c129aefa Message-ID: <20251002165053.2DCD016BE35@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 0c129aefaa77ccc0c0537006009c3362a00027d3 (commit) from acb45a0e79760135209ef30ace18af7761a48e99 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0c129aefaa77ccc0c0537006009c3362a00027d3 Author: Paul Ramsey Date: Thu Oct 2 09:50:46 2025 -0700 Match cirrus config to working 3.6 entry diff --git a/.cirrus.yml b/.cirrus.yml index c2490f510..c1eaaf1c9 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -49,15 +49,12 @@ task: - service postgresql onestop freebsd_instance: - cpu: 8 - memory: 24g + cpu: ${NCPU} + memory: 24G matrix: - # - name: 14-CURRENT - # freebsd_instance: - # image_family: freebsd-14-0-snap - - name: 13.2-RELEASE + - name: 14.2-RELEASE freebsd_instance: - image_family: freebsd-13-2 + image_family: freebsd-14-2 task: name: macOS ----------------------------------------------------------------------- Summary of changes: .cirrus.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 09:51:38 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 09:51:38 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-54-g4a1fca438 Message-ID: <20251002165138.F057516BE38@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via 4a1fca43891ff3b191abf23a47a698611e0632e4 (commit) from 567d074fb45efe85825cf32a7b63b74154ff0421 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4a1fca43891ff3b191abf23a47a698611e0632e4 Author: Paul Ramsey Date: Thu Oct 2 09:51:31 2025 -0700 Match cirrus config to working 3.6 entry diff --git a/.cirrus.yml b/.cirrus.yml index 26b3c8ab9..c0386ff35 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -29,12 +29,9 @@ task: - service postgresql onestop freebsd_instance: - cpu: 8 - memory: 24g + cpu: ${NCPU} + memory: 24G matrix: - # - name: 14-CURRENT - # freebsd_instance: - # image_family: freebsd-14-0-snap - - name: 13.2-RELEASE + - name: 14.2-RELEASE freebsd_instance: - image_family: freebsd-13-2 + image_family: freebsd-14-2 ----------------------------------------------------------------------- Summary of changes: .cirrus.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 09:52:25 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 09:52:25 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.7-57-ga46aac3ed Message-ID: <20251002165225.A73B916BF48@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via a46aac3edc1303b27c94c7a630e559c59bbcde8c (commit) from 5e99f2edfaf388110d9d6873f4180266d7533607 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a46aac3edc1303b27c94c7a630e559c59bbcde8c Author: Paul Ramsey Date: Thu Oct 2 09:52:18 2025 -0700 update Cirrus Freebsd image diff --git a/.cirrus.yml b/.cirrus.yml index dd2f4c96b..50d3bbfe7 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -29,16 +29,10 @@ task: - service postgresql onestop freebsd_instance: - cpu: 8 - memory: 24g + cpu: ${NCPU} + memory: 24G matrix: - # - name: 14-CURRENT - # freebsd_instance: - # image_family: freebsd-14-0-snap - - name: 14.1-RELEASE + - name: 14.2-RELEASE freebsd_instance: - image_family: freebsd-14-1 - #- name: 12.3-RELEASE - # freebsd_instance: - # image_family: freebsd-12-3 + image_family: freebsd-14-2 ----------------------------------------------------------------------- Summary of changes: .cirrus.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 2 13:07:51 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 02 Oct 2025 20:07:51 -0000 Subject: [PostGIS] #5983: Potential data corruption in topology.topoelement after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.159de353d6e0a04ebe8f23fd44b3f476@osgeo.org> #5983: Potential data corruption in topology.topoelement after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Changes (by francoisb): * cc: francoisb (added) -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 2 14:08:49 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 14:08:49 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-11-gbe2a0ffda Message-ID: <20251002210850.3B11716ED80@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via be2a0ffda5b08dca0d94c1498d84b62b83fe76f9 (commit) from d3f3a8bf9e23c32beb28a04c490930fd82cba95d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be2a0ffda5b08dca0d94c1498d84b62b83fe76f9 Author: Paul Ramsey Date: Thu Oct 2 14:08:21 2025 -0700 Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 diff --git a/NEWS b/NEWS index f65470d6f..98e536d63 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ PostGIS 3.6.1 - #5987, ST_GeometryN fails for non-collections (Paul Ramsey) - #5991, CircularString distance error (Paul Ramsey) - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) + - #5998, ST_Distance error on CurvePolygon (Paul Ramsey) PostGIS 3.6.0 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 610b2a593..58e7cb4ba 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -222,6 +222,11 @@ static void test_mindistance2d_tolerance(void) DIST2DTEST( "CURVEPOLYGON(CIRCULARSTRING(7874821 8715927,8907663 8715927,8844683 7750316,7937800 7750316,7874821 8715927))", "POINT(5433865 8243495)", 2271704.2698450615, default_accepted_error); + + /* Ticket 5989 */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0, -1 5, 0 10), (0 10, -10 10, -10 0, 0 0)))", + "POINT(-0.5 5)", 0.5, default_accepted_error); } static void @@ -918,6 +923,25 @@ test_lw_dist2d_arc_arc(void) B2.x = 0 ; B2.y = 1; B3.x = 1 ; B3.y = 0; + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = 0; A1.y = .5; + A2.x = -0.3; A2.y = .5; + A3.x = 0; A3.y = .6; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + printf("%g\n", dl.distance); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.271798, 0.000001); + + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -0.5; A1.y = .5; + A2.x = -0.4; A2.y = .2; + A3.x = 0; A3.y = 0; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.292893, 0.000001); + /* Arc above the unit semicircle */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -1; A1.y = 3; @@ -954,6 +978,15 @@ test_lw_dist2d_arc_arc(void) CU_ASSERT_EQUAL( rv, LW_SUCCESS ); CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0, 0.000001); + /* Closed circle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -2.0; A1.y = -0.1; + A2.x = 1.5; A2.y = -0.1; + A3.x = -2.0; A3.y = -0.1; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.480742, 0.0001); + /* Concentric: and fully parallel */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -2.0; A1.y = 0.0; diff --git a/liblwgeom/cunit/cu_ptarray.c b/liblwgeom/cunit/cu_ptarray.c index a28da5cce..99c689ac2 100644 --- a/liblwgeom/cunit/cu_ptarray.c +++ b/liblwgeom/cunit/cu_ptarray.c @@ -433,14 +433,14 @@ static void test_ptarrayarc_contains_point() { /* int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) */ - LWLINE *lwline; + LWCIRCSTRING *lwcirc; POINTARRAY *pa; POINT2D pt; int rv; /*** Collection of semi-circles surrounding unit square ***/ - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); - pa = lwline->points; + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); + pa = lwcirc->points; /* Point in middle of square */ pt.x = 0; @@ -473,9 +473,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** Two-edge ring made up of semi-circles (really, a circle) ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); + pa = lwcirc->points; /* Point outside */ pt.x = -1.5; @@ -514,9 +514,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Two-edge ring, closed ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); + pa = lwcirc->points; /* Point to left of ring */ pt.x = 20; @@ -525,9 +525,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** One-edge ring, closed circle ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, -1 0)")); + pa = lwcirc->points; /* Point inside */ pt.x = 0; @@ -548,23 +548,23 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Overshort ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); //printf("%s\n", cu_error_msg); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_raycast_intersections called with even number of points"); /*** Unclosed ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, 2 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, 2 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called on unclosed ring", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_contains_point called on unclosed ring"); - lwline_free(lwline); + lwcircstring_free(lwcirc); } static void test_ptarray_scale() diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index e51062b00..04a3504e2 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -445,13 +445,15 @@ double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, PO int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2); int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); +int lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p); double lw_seg_length(const POINT2D *A1, const POINT2D *A2); double lw_arc_length(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring); int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); -int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); +int ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); +int ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt); int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt); diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index cb3727f15..a2cb2b037 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -90,7 +90,9 @@ lw_seg_length(const POINT2D *A1, const POINT2D *A2) int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3) { - return lw_segment_side(A1, A3, A2) == lw_segment_side(A1, A3, P); + int pt_side = lw_segment_side(A1, A3, P); + int arc_side = lw_segment_side(A1, A3, A2); + return pt_side == 0 || pt_side == arc_side; } /** @@ -104,6 +106,28 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) ((A1->y <= P->y && P->y < A2->y) || (A1->y >= P->y && P->y > A2->y)); } +int +lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +{ + // Check if the point is within the bounding box of the segment + if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || + p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) + { + return LW_FALSE; + } + + // Check for collinearity using the 2D cross-product. + // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) + double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); + + if (fabs(cross_product) < DBL_EPSILON) + { + return LW_TRUE; // Point is collinear and within the bounding box + } + + return LW_TRUE; +} + /** * Returns true if arc A is actually a point (all vertices are the same) . */ diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c index 90fee3560..1e0d5c2ee 100644 --- a/liblwgeom/lwcompound.c +++ b/liblwgeom/lwcompound.c @@ -184,63 +184,48 @@ int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) return LW_FAILURE; } +/* + * Use a ray-casting count to determine if the point + * is inside or outside of the compound curve. Ray-casting + * is run against each component of the overall arc, and + * the even/odd test run against the total of all components. + * Returns LW_INSIDE / LW_BOUNDARY / LW_OUTSIDE + */ int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { - uint32_t i; - LWLINE *lwline; - LWCIRCSTRING *lwcirc; - int wn = 0; - int winding_number = 0; - int result; + int intersections = 0; - for ( i = 0; i < comp->ngeoms; i++ ) + if (lwgeom_is_empty(lwcompound_as_lwgeom(comp))) + return LW_OUTSIDE; + + for (uint32_t j = 0; j < comp->ngeoms; j++) { - LWGEOM *lwgeom = comp->geoms[i]; - if ( lwgeom->type == LINETYPE ) + int on_boundary = LW_FALSE; + const LWGEOM *sub = comp->geoms[j]; + if (sub->type == LINETYPE) { - lwline = lwgeom_as_lwline(lwgeom); - if ( comp->ngeoms == 1 ) - { - return ptarray_contains_point(lwline->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); - } + LWLINE *lwline = lwgeom_as_lwline(sub); + intersections += ptarray_raycast_intersections(lwline->points, pt, &on_boundary); + } + else if (sub->type == CIRCSTRINGTYPE) + { + LWCIRCSTRING *lwcirc = lwgeom_as_lwcircstring(sub); + intersections += ptarrayarc_raycast_intersections(lwcirc->points, pt, &on_boundary); } else { - lwcirc = lwgeom_as_lwcircstring(lwgeom); - if ( ! lwcirc ) { - lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); - return 0; - } - if ( comp->ngeoms == 1 ) - { - return ptarrayarc_contains_point(lwcirc->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); - } + lwerror("%s: unsupported type %s", __func__, lwtype_name(sub->type)); } - - /* Propagate boundary condition */ - if ( result == LW_BOUNDARY ) + if (on_boundary) return LW_BOUNDARY; - - wn += winding_number; } - /* Outside */ - if (wn == 0) - return LW_OUTSIDE; - - /* Inside */ - return LW_INSIDE; + /* + * Odd number of intersections means inside. + * Even means outside. + */ + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } LWCOMPOUND * diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index bc240eb45..62e2a3586 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1540,37 +1540,156 @@ lw_dist2d_pt_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const P return LW_TRUE; } -/* Auxiliary function to calculate the distance between 2 concentric arcs*/ -int lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl); + + +/** + * @brief Calculates the intersection points of a circle and line. + * + * This function assumes the center and test point are distinct. + * Finds the line between the circle center and test point, and + * the two intersection points on the circle defined by that line. + * If those points fall within the provided arc (A1,A2,A3) then + * the points are added to the provided array (I) and the array + * length counter is incremented. + * + * @param A1 Point of arc + * @param A2 Point of arc + * @param A3 Point of arc + * @param center_A Center of arc A circle + * @param radius_A Radius of arc A circle + * @param P Point to use in calculating intersection line + * @param I [out] Pointer to an return value array + * @param ni [out] Pointer to return array size counter + * @return int + */ +static int +lw_dist2d_circle_intersections( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *center_A, + double radius_A, + const POINT2D *P, + POINT2D *I, + uint32_t *ni) +{ + POINT2D R; + + // If the test point is on the center of the other + // arc, some other point has to be closer, by definition. + if (p2d_same(center_A, P)) + return 0; + + // Calculate vector from the center to the pt + double dir_x = center_A->x - P->x; + double dir_y = center_A->y - P->y; + double dist = sqrt(dir_x * dir_x + dir_y * dir_y); + + // Normalize the direction vector to get a unit vector (length = 1) + double unit_x = dir_x / dist; + double unit_y = dir_y / dist; + + // Calculate the two intersection points on the circle + // Point 1: Move from center_A along the unit vector by distance radius_A + R.x = center_A->x + unit_x * radius_A; + R.y = center_A->y + unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + // Point 2: Move from center_A against the unit vector by distance radius_A + R.x = center_A->x - unit_x * radius_A; + R.y = center_A->y - unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + return 0; +} + + +/** + * @brief Calculates the intersection points of two overlapping circles. + * + * This function assumes the circles are known to intersect at one or two points. + * Specifically, the distance 'd' between their centers must satisfy: + * d < (rA + rB) and d > fabs(rA - rB) + * If these conditions are not met, the results are undefined. + * + * @param cA [in] Pointer to the center point of the first circle (A). + * @param rA [in] The radius of the first circle (A). + * @param cB [in] Pointer to the center point of the second circle (B). + * @param rB [in] The radius of the second circle (B). + * @param I [out] Pointer to an array of at least 2 POINT2D structs to store the results. + * I[0] will contain the first intersection point. + * If a second exists, it will be in I[1]. + * @return int The number of intersection points found (1 or 2). Returns 0 if + * the centers are coincident or another error occurs. + */ +static uint32_t +lw_dist2d_circle_circle_intersections( + const POINT2D *cA, double rA, + const POINT2D *cB, double rB, + POINT2D *I) +{ + // Vector from center A to center B + double dx = cB->x - cA->x; + double dy = cB->y - cA->y; + + // Distance between the centers + double d = sqrt(dx * dx + dy * dy); + + // 'a' is the distance from the center of circle A to the point P, + // which is the base of the right triangle formed by cA, P, and an intersection point. + double a = (rA * rA - rB * rB + d * d) / (2.0 * d); + + // 'h' is the height of that right triangle. + double h_squared = rA * rA - a * a; + + // Due to floating point errors, h_squared can be slightly negative. + // This happens when the circles are perfectly tangent. Clamp to 0. + if (h_squared < 0.0) + h_squared = 0.0; + + double h = sqrt(h_squared); + + // Find the coordinates of point P + double Px = cA->x + a * (dx / d); + double Py = cA->y + a * (dy / d); + + // The two intersection points are found by moving from P by a distance 'h' + // in directions perpendicular to the line connecting the centers. + // The perpendicular vector to (dx, dy) is (-dy, dx). + + // Intersection point 1 + I[0].x = Px - h * (dy / d); + I[0].y = Py + h * (dx / d); + + // If h is very close to 0, the circles are tangent and there's only one intersection point. + if (FP_IS_ZERO(h)) + return 1; + + // Intersection point 2 + I[1].x = Px + h * (dy / d); + I[1].y = Py - h * (dx / d); + + return 2; +} + int -lw_dist2d_arc_arc(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - DISTPTS *dl) +lw_dist2d_arc_arc( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, + DISTPTS *dl) { - POINT2D CA, CB; /* Center points of arcs A and B */ + POINT2D pts_A[16]; /* Points on A that might be the nearest */ + POINT2D pts_B[16]; /* Points on B that might be the nearest */ + uint32_t ai = 0, bi = 0; /* Number of points in pts_A and pts_B */ + POINT2D center_A, center_B; /* Center points of arcs A and B */ double radius_A, radius_B, d; /* Radii of arcs A and B */ - POINT2D D; /* Mid-point between the centers CA and CB */ - int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */ + int is_disjoint, is_overlapping, is_contained, is_same_center; + POINT2D intersectionPts[2]; if (dl->mode != DIST_MIN) lwerror("lw_dist2d_arc_arc only supports mindistance"); - /* TODO: Handle case where arc is closed circle (A1 = A3) */ - /* What if one or both of our "arcs" is actually a point? */ if (lw_arc_is_pt(B1, B2, B3) && lw_arc_is_pt(A1, A2, A3)) return lw_dist2d_pt_pt(B1, A1, dl); @@ -1580,8 +1699,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, return lw_dist2d_pt_arc(A1, B1, B2, B3, dl); /* Calculate centers and radii of circles. */ - radius_A = lw_arc_center(A1, A2, A3, &CA); - radius_B = lw_arc_center(B1, B2, B3, &CB); + radius_A = lw_arc_center(A1, A2, A3, ¢er_A); + radius_B = lw_arc_center(B1, B2, B3, ¢er_B); /* Two co-linear arcs?!? That's two segments. */ if (radius_A < 0 && radius_B < 0) @@ -1595,275 +1714,112 @@ lw_dist2d_arc_arc(const POINT2D *A1, if (radius_B < 0) return lw_dist2d_seg_arc(B1, B3, A1, A2, A3, dl); - /* Center-center distance */ - d = distance2d_pt_pt(&CA, &CB); + /* Circle relationships */ + d = distance2d_pt_pt(¢er_A, ¢er_B); + is_disjoint = (d > (radius_A + radius_B)); + is_contained = (d < fabs(radius_A - radius_B)); + is_same_center = p2d_same(¢er_A, ¢er_B); + is_overlapping = ! (is_disjoint || is_contained || is_same_center); - /* Concentric arcs */ - if (FP_EQUALS(d, 0.0)) - return lw_dist2d_arc_arc_concentric(A1, A2, A3, radius_A, B1, B2, B3, radius_B, &CA, dl); + /* + * Prime the array of potential closest points with the + * arc end points, which frequently participate in closest + * points. + */ + pts_A[ai++] = *A1; + pts_A[ai++] = *A3; + pts_B[bi++] = *B1; + pts_B[bi++] = *B3; - /* Make sure that arc "A" has the bigger radius */ - if (radius_B > radius_A) + /* + * Overlapping circles might have a zero distance + * case if the circle intersection points are inside both + * arcs. + */ + if (is_overlapping) { - const POINT2D *tmp; - POINT2D TP; /* Temporary point P */ - double td; - tmp = B1; - B1 = A1; - A1 = tmp; - tmp = B2; - B2 = A2; - A2 = tmp; - tmp = B3; - B3 = A3; - A3 = tmp; - TP = CB; - CB = CA; - CA = TP; - td = radius_B; - radius_B = radius_A; - radius_A = td; - } - - /* Circles touch at a point. Is that point within the arcs? */ - if (d == (radius_A + radius_B)) - { - D.x = CA.x + (CB.x - CA.x) * radius_A / d; - D.y = CA.y + (CB.y - CA.y) * radius_A / d; - - pt_in_arc_A = lw_pt_in_arc(&D, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&D, B1, B2, B3); - - /* Arcs do touch at D, return it */ - if (pt_in_arc_A && pt_in_arc_B) + /* + * Find the two points the circles intersect at. + */ + uint32_t npoints = lw_dist2d_circle_circle_intersections( + ¢er_A, radius_A, + ¢er_B, radius_B, + intersectionPts); + for (uint32_t i = 0; i < npoints; i++) { - lw_dist2d_distpts_set(dl, 0.0, &D, &D); - return LW_TRUE; + /* + * If an intersection point is contained in both + * arcs, that is a location of zero distance, so + * we are done calculating. + */ + if (lw_pt_in_arc(&intersectionPts[i], A1, A2, A3) && + lw_pt_in_arc(&intersectionPts[i], B1, B2, B3)) + { + lw_dist2d_distpts_set(dl, 0.0, &intersectionPts[i], &intersectionPts[i]); + return LW_TRUE; + } } } - /* Disjoint or contained circles don't intersect. Closest point may be on */ - /* the line joining CA to CB. */ - else if (d > (radius_A + radius_B) /* Disjoint */ || d < (radius_A - radius_B) /* Contained */) + + /* + * Join the circle centers and find the places that + * line intersects the circles. Where those places + * are in the arcs, they are potential sites of the + * closest points. + */ + if (is_disjoint || is_contained || is_overlapping) { - POINT2D XA, XB; /* Points where the line from CA to CB cross their circle bounds */ - - /* Calculate hypothetical nearest points, the places on the */ - /* two circles where the center-center line crosses. If both */ - /* arcs contain their hypothetical points, that's the crossing distance */ - XA.x = CA.x + (CB.x - CA.x) * radius_A / d; - XA.y = CA.y + (CB.y - CA.y) * radius_A / d; - XB.x = CB.x + (CA.x - CB.x) * radius_B / d; - XB.y = CB.y + (CA.y - CB.y) * radius_B / d; - - pt_in_arc_A = lw_pt_in_arc(&XA, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&XB, B1, B2, B3); - - /* If the nearest points are both within the arcs, that's our answer */ - /* the shortest distance is at the nearest points */ - if (pt_in_arc_A && pt_in_arc_B) + if (!is_same_center) { - return lw_dist2d_pt_pt(&XA, &XB, dl); - } - } - /* Circles cross at two points, are either of those points in both arcs? */ - /* http://paulbourke.net/geometry/2circle/ */ - else if (d < (radius_A + radius_B)) - { - POINT2D E, F; /* Points where circle(A) and circle(B) cross */ - /* Distance from CA to D */ - double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d); - /* Distance from D to E or F */ - double h = sqrt(radius_A * radius_A - a * a); + /* Add points on A that intersect line from center_A to center_B */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, ¢er_B, + pts_A, &ai); - /* Location of D */ - D.x = CA.x + (CB.x - CA.x) * a / d; - D.y = CA.y + (CB.y - CA.y) * a / d; - - /* Start from D and project h units perpendicular to CA-D to get E */ - E.x = D.x + (D.y - CA.y) * h / a; - E.y = D.y + (D.x - CA.x) * h / a; - - /* Crossing point E contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&E, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&E, B1, B2, B3); - - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &E, &E); - return LW_TRUE; + /* Add points on B that intersect line from center_B to center_A */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, ¢er_A, + pts_B, &bi); } - /* Start from D and project h units perpendicular to CA-D to get F */ - F.x = D.x - (D.y - CA.y) * h / a; - F.y = D.y - (D.x - CA.x) * h / a; + /* Add points on A that intersect line to B1 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B1, + pts_A, &ai); - /* Crossing point F contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&F, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&F, B1, B2, B3); + /* Add points on A that intersect line to B3 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B3, + pts_A, &ai); - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &F, &F); - return LW_TRUE; - } - } - else - { - lwerror("lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!"); - return LW_FALSE; + /* Add points on B that intersect line to A1 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A1, + pts_B, &bi); + + /* Add points on B that intersect line to A3 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A3, + pts_B, &bi); } - /* Closest point is in the arc A, but not in the arc B, so */ - /* one of the B end points must be the closest. */ - if (pt_in_arc_A && !pt_in_arc_B) - { - lw_dist2d_pt_arc(B1, A1, A2, A3, dl); - lw_dist2d_pt_arc(B3, A1, A2, A3, dl); - return LW_TRUE; - } - /* Closest point is in the arc B, but not in the arc A, so */ - /* one of the A end points must be the closest. */ - else if (pt_in_arc_B && !pt_in_arc_A) - { - lw_dist2d_pt_arc(A1, B1, B2, B3, dl); - lw_dist2d_pt_arc(A3, B1, B2, B3, dl); - return LW_TRUE; - } - /* Finally, one of the end-point to end-point combos is the closest. */ - else - { - lw_dist2d_pt_pt(A1, B1, dl); - lw_dist2d_pt_pt(A1, B3, dl); - lw_dist2d_pt_pt(A3, B1, dl); - lw_dist2d_pt_pt(A3, B3, dl); - return LW_TRUE; - } + /* + * Now just brute force check all pairs of participating + * points, to find the pair that is closest together. + */ + for (uint32_t i = 0; i < ai; i++) + for (uint32_t j = 0; j < bi; j++) + lw_dist2d_pt_pt(&pts_A[i], &pts_B[j], dl); return LW_TRUE; } -int -lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl) -{ - int seg_size; - double dist_sqr, shortest_sqr; - const POINT2D *P1; - const POINT2D *P2; - POINT2D proj; - - if (radius_A == radius_B) - { - /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */ - seg_size = lw_segment_side(A1, A3, A2); - if (seg_size == lw_segment_side(A1, A3, B1)) - { - lw_dist2d_distpts_set(dl, 0.0, B1, B1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(A1, A3, B3)) - { - lw_dist2d_distpts_set(dl, 0.0, B3, B3); - return LW_TRUE; - } - /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */ - seg_size = lw_segment_side(B1, B3, B2); - if (seg_size == lw_segment_side(B1, B3, A1)) - { - lw_dist2d_distpts_set(dl, 0.0, A1, A1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(B1, B3, A3)) - { - lw_dist2d_distpts_set(dl, 0.0, A3, A3); - return LW_TRUE; - } - } - else - { - /* Check if any projection of B ends are in A*/ - seg_size = lw_segment_side(A1, A3, A2); - - /* B1 */ - proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B; - - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B1); - return LW_TRUE; - } - /* B3 */ - proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B; - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B3); - return LW_TRUE; - } - - /* Now check projections of A in B */ - seg_size = lw_segment_side(B1, B3, B2); - - /* A1 */ - proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A1); - return LW_TRUE; - } - - /* A3 */ - proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A3); - return LW_TRUE; - } - } - - /* Check the shortest between the distances of the 4 ends */ - shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1); - P1 = A1; - P2 = B1; - - dist_sqr = distance2d_sqr_pt_pt(A1, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A1; - P2 = B3; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B1); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B1; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B3; - } - - lw_dist2d_distpts_set(dl, sqrt(shortest_sqr), P1, P2); - return LW_TRUE; -} /** Finds the shortest distance between two segments. diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 82a3835e4..2bc6126b5 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -742,17 +742,285 @@ ptarray_is_closed_z(const POINTARRAY *in) } /** -* Return LW_INSIDE if the point is inside the POINTARRAY, -* LW_OUTSIDE if it is outside, and LW_BOUNDARY if it is on -* the boundary. -* LW_INSIDE == 1, LW_BOUNDARY == 0, LW_OUTSIDE == -1 -*/ + * The following is based on the "Fast Winding Number Inclusion of a Point + * in a Polygon" algorithm by Dan Sunday. + * http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number + * + * Return: + * - LW_INSIDE (1) if the point is inside the POINTARRAY + * - LW_BOUNDARY (0) if it is on the boundary. + * - LW_OUTSIDE (-1) if it is outside + */ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarray_contains_point_partial(pa, pt, LW_TRUE, NULL); + const POINT2D *seg1, *seg2; + int wn = 0; + + seg1 = getPoint2d_cp(pa, 0); + seg2 = getPoint2d_cp(pa, pa->npoints-1); + if (!p2d_same(seg1, seg2)) + lwerror("ptarray_contains_point called on unclosed ring"); + + for (uint32_t i = 1; i < pa->npoints; i++) + { + double side, ymin, ymax; + + seg2 = getPoint2d_cp(pa, i); + + /* Zero length segments are ignored. */ + if (p2d_same(seg1, seg2)) + { + seg1 = seg2; + continue; + } + + ymin = FP_MIN(seg1->y, seg2->y); + ymax = FP_MAX(seg1->y, seg2->y); + + /* Only test segments in our vertical range */ + if (pt->y > ymax || pt->y < ymin) + { + seg1 = seg2; + continue; + } + + side = lw_segment_side(seg1, seg2, pt); + + /* + * A point on the boundary of a ring is not contained. + * WAS: if (fabs(side) < 1e-12), see #852 + */ + if ((side == 0) && lw_pt_in_seg(pt, seg1, seg2)) + { + return LW_BOUNDARY; + } + + /* + * If the point is to the left of the line, and it's rising, + * then the line is to the right of the point and + * circling counter-clockwise, so increment. + */ + if ((side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y)) + { + wn++; + } + + /* + * If the point is to the right of the line, and it's falling, + * then the line is to the right of the point and circling + * clockwise, so decrement. + */ + else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) ) + { + wn--; + } + + seg1 = seg2; + } + + /* wn == 0 => Outside, wn != 0 => Inside */ + return wn == 0 ? LW_OUTSIDE : LW_INSIDE; } +int +ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + // A valid linestring must have at least 2 point + if (pa->npoints < 2) + lwerror("%s called on invalid linestring", __func__); + + int intersections = 0; + double px = p->x; + double py = p->y; + + // Iterate through each edge of the polygon + for (uint32_t i = 0; i < pa->npoints-1; ++i) + { + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + + /* Skip zero-length edges */ + if (p2d_same(p1, p2)) + continue; + + /* --- Step 1: Check if the point is ON the boundary edge --- */ + if (lw_pt_on_segment(p1, p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + /* --- Step 2: Perform the Ray Casting intersection test --- */ + + /* + * Check if the horizontal ray from p intersects the edge (p1, p2). + * This is the core condition for handling vertices correctly: + * - One vertex must be strictly above the ray (py < vertex.y) + * - The other must be on or below the ray (py >= vertex.y) + */ + if (((p1->y <= py) && (py < p2->y)) || ((p2->y <= py) && (py < p1->y))) + { + /* + * Calculate the x-coordinate where the edge intersects the ray's horizontal line. + * Formula: x = x1 + (y - y1) * (x2 - x1) / (y2 - y1) + */ + double x_intersection = p1->x + (py - p1->y) * (p2->x - p1->x) / (p2->y - p1->y); + + /* + * If the intersection point is to the right of our test point, + * it's a valid "crossing". + */ + if (x_intersection > px) + { + intersections++; + } + } + } + + return intersections; +} + + +/** + * @brief Calculates the intersection points of a circle and a horizontal line. + * + * The equation of a circle is (x - cx)^2 + (y - cy)^2 = r^2. + * The equation of the horizontal line is y = y_line. + * Substituting y_line into the circle equation gives: + * (x - cx)^2 = r^2 - (y_line - cy)^2 + * This function solves for x. + * + * @param center A pointer to the center point of the circle. + * @param radius The radius of the circle. + * @param ray The y-coordinate of the horizontal line. + * @param i0 A pointer to a POINT2D to store the first intersection point. + * @param i1 A pointer to a POINT2D to store the second intersection point. + * + * @return The number of intersection points found (0, 1, or 2). + */ +static int +circle_raycast_intersections(const POINT2D *center, double radius, double ray, POINT2D *i0, POINT2D *i1) +{ + // Calculate the vertical distance from the circle's center to the horizontal line. + double dy = ray - center->y; + + // If the absolute vertical distance is greater than the radius, there are no intersections. + if (fabs(dy) > radius) + return 0; + + // Use the Pythagorean theorem to find the horizontal distance (dx) from the + // center's x-coordinate to the intersection points. + // dx^2 + dy^2 = radius^2 => dx^2 = radius^2 - dy^2 + double dx_squared = radius * radius - dy * dy; + + // Case 1: One intersection (tangent) + // This occurs when the line just touches the top or bottom of the circle. + // dx_squared will be zero. We check against a small epsilon for floating-point safety. + if (FP_EQUALS(dx_squared, 0.0)) + { + i0->x = center->x; + i0->y = ray; + return 1; + } + + // Case 2: Two intersections + // The line cuts through the circle. + double dx = sqrt(dx_squared); + + // The first intersection point has the smaller x-value. + i0->x = center->x - dx; + i0->y = ray; + + // The second intersection point has the larger x-value. + i1->x = center->x + dx; + i1->y = ray; + + return 2; +} + + +int +ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + int intersections = 0; + double px = p->x; + double py = p->y; + + assert(on_boundary); + + // A valid circular arc must have at least 3 vertices (circle). + if (pa->npoints < 3) + lwerror("%s called on invalid circularstring", __func__); + + if (pa->npoints % 2 == 0) + lwerror("%s called with even number of points", __func__); + + // Iterate through each arc of the circularstring + for (uint32_t i = 1; i < pa->npoints-1; i +=2) + { + const POINT2D* p0 = getPoint2d_cp(pa, i-1); + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + POINT2D center = {0,0}; + double radius, d; + GBOX gbox; + + // Skip zero-length arc + if (lw_arc_is_pt(p0, p1, p2)) + continue; + + // --- Step 1: Check if the point is ON the boundary edge --- + if (p2d_same(p0, p) || p2d_same(p1, p) || p2d_same(p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // Calculate some important pieces + radius = lw_arc_center(p0, p1, p2, ¢er); + + d = distance2d_pt_pt(p, ¢er); + if (FP_EQUALS(d, radius) && lw_pt_in_arc(p, p0, p1, p2)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // --- Step 2: Perform the Ray Casting intersection test --- + + // Only process arcs that our ray crosses + lw_arc_calculate_gbox_cartesian_2d(p0, p1, p2, &gbox); + if ((gbox.ymin <= py) && (py < gbox.ymax)) + { + // Point of intersection on the circle that defines the arc + POINT2D i0, i1; + + // How many points of intersection are there + int iCount = circle_raycast_intersections(¢er, radius, py, &i0, &i1); + + // Nothing to see here + if (iCount == 0) + continue; + + // Cannot think of a case where a grazing is not a + // no-op + if (iCount == 1) + continue; + + // So we must have 2 intersections + // Only increment the counter for intersections to the right + // of the test point + if (i0.x > px && lw_pt_in_arc(&i0, p0, p1, p2)) + intersections++; + + if (i1.x > px && lw_pt_in_arc(&i1, p0, p1, p2)) + intersections++; + } + } + + return intersections; +} /* * The following is based on the "Fast Winding Number Inclusion of a Point @@ -765,8 +1033,7 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int wn = 0; uint32_t i; double side; - const POINT2D *seg1; - const POINT2D *seg2; + const POINT2D *seg1, *seg2; double ymin, ymax; seg1 = getPoint2d_cp(pa, 0); @@ -855,160 +1122,16 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarrayarc_contains_point_partial(pa, pt, LW_TRUE /* Check closed*/, NULL); -} + int on_boundary = LW_FALSE; + int intersections; + if (!ptarray_is_closed_2d(pa)) + lwerror("%s called on unclosed ring", __func__); -int -ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number) -{ - int wn = 0; - uint32_t i; - int side; - const POINT2D *seg1; - const POINT2D *seg2; - const POINT2D *seg3; - GBOX gbox; - - /* Check for not an arc ring (always have odd # of points) */ - if ( (pa->npoints % 2) == 0 ) - { - lwerror("ptarrayarc_contains_point called with even number of points"); - return LW_OUTSIDE; - } - - /* Check for not an arc ring (always have >= 3 points) */ - if ( pa->npoints < 3 ) - { - lwerror("ptarrayarc_contains_point called too-short pointarray"); - return LW_OUTSIDE; - } - - /* Check for unclosed case */ - seg1 = getPoint2d_cp(pa, 0); - seg3 = getPoint2d_cp(pa, pa->npoints-1); - if ( check_closed && ! p2d_same(seg1, seg3) ) - { - lwerror("ptarrayarc_contains_point called on unclosed ring"); - return LW_OUTSIDE; - } - /* OK, it's closed. Is it just one circle? */ - else if ( p2d_same(seg1, seg3) && pa->npoints == 3 ) - { - double radius, d; - POINT2D c; - seg2 = getPoint2d_cp(pa, 1); - - /* Wait, it's just a point, so it can't contain anything */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - return LW_OUTSIDE; - - /* See if the point is within the circle radius */ - radius = lw_arc_center(seg1, seg2, seg3, &c); - d = distance2d_pt_pt(pt, &c); - if ( FP_EQUALS(d, radius) ) - return LW_BOUNDARY; /* Boundary of circle */ - else if ( d < radius ) - return LW_INSIDE; /* Inside circle */ - else - return LW_OUTSIDE; /* Outside circle */ - } - else if ( p2d_same(seg1, pt) || p2d_same(seg3, pt) ) - { - return LW_BOUNDARY; /* Boundary case */ - } - - /* Start on the ring */ - seg1 = getPoint2d_cp(pa, 0); - for ( i=1; i < pa->npoints; i += 2 ) - { - seg2 = getPoint2d_cp(pa, i); - seg3 = getPoint2d_cp(pa, i+1); - - /* Catch an easy boundary case */ - if( p2d_same(seg3, pt) ) - return LW_BOUNDARY; - - /* Skip arcs that have no size */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - { - seg1 = seg3; - continue; - } - - /* Only test segments in our vertical range */ - lw_arc_calculate_gbox_cartesian_2d(seg1, seg2, seg3, &gbox); - if ( pt->y > gbox.ymax || pt->y < gbox.ymin ) - { - seg1 = seg3; - continue; - } - - /* Outside of horizontal range, and not between end points we also skip */ - if ( (pt->x > gbox.xmax || pt->x < gbox.xmin) && - (pt->y > FP_MAX(seg1->y, seg3->y) || pt->y < FP_MIN(seg1->y, seg3->y)) ) - { - seg1 = seg3; - continue; - } - - side = lw_arc_side(seg1, seg2, seg3, pt); - - /* On the boundary */ - if ( (side == 0) && lw_pt_in_arc(pt, seg1, seg2, seg3) ) - { - return LW_BOUNDARY; - } - - /* Going "up"! Point to left of arc. */ - if ( side < 0 && (seg1->y <= pt->y) && (pt->y < seg3->y) ) - { - wn++; - } - - /* Going "down"! */ - if ( side > 0 && (seg3->y <= pt->y) && (pt->y < seg1->y) ) - { - wn--; - } - - /* Inside the arc! */ - if ( pt->x <= gbox.xmax && pt->x >= gbox.xmin ) - { - POINT2D C; - double radius = lw_arc_center(seg1, seg2, seg3, &C); - double d = distance2d_pt_pt(pt, &C); - - /* On the boundary! */ - if ( d == radius ) - return LW_BOUNDARY; - - /* Within the arc! */ - if ( d < radius ) - { - /* Left side, increment winding number */ - if ( side < 0 ) - wn++; - /* Right side, decrement winding number */ - if ( side > 0 ) - wn--; - } - } - - seg1 = seg3; - } - - /* Sent out the winding number for calls that are building on this as a primitive */ - if ( winding_number ) - *winding_number = wn; - - /* Outside */ - if (wn == 0) - { - return LW_OUTSIDE; - } - - /* Inside */ - return LW_INSIDE; + intersections = ptarrayarc_raycast_intersections(pa, pt, &on_boundary); + if (on_boundary) + return LW_BOUNDARY; + else + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } /** ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + liblwgeom/cunit/cu_measures.c | 33 +++ liblwgeom/cunit/cu_ptarray.c | 42 ++-- liblwgeom/liblwgeom_internal.h | 4 +- liblwgeom/lwalgorithm.c | 26 ++- liblwgeom/lwcompound.c | 73 +++--- liblwgeom/measures.c | 508 +++++++++++++++++++---------------------- liblwgeom/ptarray.c | 415 +++++++++++++++++++++------------ 8 files changed, 613 insertions(+), 489 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 2 14:09:00 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 02 Oct 2025 21:09:00 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.24a18fcf6dee79a7a45e0ff362622012@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"be2a0ffda5b08dca0d94c1498d84b62b83fe76f9/git" be2a0ff/git]: {{{#!CommitTicketReference repository="git" revision="be2a0ffda5b08dca0d94c1498d84b62b83fe76f9" Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 2 14:10:33 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 14:10:33 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-62-gae2d86d16 Message-ID: <20251002211033.6EB2D16EAAE@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via ae2d86d16b3ebf9f69baf1429fe4be6ab1bcf1cf (commit) from 0c129aefaa77ccc0c0537006009c3362a00027d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ae2d86d16b3ebf9f69baf1429fe4be6ab1bcf1cf Author: Paul Ramsey Date: Thu Oct 2 14:09:52 2025 -0700 Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 diff --git a/NEWS b/NEWS index 67e50c200..28fee762f 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. - #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) - #5991, CircularString distance error (Paul Ramsey) - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) +- #5989, ST_Distance error on CurvePolygon (Paul Ramsey) PostGIS 3.5.3 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 610b2a593..58e7cb4ba 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -222,6 +222,11 @@ static void test_mindistance2d_tolerance(void) DIST2DTEST( "CURVEPOLYGON(CIRCULARSTRING(7874821 8715927,8907663 8715927,8844683 7750316,7937800 7750316,7874821 8715927))", "POINT(5433865 8243495)", 2271704.2698450615, default_accepted_error); + + /* Ticket 5989 */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0, -1 5, 0 10), (0 10, -10 10, -10 0, 0 0)))", + "POINT(-0.5 5)", 0.5, default_accepted_error); } static void @@ -918,6 +923,25 @@ test_lw_dist2d_arc_arc(void) B2.x = 0 ; B2.y = 1; B3.x = 1 ; B3.y = 0; + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = 0; A1.y = .5; + A2.x = -0.3; A2.y = .5; + A3.x = 0; A3.y = .6; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + printf("%g\n", dl.distance); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.271798, 0.000001); + + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -0.5; A1.y = .5; + A2.x = -0.4; A2.y = .2; + A3.x = 0; A3.y = 0; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.292893, 0.000001); + /* Arc above the unit semicircle */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -1; A1.y = 3; @@ -954,6 +978,15 @@ test_lw_dist2d_arc_arc(void) CU_ASSERT_EQUAL( rv, LW_SUCCESS ); CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0, 0.000001); + /* Closed circle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -2.0; A1.y = -0.1; + A2.x = 1.5; A2.y = -0.1; + A3.x = -2.0; A3.y = -0.1; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.480742, 0.0001); + /* Concentric: and fully parallel */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -2.0; A1.y = 0.0; diff --git a/liblwgeom/cunit/cu_ptarray.c b/liblwgeom/cunit/cu_ptarray.c index 3b6cec8fc..bfb830284 100644 --- a/liblwgeom/cunit/cu_ptarray.c +++ b/liblwgeom/cunit/cu_ptarray.c @@ -433,14 +433,14 @@ static void test_ptarrayarc_contains_point() { /* int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) */ - LWLINE *lwline; + LWCIRCSTRING *lwcirc; POINTARRAY *pa; POINT2D pt; int rv; /*** Collection of semi-circles surrounding unit square ***/ - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); - pa = lwline->points; + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); + pa = lwcirc->points; /* Point in middle of square */ pt.x = 0; @@ -473,9 +473,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** Two-edge ring made up of semi-circles (really, a circle) ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); + pa = lwcirc->points; /* Point outside */ pt.x = -1.5; @@ -514,9 +514,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Two-edge ring, closed ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); + pa = lwcirc->points; /* Point to left of ring */ pt.x = 20; @@ -525,9 +525,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** One-edge ring, closed circle ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, -1 0)")); + pa = lwcirc->points; /* Point inside */ pt.x = 0; @@ -548,23 +548,23 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Overshort ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); //printf("%s\n", cu_error_msg); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_raycast_intersections called with even number of points"); /*** Unclosed ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, 2 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, 2 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called on unclosed ring", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_contains_point called on unclosed ring"); - lwline_free(lwline); + lwcircstring_free(lwcirc); } static void test_ptarray_scale() diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index f1e28eac0..0063b135a 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -445,13 +445,15 @@ double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, PO int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2); int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); +int lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p); double lw_seg_length(const POINT2D *A1, const POINT2D *A2); double lw_arc_length(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring); int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); -int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); +int ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); +int ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt); int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt); diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index a60d0b0f2..ea59575d3 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -90,7 +90,9 @@ lw_seg_length(const POINT2D *A1, const POINT2D *A2) int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3) { - return lw_segment_side(A1, A3, A2) == lw_segment_side(A1, A3, P); + int pt_side = lw_segment_side(A1, A3, P); + int arc_side = lw_segment_side(A1, A3, A2); + return pt_side == 0 || pt_side == arc_side; } /** @@ -104,6 +106,28 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) ((A1->y <= P->y && P->y < A2->y) || (A1->y >= P->y && P->y > A2->y)); } +int +lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +{ + // Check if the point is within the bounding box of the segment + if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || + p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) + { + return LW_FALSE; + } + + // Check for collinearity using the 2D cross-product. + // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) + double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); + + if (fabs(cross_product) < DBL_EPSILON) + { + return LW_TRUE; // Point is collinear and within the bounding box + } + + return LW_TRUE; +} + /** * Returns true if arc A is actually a point (all vertices are the same) . */ diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c index 90fee3560..1e0d5c2ee 100644 --- a/liblwgeom/lwcompound.c +++ b/liblwgeom/lwcompound.c @@ -184,63 +184,48 @@ int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) return LW_FAILURE; } +/* + * Use a ray-casting count to determine if the point + * is inside or outside of the compound curve. Ray-casting + * is run against each component of the overall arc, and + * the even/odd test run against the total of all components. + * Returns LW_INSIDE / LW_BOUNDARY / LW_OUTSIDE + */ int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { - uint32_t i; - LWLINE *lwline; - LWCIRCSTRING *lwcirc; - int wn = 0; - int winding_number = 0; - int result; + int intersections = 0; - for ( i = 0; i < comp->ngeoms; i++ ) + if (lwgeom_is_empty(lwcompound_as_lwgeom(comp))) + return LW_OUTSIDE; + + for (uint32_t j = 0; j < comp->ngeoms; j++) { - LWGEOM *lwgeom = comp->geoms[i]; - if ( lwgeom->type == LINETYPE ) + int on_boundary = LW_FALSE; + const LWGEOM *sub = comp->geoms[j]; + if (sub->type == LINETYPE) { - lwline = lwgeom_as_lwline(lwgeom); - if ( comp->ngeoms == 1 ) - { - return ptarray_contains_point(lwline->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); - } + LWLINE *lwline = lwgeom_as_lwline(sub); + intersections += ptarray_raycast_intersections(lwline->points, pt, &on_boundary); + } + else if (sub->type == CIRCSTRINGTYPE) + { + LWCIRCSTRING *lwcirc = lwgeom_as_lwcircstring(sub); + intersections += ptarrayarc_raycast_intersections(lwcirc->points, pt, &on_boundary); } else { - lwcirc = lwgeom_as_lwcircstring(lwgeom); - if ( ! lwcirc ) { - lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); - return 0; - } - if ( comp->ngeoms == 1 ) - { - return ptarrayarc_contains_point(lwcirc->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); - } + lwerror("%s: unsupported type %s", __func__, lwtype_name(sub->type)); } - - /* Propagate boundary condition */ - if ( result == LW_BOUNDARY ) + if (on_boundary) return LW_BOUNDARY; - - wn += winding_number; } - /* Outside */ - if (wn == 0) - return LW_OUTSIDE; - - /* Inside */ - return LW_INSIDE; + /* + * Odd number of intersections means inside. + * Even means outside. + */ + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } LWCOMPOUND * diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 1f88b244d..14202917a 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1540,37 +1540,156 @@ lw_dist2d_pt_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const P return LW_TRUE; } -/* Auxiliary function to calculate the distance between 2 concentric arcs*/ -int lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl); + + +/** + * @brief Calculates the intersection points of a circle and line. + * + * This function assumes the center and test point are distinct. + * Finds the line between the circle center and test point, and + * the two intersection points on the circle defined by that line. + * If those points fall within the provided arc (A1,A2,A3) then + * the points are added to the provided array (I) and the array + * length counter is incremented. + * + * @param A1 Point of arc + * @param A2 Point of arc + * @param A3 Point of arc + * @param center_A Center of arc A circle + * @param radius_A Radius of arc A circle + * @param P Point to use in calculating intersection line + * @param I [out] Pointer to an return value array + * @param ni [out] Pointer to return array size counter + * @return int + */ +static int +lw_dist2d_circle_intersections( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *center_A, + double radius_A, + const POINT2D *P, + POINT2D *I, + uint32_t *ni) +{ + POINT2D R; + + // If the test point is on the center of the other + // arc, some other point has to be closer, by definition. + if (p2d_same(center_A, P)) + return 0; + + // Calculate vector from the center to the pt + double dir_x = center_A->x - P->x; + double dir_y = center_A->y - P->y; + double dist = sqrt(dir_x * dir_x + dir_y * dir_y); + + // Normalize the direction vector to get a unit vector (length = 1) + double unit_x = dir_x / dist; + double unit_y = dir_y / dist; + + // Calculate the two intersection points on the circle + // Point 1: Move from center_A along the unit vector by distance radius_A + R.x = center_A->x + unit_x * radius_A; + R.y = center_A->y + unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + // Point 2: Move from center_A against the unit vector by distance radius_A + R.x = center_A->x - unit_x * radius_A; + R.y = center_A->y - unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + return 0; +} + + +/** + * @brief Calculates the intersection points of two overlapping circles. + * + * This function assumes the circles are known to intersect at one or two points. + * Specifically, the distance 'd' between their centers must satisfy: + * d < (rA + rB) and d > fabs(rA - rB) + * If these conditions are not met, the results are undefined. + * + * @param cA [in] Pointer to the center point of the first circle (A). + * @param rA [in] The radius of the first circle (A). + * @param cB [in] Pointer to the center point of the second circle (B). + * @param rB [in] The radius of the second circle (B). + * @param I [out] Pointer to an array of at least 2 POINT2D structs to store the results. + * I[0] will contain the first intersection point. + * If a second exists, it will be in I[1]. + * @return int The number of intersection points found (1 or 2). Returns 0 if + * the centers are coincident or another error occurs. + */ +static uint32_t +lw_dist2d_circle_circle_intersections( + const POINT2D *cA, double rA, + const POINT2D *cB, double rB, + POINT2D *I) +{ + // Vector from center A to center B + double dx = cB->x - cA->x; + double dy = cB->y - cA->y; + + // Distance between the centers + double d = sqrt(dx * dx + dy * dy); + + // 'a' is the distance from the center of circle A to the point P, + // which is the base of the right triangle formed by cA, P, and an intersection point. + double a = (rA * rA - rB * rB + d * d) / (2.0 * d); + + // 'h' is the height of that right triangle. + double h_squared = rA * rA - a * a; + + // Due to floating point errors, h_squared can be slightly negative. + // This happens when the circles are perfectly tangent. Clamp to 0. + if (h_squared < 0.0) + h_squared = 0.0; + + double h = sqrt(h_squared); + + // Find the coordinates of point P + double Px = cA->x + a * (dx / d); + double Py = cA->y + a * (dy / d); + + // The two intersection points are found by moving from P by a distance 'h' + // in directions perpendicular to the line connecting the centers. + // The perpendicular vector to (dx, dy) is (-dy, dx). + + // Intersection point 1 + I[0].x = Px - h * (dy / d); + I[0].y = Py + h * (dx / d); + + // If h is very close to 0, the circles are tangent and there's only one intersection point. + if (FP_IS_ZERO(h)) + return 1; + + // Intersection point 2 + I[1].x = Px + h * (dy / d); + I[1].y = Py - h * (dx / d); + + return 2; +} + int -lw_dist2d_arc_arc(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - DISTPTS *dl) +lw_dist2d_arc_arc( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, + DISTPTS *dl) { - POINT2D CA, CB; /* Center points of arcs A and B */ + POINT2D pts_A[16]; /* Points on A that might be the nearest */ + POINT2D pts_B[16]; /* Points on B that might be the nearest */ + uint32_t ai = 0, bi = 0; /* Number of points in pts_A and pts_B */ + POINT2D center_A, center_B; /* Center points of arcs A and B */ double radius_A, radius_B, d; /* Radii of arcs A and B */ - POINT2D D; /* Mid-point between the centers CA and CB */ - int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */ + int is_disjoint, is_overlapping, is_contained, is_same_center; + POINT2D intersectionPts[2]; if (dl->mode != DIST_MIN) lwerror("lw_dist2d_arc_arc only supports mindistance"); - /* TODO: Handle case where arc is closed circle (A1 = A3) */ - /* What if one or both of our "arcs" is actually a point? */ if (lw_arc_is_pt(B1, B2, B3) && lw_arc_is_pt(A1, A2, A3)) return lw_dist2d_pt_pt(B1, A1, dl); @@ -1580,8 +1699,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, return lw_dist2d_pt_arc(A1, B1, B2, B3, dl); /* Calculate centers and radii of circles. */ - radius_A = lw_arc_center(A1, A2, A3, &CA); - radius_B = lw_arc_center(B1, B2, B3, &CB); + radius_A = lw_arc_center(A1, A2, A3, ¢er_A); + radius_B = lw_arc_center(B1, B2, B3, ¢er_B); /* Two co-linear arcs?!? That's two segments. */ if (radius_A < 0 && radius_B < 0) @@ -1595,275 +1714,112 @@ lw_dist2d_arc_arc(const POINT2D *A1, if (radius_B < 0) return lw_dist2d_seg_arc(B1, B3, A1, A2, A3, dl); - /* Center-center distance */ - d = distance2d_pt_pt(&CA, &CB); + /* Circle relationships */ + d = distance2d_pt_pt(¢er_A, ¢er_B); + is_disjoint = (d > (radius_A + radius_B)); + is_contained = (d < fabs(radius_A - radius_B)); + is_same_center = p2d_same(¢er_A, ¢er_B); + is_overlapping = ! (is_disjoint || is_contained || is_same_center); - /* Concentric arcs */ - if (FP_EQUALS(d, 0.0)) - return lw_dist2d_arc_arc_concentric(A1, A2, A3, radius_A, B1, B2, B3, radius_B, &CA, dl); + /* + * Prime the array of potential closest points with the + * arc end points, which frequently participate in closest + * points. + */ + pts_A[ai++] = *A1; + pts_A[ai++] = *A3; + pts_B[bi++] = *B1; + pts_B[bi++] = *B3; - /* Make sure that arc "A" has the bigger radius */ - if (radius_B > radius_A) + /* + * Overlapping circles might have a zero distance + * case if the circle intersection points are inside both + * arcs. + */ + if (is_overlapping) { - const POINT2D *tmp; - POINT2D TP; /* Temporary point P */ - double td; - tmp = B1; - B1 = A1; - A1 = tmp; - tmp = B2; - B2 = A2; - A2 = tmp; - tmp = B3; - B3 = A3; - A3 = tmp; - TP = CB; - CB = CA; - CA = TP; - td = radius_B; - radius_B = radius_A; - radius_A = td; - } - - /* Circles touch at a point. Is that point within the arcs? */ - if (d == (radius_A + radius_B)) - { - D.x = CA.x + (CB.x - CA.x) * radius_A / d; - D.y = CA.y + (CB.y - CA.y) * radius_A / d; - - pt_in_arc_A = lw_pt_in_arc(&D, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&D, B1, B2, B3); - - /* Arcs do touch at D, return it */ - if (pt_in_arc_A && pt_in_arc_B) + /* + * Find the two points the circles intersect at. + */ + uint32_t npoints = lw_dist2d_circle_circle_intersections( + ¢er_A, radius_A, + ¢er_B, radius_B, + intersectionPts); + for (uint32_t i = 0; i < npoints; i++) { - lw_dist2d_distpts_set(dl, 0.0, &D, &D); - return LW_TRUE; + /* + * If an intersection point is contained in both + * arcs, that is a location of zero distance, so + * we are done calculating. + */ + if (lw_pt_in_arc(&intersectionPts[i], A1, A2, A3) && + lw_pt_in_arc(&intersectionPts[i], B1, B2, B3)) + { + lw_dist2d_distpts_set(dl, 0.0, &intersectionPts[i], &intersectionPts[i]); + return LW_TRUE; + } } } - /* Disjoint or contained circles don't intersect. Closest point may be on */ - /* the line joining CA to CB. */ - else if (d > (radius_A + radius_B) /* Disjoint */ || d < (radius_A - radius_B) /* Contained */) + + /* + * Join the circle centers and find the places that + * line intersects the circles. Where those places + * are in the arcs, they are potential sites of the + * closest points. + */ + if (is_disjoint || is_contained || is_overlapping) { - POINT2D XA, XB; /* Points where the line from CA to CB cross their circle bounds */ - - /* Calculate hypothetical nearest points, the places on the */ - /* two circles where the center-center line crosses. If both */ - /* arcs contain their hypothetical points, that's the crossing distance */ - XA.x = CA.x + (CB.x - CA.x) * radius_A / d; - XA.y = CA.y + (CB.y - CA.y) * radius_A / d; - XB.x = CB.x + (CA.x - CB.x) * radius_B / d; - XB.y = CB.y + (CA.y - CB.y) * radius_B / d; - - pt_in_arc_A = lw_pt_in_arc(&XA, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&XB, B1, B2, B3); - - /* If the nearest points are both within the arcs, that's our answer */ - /* the shortest distance is at the nearest points */ - if (pt_in_arc_A && pt_in_arc_B) + if (!is_same_center) { - return lw_dist2d_pt_pt(&XA, &XB, dl); - } - } - /* Circles cross at two points, are either of those points in both arcs? */ - /* http://paulbourke.net/geometry/2circle/ */ - else if (d < (radius_A + radius_B)) - { - POINT2D E, F; /* Points where circle(A) and circle(B) cross */ - /* Distance from CA to D */ - double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d); - /* Distance from D to E or F */ - double h = sqrt(radius_A * radius_A - a * a); + /* Add points on A that intersect line from center_A to center_B */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, ¢er_B, + pts_A, &ai); - /* Location of D */ - D.x = CA.x + (CB.x - CA.x) * a / d; - D.y = CA.y + (CB.y - CA.y) * a / d; - - /* Start from D and project h units perpendicular to CA-D to get E */ - E.x = D.x + (D.y - CA.y) * h / a; - E.y = D.y + (D.x - CA.x) * h / a; - - /* Crossing point E contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&E, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&E, B1, B2, B3); - - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &E, &E); - return LW_TRUE; + /* Add points on B that intersect line from center_B to center_A */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, ¢er_A, + pts_B, &bi); } - /* Start from D and project h units perpendicular to CA-D to get F */ - F.x = D.x - (D.y - CA.y) * h / a; - F.y = D.y - (D.x - CA.x) * h / a; + /* Add points on A that intersect line to B1 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B1, + pts_A, &ai); - /* Crossing point F contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&F, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&F, B1, B2, B3); + /* Add points on A that intersect line to B3 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B3, + pts_A, &ai); - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &F, &F); - return LW_TRUE; - } - } - else - { - lwerror("lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!"); - return LW_FALSE; + /* Add points on B that intersect line to A1 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A1, + pts_B, &bi); + + /* Add points on B that intersect line to A3 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A3, + pts_B, &bi); } - /* Closest point is in the arc A, but not in the arc B, so */ - /* one of the B end points must be the closest. */ - if (pt_in_arc_A && !pt_in_arc_B) - { - lw_dist2d_pt_arc(B1, A1, A2, A3, dl); - lw_dist2d_pt_arc(B3, A1, A2, A3, dl); - return LW_TRUE; - } - /* Closest point is in the arc B, but not in the arc A, so */ - /* one of the A end points must be the closest. */ - else if (pt_in_arc_B && !pt_in_arc_A) - { - lw_dist2d_pt_arc(A1, B1, B2, B3, dl); - lw_dist2d_pt_arc(A3, B1, B2, B3, dl); - return LW_TRUE; - } - /* Finally, one of the end-point to end-point combos is the closest. */ - else - { - lw_dist2d_pt_pt(A1, B1, dl); - lw_dist2d_pt_pt(A1, B3, dl); - lw_dist2d_pt_pt(A3, B1, dl); - lw_dist2d_pt_pt(A3, B3, dl); - return LW_TRUE; - } + /* + * Now just brute force check all pairs of participating + * points, to find the pair that is closest together. + */ + for (uint32_t i = 0; i < ai; i++) + for (uint32_t j = 0; j < bi; j++) + lw_dist2d_pt_pt(&pts_A[i], &pts_B[j], dl); return LW_TRUE; } -int -lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl) -{ - int seg_size; - double dist_sqr, shortest_sqr; - const POINT2D *P1; - const POINT2D *P2; - POINT2D proj; - - if (radius_A == radius_B) - { - /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */ - seg_size = lw_segment_side(A1, A3, A2); - if (seg_size == lw_segment_side(A1, A3, B1)) - { - lw_dist2d_distpts_set(dl, 0.0, B1, B1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(A1, A3, B3)) - { - lw_dist2d_distpts_set(dl, 0.0, B3, B3); - return LW_TRUE; - } - /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */ - seg_size = lw_segment_side(B1, B3, B2); - if (seg_size == lw_segment_side(B1, B3, A1)) - { - lw_dist2d_distpts_set(dl, 0.0, A1, A1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(B1, B3, A3)) - { - lw_dist2d_distpts_set(dl, 0.0, A3, A3); - return LW_TRUE; - } - } - else - { - /* Check if any projection of B ends are in A*/ - seg_size = lw_segment_side(A1, A3, A2); - - /* B1 */ - proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B; - - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B1); - return LW_TRUE; - } - /* B3 */ - proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B; - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B3); - return LW_TRUE; - } - - /* Now check projections of A in B */ - seg_size = lw_segment_side(B1, B3, B2); - - /* A1 */ - proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A1); - return LW_TRUE; - } - - /* A3 */ - proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A3); - return LW_TRUE; - } - } - - /* Check the shortest between the distances of the 4 ends */ - shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1); - P1 = A1; - P2 = B1; - - dist_sqr = distance2d_sqr_pt_pt(A1, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A1; - P2 = B3; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B1); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B1; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B3; - } - - lw_dist2d_distpts_set(dl, sqrt(shortest_sqr), P1, P2); - return LW_TRUE; -} /** Finds the shortest distance between two segments. diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 905083da0..2369bff18 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -742,17 +742,285 @@ ptarray_is_closed_z(const POINTARRAY *in) } /** -* Return LW_INSIDE if the point is inside the POINTARRAY, -* LW_OUTSIDE if it is outside, and LW_BOUNDARY if it is on -* the boundary. -* LW_INSIDE == 1, LW_BOUNDARY == 0, LW_OUTSIDE == -1 -*/ + * The following is based on the "Fast Winding Number Inclusion of a Point + * in a Polygon" algorithm by Dan Sunday. + * http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number + * + * Return: + * - LW_INSIDE (1) if the point is inside the POINTARRAY + * - LW_BOUNDARY (0) if it is on the boundary. + * - LW_OUTSIDE (-1) if it is outside + */ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarray_contains_point_partial(pa, pt, LW_TRUE, NULL); + const POINT2D *seg1, *seg2; + int wn = 0; + + seg1 = getPoint2d_cp(pa, 0); + seg2 = getPoint2d_cp(pa, pa->npoints-1); + if (!p2d_same(seg1, seg2)) + lwerror("ptarray_contains_point called on unclosed ring"); + + for (uint32_t i = 1; i < pa->npoints; i++) + { + double side, ymin, ymax; + + seg2 = getPoint2d_cp(pa, i); + + /* Zero length segments are ignored. */ + if (p2d_same(seg1, seg2)) + { + seg1 = seg2; + continue; + } + + ymin = FP_MIN(seg1->y, seg2->y); + ymax = FP_MAX(seg1->y, seg2->y); + + /* Only test segments in our vertical range */ + if (pt->y > ymax || pt->y < ymin) + { + seg1 = seg2; + continue; + } + + side = lw_segment_side(seg1, seg2, pt); + + /* + * A point on the boundary of a ring is not contained. + * WAS: if (fabs(side) < 1e-12), see #852 + */ + if ((side == 0) && lw_pt_in_seg(pt, seg1, seg2)) + { + return LW_BOUNDARY; + } + + /* + * If the point is to the left of the line, and it's rising, + * then the line is to the right of the point and + * circling counter-clockwise, so increment. + */ + if ((side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y)) + { + wn++; + } + + /* + * If the point is to the right of the line, and it's falling, + * then the line is to the right of the point and circling + * clockwise, so decrement. + */ + else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) ) + { + wn--; + } + + seg1 = seg2; + } + + /* wn == 0 => Outside, wn != 0 => Inside */ + return wn == 0 ? LW_OUTSIDE : LW_INSIDE; } +int +ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + // A valid linestring must have at least 2 point + if (pa->npoints < 2) + lwerror("%s called on invalid linestring", __func__); + + int intersections = 0; + double px = p->x; + double py = p->y; + + // Iterate through each edge of the polygon + for (uint32_t i = 0; i < pa->npoints-1; ++i) + { + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + + /* Skip zero-length edges */ + if (p2d_same(p1, p2)) + continue; + + /* --- Step 1: Check if the point is ON the boundary edge --- */ + if (lw_pt_on_segment(p1, p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + /* --- Step 2: Perform the Ray Casting intersection test --- */ + + /* + * Check if the horizontal ray from p intersects the edge (p1, p2). + * This is the core condition for handling vertices correctly: + * - One vertex must be strictly above the ray (py < vertex.y) + * - The other must be on or below the ray (py >= vertex.y) + */ + if (((p1->y <= py) && (py < p2->y)) || ((p2->y <= py) && (py < p1->y))) + { + /* + * Calculate the x-coordinate where the edge intersects the ray's horizontal line. + * Formula: x = x1 + (y - y1) * (x2 - x1) / (y2 - y1) + */ + double x_intersection = p1->x + (py - p1->y) * (p2->x - p1->x) / (p2->y - p1->y); + + /* + * If the intersection point is to the right of our test point, + * it's a valid "crossing". + */ + if (x_intersection > px) + { + intersections++; + } + } + } + + return intersections; +} + + +/** + * @brief Calculates the intersection points of a circle and a horizontal line. + * + * The equation of a circle is (x - cx)^2 + (y - cy)^2 = r^2. + * The equation of the horizontal line is y = y_line. + * Substituting y_line into the circle equation gives: + * (x - cx)^2 = r^2 - (y_line - cy)^2 + * This function solves for x. + * + * @param center A pointer to the center point of the circle. + * @param radius The radius of the circle. + * @param ray The y-coordinate of the horizontal line. + * @param i0 A pointer to a POINT2D to store the first intersection point. + * @param i1 A pointer to a POINT2D to store the second intersection point. + * + * @return The number of intersection points found (0, 1, or 2). + */ +static int +circle_raycast_intersections(const POINT2D *center, double radius, double ray, POINT2D *i0, POINT2D *i1) +{ + // Calculate the vertical distance from the circle's center to the horizontal line. + double dy = ray - center->y; + + // If the absolute vertical distance is greater than the radius, there are no intersections. + if (fabs(dy) > radius) + return 0; + + // Use the Pythagorean theorem to find the horizontal distance (dx) from the + // center's x-coordinate to the intersection points. + // dx^2 + dy^2 = radius^2 => dx^2 = radius^2 - dy^2 + double dx_squared = radius * radius - dy * dy; + + // Case 1: One intersection (tangent) + // This occurs when the line just touches the top or bottom of the circle. + // dx_squared will be zero. We check against a small epsilon for floating-point safety. + if (FP_EQUALS(dx_squared, 0.0)) + { + i0->x = center->x; + i0->y = ray; + return 1; + } + + // Case 2: Two intersections + // The line cuts through the circle. + double dx = sqrt(dx_squared); + + // The first intersection point has the smaller x-value. + i0->x = center->x - dx; + i0->y = ray; + + // The second intersection point has the larger x-value. + i1->x = center->x + dx; + i1->y = ray; + + return 2; +} + + +int +ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + int intersections = 0; + double px = p->x; + double py = p->y; + + assert(on_boundary); + + // A valid circular arc must have at least 3 vertices (circle). + if (pa->npoints < 3) + lwerror("%s called on invalid circularstring", __func__); + + if (pa->npoints % 2 == 0) + lwerror("%s called with even number of points", __func__); + + // Iterate through each arc of the circularstring + for (uint32_t i = 1; i < pa->npoints-1; i +=2) + { + const POINT2D* p0 = getPoint2d_cp(pa, i-1); + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + POINT2D center = {0,0}; + double radius, d; + GBOX gbox; + + // Skip zero-length arc + if (lw_arc_is_pt(p0, p1, p2)) + continue; + + // --- Step 1: Check if the point is ON the boundary edge --- + if (p2d_same(p0, p) || p2d_same(p1, p) || p2d_same(p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // Calculate some important pieces + radius = lw_arc_center(p0, p1, p2, ¢er); + + d = distance2d_pt_pt(p, ¢er); + if (FP_EQUALS(d, radius) && lw_pt_in_arc(p, p0, p1, p2)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // --- Step 2: Perform the Ray Casting intersection test --- + + // Only process arcs that our ray crosses + lw_arc_calculate_gbox_cartesian_2d(p0, p1, p2, &gbox); + if ((gbox.ymin <= py) && (py < gbox.ymax)) + { + // Point of intersection on the circle that defines the arc + POINT2D i0, i1; + + // How many points of intersection are there + int iCount = circle_raycast_intersections(¢er, radius, py, &i0, &i1); + + // Nothing to see here + if (iCount == 0) + continue; + + // Cannot think of a case where a grazing is not a + // no-op + if (iCount == 1) + continue; + + // So we must have 2 intersections + // Only increment the counter for intersections to the right + // of the test point + if (i0.x > px && lw_pt_in_arc(&i0, p0, p1, p2)) + intersections++; + + if (i1.x > px && lw_pt_in_arc(&i1, p0, p1, p2)) + intersections++; + } + } + + return intersections; +} /* * The following is based on the "Fast Winding Number Inclusion of a Point @@ -765,8 +1033,7 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int wn = 0; uint32_t i; double side; - const POINT2D *seg1; - const POINT2D *seg2; + const POINT2D *seg1, *seg2; double ymin, ymax; seg1 = getPoint2d_cp(pa, 0); @@ -855,160 +1122,16 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarrayarc_contains_point_partial(pa, pt, LW_TRUE /* Check closed*/, NULL); -} + int on_boundary = LW_FALSE; + int intersections; + if (!ptarray_is_closed_2d(pa)) + lwerror("%s called on unclosed ring", __func__); -int -ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number) -{ - int wn = 0; - uint32_t i; - int side; - const POINT2D *seg1; - const POINT2D *seg2; - const POINT2D *seg3; - GBOX gbox; - - /* Check for not an arc ring (always have odd # of points) */ - if ( (pa->npoints % 2) == 0 ) - { - lwerror("ptarrayarc_contains_point called with even number of points"); - return LW_OUTSIDE; - } - - /* Check for not an arc ring (always have >= 3 points) */ - if ( pa->npoints < 3 ) - { - lwerror("ptarrayarc_contains_point called too-short pointarray"); - return LW_OUTSIDE; - } - - /* Check for unclosed case */ - seg1 = getPoint2d_cp(pa, 0); - seg3 = getPoint2d_cp(pa, pa->npoints-1); - if ( check_closed && ! p2d_same(seg1, seg3) ) - { - lwerror("ptarrayarc_contains_point called on unclosed ring"); - return LW_OUTSIDE; - } - /* OK, it's closed. Is it just one circle? */ - else if ( p2d_same(seg1, seg3) && pa->npoints == 3 ) - { - double radius, d; - POINT2D c; - seg2 = getPoint2d_cp(pa, 1); - - /* Wait, it's just a point, so it can't contain anything */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - return LW_OUTSIDE; - - /* See if the point is within the circle radius */ - radius = lw_arc_center(seg1, seg2, seg3, &c); - d = distance2d_pt_pt(pt, &c); - if ( FP_EQUALS(d, radius) ) - return LW_BOUNDARY; /* Boundary of circle */ - else if ( d < radius ) - return LW_INSIDE; /* Inside circle */ - else - return LW_OUTSIDE; /* Outside circle */ - } - else if ( p2d_same(seg1, pt) || p2d_same(seg3, pt) ) - { - return LW_BOUNDARY; /* Boundary case */ - } - - /* Start on the ring */ - seg1 = getPoint2d_cp(pa, 0); - for ( i=1; i < pa->npoints; i += 2 ) - { - seg2 = getPoint2d_cp(pa, i); - seg3 = getPoint2d_cp(pa, i+1); - - /* Catch an easy boundary case */ - if( p2d_same(seg3, pt) ) - return LW_BOUNDARY; - - /* Skip arcs that have no size */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - { - seg1 = seg3; - continue; - } - - /* Only test segments in our vertical range */ - lw_arc_calculate_gbox_cartesian_2d(seg1, seg2, seg3, &gbox); - if ( pt->y > gbox.ymax || pt->y < gbox.ymin ) - { - seg1 = seg3; - continue; - } - - /* Outside of horizontal range, and not between end points we also skip */ - if ( (pt->x > gbox.xmax || pt->x < gbox.xmin) && - (pt->y > FP_MAX(seg1->y, seg3->y) || pt->y < FP_MIN(seg1->y, seg3->y)) ) - { - seg1 = seg3; - continue; - } - - side = lw_arc_side(seg1, seg2, seg3, pt); - - /* On the boundary */ - if ( (side == 0) && lw_pt_in_arc(pt, seg1, seg2, seg3) ) - { - return LW_BOUNDARY; - } - - /* Going "up"! Point to left of arc. */ - if ( side < 0 && (seg1->y <= pt->y) && (pt->y < seg3->y) ) - { - wn++; - } - - /* Going "down"! */ - if ( side > 0 && (seg3->y <= pt->y) && (pt->y < seg1->y) ) - { - wn--; - } - - /* Inside the arc! */ - if ( pt->x <= gbox.xmax && pt->x >= gbox.xmin ) - { - POINT2D C; - double radius = lw_arc_center(seg1, seg2, seg3, &C); - double d = distance2d_pt_pt(pt, &C); - - /* On the boundary! */ - if ( d == radius ) - return LW_BOUNDARY; - - /* Within the arc! */ - if ( d < radius ) - { - /* Left side, increment winding number */ - if ( side < 0 ) - wn++; - /* Right side, decrement winding number */ - if ( side > 0 ) - wn--; - } - } - - seg1 = seg3; - } - - /* Sent out the winding number for calls that are building on this as a primitive */ - if ( winding_number ) - *winding_number = wn; - - /* Outside */ - if (wn == 0) - { - return LW_OUTSIDE; - } - - /* Inside */ - return LW_INSIDE; + intersections = ptarrayarc_raycast_intersections(pa, pt, &on_boundary); + if (on_boundary) + return LW_BOUNDARY; + else + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } /** ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + liblwgeom/cunit/cu_measures.c | 33 +++ liblwgeom/cunit/cu_ptarray.c | 42 ++-- liblwgeom/liblwgeom_internal.h | 4 +- liblwgeom/lwalgorithm.c | 26 ++- liblwgeom/lwcompound.c | 73 +++--- liblwgeom/measures.c | 508 +++++++++++++++++++---------------------- liblwgeom/ptarray.c | 415 +++++++++++++++++++++------------ 8 files changed, 613 insertions(+), 489 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 2 14:10:43 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 02 Oct 2025 21:10:43 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.d9b63f94d42ccffb86b50270f99d7828@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"ae2d86d16b3ebf9f69baf1429fe4be6ab1bcf1cf/git" ae2d86d/git]: {{{#!CommitTicketReference repository="git" revision="ae2d86d16b3ebf9f69baf1429fe4be6ab1bcf1cf" Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 2 14:19:58 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 14:19:58 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-55-g8dc414411 Message-ID: <20251002211959.2963916EB2F@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via 8dc414411446c0d8a711a0c565c29ff1c2028fd6 (commit) from 4a1fca43891ff3b191abf23a47a698611e0632e4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8dc414411446c0d8a711a0c565c29ff1c2028fd6 Author: Paul Ramsey Date: Thu Oct 2 14:19:47 2025 -0700 Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 diff --git a/NEWS b/NEWS index aec4992eb..53f01c3bf 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ Proj 6.1+ required. - #5082, LRS proportions clamped to [0,1] (Pawel Ostrowski) - #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) - #5991, CircularString distance error (Paul Ramsey) + - #5989, ST_Distance error on CurvePolygon (Paul Ramsey) PostGIS 3.4.4 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 610b2a593..58e7cb4ba 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -222,6 +222,11 @@ static void test_mindistance2d_tolerance(void) DIST2DTEST( "CURVEPOLYGON(CIRCULARSTRING(7874821 8715927,8907663 8715927,8844683 7750316,7937800 7750316,7874821 8715927))", "POINT(5433865 8243495)", 2271704.2698450615, default_accepted_error); + + /* Ticket 5989 */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0, -1 5, 0 10), (0 10, -10 10, -10 0, 0 0)))", + "POINT(-0.5 5)", 0.5, default_accepted_error); } static void @@ -918,6 +923,25 @@ test_lw_dist2d_arc_arc(void) B2.x = 0 ; B2.y = 1; B3.x = 1 ; B3.y = 0; + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = 0; A1.y = .5; + A2.x = -0.3; A2.y = .5; + A3.x = 0; A3.y = .6; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + printf("%g\n", dl.distance); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.271798, 0.000001); + + /* Arc inside the semicircle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -0.5; A1.y = .5; + A2.x = -0.4; A2.y = .2; + A3.x = 0; A3.y = 0; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.292893, 0.000001); + /* Arc above the unit semicircle */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -1; A1.y = 3; @@ -954,6 +978,15 @@ test_lw_dist2d_arc_arc(void) CU_ASSERT_EQUAL( rv, LW_SUCCESS ); CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0, 0.000001); + /* Closed circle */ + lw_dist2d_distpts_init(&dl, DIST_MIN); + A1.x = -2.0; A1.y = -0.1; + A2.x = 1.5; A2.y = -0.1; + A3.x = -2.0; A3.y = -0.1; + rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl); + CU_ASSERT_EQUAL( rv, LW_SUCCESS ); + CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.480742, 0.0001); + /* Concentric: and fully parallel */ lw_dist2d_distpts_init(&dl, DIST_MIN); A1.x = -2.0; A1.y = 0.0; diff --git a/liblwgeom/cunit/cu_ptarray.c b/liblwgeom/cunit/cu_ptarray.c index 3b6cec8fc..bfb830284 100644 --- a/liblwgeom/cunit/cu_ptarray.c +++ b/liblwgeom/cunit/cu_ptarray.c @@ -433,14 +433,14 @@ static void test_ptarrayarc_contains_point() { /* int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) */ - LWLINE *lwline; + LWCIRCSTRING *lwcirc; POINTARRAY *pa; POINT2D pt; int rv; /*** Collection of semi-circles surrounding unit square ***/ - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); - pa = lwline->points; + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 -1, -2 0, -1 1, 0 2, 1 1, 2 0, 1 -1, 0 -2, -1 -1)")); + pa = lwcirc->points; /* Point in middle of square */ pt.x = 0; @@ -473,9 +473,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** Two-edge ring made up of semi-circles (really, a circle) ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 0 1, 1 0, 0 -1, -1 0)")); + pa = lwcirc->points; /* Point outside */ pt.x = -1.5; @@ -514,9 +514,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Two-edge ring, closed ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(1 6, 6 1, 9 7, 6 10, 1 6)")); + pa = lwcirc->points; /* Point to left of ring */ pt.x = 20; @@ -525,9 +525,9 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_OUTSIDE); /*** One-edge ring, closed circle ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, -1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, -1 0)")); + pa = lwcirc->points; /* Point inside */ pt.x = 0; @@ -548,23 +548,23 @@ static void test_ptarrayarc_contains_point() CU_ASSERT_EQUAL(rv, LW_BOUNDARY); /*** Overshort ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); //printf("%s\n", cu_error_msg); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_raycast_intersections called with even number of points"); /*** Unclosed ring ***/ - lwline_free(lwline); - lwline = lwgeom_as_lwline(lwgeom_from_text("LINESTRING(-1 0, 1 0, 2 0)")); - pa = lwline->points; + lwcircstring_free(lwcirc); + lwcirc = lwgeom_as_lwcircstring(lwgeom_from_text("CIRCULARSTRING(-1 0, 1 0, 2 0)")); + pa = lwcirc->points; cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called on unclosed ring", cu_error_msg); + ASSERT_STRING_EQUAL(cu_error_msg, "ptarrayarc_contains_point called on unclosed ring"); - lwline_free(lwline); + lwcircstring_free(lwcirc); } static void test_ptarray_scale() diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index 68295766a..66dabaffa 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -443,13 +443,15 @@ double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, PO int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2); int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); +int lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p); double lw_seg_length(const POINT2D *A1, const POINT2D *A2); double lw_arc_length(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int pt_in_ring_2d(const POINT2D *p, const POINTARRAY *ring); int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); -int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); +int ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); +int ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt); int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt); diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index a2220048c..331d4c14d 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -82,7 +82,9 @@ lw_seg_length(const POINT2D *A1, const POINT2D *A2) int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3) { - return lw_segment_side(A1, A3, A2) == lw_segment_side(A1, A3, P); + int pt_side = lw_segment_side(A1, A3, P); + int arc_side = lw_segment_side(A1, A3, A2); + return pt_side == 0 || pt_side == arc_side; } /** @@ -96,6 +98,28 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) ((A1->y <= P->y && P->y < A2->y) || (A1->y >= P->y && P->y > A2->y)); } +int +lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +{ + // Check if the point is within the bounding box of the segment + if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || + p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) + { + return LW_FALSE; + } + + // Check for collinearity using the 2D cross-product. + // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) + double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); + + if (fabs(cross_product) < DBL_EPSILON) + { + return LW_TRUE; // Point is collinear and within the bounding box + } + + return LW_TRUE; +} + /** * Returns true if arc A is actually a point (all vertices are the same) . */ diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c index 03f4201cd..666b455da 100644 --- a/liblwgeom/lwcompound.c +++ b/liblwgeom/lwcompound.c @@ -141,63 +141,49 @@ int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) return LW_FAILURE; } +/* + * Use a ray-casting count to determine if the point + * is inside or outside of the compound curve. Ray-casting + * is run against each component of the overall arc, and + * the even/odd test run against the total of all components. + * Returns LW_INSIDE / LW_BOUNDARY / LW_OUTSIDE + */ int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { - uint32_t i; - LWLINE *lwline; - LWCIRCSTRING *lwcirc; - int wn = 0; - int winding_number = 0; - int result; + int intersections = 0; - for ( i = 0; i < comp->ngeoms; i++ ) - { - LWGEOM *lwgeom = comp->geoms[i]; - if ( lwgeom->type == LINETYPE ) - { - lwline = lwgeom_as_lwline(lwgeom); - if ( comp->ngeoms == 1 ) - { - return ptarray_contains_point(lwline->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); - } - } - else - { - lwcirc = lwgeom_as_lwcircstring(lwgeom); - if ( ! lwcirc ) { - lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); - return 0; - } - if ( comp->ngeoms == 1 ) - { - return ptarrayarc_contains_point(lwcirc->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); - } - } - - /* Propogate boundary condition */ - if ( result == LW_BOUNDARY ) - return LW_BOUNDARY; - - wn += winding_number; - } - - /* Outside */ - if (wn == 0) + if (lwgeom_is_empty(lwcompound_as_lwgeom(comp))) return LW_OUTSIDE; - /* Inside */ - return LW_INSIDE; + for (uint32_t j = 0; j < comp->ngeoms; j++) + { + int on_boundary = LW_FALSE; + const LWGEOM *sub = comp->geoms[j]; + if (sub->type == LINETYPE) + { + LWLINE *lwline = lwgeom_as_lwline(sub); + intersections += ptarray_raycast_intersections(lwline->points, pt, &on_boundary); + } + else if (sub->type == CIRCSTRINGTYPE) + { + LWCIRCSTRING *lwcirc = lwgeom_as_lwcircstring(sub); + intersections += ptarrayarc_raycast_intersections(lwcirc->points, pt, &on_boundary); + } + else + { + lwerror("%s: unsupported type %s", __func__, lwtype_name(sub->type)); + } + + if (on_boundary) + return LW_BOUNDARY; + } + + /* + * Odd number of intersections means inside. + * Even means outside. + */ + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } LWCOMPOUND * diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 2d95060ec..e2b3154cf 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1540,37 +1540,156 @@ lw_dist2d_pt_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const P return LW_TRUE; } -/* Auxiliary function to calculate the distance between 2 concentric arcs*/ -int lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl); + + +/** + * @brief Calculates the intersection points of a circle and line. + * + * This function assumes the center and test point are distinct. + * Finds the line between the circle center and test point, and + * the two intersection points on the circle defined by that line. + * If those points fall within the provided arc (A1,A2,A3) then + * the points are added to the provided array (I) and the array + * length counter is incremented. + * + * @param A1 Point of arc + * @param A2 Point of arc + * @param A3 Point of arc + * @param center_A Center of arc A circle + * @param radius_A Radius of arc A circle + * @param P Point to use in calculating intersection line + * @param I [out] Pointer to an return value array + * @param ni [out] Pointer to return array size counter + * @return int + */ +static int +lw_dist2d_circle_intersections( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *center_A, + double radius_A, + const POINT2D *P, + POINT2D *I, + uint32_t *ni) +{ + POINT2D R; + + // If the test point is on the center of the other + // arc, some other point has to be closer, by definition. + if (p2d_same(center_A, P)) + return 0; + + // Calculate vector from the center to the pt + double dir_x = center_A->x - P->x; + double dir_y = center_A->y - P->y; + double dist = sqrt(dir_x * dir_x + dir_y * dir_y); + + // Normalize the direction vector to get a unit vector (length = 1) + double unit_x = dir_x / dist; + double unit_y = dir_y / dist; + + // Calculate the two intersection points on the circle + // Point 1: Move from center_A along the unit vector by distance radius_A + R.x = center_A->x + unit_x * radius_A; + R.y = center_A->y + unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + // Point 2: Move from center_A against the unit vector by distance radius_A + R.x = center_A->x - unit_x * radius_A; + R.y = center_A->y - unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + return 0; +} + + +/** + * @brief Calculates the intersection points of two overlapping circles. + * + * This function assumes the circles are known to intersect at one or two points. + * Specifically, the distance 'd' between their centers must satisfy: + * d < (rA + rB) and d > fabs(rA - rB) + * If these conditions are not met, the results are undefined. + * + * @param cA [in] Pointer to the center point of the first circle (A). + * @param rA [in] The radius of the first circle (A). + * @param cB [in] Pointer to the center point of the second circle (B). + * @param rB [in] The radius of the second circle (B). + * @param I [out] Pointer to an array of at least 2 POINT2D structs to store the results. + * I[0] will contain the first intersection point. + * If a second exists, it will be in I[1]. + * @return int The number of intersection points found (1 or 2). Returns 0 if + * the centers are coincident or another error occurs. + */ +static uint32_t +lw_dist2d_circle_circle_intersections( + const POINT2D *cA, double rA, + const POINT2D *cB, double rB, + POINT2D *I) +{ + // Vector from center A to center B + double dx = cB->x - cA->x; + double dy = cB->y - cA->y; + + // Distance between the centers + double d = sqrt(dx * dx + dy * dy); + + // 'a' is the distance from the center of circle A to the point P, + // which is the base of the right triangle formed by cA, P, and an intersection point. + double a = (rA * rA - rB * rB + d * d) / (2.0 * d); + + // 'h' is the height of that right triangle. + double h_squared = rA * rA - a * a; + + // Due to floating point errors, h_squared can be slightly negative. + // This happens when the circles are perfectly tangent. Clamp to 0. + if (h_squared < 0.0) + h_squared = 0.0; + + double h = sqrt(h_squared); + + // Find the coordinates of point P + double Px = cA->x + a * (dx / d); + double Py = cA->y + a * (dy / d); + + // The two intersection points are found by moving from P by a distance 'h' + // in directions perpendicular to the line connecting the centers. + // The perpendicular vector to (dx, dy) is (-dy, dx). + + // Intersection point 1 + I[0].x = Px - h * (dy / d); + I[0].y = Py + h * (dx / d); + + // If h is very close to 0, the circles are tangent and there's only one intersection point. + if (FP_IS_ZERO(h)) + return 1; + + // Intersection point 2 + I[1].x = Px + h * (dy / d); + I[1].y = Py - h * (dx / d); + + return 2; +} + int -lw_dist2d_arc_arc(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - DISTPTS *dl) +lw_dist2d_arc_arc( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, + DISTPTS *dl) { - POINT2D CA, CB; /* Center points of arcs A and B */ + POINT2D pts_A[16]; /* Points on A that might be the nearest */ + POINT2D pts_B[16]; /* Points on B that might be the nearest */ + uint32_t ai = 0, bi = 0; /* Number of points in pts_A and pts_B */ + POINT2D center_A, center_B; /* Center points of arcs A and B */ double radius_A, radius_B, d; /* Radii of arcs A and B */ - POINT2D D; /* Mid-point between the centers CA and CB */ - int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */ + int is_disjoint, is_overlapping, is_contained, is_same_center; + POINT2D intersectionPts[2]; if (dl->mode != DIST_MIN) lwerror("lw_dist2d_arc_arc only supports mindistance"); - /* TODO: Handle case where arc is closed circle (A1 = A3) */ - /* What if one or both of our "arcs" is actually a point? */ if (lw_arc_is_pt(B1, B2, B3) && lw_arc_is_pt(A1, A2, A3)) return lw_dist2d_pt_pt(B1, A1, dl); @@ -1580,8 +1699,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, return lw_dist2d_pt_arc(A1, B1, B2, B3, dl); /* Calculate centers and radii of circles. */ - radius_A = lw_arc_center(A1, A2, A3, &CA); - radius_B = lw_arc_center(B1, B2, B3, &CB); + radius_A = lw_arc_center(A1, A2, A3, ¢er_A); + radius_B = lw_arc_center(B1, B2, B3, ¢er_B); /* Two co-linear arcs?!? That's two segments. */ if (radius_A < 0 && radius_B < 0) @@ -1595,275 +1714,112 @@ lw_dist2d_arc_arc(const POINT2D *A1, if (radius_B < 0) return lw_dist2d_seg_arc(B1, B3, A1, A2, A3, dl); - /* Center-center distance */ - d = distance2d_pt_pt(&CA, &CB); + /* Circle relationships */ + d = distance2d_pt_pt(¢er_A, ¢er_B); + is_disjoint = (d > (radius_A + radius_B)); + is_contained = (d < fabs(radius_A - radius_B)); + is_same_center = p2d_same(¢er_A, ¢er_B); + is_overlapping = ! (is_disjoint || is_contained || is_same_center); - /* Concentric arcs */ - if (FP_EQUALS(d, 0.0)) - return lw_dist2d_arc_arc_concentric(A1, A2, A3, radius_A, B1, B2, B3, radius_B, &CA, dl); + /* + * Prime the array of potential closest points with the + * arc end points, which frequently participate in closest + * points. + */ + pts_A[ai++] = *A1; + pts_A[ai++] = *A3; + pts_B[bi++] = *B1; + pts_B[bi++] = *B3; - /* Make sure that arc "A" has the bigger radius */ - if (radius_B > radius_A) + /* + * Overlapping circles might have a zero distance + * case if the circle intersection points are inside both + * arcs. + */ + if (is_overlapping) { - const POINT2D *tmp; - POINT2D TP; /* Temporary point P */ - double td; - tmp = B1; - B1 = A1; - A1 = tmp; - tmp = B2; - B2 = A2; - A2 = tmp; - tmp = B3; - B3 = A3; - A3 = tmp; - TP = CB; - CB = CA; - CA = TP; - td = radius_B; - radius_B = radius_A; - radius_A = td; - } - - /* Circles touch at a point. Is that point within the arcs? */ - if (d == (radius_A + radius_B)) - { - D.x = CA.x + (CB.x - CA.x) * radius_A / d; - D.y = CA.y + (CB.y - CA.y) * radius_A / d; - - pt_in_arc_A = lw_pt_in_arc(&D, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&D, B1, B2, B3); - - /* Arcs do touch at D, return it */ - if (pt_in_arc_A && pt_in_arc_B) + /* + * Find the two points the circles intersect at. + */ + uint32_t npoints = lw_dist2d_circle_circle_intersections( + ¢er_A, radius_A, + ¢er_B, radius_B, + intersectionPts); + for (uint32_t i = 0; i < npoints; i++) { - lw_dist2d_distpts_set(dl, 0.0, &D, &D); - return LW_TRUE; + /* + * If an intersection point is contained in both + * arcs, that is a location of zero distance, so + * we are done calculating. + */ + if (lw_pt_in_arc(&intersectionPts[i], A1, A2, A3) && + lw_pt_in_arc(&intersectionPts[i], B1, B2, B3)) + { + lw_dist2d_distpts_set(dl, 0.0, &intersectionPts[i], &intersectionPts[i]); + return LW_TRUE; + } } } - /* Disjoint or contained circles don't intersect. Closest point may be on */ - /* the line joining CA to CB. */ - else if (d > (radius_A + radius_B) /* Disjoint */ || d < (radius_A - radius_B) /* Contained */) + + /* + * Join the circle centers and find the places that + * line intersects the circles. Where those places + * are in the arcs, they are potential sites of the + * closest points. + */ + if (is_disjoint || is_contained || is_overlapping) { - POINT2D XA, XB; /* Points where the line from CA to CB cross their circle bounds */ - - /* Calculate hypothetical nearest points, the places on the */ - /* two circles where the center-center line crosses. If both */ - /* arcs contain their hypothetical points, that's the crossing distance */ - XA.x = CA.x + (CB.x - CA.x) * radius_A / d; - XA.y = CA.y + (CB.y - CA.y) * radius_A / d; - XB.x = CB.x + (CA.x - CB.x) * radius_B / d; - XB.y = CB.y + (CA.y - CB.y) * radius_B / d; - - pt_in_arc_A = lw_pt_in_arc(&XA, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&XB, B1, B2, B3); - - /* If the nearest points are both within the arcs, that's our answer */ - /* the shortest distance is at the nearest points */ - if (pt_in_arc_A && pt_in_arc_B) + if (!is_same_center) { - return lw_dist2d_pt_pt(&XA, &XB, dl); - } - } - /* Circles cross at two points, are either of those points in both arcs? */ - /* http://paulbourke.net/geometry/2circle/ */ - else if (d < (radius_A + radius_B)) - { - POINT2D E, F; /* Points where circle(A) and circle(B) cross */ - /* Distance from CA to D */ - double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d); - /* Distance from D to E or F */ - double h = sqrt(radius_A * radius_A - a * a); + /* Add points on A that intersect line from center_A to center_B */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, ¢er_B, + pts_A, &ai); - /* Location of D */ - D.x = CA.x + (CB.x - CA.x) * a / d; - D.y = CA.y + (CB.y - CA.y) * a / d; - - /* Start from D and project h units perpendicular to CA-D to get E */ - E.x = D.x + (D.y - CA.y) * h / a; - E.y = D.y + (D.x - CA.x) * h / a; - - /* Crossing point E contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&E, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&E, B1, B2, B3); - - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &E, &E); - return LW_TRUE; + /* Add points on B that intersect line from center_B to center_A */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, ¢er_A, + pts_B, &bi); } - /* Start from D and project h units perpendicular to CA-D to get F */ - F.x = D.x - (D.y - CA.y) * h / a; - F.y = D.y - (D.x - CA.x) * h / a; + /* Add points on A that intersect line to B1 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B1, + pts_A, &ai); - /* Crossing point F contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&F, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&F, B1, B2, B3); + /* Add points on A that intersect line to B3 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B3, + pts_A, &ai); - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &F, &F); - return LW_TRUE; - } - } - else - { - lwerror("lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!"); - return LW_FALSE; + /* Add points on B that intersect line to A1 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A1, + pts_B, &bi); + + /* Add points on B that intersect line to A3 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A3, + pts_B, &bi); } - /* Closest point is in the arc A, but not in the arc B, so */ - /* one of the B end points must be the closest. */ - if (pt_in_arc_A && !pt_in_arc_B) - { - lw_dist2d_pt_arc(B1, A1, A2, A3, dl); - lw_dist2d_pt_arc(B3, A1, A2, A3, dl); - return LW_TRUE; - } - /* Closest point is in the arc B, but not in the arc A, so */ - /* one of the A end points must be the closest. */ - else if (pt_in_arc_B && !pt_in_arc_A) - { - lw_dist2d_pt_arc(A1, B1, B2, B3, dl); - lw_dist2d_pt_arc(A3, B1, B2, B3, dl); - return LW_TRUE; - } - /* Finally, one of the end-point to end-point combos is the closest. */ - else - { - lw_dist2d_pt_pt(A1, B1, dl); - lw_dist2d_pt_pt(A1, B3, dl); - lw_dist2d_pt_pt(A3, B1, dl); - lw_dist2d_pt_pt(A3, B3, dl); - return LW_TRUE; - } + /* + * Now just brute force check all pairs of participating + * points, to find the pair that is closest together. + */ + for (uint32_t i = 0; i < ai; i++) + for (uint32_t j = 0; j < bi; j++) + lw_dist2d_pt_pt(&pts_A[i], &pts_B[j], dl); return LW_TRUE; } -int -lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl) -{ - int seg_size; - double dist_sqr, shortest_sqr; - const POINT2D *P1; - const POINT2D *P2; - POINT2D proj; - - if (radius_A == radius_B) - { - /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */ - seg_size = lw_segment_side(A1, A3, A2); - if (seg_size == lw_segment_side(A1, A3, B1)) - { - lw_dist2d_distpts_set(dl, 0.0, B1, B1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(A1, A3, B3)) - { - lw_dist2d_distpts_set(dl, 0.0, B3, B3); - return LW_TRUE; - } - /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */ - seg_size = lw_segment_side(B1, B3, B2); - if (seg_size == lw_segment_side(B1, B3, A1)) - { - lw_dist2d_distpts_set(dl, 0.0, A1, A1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(B1, B3, A3)) - { - lw_dist2d_distpts_set(dl, 0.0, A3, A3); - return LW_TRUE; - } - } - else - { - /* Check if any projection of B ends are in A*/ - seg_size = lw_segment_side(A1, A3, A2); - - /* B1 */ - proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B; - - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B1); - return LW_TRUE; - } - /* B3 */ - proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B; - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B3); - return LW_TRUE; - } - - /* Now check projections of A in B */ - seg_size = lw_segment_side(B1, B3, B2); - - /* A1 */ - proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A1); - return LW_TRUE; - } - - /* A3 */ - proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A3); - return LW_TRUE; - } - } - - /* Check the shortest between the distances of the 4 ends */ - shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1); - P1 = A1; - P2 = B1; - - dist_sqr = distance2d_sqr_pt_pt(A1, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A1; - P2 = B3; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B1); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B1; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B3; - } - - lw_dist2d_distpts_set(dl, sqrt(shortest_sqr), P1, P2); - return LW_TRUE; -} /** Finds the shortest distance between two segments. diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 91984e860..12114bbf2 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -753,16 +753,6 @@ ptarray_is_closed_z(const POINTARRAY *in) return ptarray_is_closed_2d(in); } -/** -* Return 1 if the point is inside the POINTARRAY, -1 if it is outside, -* and 0 if it is on the boundary. -*/ -int -ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) -{ - return ptarray_contains_point_partial(pa, pt, LW_TRUE, NULL); -} - int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number) { @@ -792,6 +782,288 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec ymin = FP_MIN(seg1->y, seg2->y); ymax = FP_MAX(seg1->y, seg2->y); + /* Only test segments in our vertical range */ + if (pt->y > ymax || pt->y < ymin) + { + seg1 = seg2; + continue; + } + + side = lw_segment_side(seg1, seg2, pt); + + /* + * A point on the boundary of a ring is not contained. + * WAS: if (fabs(side) < 1e-12), see #852 + */ + if ((side == 0) && lw_pt_in_seg(pt, seg1, seg2)) + { + return LW_BOUNDARY; + } + + /* + * If the point is to the left of the line, and it's rising, + * then the line is to the right of the point and + * circling counter-clockwise, so increment. + */ + if ((side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y)) + { + wn++; + } + + /* + * If the point is to the right of the line, and it's falling, + * then the line is to the right of the point and circling + * clockwise, so decrement. + */ + else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) ) + { + wn--; + } + + seg1 = seg2; + } + + /* wn == 0 => Outside, wn != 0 => Inside */ + return wn == 0 ? LW_OUTSIDE : LW_INSIDE; +} + +int +ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + // A valid linestring must have at least 2 point + if (pa->npoints < 2) + lwerror("%s called on invalid linestring", __func__); + + int intersections = 0; + double px = p->x; + double py = p->y; + + // Iterate through each edge of the polygon + for (uint32_t i = 0; i < pa->npoints-1; ++i) + { + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + + /* Skip zero-length edges */ + if (p2d_same(p1, p2)) + continue; + + /* --- Step 1: Check if the point is ON the boundary edge --- */ + if (lw_pt_on_segment(p1, p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + /* --- Step 2: Perform the Ray Casting intersection test --- */ + + /* + * Check if the horizontal ray from p intersects the edge (p1, p2). + * This is the core condition for handling vertices correctly: + * - One vertex must be strictly above the ray (py < vertex.y) + * - The other must be on or below the ray (py >= vertex.y) + */ + if (((p1->y <= py) && (py < p2->y)) || ((p2->y <= py) && (py < p1->y))) + { + /* + * Calculate the x-coordinate where the edge intersects the ray's horizontal line. + * Formula: x = x1 + (y - y1) * (x2 - x1) / (y2 - y1) + */ + double x_intersection = p1->x + (py - p1->y) * (p2->x - p1->x) / (p2->y - p1->y); + + /* + * If the intersection point is to the right of our test point, + * it's a valid "crossing". + */ + if (x_intersection > px) + { + intersections++; + } + } + } + + return intersections; +} + + +/** + * @brief Calculates the intersection points of a circle and a horizontal line. + * + * The equation of a circle is (x - cx)^2 + (y - cy)^2 = r^2. + * The equation of the horizontal line is y = y_line. + * Substituting y_line into the circle equation gives: + * (x - cx)^2 = r^2 - (y_line - cy)^2 + * This function solves for x. + * + * @param center A pointer to the center point of the circle. + * @param radius The radius of the circle. + * @param ray The y-coordinate of the horizontal line. + * @param i0 A pointer to a POINT2D to store the first intersection point. + * @param i1 A pointer to a POINT2D to store the second intersection point. + * + * @return The number of intersection points found (0, 1, or 2). + */ +static int +circle_raycast_intersections(const POINT2D *center, double radius, double ray, POINT2D *i0, POINT2D *i1) +{ + // Calculate the vertical distance from the circle's center to the horizontal line. + double dy = ray - center->y; + + // If the absolute vertical distance is greater than the radius, there are no intersections. + if (fabs(dy) > radius) + return 0; + + // Use the Pythagorean theorem to find the horizontal distance (dx) from the + // center's x-coordinate to the intersection points. + // dx^2 + dy^2 = radius^2 => dx^2 = radius^2 - dy^2 + double dx_squared = radius * radius - dy * dy; + + // Case 1: One intersection (tangent) + // This occurs when the line just touches the top or bottom of the circle. + // dx_squared will be zero. We check against a small epsilon for floating-point safety. + if (FP_EQUALS(dx_squared, 0.0)) + { + i0->x = center->x; + i0->y = ray; + return 1; + } + + // Case 2: Two intersections + // The line cuts through the circle. + double dx = sqrt(dx_squared); + + // The first intersection point has the smaller x-value. + i0->x = center->x - dx; + i0->y = ray; + + // The second intersection point has the larger x-value. + i1->x = center->x + dx; + i1->y = ray; + + return 2; +} + + +int +ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + int intersections = 0; + double px = p->x; + double py = p->y; + + assert(on_boundary); + + // A valid circular arc must have at least 3 vertices (circle). + if (pa->npoints < 3) + lwerror("%s called on invalid circularstring", __func__); + + if (pa->npoints % 2 == 0) + lwerror("%s called with even number of points", __func__); + + // Iterate through each arc of the circularstring + for (uint32_t i = 1; i < pa->npoints-1; i +=2) + { + const POINT2D* p0 = getPoint2d_cp(pa, i-1); + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + POINT2D center = {0,0}; + double radius, d; + GBOX gbox; + + // Skip zero-length arc + if (lw_arc_is_pt(p0, p1, p2)) + continue; + + // --- Step 1: Check if the point is ON the boundary edge --- + if (p2d_same(p0, p) || p2d_same(p1, p) || p2d_same(p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // Calculate some important pieces + radius = lw_arc_center(p0, p1, p2, ¢er); + + d = distance2d_pt_pt(p, ¢er); + if (FP_EQUALS(d, radius) && lw_pt_in_arc(p, p0, p1, p2)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // --- Step 2: Perform the Ray Casting intersection test --- + + // Only process arcs that our ray crosses + lw_arc_calculate_gbox_cartesian_2d(p0, p1, p2, &gbox); + if ((gbox.ymin <= py) && (py < gbox.ymax)) + { + // Point of intersection on the circle that defines the arc + POINT2D i0, i1; + + // How many points of intersection are there + int iCount = circle_raycast_intersections(¢er, radius, py, &i0, &i1); + + // Nothing to see here + if (iCount == 0) + continue; + + // Cannot think of a case where a grazing is not a + // no-op + if (iCount == 1) + continue; + + // So we must have 2 intersections + // Only increment the counter for intersections to the right + // of the test point + if (i0.x > px && lw_pt_in_arc(&i0, p0, p1, p2)) + intersections++; + + if (i1.x > px && lw_pt_in_arc(&i1, p0, p1, p2)) + intersections++; + } + } + + return intersections; +} + +/* + * The following is based on the "Fast Winding Number Inclusion of a Point + * in a Polygon" algorithm by Dan Sunday. + * http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number + * + * Return: + * - LW_INSIDE (1) if the point is inside the POINTARRAY + * - LW_BOUNDARY (0) if it is on the boundary. + * - LW_OUTSIDE (-1) if it is outside + */ +int +ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) +{ + const POINT2D *seg1, *seg2; + int wn = 0; + + seg1 = getPoint2d_cp(pa, 0); + seg2 = getPoint2d_cp(pa, pa->npoints-1); + + if (!p2d_same(seg1, seg2)) + lwerror("ptarray_contains_point called on unclosed ring"); + + for (uint32_t i = 1; i < pa->npoints; i++) + { + double side, ymin, ymax; + + seg2 = getPoint2d_cp(pa, i); + + /* Zero length segments are ignored. */ + if (p2d_same(seg1, seg2)) + { + seg1 = seg2; + continue; + } + + ymin = FP_MIN(seg1->y, seg2->y); + ymax = FP_MAX(seg1->y, seg2->y); + /* Only test segments in our vertical range */ if ( pt->y > ymax || pt->y < ymin ) { @@ -833,18 +1105,7 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec seg1 = seg2; } - /* Sent out the winding number for calls that are building on this as a primitive */ - if ( winding_number ) - *winding_number = wn; - - /* Outside */ - if (wn == 0) - { - return LW_OUTSIDE; - } - - /* Inside */ - return LW_INSIDE; + return (wn == 0) ? LW_OUTSIDE : LW_INSIDE; } /** @@ -859,160 +1120,16 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarrayarc_contains_point_partial(pa, pt, LW_TRUE /* Check closed*/, NULL); -} + int on_boundary = LW_FALSE; + int intersections; + if (!ptarray_is_closed_2d(pa)) + lwerror("%s called on unclosed ring", __func__); -int -ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number) -{ - int wn = 0; - uint32_t i; - int side; - const POINT2D *seg1; - const POINT2D *seg2; - const POINT2D *seg3; - GBOX gbox; - - /* Check for not an arc ring (always have odd # of points) */ - if ( (pa->npoints % 2) == 0 ) - { - lwerror("ptarrayarc_contains_point called with even number of points"); - return LW_OUTSIDE; - } - - /* Check for not an arc ring (always have >= 3 points) */ - if ( pa->npoints < 3 ) - { - lwerror("ptarrayarc_contains_point called too-short pointarray"); - return LW_OUTSIDE; - } - - /* Check for unclosed case */ - seg1 = getPoint2d_cp(pa, 0); - seg3 = getPoint2d_cp(pa, pa->npoints-1); - if ( check_closed && ! p2d_same(seg1, seg3) ) - { - lwerror("ptarrayarc_contains_point called on unclosed ring"); - return LW_OUTSIDE; - } - /* OK, it's closed. Is it just one circle? */ - else if ( p2d_same(seg1, seg3) && pa->npoints == 3 ) - { - double radius, d; - POINT2D c; - seg2 = getPoint2d_cp(pa, 1); - - /* Wait, it's just a point, so it can't contain anything */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - return LW_OUTSIDE; - - /* See if the point is within the circle radius */ - radius = lw_arc_center(seg1, seg2, seg3, &c); - d = distance2d_pt_pt(pt, &c); - if ( FP_EQUALS(d, radius) ) - return LW_BOUNDARY; /* Boundary of circle */ - else if ( d < radius ) - return LW_INSIDE; /* Inside circle */ - else - return LW_OUTSIDE; /* Outside circle */ - } - else if ( p2d_same(seg1, pt) || p2d_same(seg3, pt) ) - { - return LW_BOUNDARY; /* Boundary case */ - } - - /* Start on the ring */ - seg1 = getPoint2d_cp(pa, 0); - for ( i=1; i < pa->npoints; i += 2 ) - { - seg2 = getPoint2d_cp(pa, i); - seg3 = getPoint2d_cp(pa, i+1); - - /* Catch an easy boundary case */ - if( p2d_same(seg3, pt) ) - return LW_BOUNDARY; - - /* Skip arcs that have no size */ - if ( lw_arc_is_pt(seg1, seg2, seg3) ) - { - seg1 = seg3; - continue; - } - - /* Only test segments in our vertical range */ - lw_arc_calculate_gbox_cartesian_2d(seg1, seg2, seg3, &gbox); - if ( pt->y > gbox.ymax || pt->y < gbox.ymin ) - { - seg1 = seg3; - continue; - } - - /* Outside of horizontal range, and not between end points we also skip */ - if ( (pt->x > gbox.xmax || pt->x < gbox.xmin) && - (pt->y > FP_MAX(seg1->y, seg3->y) || pt->y < FP_MIN(seg1->y, seg3->y)) ) - { - seg1 = seg3; - continue; - } - - side = lw_arc_side(seg1, seg2, seg3, pt); - - /* On the boundary */ - if ( (side == 0) && lw_pt_in_arc(pt, seg1, seg2, seg3) ) - { - return LW_BOUNDARY; - } - - /* Going "up"! Point to left of arc. */ - if ( side < 0 && (seg1->y <= pt->y) && (pt->y < seg3->y) ) - { - wn++; - } - - /* Going "down"! */ - if ( side > 0 && (seg3->y <= pt->y) && (pt->y < seg1->y) ) - { - wn--; - } - - /* Inside the arc! */ - if ( pt->x <= gbox.xmax && pt->x >= gbox.xmin ) - { - POINT2D C; - double radius = lw_arc_center(seg1, seg2, seg3, &C); - double d = distance2d_pt_pt(pt, &C); - - /* On the boundary! */ - if ( d == radius ) - return LW_BOUNDARY; - - /* Within the arc! */ - if ( d < radius ) - { - /* Left side, increment winding number */ - if ( side < 0 ) - wn++; - /* Right side, decrement winding number */ - if ( side > 0 ) - wn--; - } - } - - seg1 = seg3; - } - - /* Sent out the winding number for calls that are building on this as a primitive */ - if ( winding_number ) - *winding_number = wn; - - /* Outside */ - if (wn == 0) - { - return LW_OUTSIDE; - } - - /* Inside */ - return LW_INSIDE; + intersections = ptarrayarc_raycast_intersections(pa, pt, &on_boundary); + if (on_boundary) + return LW_BOUNDARY; + else + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } /** ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + liblwgeom/cunit/cu_measures.c | 33 +++ liblwgeom/cunit/cu_ptarray.c | 42 ++-- liblwgeom/liblwgeom_internal.h | 4 +- liblwgeom/lwalgorithm.c | 26 ++- liblwgeom/lwcompound.c | 82 +++---- liblwgeom/measures.c | 508 +++++++++++++++++++---------------------- liblwgeom/ptarray.c | 405 ++++++++++++++++++++------------ 8 files changed, 610 insertions(+), 491 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 2 14:20:07 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 02 Oct 2025 21:20:07 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.edf10a9b6c22119deb5b19525bb65b66@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"8dc414411446c0d8a711a0c565c29ff1c2028fd6/git" 8dc4144/git]: {{{#!CommitTicketReference repository="git" revision="8dc414411446c0d8a711a0c565c29ff1c2028fd6" Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 2 14:21:35 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 02 Oct 2025 21:21:35 -0000 Subject: [PostGIS] #1195: CopyTopologyLayer In-Reply-To: <046.e952a8fc537adea5cf71ad296f52ee27@osgeo.org> References: <046.e952a8fc537adea5cf71ad296f52ee27@osgeo.org> Message-ID: <061.67aa981007b7ca3fb70416b0b2c4046c@osgeo.org> #1195: CopyTopologyLayer --------------------------+----------------------------- Reporter: robe | Owner: strk Type: enhancement | Status: new Priority: medium | Milestone: PostGIS Fund Me Component: topology | Version: master Resolution: | Keywords: usability --------------------------+----------------------------- Changes (by francoisb): * cc: francoisb (added) -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 2 14:53:02 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 02 Oct 2025 21:53:02 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.1f41ce7b56cc9e8f97932ff23e3ca07b@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed Comment: Patch applied back to 3.3 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 2 15:02:43 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 15:02:43 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-77-gdb3ade430 Message-ID: <20251002220244.47C2816EC63@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via db3ade4307c67561e7a59eb9c9badd1117dd1010 (commit) via c5b7ca28fddd59b3af2f3fff5ff1f5624531f970 (commit) from dc860997c4d074ad8ca11e5f1c53aec7254d8ff0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit db3ade4307c67561e7a59eb9c9badd1117dd1010 Merge: dc860997c c5b7ca28f Author: Paul Ramsey Date: Thu Oct 2 15:02:37 2025 -0700 Merge branch 'ProjectMutilation-fix-typo' commit c5b7ca28fddd59b3af2f3fff5ff1f5624531f970 Author: Maksim Korotkov Date: Thu Oct 2 13:52:26 2025 +0300 Fix NULL-pointer checks for gaztab and rultab in GetStdFromPortalCache Bad copy paste was potential reason of NULL pointer dereference Found by Svace static analyzer. Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/std_pg_hash.c b/extensions/address_standardizer/std_pg_hash.c index 17f5e772e..63f490415 100644 --- a/extensions/address_standardizer/std_pg_hash.c +++ b/extensions/address_standardizer/std_pg_hash.c @@ -251,8 +251,8 @@ GetStdFromPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, cha for (i=0; iStdCache[i]; if (ci->lextab && !strcmp(ci->lextab, lextab) && - ci->lextab && !strcmp(ci->gaztab, gaztab) && - ci->lextab && !strcmp(ci->rultab, rultab)) + ci->gaztab && !strcmp(ci->gaztab, gaztab) && + ci->rultab && !strcmp(ci->rultab, rultab)) return STDCache->StdCache[i].std; } ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/std_pg_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 15:03:52 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 15:03:52 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-12-gbaaca3530 Message-ID: <20251002220352.E362C16F7FC@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via baaca3530e5918e2b8392905ad2282c00ef2d4fb (commit) from be2a0ffda5b08dca0d94c1498d84b62b83fe76f9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit baaca3530e5918e2b8392905ad2282c00ef2d4fb Author: Maksim Korotkov Date: Thu Oct 2 13:52:26 2025 +0300 Fix NULL-pointer checks for gaztab and rultab in GetStdFromPortalCache Bad copy paste was potential reason of NULL pointer dereference Found by Svace static analyzer. Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/std_pg_hash.c b/extensions/address_standardizer/std_pg_hash.c index 17f5e772e..63f490415 100644 --- a/extensions/address_standardizer/std_pg_hash.c +++ b/extensions/address_standardizer/std_pg_hash.c @@ -251,8 +251,8 @@ GetStdFromPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, cha for (i=0; iStdCache[i]; if (ci->lextab && !strcmp(ci->lextab, lextab) && - ci->lextab && !strcmp(ci->gaztab, gaztab) && - ci->lextab && !strcmp(ci->rultab, rultab)) + ci->gaztab && !strcmp(ci->gaztab, gaztab) && + ci->rultab && !strcmp(ci->rultab, rultab)) return STDCache->StdCache[i].std; } ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/std_pg_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 15:04:04 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 15:04:04 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-63-g1c88b96de Message-ID: <20251002220404.44D8B16FD80@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 1c88b96de3d387aea45d47f53f0ac8f0be6ee813 (commit) from ae2d86d16b3ebf9f69baf1429fe4be6ab1bcf1cf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1c88b96de3d387aea45d47f53f0ac8f0be6ee813 Author: Maksim Korotkov Date: Thu Oct 2 13:52:26 2025 +0300 Fix NULL-pointer checks for gaztab and rultab in GetStdFromPortalCache Bad copy paste was potential reason of NULL pointer dereference Found by Svace static analyzer. Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/std_pg_hash.c b/extensions/address_standardizer/std_pg_hash.c index 17f5e772e..63f490415 100644 --- a/extensions/address_standardizer/std_pg_hash.c +++ b/extensions/address_standardizer/std_pg_hash.c @@ -251,8 +251,8 @@ GetStdFromPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, cha for (i=0; iStdCache[i]; if (ci->lextab && !strcmp(ci->lextab, lextab) && - ci->lextab && !strcmp(ci->gaztab, gaztab) && - ci->lextab && !strcmp(ci->rultab, rultab)) + ci->gaztab && !strcmp(ci->gaztab, gaztab) && + ci->rultab && !strcmp(ci->rultab, rultab)) return STDCache->StdCache[i].std; } ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/std_pg_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 15:04:10 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 15:04:10 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-56-gceb807b1c Message-ID: <20251002220410.9ED5916FA37@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via ceb807b1c4ebd8c00179707738aad8fc09f490d1 (commit) from 8dc414411446c0d8a711a0c565c29ff1c2028fd6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ceb807b1c4ebd8c00179707738aad8fc09f490d1 Author: Maksim Korotkov Date: Thu Oct 2 13:52:26 2025 +0300 Fix NULL-pointer checks for gaztab and rultab in GetStdFromPortalCache Bad copy paste was potential reason of NULL pointer dereference Found by Svace static analyzer. Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/std_pg_hash.c b/extensions/address_standardizer/std_pg_hash.c index a800a0d8e..9b6d6af1c 100644 --- a/extensions/address_standardizer/std_pg_hash.c +++ b/extensions/address_standardizer/std_pg_hash.c @@ -251,8 +251,8 @@ GetStdFromPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, cha for (i=0; iStdCache[i]; if (ci->lextab && !strcmp(ci->lextab, lextab) && - ci->lextab && !strcmp(ci->gaztab, gaztab) && - ci->lextab && !strcmp(ci->rultab, rultab)) + ci->gaztab && !strcmp(ci->gaztab, gaztab) && + ci->rultab && !strcmp(ci->rultab, rultab)) return STDCache->StdCache[i].std; } ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/std_pg_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 2 15:06:40 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 2 Oct 2025 15:06:40 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.7-58-g9c7b4d441 Message-ID: <20251002220640.4632916FD15@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via 9c7b4d441b4470dbaef1ca869ee2eeb0f7d59bed (commit) from a46aac3edc1303b27c94c7a630e559c59bbcde8c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9c7b4d441b4470dbaef1ca869ee2eeb0f7d59bed Author: Maksim Korotkov Date: Thu Oct 2 13:52:26 2025 +0300 Fix NULL-pointer checks for gaztab and rultab in GetStdFromPortalCache Bad copy paste was potential reason of NULL pointer dereference Found by Svace static analyzer. Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/std_pg_hash.c b/extensions/address_standardizer/std_pg_hash.c index a800a0d8e..9b6d6af1c 100644 --- a/extensions/address_standardizer/std_pg_hash.c +++ b/extensions/address_standardizer/std_pg_hash.c @@ -251,8 +251,8 @@ GetStdFromPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, cha for (i=0; iStdCache[i]; if (ci->lextab && !strcmp(ci->lextab, lextab) && - ci->lextab && !strcmp(ci->gaztab, gaztab) && - ci->lextab && !strcmp(ci->rultab, rultab)) + ci->gaztab && !strcmp(ci->gaztab, gaztab) && + ci->rultab && !strcmp(ci->rultab, rultab)) return STDCache->StdCache[i].std; } ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/std_pg_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Oct 3 08:47:57 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 3 Oct 2025 08:47:57 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-78-g455756d75 Message-ID: <20251003154758.1D0811908DF@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 455756d75996961f41b0bc5404b2f2daffb41f44 (commit) from db3ade4307c67561e7a59eb9c9badd1117dd1010 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 455756d75996961f41b0bc5404b2f2daffb41f44 Author: Denys Kovshun Date: Fri Oct 3 14:45:16 2025 +0000 Translated PostGIS Manual using Weblate (Ukrainian) Currently translated at 64.0% (3749 of 5857 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/uk/ diff --git a/doc/po/uk/postgis-manual.po b/doc/po/uk/postgis-manual.po index 24ad6835e..83bb630d2 100644 --- a/doc/po/uk/postgis-manual.po +++ b/doc/po/uk/postgis-manual.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-08-21 03:28+0000\n" -"PO-Revision-Date: 2025-09-21 01:47+0000\n" +"PO-Revision-Date: 2025-10-03 15:47+0000\n" "Last-Translator: Denys Kovshun \n" "Language-Team: Ukrainian \n" @@ -30853,6 +30853,11 @@ msgid "" "a new raster with the same size, alignment and SRID. If srid is left out, " "the spatial ref is set to unknown (0)." msgstr "" +"???????? ???????? ????? (??? ???????) ??????? ???????? (?????? ? ??????), " +"????????? ?????? ???? X ? Y, ??????? ??????? ? ???????? (scalex, scaley, " +"skewx ? skewy) ?? ??????? ????????? (srid). ???? ???????? ?????, ???????? " +"????? ????? ? ??? ????? ????????, ????????????? ?? SRID. ???? srid ?? " +"???????, ?????????? ??????? ????????? ?????????????? ?? ???????? (0)." #. Tag: para #, no-c-format @@ -30862,6 +30867,10 @@ msgid "" "X (upperleftx), upper left Y (upperlefty), pixel size and rotation (scalex, " "scaley, skewx & skewy) and reference system (srid)." msgstr "" +"???????? ???????? ????? (??? ??????) ??????? ???????? (?????? ?? ??????) ? " +"?????????????? ? ??????????? (??? ????????) ??????????? ? ??????? ????? X " +"(upperleftx), ??????? ????? Y (upperlefty), ???????? ??????? ?? ?????????? (" +"scalex, scaley, skewx ?? skewy) ? ??????? ????????? (srid)." #. Tag: para #, no-c-format @@ -30870,6 +30879,10 @@ msgid "" "(pixelsize). scalex is set to this argument and scaley is set to the " "negative value of this argument. skewx and skewy are set to 0." msgstr "" +"? ???????? ?????? ??? ?????????? ??????? ??????? (pixelsize) " +"???????????????? ?????? ????????. scalex ?????????????? ?? ???????? ????? " +"?????????, ? scaley ? ?? ???'???? ???????? ????? ?????????. skewx ? skewy " +"?????????????? ?? 0." #. Tag: para #, no-c-format @@ -30877,6 +30890,8 @@ msgid "" "If an existing raster is passed in, it returns a new raster with the same " "meta data settings (without the bands)." msgstr "" +"???? ??????????? ???????? ?????, ??? ???????? ????? ????? ? ???? ? " +"?????????????? ????????? (??? ???????)." #. Tag: para #, no-c-format @@ -30886,6 +30901,11 @@ msgid "" "linkend=\"RT_ST_AddBand\"/> to define bands and to set initial pixel values." msgstr "" +"???? srid ?? ???????, ?? ????????????? ???????????????? ???????? 0. ????? " +"????????? ?????????? ?????? ??, ????????, ???????? ?????? ?? ????? ?????? ?, " +"???????, ????????????? ????. ???????? ??? " +"?????????? ??????? ? ??? ???????????? " +"?????????? ??????? ????????." #. Tag: para #, no-c-format @@ -30894,6 +30914,9 @@ msgid "" ", , , , " msgstr "" +", , , " +", , , , " #. Tag: refpurpose #, no-c-format @@ -30901,6 +30924,8 @@ msgid "" "Returns a set of rasters resulting from the split of the input " "raster based upon the desired dimensions of the output rasters." msgstr "" +"???????? ????? ???????, ????????? ? ?????????? ?????????? " +"???????? ?????? ?? ?????? ??????? ???????? ???????? ???????." #. Tag: para #, no-c-format @@ -30908,6 +30933,8 @@ msgid "" "Returns a set of rasters resulting from the split of the input raster " "based upon the desired dimensions of the output rasters." msgstr "" +"???????? ????? ???????, ????????? ? ?????????? ?????????? ???????? " +"?????? ?? ?????? ??????? ???????? ???????? ???????." #. Tag: para #, no-c-format @@ -30919,6 +30946,12 @@ msgid "" "NODATA values. If raster band(s) do not have NODATA value(s) specified, one " "can be specified by setting nodataval." msgstr "" +"???? padwithnodata = FALSE, ?????? ?????? ? ??????? ?? " +"???????? ????? ?????? ?????? ???? ???? ???????, ??? ????? ??????. ???? " +"padwithnodata = TRUE, ??? ?????? ???????? ???????? " +"???????, ??? ????? ?????? ?????? ?????? ???? ????????? ?????????? NODATA. " +"???? ??? ????????? ???? ?? ??????? ???????? NODATA, ???? ????? ???????, " +"??????????? nodataval." #. Tag: para #, no-c-format @@ -30926,17 +30959,21 @@ msgid "" "If a specified band of the input raster is out-of-db, the corresponding band " "in the output rasters will also be out-of-db." msgstr "" +"???? ???????? ???????? ???????? ?????? ??????????? ???? ?????? ???? ?????, " +"??????????? ???????? ? ???????? ??????? ????? ???? ???? ?????? ???? ?????." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "" "Return a set of configured tiles from an arbitrarily tiled raster coverage." msgstr "" +"????????? ????? ???????????? ?????? ? ???????? ????????? ?? ?????? " +"?????????? ????????." #. Tag: para #, no-c-format @@ -30947,11 +30984,16 @@ msgid "" "data coming from the specified raster coverage (tab, " "col)." msgstr "" +"????????? ????? ?????? ?? ??????? ????????? (sfx, " +"sfy) ? ???????????? ?????? (tw, " +"th), ?? ?????????? ??????? ????? (ext) " +"? ??????, ?? ????????? ?? ????????? ?????????? ???????? (tab, col)." #. Tag: refpurpose #, no-c-format msgid "Returns a raster from a supported GDAL raster file." -msgstr "" +msgstr "???????? ????? ?? ?????????????? ????? ?????? GDAL." #. Tag: para #, no-c-format @@ -30959,6 +31001,8 @@ msgid "" "Returns a raster from a supported GDAL raster file. gdaldata is of type bytea and should be the contents of the GDAL raster file." msgstr "" +"???????? ????? ?? ?????????????? ????? ?????? GDAL. gdaldata ??? ??? bytea ? ??????? ??????? ????? ????? ?????? GDAL." #. Tag: para #, no-c-format @@ -30967,11 +31011,14 @@ msgid "" "assign the SRID from the GDAL raster. If srid is " "provided, the value provided will override any automatically assigned SRID." msgstr "" +"???? srid ??? ???????? NULL, ??????? ??????? ??????????? " +"?????????? SRID ? ?????? GDAL. ???? srid ???????, ?????? " +"???????? ???????? ????-???? ??????????? ??????????? SRID." #. Tag: title #, no-c-format msgid "Raster Accessors" -msgstr "" +msgstr "???????? ????????" #. Tag: refpurpose #, no-c-format @@ -30979,6 +31026,8 @@ msgid "" "Returns the georeference meta data in GDAL or ESRI format as commonly seen " "in a world file. Default is GDAL." msgstr "" +"???????? ???????? ????????????? ? ??????? GDAL ??? ESRI, ?? ?? ???????? " +"????????????? ? ????????? ?????. ?? ????????????? ???????????????? GDAL." #. Tag: para #, no-c-format @@ -30988,36 +31037,40 @@ msgid "" "World_file\">world file. Default is GDAL if no type specified. type " "is string 'GDAL' or 'ESRI'." msgstr "" +"???????? ???????? ?????????????, ????????? ?????????? ???????, ? ??????? " +"GDAL ??? ESRI, ?? ?? ???????? ?????? ? ????? world. ?? ????????????? ???????????????? " +"GDAL, ???? ??? ?? ???????. ??? ? ?? ????? ?GDAL? ??? ?ESRI?." #. Tag: para #, no-c-format msgid "Difference between format representations is as follows:" -msgstr "" +msgstr "??????? ??? ????????? ????????????? ??????? ? ??????????:" #. Tag: para #, no-c-format msgid "GDAL:" -msgstr "" +msgstr "GDAL:" #. Tag: para #, no-c-format msgid "ESRI:" -msgstr "" +msgstr "ESRI:" #. Tag: para #, no-c-format msgid ", , " -msgstr "" +msgstr ", , " #. Tag: refpurpose #, no-c-format msgid "Returns the height of the raster in pixels." -msgstr "" +msgstr "???????? ?????? ?????? ? ????????." #. Tag: para #, no-c-format msgid "Returns the height of the raster." -msgstr "" +msgstr "???????? ?????? ??????." #. Tag: refpurpose #, no-c-format @@ -31025,6 +31078,8 @@ msgid "" "Returns true if the raster is empty (width = 0 and height = 0). " "Otherwise, returns false." msgstr "" +"???????? ???????? true, ???? ????? ???????? (?????? = 0 ? ?????? " +"= 0). ? ?????? ??????? ???????? ???????? false." #. Tag: para #, no-c-format @@ -31032,6 +31087,8 @@ msgid "" "Returns true if the raster is empty (width = 0 and height = 0). " "Otherwise, returns false." msgstr "" +"???????? ???????? true, ???? ????? ???????? (?????? = 0 ? ?????? = 0). " +"? ?????? ??????? ???????? ???????? false." #. Tag: refpurpose #, no-c-format @@ -31039,11 +31096,13 @@ msgid "" "Returns the amount of space (in bytes) the raster takes." msgstr "" +"???????? ????? ???????? (? ??????), ???? ?????? " +"?????." #. Tag: para #, no-c-format msgid "Returns the amount of space (in bytes) the raster takes." -msgstr "" +msgstr "???????? ????? ???????? (? ??????), ???? ?????? ?????." #. Tag: para #, no-c-format @@ -31051,6 +31110,8 @@ msgid "" "This is a nice compliment to PostgreSQL built in functions pg_column_size, " "pg_size_pretty, pg_relation_size, pg_total_relation_size." msgstr "" +"?? ????? ?????????? ?? ?????????? ??????? PostgreSQL pg_column_size, " +"pg_size_pretty, pg_relation_size, pg_total_relation_size." #. Tag: para #, no-c-format @@ -31060,6 +31121,11 @@ msgid "" "table contribution and large geometries are stored in TOAST tables. " "pg_column_size might return lower because it returns the compressed size." msgstr "" +"pg_relation_size, ?? ???????? ?????? ??????? ? ??????, ???? ????????? " +"??????, ?????? ?? ST_MemSize. ?? ???'????? ? ???, ?? pg_relation_size ?? " +"????? ?????? ?????????? ???????, ? ?????? ????????? ???????????? ? ???????? " +"TOAST. pg_column_size ???? ????????? ?????? ??????, ???????? ??? ???????? " +"??????? ??????." #. Tag: refpurpose #, no-c-format @@ -31067,6 +31133,8 @@ msgid "" "Returns basic meta data about a raster object such as pixel size, rotation " "(skew), upper, lower left, etc." msgstr "" +"???????? ??????? ???????? ??? ????????? ??'???, ???? ?? ?????? ???????, " +"??????? (???????), ???????, ?????? ????? ??? ????." #. Tag: para #, no-c-format @@ -31075,28 +31143,35 @@ msgid "" "(skew), upper, lower left, etc. Columns returned: upperleftx | upperlefty | " "width | height | scalex | scaley | skewx | skewy | srid | numbands" msgstr "" +"???????? ??????? ???????? ??? ????????? ??'???, ???? ?? ?????? ???????, " +"??????? (???????), ???????, ?????? ????? ??? ????. ???????????? ???????: " +"upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | " +"srid | numbands" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "" "Returns the number of bands in the raster object." msgstr "" +"???????? ????????? ??????? ? ?????????? ??'????." #. Tag: para #, no-c-format msgid "Returns the number of bands in the raster object." -msgstr "" +msgstr "???????? ????????? ??????? ? ?????????? ??'????." #. Tag: refpurpose #, no-c-format msgid "" "Returns the pixel height in geometric units of the spatial reference system." msgstr "" +"???????? ?????? ??????? ? ???????????? ???????? ??????????? ??????? " +"?????????." #. Tag: para #, no-c-format @@ -31105,6 +31180,10 @@ msgid "" "system. In the common case where there is no skew, the pixel height is just " "the scale ratio between geometric coordinates and raster pixels." msgstr "" +"???????? ?????? ??????? ? ???????????? ???????? ??????????? ??????? " +"?????????. ? ?????????? ???????, ???? ????? ??????, ?????? ??????? ???????? " +"?????????????? ???????? ??? ????????????? ???????????? ?? ?????????? " +"?????????." #. Tag: para #, no-c-format @@ -31112,16 +31191,18 @@ msgid "" "Refer to for a diagrammatic " "visualization of the relationship." msgstr "" +"???????? ??? ???????????? ?????????? " +"????? ????????'????." #. Tag: title #, no-c-format msgid "Examples: Rasters with no skew" -msgstr "" +msgstr "????????: ?????? ??? ??????" #. Tag: title #, no-c-format msgid "Examples: Rasters with skew different than 0" -msgstr "" +msgstr "????????: ??????? ? ???????, ????????? ??? 0" #. Tag: para #, no-c-format @@ -31129,12 +31210,16 @@ msgid "" ", , , , " msgstr "" +", , , , " #. Tag: refpurpose #, no-c-format msgid "" "Returns the pixel width in geometric units of the spatial reference system." msgstr "" +"???????? ?????? ??????? ? ???????????? ???????? ??????????? ??????? " +"?????????." #. Tag: para #, no-c-format @@ -31143,28 +31228,32 @@ msgid "" "system. In the common case where there is no skew, the pixel width is just " "the scale ratio between geometric coordinates and raster pixels." msgstr "" +"???????? ?????? ??????? ? ???????????? ???????? ??????????? ??????? " +"?????????. ? ?????????? ???????, ???? ????? ??????, ?????? ??????? ???????? " +"?????????????? ???????? ??? ????????????? ???????????? ?? ?????????? " +"?????????." #. Tag: para #, no-c-format msgid "The following diagram demonstrates the relationship:" -msgstr "" +msgstr "???????? ???????? ???????? ????????'????:" #. Tag: para #, no-c-format msgid "Pixel Height: Pixel size in the j direction" -msgstr "" +msgstr "?????? ???????: ?????? ??????? ? ???????? j" #. Tag: para #, no-c-format msgid "Pixel Width: Pixel size in the i direction" -msgstr "" +msgstr "?????? ???????: ?????? ??????? ? ???????? i" #. Tag: refpurpose #, no-c-format msgid "" "Returns the X component of the pixel width in units of coordinate reference " "system." -msgstr "" +msgstr "???????? X-?????????? ?????? ??????? ? ???????? ??????? ?????????." #. Tag: para #, no-c-format @@ -31173,18 +31262,21 @@ msgid "" "system. Refer to World File for more details." msgstr "" +"???????? ????????? X ?????? ??????? ? ???????? ??????? ?????????. ?????????? " +"?????????? ???. ? World File." #. Tag: para #, no-c-format msgid "Changed: 2.0.0. In WKTRaster versions this was called ST_PixelSizeX." -msgstr "" +msgstr "???????: 2.0.0. ? ??????? WKTRaster ?? ?????????? ST_PixelSizeX." #. Tag: refpurpose #, no-c-format msgid "" "Returns the Y component of the pixel height in units of coordinate reference " "system." -msgstr "" +msgstr "???????? ????????? Y ?????? ??????? ? ???????? ??????? ?????????." #. Tag: para #, no-c-format @@ -31193,11 +31285,14 @@ msgid "" "system. May be negative. Refer to World File for more details." msgstr "" +"???????? ????????? Y ?????? ??????? ? ???????? ??????? ?????????. ???? ???? " +"???'?????. ?????????? ?????????? ???. ? World File." #. Tag: para #, no-c-format msgid "Changed: 2.0.0. In WKTRaster versions this was called ST_PixelSizeY." -msgstr "" +msgstr "???????: 2.0.0. ? ??????? WKTRaster ?? ?????????? ST_PixelSizeY." #. Tag: refpurpose #, no-c-format @@ -31205,6 +31300,9 @@ msgid "" "Returns the raster's upper left corner as geometric X and Y (longitude and " "latitude) given a column and row. Column and row starts at 1." msgstr "" +"???????? ??????? ????? ??? ?????? ? ??????? ???????????? ????????? X ?? Y (" +"??????? ?? ??????) ?? ??????? ???????? ?? ??????. ???????? ?? ????? " +"??????????? ? 1." #. Tag: para #, no-c-format @@ -31778,6 +31876,10 @@ msgid "" "ST_BandFileTimestamp() so a client can determine if the filename of a outdb " "raster as seen by it is the same as the one seen by the server." msgstr "" +"?? ??????? ???????? ???????????????? ????? ?? ST_BandPath() ?? " +"ST_BandFileTimestamp(), ??? ?????? ??? ?????????, ?? ??'? ????? ?????????? " +"?????????? outdb, ??? ??? ??????, ?????????? ? ??'?? ?????, ??? ?????? " +"??????." #. Tag: refpurpose #, no-c-format @@ -31785,6 +31887,8 @@ msgid "" "Returns the file timestamp of a band stored in file system. If no bandnum " "specified, 1 is assumed." msgstr "" +"???????? ????? ???? ????? ?????, ?? ???????????? ? ???????? ???????. ???? " +"????? ????? ?? ???????, ??????????, ?? ??? ???????? 1." #. Tag: para #, no-c-format @@ -31793,6 +31897,9 @@ msgid "" "UTC) of a band stored in file system. Throws an error if called with an in " "db band, or if outdb access is not enabled." msgstr "" +"???????? ????? ???? ????? (????????? ?????? ? 1 ????? 1970 ???? 00:00:00 UTC)" +" ?????, ?? ???????????? ? ???????? ???????. ????? ???????, ???? ???????????? " +"?? ?????? ? ???? ????? ??? ???? ?????? outdb ?? ?????????." #. Tag: para #, no-c-format @@ -31801,6 +31908,10 @@ msgid "" "ST_BandFileSize() so a client can determine if the filename of a outdb " "raster as seen by it is the same as the one seen by the server." msgstr "" +"?? ??????? ???????? ???????????????? ????? ? ST_BandPath() ?? " +"ST_BandFileSize(), ??? ?????? ??? ?????????, ?? ??'? ????? ?????????? " +"?????????? outdb, ??? ??? ??????, ?????????? ? ??'?? ?????, ??? ?????? " +"??????." #. Tag: refpurpose #, no-c-format @@ -31808,6 +31919,8 @@ msgid "" "Returns the type of pixel for given band. If no bandnum specified, 1 is " "assumed." msgstr "" +"???????? ??? ??????? ??? ???????? ?????????. ???? ???????? ?? ???????, " +"??????????? ???????? 1." #. Tag: para #, no-c-format @@ -31815,77 +31928,83 @@ msgid "" "Returns name describing data type and size of values stored in each cell of " "given band." msgstr "" +"???????? ??'?, ?? ?????? ??? ????? ? ?????? ???????, ?? ???????????? ? " +"?????? ??????? ???????? ?????????." #. Tag: para #, no-c-format msgid "There are 11 pixel types. Pixel Types supported are as follows:" -msgstr "" +msgstr "????? 11 ????? ????????. ????????????? ???? ???? ????????:" #. Tag: para #, no-c-format msgid "1BB - 1-bit boolean" -msgstr "" +msgstr "1BB - 1-?????? ????????" #. Tag: para #, no-c-format msgid "2BUI - 2-bit unsigned integer" -msgstr "" +msgstr "2BUI - 2-????? ???? ????? ??? ?????" #. Tag: para #, no-c-format msgid "4BUI - 4-bit unsigned integer" -msgstr "" +msgstr "4BUI - 4-????? ???? ????? ??? ?????" #. Tag: para #, no-c-format msgid "8BSI - 8-bit signed integer" -msgstr "" +msgstr "8BSI ? 8-????? ???? ????? ?? ??????" #. Tag: para #, no-c-format msgid "8BUI - 8-bit unsigned integer" -msgstr "" +msgstr "8BUI ? 8-????? ???? ????? ??? ?????" #. Tag: para #, no-c-format msgid "16BSI - 16-bit signed integer" -msgstr "" +msgstr "16BSI ? 16-????? ???? ????? ?? ??????" #. Tag: para #, no-c-format msgid "16BUI - 16-bit unsigned integer" -msgstr "" +msgstr "16BUI ? 16-????? ???? ????? ??? ?????" #. Tag: para #, no-c-format msgid "32BSI - 32-bit signed integer" -msgstr "" +msgstr "32BSI ? 32-????? ???? ????? ??? ?????" #. Tag: para #, no-c-format msgid "32BUI - 32-bit unsigned integer" -msgstr "" +msgstr "32BUI ? 32-????? ???? ????? ??? ?????" #. Tag: para #, no-c-format msgid "32BF - 32-bit float" -msgstr "" +msgstr "32BF - 32-?????? ? ????????? ?????" #. Tag: para #, no-c-format msgid "64BF - 64-bit float" -msgstr "" +msgstr "64BF - 64-?????? ? ????????? ?????" #. Tag: refpurpose #, no-c-format msgid "" "Returns the minimum value this pixeltype can store." msgstr "" +"???????? ?????????? ????????, ??? ???? ????????? ??? ??? " +"????????." #. Tag: para #, no-c-format msgid "Returns the minimum value this pixeltype can store." msgstr "" +"???????? ?????????? ????????, ??? ???? ????????? ??? ??? " +"????????." #. Tag: refpurpose #, no-c-format @@ -31893,6 +32012,9 @@ msgid "" "Returns true if there is no band with given band number. If no " "band number is specified, then band number 1 is assumed." msgstr "" +"???????? ???????? true, ???? ????? ????????? ? ???????? ???????. " +"???? ????? ????????? ?? ???????, ?? ??????????, ?? ?? ???????? ? " +"1." #. Tag: para #, no-c-format @@ -31900,11 +32022,13 @@ msgid "" "Returns true if there is no band with given band number. If no band " "number is specified, then band number 1 is assumed." msgstr "" +"???????? ???????? true, ???? ????? ????????? ? ???????? ???????. ???? " +"????? ????????? ?? ???????, ?? ??????????, ?? ?? ???????? ? 1." #. Tag: title #, no-c-format msgid "Raster Pixel Accessors and Setters" -msgstr "" +msgstr "?????? ?? ????????? ???????? ?? ?? ????????????" #. Tag: refpurpose #, no-c-format @@ -31912,6 +32036,8 @@ msgid "" "Returns the polygon geometry that bounds the pixel for a " "particular row and column." msgstr "" +"???????? ????????? ????????, ?? ??????? ??????? ??? ??????? " +"????? ?? ???????." #. Tag: para #, no-c-format @@ -31919,6 +32045,8 @@ msgid "" "Returns the polygon geometry that bounds the pixel for a particular " "row and column." msgstr "" +"???????? ????????? ????????, ?? ??????? ??????? ??? ??????? ????? ?? " +"???????." #. Tag: para #, no-c-format @@ -31929,6 +32057,10 @@ msgid "" "linkend=\"RT_ST_PixelAsCentroids\"/>, , " msgstr "" +", , , , , , , " #. Tag: refpurpose #, no-c-format @@ -31936,6 +32068,8 @@ msgid "" "Returns the polygon geometry that bounds every pixel of a raster band along " "with the value, the X and the Y raster coordinates of each pixel." msgstr "" +"???????? ????????? ????????, ?? ??????? ????? ??????? ?????????? ??????, " +"????? ?? ?????????, X- ?? Y-???????????? ??????? ???????." #. Tag: para #, no-c-format @@ -31944,14 +32078,20 @@ msgid "" "with the value (double precision), the X and the Y raster coordinates " "(integers) of each pixel." msgstr "" +"???????? ????????? ????????, ?? ??????? ????? ??????? ?????????? ??????, " +"????? ?? ????????? (???????? ????????), X- ?? Y-???????????? ?????? (?????? " +"???????) ??????? ???????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Return record format: geom , val double precision, x " "integer, y integers." msgstr "" +"?????? ?????? ??????????: geom , val ???????? ????????, x " +"???? ?????, y ???? ?????." #. Tag: para #, no-c-format @@ -31959,6 +32099,8 @@ msgid "" "When exclude_nodata_value = TRUE, only those pixels " "whose values are not NODATA are returned as points." msgstr "" +"???? exclude_nodata_value = TRUE, ?? ????? " +"???????????? ?????? ?? ???????, ???????? ???? ?? ? NODATA." #. Tag: para #, no-c-format @@ -31967,16 +32109,19 @@ msgid "" "different than ST_DumpAsPolygons where each geometry represents one or more " "pixels with the same pixel value." msgstr "" +"ST_PixelAsPolygons ???????? ???? ????????? ???????? ??? ??????? ???????. ?? " +"????????????? ??? ST_DumpAsPolygons, ?? ????? ????????? ??????????? ???? ??? " +"?????? ???????? ? ????????? ????????? ???????." #. Tag: para #, no-c-format msgid "Enhanced: 2.1.0 exclude_nodata_value optional argument was added." -msgstr "" +msgstr "?????????: 2.1.0 ?????? ???????????? ???????? exclude_nodata_value." #. Tag: para #, no-c-format msgid "Changed: 2.1.1 Changed behavior of exclude_nodata_value." -msgstr "" +msgstr "???????: 2.1.1 ??????? ????????? exclude_nodata_value." #. Tag: para #, no-c-format @@ -31986,6 +32131,10 @@ msgid "" ", , " msgstr "" +", , , , , , " #. Tag: refpurpose #, no-c-format @@ -31993,11 +32142,13 @@ msgid "" "Returns a point geometry of the pixel's upper-left corner." msgstr "" +"???????? ????????? ????? ????????? ?????? ???? " +"???????." #. Tag: para #, no-c-format msgid "Returns a point geometry of the pixel's upper-left corner." -msgstr "" +msgstr "???????? ??????? ????????? ????????? ?????? ???? ???????." #. Tag: para #, no-c-format @@ -32007,6 +32158,10 @@ msgid "" ">, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -32016,6 +32171,10 @@ msgid "" "coordinates of the point geometry are of the pixel's upper-left corner." msgstr "" +"???????? ??????? ????????? ??? ??????? ??????? ?????????? " +"????????? ????? ?? ?????????, X- ?? Y-???????????? ??????? ???????. " +"?????????? ???????? ????????? ???????????? ????????? ?????? ???? " +"???????." #. Tag: para #, no-c-format @@ -32024,6 +32183,9 @@ msgid "" "the value, the X and the Y raster coordinates of each pixel. The coordinates " "of the point geometry are of the pixel's upper-left corner." msgstr "" +"???????? ??????? ????????? ??? ??????? ??????? ?????????? ????????? " +"????? ?? ?????????, X- ?? Y-???????????? ??????? ???????. ?????????? " +"???????? ????????? ???????????? ????????? ?????? ???? ???????." #. Tag: para #, no-c-format @@ -32033,6 +32195,10 @@ msgid "" ", " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -32040,6 +32206,8 @@ msgid "" "Returns the centroid (point geometry) of the area represented by " "a pixel." msgstr "" +"???????? ???????? (??????? ?????????) ???????, ????????????? " +"????????." #. Tag: para #, no-c-format @@ -32047,11 +32215,13 @@ msgid "" "Returns the centroid (point geometry) of the area represented by a " "pixel." msgstr "" +"???????? ???????? (??????? ?????????) ???????, ????????????? " +"????????." #. Tag: para #, no-c-format msgid "Enhanced: 3.2.0 Faster now implemented in C." -msgstr "" +msgstr "?????????: 3.2.0 ????? ?????? ??????????? ? C." #. Tag: para #, no-c-format @@ -32061,6 +32231,9 @@ msgid "" ", " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -32070,6 +32243,9 @@ msgid "" "The point geometry is the centroid of the area represented by a pixel." msgstr "" +"???????? ???????? ( ??????? ?????????) ??? ??????? ??????? " +"?????????? ?????? ????? ?? ?????????, X- ?? Y-???????????? ??????? ???????. " +"??????? ????????? ? ?? ???????? ???????, ????????????? ????????." #. Tag: para #, no-c-format @@ -32078,6 +32254,9 @@ msgid "" "along with the value, the X and the Y raster coordinates of each pixel. The " "point geometry is the centroid of the area represented by a pixel." msgstr "" +"???????? ???????? ( ??????? ?????????) ??? ??????? ??????? ?????????? " +"?????? ????? ?? ?????????, X- ?? Y-???????????? ??????? ???????. ??????? " +"????????? ? ?????????? ???????, ????????????? ????????.." #. Tag: para #, no-c-format @@ -32087,6 +32266,9 @@ msgid "" ", " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -32098,6 +32280,13 @@ msgid "" "intersect and return value. If exclude_nodata_value is " "not passed in then reads it from metadata of raster." msgstr "" +"???????? ???????? ???????? ?????? ? ???????? ??????? x, ????? y ??????? ??? " +"? ?????? ???????????? ?????. ?????? ???? ??????????? ? 1 ?, ???? ?? ???????, " +"??????????? ?? 1. ???? exclude_nodata_value ??????????? " +"?? false, ?? ??? ???????, ????????? ??????? nodata, " +"?????????? ??????????? ? ?????????? ????????. ???? " +"exclude_nodata_value ?? ????????, ?? ???? ?????????? ? " +"????????? ??????." #. Tag: para #, no-c-format @@ -32106,6 +32295,9 @@ msgid "" "given geometry point. Band numbers start at 1 and band is assumed to be 1 if " "not specified." msgstr "" +"???????? ???????? ???????? ?????? ? ???????? ??????? x, ????? y ??????? ??? " +"? ??????? ???????????? ?????. ?????? ?????????? ??????????? ? 1, ? ???? " +"???????? ?? ???????, ?? ??????????, ?? ??? ???????? 1." #. Tag: para #, no-c-format @@ -32115,6 +32307,10 @@ msgid "" "exclude_nodata_value is set to false, then all pixels are " "considered." msgstr "" +"???? exclude_nodata_value ??????????? ?? true, ?? " +"???????????? ?????? ???????, ?? ?? ? nodata. ???? " +"exclude_nodata_value ??????????? ?? false, ?? " +"???????????? ??? ???????." #. Tag: para #, no-c-format @@ -32125,16 +32321,21 @@ msgid "" "wiki/Bilinear_interpolation\">bilinear interpolation to estimate the " "value between pixel centers." msgstr "" +"??????????? ?????????? ????????? resample ? ?nearest?, ?? " +"??????? ?????????? ????????????? ?? ?????????? ???????, ?? ?bilinear?, ?? " +"??????? ????????? ???????????? ??? ?????? ???????? " +"??? ???????? ????????." #. Tag: para #, no-c-format msgid "Enhanced: 3.2.0 resample optional argument was added." -msgstr "" +msgstr "?????????: 3.2.0 ?????? ???????????? ???????? resample." #. Tag: para #, no-c-format msgid "Enhanced: 2.0.0 exclude_nodata_value optional argument was added." -msgstr "" +msgstr "?????????: 2.0.0 ?????? ???????????? ???????? exclude_nodata_value." #. Tag: para #, no-c-format @@ -32148,6 +32349,13 @@ msgid "" "linkend=\"ST_MakeEnvelope\"/>, , " msgstr "" +", , , , , , , " +", , " +", , , , , " #. Tag: refpurpose #, no-c-format @@ -32156,6 +32364,10 @@ msgid "" "pixel specified by a columnx and rowy or a geometric point expressed in the " "same spatial reference coordinate system as the raster." msgstr "" +"???????? ????????? ????????, ??? ?? ? NODATA, ??????? " +"???????? ?????????, ??????????? ???????? x ? ?????? y, ??? ???????????? " +"?????, ????????? ? ??? ????? ??????? ????????? ??????????? ????'????, ?? ? " +"?????." #. Tag: para #, no-c-format @@ -32166,6 +32378,12 @@ msgid "" "varname>, the function will find the nearest pixel to the columnx, rowy " "pixel or geometric point whose value is not NODATA." msgstr "" +"???????? ????????? ????????, ??? ?? ? NODATA, ???????? " +"????????? ? ???????? ??????? x, ????? y ??????? ??? ? ?????????? " +"???????????? ?????. ???? ???????? x, ????? y ??????? ??? ??????? ? ??????? " +"???????????? ????? ? NODATA, ??????? ?????? ?????????? " +"??????? ?? ??????? x, ????? y ??????? ??? ???????????? ?????, ???????? ????? " +"?? ? NODATA." #. Tag: para #, no-c-format @@ -32176,16 +32394,22 @@ msgid "" "intersect and return value. If exclude_nodata_value is " "not passed in then reads it from metadata of raster." msgstr "" +"?????? ???? ??????????? ? 1, ? ???? ?? ??????? ????, ?? bandnum ?????????? ?????? 1. ???? exclude_nodata_value " +"??????????? ?? false, ?? ??? ???????, ????????? ??????? nodata, ?????????? ??????????? ? ?????????? ????????. ???? " +"exclude_nodata_value ?? ???????????, ?? ???? ?????????? ? " +"????????? ??????." #. Tag: para #, no-c-format msgid "ST_NearestValue is a drop-in replacement for ST_Value." -msgstr "" +msgstr "ST_NearestValue ? ??????????? ??????? ??? ST_Value." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -32194,6 +32418,9 @@ msgid "" "values from the raster copied into the Z dimension using the requested " "resample algorithm." msgstr "" +"???????? ????????? ? ???? ?????? ???????????? X/Y, ?? ? ?????? ?????????, ?? " +"?????????? ? ??????, ????????????? ? ????? Z ?? ????????? ???????? ????????? " +"?????????????." #. Tag: para #, no-c-format @@ -32202,6 +32429,9 @@ msgid "" "values from the raster copied into the Z dimensions using the requested " "resample algorithm." msgstr "" +"???????? ????????? ? ???? ?????? ???????????? X/Y, ?? ? ?????? ?????????, ?? " +"?????????? ? ??????, ????????????? ? ????? Z ?? ????????? ???????? ????????? " +"?????????????." #. Tag: para #, no-c-format @@ -32212,11 +32442,16 @@ msgid "" "Bilinear_interpolation\">bilinear interpolation to calculate a value " "that takes neighboring cells into account also." msgstr "" +"???????? resample ????? ?????????? ?? ???????? ?nearest?, " +"??? ?????????? ???????? ? ???????, ? ??? ????????? ????? ???????, ??? " +"?bilinear?, ??? ??????????????? ????????? ???????????? ??? ?????????? " +"????????, ??? ????? ???????? ??????? ???????." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -32225,6 +32460,9 @@ msgid "" "values from the raster copied into the M dimension using the requested " "resample algorithm." msgstr "" +"???????? ????????? ? ???? ?????? ???????????? X/Y, ?? ? ?????? ?????????, ?? " +"?????????? ? ??????, ????????????? ? ??????????? M ?? ????????? ???????? " +"????????? ?????????????." #. Tag: para #, no-c-format @@ -32233,11 +32471,14 @@ msgid "" "values from the raster copied into the M dimensions using the requested " "resample algorithm." msgstr "" +"???????? ????????? ? ???? ?????? ???????????? X/Y, ?? ? ?????? ?????????, ?? " +"?????????? ? ??????, ????????????? ? M ?????? ?? ????????? ???????????? " +"????????? ?????????????." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -32247,6 +32488,10 @@ msgid "" "a geometric point expressed in the same spatial reference coordinate system " "as the raster." msgstr "" +"???????? ??????????? ????? ????????? ???????? ???????, ?? ?? ? " +"NODATA, ??????? ??????? ???????? ?????????, ??????????? " +"??? ????????X ? ??????Y, ??? ???????????? ??????, ????????? ? ??? ????? " +"??????? ????????? ??????????? ????'????, ?? ? ?????." #. Tag: para #, no-c-format @@ -32261,6 +32506,16 @@ msgid "" "interest. The center value of the 2-D array will be the value at the pixel " "specified by the columnX and rowY or the geometric point." msgstr "" +"???????? ??????????? ????? ????????? ???????? ???????, ?? ?? ? " +"NODATA, ??????? ??????? ???????? ?????????, ??????????? " +"??? ????????X ? ??????Y, ??? ???????????? ??????, ????????? ? ??? ????? " +"??????? ????????? ??????????? ????'????, ?? ? ?????. ????????? " +"distanceX ?? distanceY ?????????? " +"????????? ???????? ??????? ???????? ??????? ?? ???? X ?? Y, ?????????, ? " +"???? ???????? ??? ???????? ? ????? 3 ???????? ?? ??? X ?? 2 ???????? ?? ??? " +"Y ??????? ???????, ?? ???? ????????. ??????????? ????????? ???????????? " +"?????? ???? ???????? ? ???????, ????????? ???????? X ? ?????? Y, ??? " +"???????????? ??????." #. Tag: para #, no-c-format @@ -32270,6 +32525,10 @@ msgid "" "distanceX and distanceY of 1, the " "returning array will be 3x3." msgstr "" +"????????? ????????? ?????? ?????? ??? ???????????? ??????, ?? ????????????, " +"???????? 2 * (distanceX|distanceY) + " +"1. ????, ??? distanceX ? distanceY " +"?????? 1 ?????, ?? ????????????, ???? 3x3." #. Tag: para #, no-c-format @@ -32277,6 +32536,8 @@ msgid "" "The 2-D array output can be passed to any of the raster processing builtin " "functions, e.g. ST_Min4ma, ST_Sum4ma, ST_Mean4ma." msgstr "" +"??????? ???? ???????????? ?????? ????? ???????? ?? ????-???? ? ?????????? " +"??????? ??????? ????????? ?????, ????????? ST_Min4ma, ST_Sum4ma, ST_Mean4ma." #. Tag: para #, no-c-format @@ -32286,6 +32547,10 @@ msgid "" "linkend=\"RT_ST_Range4ma\"/>, , " msgstr "" +", , , , , , , " #. Tag: refpurpose #, no-c-format @@ -32294,6 +32559,10 @@ msgid "" "a given columnx, rowy pixel or the pixels that intersect a particular " "geometry. Band numbers start at 1 and assumed to be 1 if not specified." msgstr "" +"???????? ????????????? ?????, ????????? ? ?????????? ???????????? ???????? " +"???????? ?????? ? ???????? ??????? x, ????? y ??????? ??? ????????, ?? " +"??????????? ????? ?????????. ?????? ??????? ??????????? ? 1 ?, ???? ?? " +"??????? ????, ??????????? ?? 1." #. Tag: para #, no-c-format @@ -32302,6 +32571,10 @@ msgid "" "to new value for the designated band given the raster's row and column or a " "geometry. If no band is specified, then band 1 is assumed." msgstr "" +"???????? ????????????? ?????, ????????? ? ?????????? ???????????? ??????? " +"???????? ???????? ?? ???? ???????? ??? ???????????? ??????, ?????????? ????? " +"? ???????? ?????? ??? ?????????. ???? ????? ?? ???????, ?? ??????????, ?? ?? " +"???????? 1." #. Tag: para #, no-c-format @@ -32310,17 +32583,22 @@ msgid "" "type, not just point. The geometry variant is a wrapper around the geomval[] " "variant of ST_SetValues()" msgstr "" +"?????????: 2.1.0 ??????? ????????? ST_SetValue() ????? ????????? ????-???? " +"??? ?????????, ? ?? ?????? ?????. ??????? ????????? ? ????????? ??????? " +"???????? geomval[] ??????? ST_SetValues()" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "" "Returns modified raster resulting from setting the values of a given band." msgstr "" +"???????? ???????? ?????, ????????? ? ?????????? ???????????? ??????? " +"???????? ??????." #. Tag: para #, no-c-format @@ -32329,6 +32607,9 @@ msgid "" "value(s) for the designated band. columnx and " "rowy are 1-indexed." msgstr "" +"???????? ???????? ?????, ????????? ? ?????????? ???????????? ?????????? " +"???????? ?? ???? ???????? ??? ????????? ??????. columnx " +"?? rowy ???????????? ? 1." #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/uk/postgis-manual.po | 375 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 328 insertions(+), 47 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Oct 3 12:47:53 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 3 Oct 2025 12:47:53 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-80-gee5cb19e4 Message-ID: <20251003194753.E5D4E19533F@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via ee5cb19e43c1acfe1a9c6285a0402dccb3d7aa20 (commit) from 9492eba2e4d77cfaf591ff3a115d8c2350889bb2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ee5cb19e43c1acfe1a9c6285a0402dccb3d7aa20 Author: Denys Kovshun Date: Fri Oct 3 17:50:32 2025 +0000 Translated PostGIS Manual using Weblate (Ukrainian) Currently translated at 71.4% (4183 of 5857 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/uk/ diff --git a/doc/po/uk/postgis-manual.po b/doc/po/uk/postgis-manual.po index 46b60c2a2..9a257539d 100644 --- a/doc/po/uk/postgis-manual.po +++ b/doc/po/uk/postgis-manual.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-08-21 03:28+0000\n" -"PO-Revision-Date: 2025-10-03 17:47+0000\n" +"PO-Revision-Date: 2025-10-03 19:47+0000\n" "Last-Translator: Denys Kovshun \n" "Language-Team: Ukrainian \n" @@ -36698,12 +36698,14 @@ msgid "" "Raster processing function that calculates the standard deviation of pixel " "values in a neighborhood." msgstr "" +"??????? ??????? ??????, ??? ???????? ?????????? ?????????? ??????? ???????? " +"????????." #. Tag: para #, no-c-format msgid "" "Calculate the standard deviation of pixel values in a neighborhood of pixels." -msgstr "" +msgstr "????????? ?????????? ?????????? ??????? ???????? ? ???????? ????????." #. Tag: refpurpose #, no-c-format @@ -36711,11 +36713,12 @@ msgid "" "Raster processing function that calculates the sum of all pixel values in a " "neighborhood." msgstr "" +"??????? ??????? ??????, ??? ???????? ???? ???? ??????? ???????? ????????." #. Tag: para #, no-c-format msgid "Calculate the sum of all pixel values in a neighborhood of pixels." -msgstr "" +msgstr "????????? ???? ???? ??????? ???????? ? ???????? ????????." #. Tag: para #, no-c-format @@ -36725,11 +36728,15 @@ msgid "" "linkend=\"RT_ST_Range4ma\"/>, , " msgstr "" +", , , " +", , , , " #. Tag: title #, no-c-format msgid "Raster Processing: DEM (Elevation)" -msgstr "" +msgstr "???????? ???????: DEM (?????? ??? ?????? ????)" #. Tag: refpurpose #, no-c-format @@ -36737,6 +36744,8 @@ msgid "" "Returns the aspect (in degrees by default) of an elevation raster band. " "Useful for analyzing terrain." msgstr "" +"???????? ?????? (?? ????????????? ? ????????) ?????????? ?????? ??????. " +"??????? ??? ??????? ??????? ??????????." #. Tag: para #, no-c-format @@ -36744,6 +36753,9 @@ msgid "" "Returns the aspect (in degrees by default) of an elevation raster band. " "Utilizes map algebra and applies the aspect equation to neighboring pixels." msgstr "" +"???????? ?????? (?? ????????????? ? ????????) ?????? ?????????? ?????????? " +"??????. ???????????? ??????? ???? ? ?????????? ???????? ??????? ?? ???????? " +"????????." #. Tag: para #, no-c-format @@ -36751,6 +36763,8 @@ msgid "" "units indicates the units of the aspect. Possible values " "are: RADIANS, DEGREES (default)." msgstr "" +"units ?????? ??????? ?????? ???????. ??????? ????????: " +"RADIANS, DEGREES (?? ?????????????)." #. Tag: para #, no-c-format @@ -36758,6 +36772,8 @@ msgid "" "When units = RADIANS, values are between 0 and 2 * pi " "radians measured clockwise from North." msgstr "" +"???? units = RADIANS, ???????? ??????????? ? ????????? " +"??? 0 ?? 2 * pi ??????, ????????? ?? ???????????? ???????? ??? ???????." #. Tag: para #, no-c-format @@ -36765,11 +36781,13 @@ msgid "" "When units = DEGREES, values are between 0 and 360 " "degrees measured clockwise from North." msgstr "" +"???? units = DEGREES, ???????? ??????????? ? ????????? " +"??? 0 ?? 360 ????????, ????????? ?? ???????????? ???????? ??? ???????." #. Tag: para #, no-c-format msgid "If slope of pixel is zero, aspect of pixel is -1." -msgstr "" +msgstr "???? ??????? ??????? ???????? ????, ?????? ??????? ???????? -1." #. Tag: para #, no-c-format @@ -36781,6 +36799,12 @@ msgid "" "html/wwhelp.htm?context=FieldGuide&file=Aspect_Images.html\">ERDAS Field " "Guide - Aspect Images." msgstr "" +"??? ????????? ?????????? ?????????? ??? ???????, ?????????? ?? ??????? " +"????????? ???. ESRI - ?? ?????? ??????? " +"????????? ?? ???????? ???????? ERDAS - ?????????? ????????." #. Tag: para #, no-c-format @@ -36788,6 +36812,8 @@ msgid "" "Enhanced: 2.1.0 Uses ST_MapAlgebra() and added optional " "interpolate_nodata function parameter" msgstr "" +"?????????: 2.1.0 ???????????? ST_MapAlgebra() ?? ?????? ???????????? " +"???????? ??????? interpolate_nodata" #. Tag: para #, no-c-format @@ -36795,6 +36821,8 @@ msgid "" "Changed: 2.1.0 In prior versions, return values were in radians. Now, return " "values default to degrees" msgstr "" +"???????: 2.1.0 ? ?????????? ??????? ???????? ???????? ???? ? ????????. ????? " +"???????? ???????? ?? ????????????? ? ????????" #. Tag: para #, no-c-format @@ -36802,6 +36830,8 @@ msgid "" "Complete example of tiles of a coverage. This query only works with " "PostgreSQL 9.1 or higher." msgstr "" +"?????? ??????? ?????? ????????. ??? ????? ?????? ?????? ? PostgreSQL 9.1 ??? " +"????." #. Tag: para #, no-c-format @@ -36810,6 +36840,9 @@ msgid "" "linkend=\"RT_ST_Roughness\"/>, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -36817,6 +36850,8 @@ msgid "" "Returns the hypothetical illumination of an elevation raster band using " "provided azimuth, altitude, brightness and scale inputs." msgstr "" +"???????? ??????????? ?????????? ?????????? ?????? ?????? ?? ????????? " +"???????? ??????? ???????, ??????, ?????????? ?? ????????." #. Tag: para #, no-c-format @@ -36826,6 +36861,10 @@ msgid "" "applies the hill shade equation to neighboring pixels. Return pixel values " "are between 0 and 255." msgstr "" +"???????? ??????????? ?????????? ?????????? ?????? ?????? ?? ????????? " +"??????? ????? ???????, ??????, ?????????? ?? ????????. ???????????? ??????? " +"???? ? ?????????? ???????? ????????? ???????? ?? ???????? ????????. ???????? " +"????????, ?? ????????????, ??????????? ? ????????? ??? 0 ?? 255." #. Tag: para #, no-c-format @@ -36833,6 +36872,8 @@ msgid "" "azimuth is a value between 0 and 360 degrees measured " "clockwise from North." msgstr "" +"azimuth ? ?? ???????? ??? 0 ?? 360 ????????, ???????? ?? " +"???????????? ???????? ??? ???????." #. Tag: para #, no-c-format @@ -36840,6 +36881,8 @@ msgid "" "altitude is a value between 0 and 90 degrees where 0 " "degrees is at the horizon and 90 degrees is directly overhead." msgstr "" +"altitude ? ?? ???????? ??? 0 ?? 90 ????????, ?? 0 " +"???????? ?????????? ?????????, ? 90 ???????? ? ????? ??? ???????." #. Tag: para #, no-c-format @@ -36847,6 +36890,8 @@ msgid "" "max_bright is a value between 0 and 255 with 0 as no " "brightness and 255 as max brightness." msgstr "" +"max_bright ? ?? ???????? ??? 0 ?? 255, ?? 0 ??????? " +"??????????? ??????????, ? 255 ? ??????????? ??????????." #. Tag: para #, no-c-format @@ -36854,6 +36899,9 @@ msgid "" "scale is the ratio of vertical units to horizontal. For " "Feet:LatLon use scale=370400, for Meters:LatLon use scale=111120." msgstr "" +"scale ? ?? ?????????????? ???????????? ??????? ?? " +"??????????????. ??? Feet:LatLon ?????????????? scale=370400, ??? Meters:" +"LatLon ?????????????? scale=111120." #. Tag: para #, no-c-format @@ -36863,6 +36911,10 @@ msgid "" "linkend=\"RT_ST_InvDistWeight4ma\"/> before computing the hillshade " "illumination." msgstr "" +"???? interpolate_nodata ??? ???????? TRUE, ???????? " +"???????? NODATA ? ???????? ?????? ?????? ?????????????? ?? ????????? ????? ??????????? ?????????? ????????? " +"???????." #. Tag: para #, no-c-format @@ -36871,6 +36923,9 @@ msgid "" "href=\"http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?" "TopicName=How%20Hillshade%20works\">How hillshade works." msgstr "" +"??? ????????? ?????????? ?????????? ??? Hillshade, ???? ?????, ?????????? ?? " +"?? ?????? hillshade." #. Tag: para #, no-c-format @@ -36878,6 +36933,8 @@ msgid "" "Changed: 2.1.0 In prior versions, azimuth and altitude were expressed in " "radians. Now, azimuth and altitude are expressed in degrees" msgstr "" +"???????: 2.1.0 ? ?????????? ??????? ?????? ? ?????? ?????????? ? ????????. " +"????? ?????? ? ?????? ??????????? ? ????????" #. Tag: para #, no-c-format @@ -36886,11 +36943,14 @@ msgid "" "linkend=\"RT_ST_Roughness\"/>, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format msgid "Returns a raster with the calculated \"roughness\" of a DEM." -msgstr "" +msgstr "???????? ????? ? ?????????? ???????????? ???????? ?????? ??????? (DEM)." #. Tag: para #, no-c-format @@ -36898,6 +36958,8 @@ msgid "" "Calculates the \"roughness\" of a DEM, by subtracting the maximum from the " "minimum for a given area." msgstr "" +"???????? ???????????? ???????? ?????? ??????? (DEM), ?????????? ??????????? " +"???????? ??? ???????????? ??? ??????? ???????." #. Tag: para #, no-c-format @@ -36906,6 +36968,9 @@ msgid "" "linkend=\"RT_ST_Slope\"/>, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -36913,6 +36978,8 @@ msgid "" "Returns the slope (in degrees by default) of an elevation raster band. " "Useful for analyzing terrain." msgstr "" +"???????? ????? (?? ????????????? ? ????????) ?????????? ????????? ?????. " +"??????? ??? ??????? ??????? ??????????." #. Tag: para #, no-c-format @@ -36920,6 +36987,8 @@ msgid "" "Returns the slope (in degrees by default) of an elevation raster band. " "Utilizes map algebra and applies the slope equation to neighboring pixels." msgstr "" +"???????? ????? (?? ????????????? ? ????????) ?????????? ????????? ?????. " +"???????????? ??????? ???? ? ?????????? ???????? ?????? ?? ???????? ????????." #. Tag: para #, no-c-format @@ -36927,6 +36996,8 @@ msgid "" "units indicates the units of the slope. Possible values " "are: RADIANS, DEGREES (default), PERCENT." msgstr "" +"units ?????? ??????? ?????? ??????. ??????? ????????: " +"RADIANS, DEGREES (?? ?????????????), PERCENT." #. Tag: para #, no-c-format @@ -36935,6 +37006,9 @@ msgid "" "from the input raster will be interpolated using before computing the surface slope." msgstr "" +"???? interpolate_nodata ??? ???????? TRUE, ???????? " +"???????? NODATA ? ???????? ?????? ?????? ?????????????? ?? ????????? ????? ??????????? ?????? ????????." #. Tag: para #, no-c-format @@ -36946,6 +37020,12 @@ msgid "" "html/wwhelp.htm?context=FieldGuide&file=Slope_Images.html\">ERDAS Field " "Guide - Slope Images." msgstr "" +"??? ????????? ?????????? ?????????? ??? ?????, ?????????? ?? ??????? " +"????????? ???. ESRI - ?? ?????? ??????? " +"????????? ?? ???????? ???????? ERDAS - ?????????? ??????." #. Tag: para #, no-c-format @@ -36954,6 +37034,9 @@ msgid "" "varname>, scale, interpolate_nodata " "function parameters" msgstr "" +"?????????: 2.1.0 ???????????? ST_MapAlgebra() ?? ?????? ??????????? " +"????????? ??????? units, scale, " +"interpolate_nodata" #. Tag: para #, no-c-format @@ -36962,11 +37045,14 @@ msgid "" "linkend=\"RT_ST_Roughness\"/>, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format msgid "Returns a raster with the calculated Topographic Position Index." -msgstr "" +msgstr "???????? ????? ? ?????????? ???????? ?????????????? ?????????." #. Tag: para #, no-c-format @@ -36974,11 +37060,13 @@ msgid "" "Calculates the Topographic Position Index, which is defined as the focal " "mean with radius of one minus the center cell." msgstr "" +"???????? ?????? ?????????????? ?????????, ???? ???????????? ?? ???????? " +"??????? ???????? ? ????????, ?? ???????? ??????? ????? ?????????? ???????." #. Tag: para #, no-c-format msgid "This function only supports a focalmean radius of one." -msgstr "" +msgstr "?? ??????? ????????? ?????? ????????? ???????? ??????, ?????? ???????." #. Tag: para #, no-c-format @@ -36987,11 +37075,14 @@ msgid "" "linkend=\"RT_ST_Slope\"/>, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format msgid "Returns a raster with the calculated Terrain Ruggedness Index." -msgstr "" +msgstr "???????? ????? ? ?????????? ???????? ?????????? ???????." #. Tag: para #, no-c-format @@ -37000,6 +37091,9 @@ msgid "" "neighbors, taking the absolute values of the differences, and averaging the " "result." msgstr "" +"?????? ?????????? ??????? ?????????????? ?????? ?????????? ???????????? " +"??????? ? ?????????, ??????????? ?????????? ??????? ??????? ? ??????????? " +"??????????." #. Tag: para #, no-c-format @@ -37008,6 +37102,9 @@ msgid "" "linkend=\"RT_ST_Slope\"/>, , " msgstr "" +", , , , , " #. Tag: refpurpose #, no-c-format @@ -37016,6 +37113,9 @@ msgid "" "the X- and Y-values to position the points on the grid and the Z-value of " "the points as the surface elevation." msgstr "" +"?????????? ???????? ????? ?? ?????? ???????? ?????? 3-D ?????, " +"?????????????? ???????? X ? Y ??? ?????????????? ????? ?? ?????, ? ???????? " +"Z ????? ? ?? ?????? ????????." #. Tag: para #, no-c-format @@ -37031,11 +37131,21 @@ msgid "" "are calculated, see the GDAL grid tutorial." msgstr "" +"?????????? ???????? ????? ?? ?????? ???????? ?????? 3-???????? ?????, " +"?????????????? ???????? X ? Y ??? ?????????????? ????? ?? ?????, ? ???????? " +"Z ????? ? ?? ?????? ????????. ???????? ?'??? ?????????? ????????????: " +"???????? ????????, ???????? ???????? ??????????? ??????, ?????? ???????, " +"?????????? ????? ? ??????? ????????????. ????? ???????? ?????????? ??? " +"????????? ?? ???? ????????? ???. ? ???????????? gdal_grid. ?????? ?????????? ??? ??, ?? ???????????? ????????????, ???. ???????? ? ?????? " +"? ?????? GDAL." #. Tag: para #, no-c-format msgid "Input parameters are:" -msgstr "" +msgstr "?????? ?????????:" #. Tag: para #, no-c-format @@ -37043,6 +37153,8 @@ msgid "" "The points to drive the interpolation. Any geometry with Z-values is " "acceptable, all points in the input will be used." msgstr "" +"????? ??? ????????????. ????????? ????-??? ????????? ?? ?????????? Z, ?????? " +"??????????? ??? ????? ? ??????? ?????." #. Tag: para #, no-c-format @@ -37052,6 +37164,11 @@ msgid "" "algorithms\">gdal_grid. For example, for an inverse-distance " "interpolation with a smoothing of 2, you would use \"invdist:smoothing=2.0\"" msgstr "" +"?????, ?? ???????? ???????? ?? ????????? ?????????, ? ???????, ???? " +"???????????????? gdal_grid. ?????????, ??? ???????????? ? " +"????????? ????????? ?? ????????????? 2 ???? ??????????????? \"invdist" +":smoothing=2.0\"" #. Tag: para #, no-c-format @@ -37060,6 +37177,9 @@ msgid "" "height, pixel size, spatial extent and pixel type will be read from this " "template." msgstr "" +"????????? ?????? ??? ?????????? ?????????? ????????? ??????. ??????, ??????, " +"?????? ???????, ?????????? ??????????? ? ??? ??????? ?????? ??????????? ? " +"????? ???????." #. Tag: para #, no-c-format @@ -37067,6 +37187,9 @@ msgid "" "By default the first band in the template raster is used to drive the output " "raster, but that can be adjusted with this parameter." msgstr "" +"?? ????????????? ??? ????????? ???????? ??????? ???????????????? ?????? " +"????? ? ??????? ??????, ??? ?? ????? ??????????? ?? ????????? ????? " +"?????????." #. Tag: refpurpose #, no-c-format @@ -37076,6 +37199,11 @@ msgid "" "highlight=contour#_CPPv421GDALContourGenerateEx15GDALRasterBandHPv12CSLConstList16GDALProgressFuncPv\">GDAL " "contouring algorithm." msgstr "" +"??????? ????? ????????? ???????? ?? ???????? ?????????? ??????, " +"?????????????? ???????? ?????????? ???????????? " +"GDAL." #. Tag: para #, no-c-format @@ -37085,6 +37213,11 @@ msgid "" "highlight=contour#_CPPv421GDALContourGenerateEx15GDALRasterBandHPv12CSLConstList16GDALProgressFuncPv\">GDAL " "contouring algorithm." msgstr "" +"??????? ????? ????????? ???????? ?? ???????? ?????????? rfyfke, " +"?????????????? ????????? ?????????? ???????????? " +"GDAL." #. Tag: para #, no-c-format @@ -37093,21 +37226,24 @@ msgid "" "level_interval and level_base " "parameters are ignored." msgstr "" +"???? ???????? fixed_levels ? ?? ???????? ???????, " +"????????? level_interval ?? level_base " +"???????????." #. Tag: para #, no-c-format msgid "The raster to generate the contour of" -msgstr "" +msgstr "????? ??? ????????? ???????" #. Tag: para #, no-c-format msgid "The band to generate the contour of" -msgstr "" +msgstr "????? ??? ?????????? ???????" #. Tag: para #, no-c-format msgid "The elevation interval between contours generated" -msgstr "" +msgstr "???????? ?????? ??? ?????????? ?????????" #. Tag: para #, no-c-format @@ -37116,6 +37252,9 @@ msgid "" "normally zero, but could be different. To generate 10m contours at 5, 15, " "25, ... the LEVEL_BASE would be 5." msgstr "" +"??????, ???????? ???? ?????????????? ????????? ????????, ???????? ???????? " +"????, ??? ???? ???? ?????. ??? ???????? 10-??????? ??????? ?? 5, 15, 25, ... " +"LEVEL_BASE ????????????? 5." #. Tag: para #, no-c-format @@ -37123,21 +37262,23 @@ msgid "" "If true, contour polygons will be created, rather than " "polygon lines." msgstr "" +"???? true, ?????? ???????? ???????? ????????, ? ?? " +"???????????? ?????." #. Tag: para #, no-c-format msgid "Return values are a set of records with the following attributes:" -msgstr "" +msgstr "????????, ?? ????????????, ? ?? ????? ??????? ?? ?????? ??????????:" #. Tag: para #, no-c-format msgid "The geometry of the contour line." -msgstr "" +msgstr "????????? ????????? ?????." #. Tag: para #, no-c-format msgid "A unique identifier given to the contour line by GDAL." -msgstr "" +msgstr "?????????? ?????????????, ?????????? ????????? ????? GDAL." #. Tag: para #, no-c-format @@ -37145,21 +37286,23 @@ msgid "" "The raster value the line represents. For an elevation DEM input, this would " "be the elevation of the output contour." msgstr "" +"???????? ????????, ??? ??????????? ?????. ??? ??????? ????? DEM ?????? ?? " +"???? ?????? ????????? ???????." #. Tag: title #, no-c-format msgid "Raster Processing: Raster to Geometry" -msgstr "" +msgstr "??????? ????????? ?????: ???????????? ????????? ????? ? ???????????" #. Tag: refpurpose #, no-c-format msgid "Returns the box 3d representation of the enclosing box of the raster." -msgstr "" +msgstr "???????? 3D-????????????? ????????????? ????? ??????." #. Tag: para #, no-c-format msgid "Returns the box representing the extent of the raster." -msgstr "" +msgstr "???????? ????, ?? ??????????? ?????? ??????." #. Tag: para #, no-c-format @@ -37168,6 +37311,9 @@ msgid "" "((MINX, MINY), (MAXX, MAXY))" msgstr "" +"???????????? ???????????? ???????? ??????? ?????????????? ???????????? " +"((MINX, MINY), (MAXX, MAXY))" #. Tag: para #, no-c-format @@ -37175,6 +37321,8 @@ msgid "" "Changed: 2.0.0 In pre-2.0 versions, there used to be a box2d instead of " "box3d. Since box2d is a deprecated type, this was changed to box3d." msgstr "" +"???????: 2.0.0 ? ??????? ?? 2.0 ??????? box3d ???????????????? box2d. " +"???????? box2d ? ?????????? ?????, ???? ???? ??????? ?? box3d." #. Tag: refpurpose #, no-c-format @@ -37184,6 +37332,10 @@ msgid "" "the same result as ST_Envelope so only useful for irregularly shaped or " "skewed rasters." msgstr "" +"???????? ????????? ??????? ???????? ??????, ????????? ???????? ????????, " +"????? BandNoDataValue. ??? ??????? ?????????? ????? ?? ??? ?????? ?? ??? ??? " +"????? ?????????, ?? ? ST_Envelope, ???? ??????? ???? ??? ??????? " +"???????????? ????? ??? ? ???????." #. Tag: para #, no-c-format @@ -37193,6 +37345,10 @@ msgid "" "less the same result as ST_Envelope so only useful for irregularly shaped or " "skewed rasters." msgstr "" +"???????? ????????? ??????? ???????? ??????, ????????? ??????? ?????? " +"NoDataBandValue. ??? ??????? ?????????? ????? ?? ??? ?????? ?? ??? ????????? " +"??? ????? ?????????, ?? ? ST_Envelope, ???? ??????? ???? ??? ??????? " +"???????????? ????? ??? ? ???????." #. Tag: para #, no-c-format @@ -37201,6 +37357,9 @@ msgid "" "raster so the answer is subtly different from ST_ConvexHull which does not " "floor." msgstr "" +"ST_Envelope ???????? ?????????? ?, ????, ????? ????????? ????? ??????? " +"??????, ???? ????????? ???? ????????????? ??? ST_ConvexHull, ???? ?? " +"????????." #. Tag: para #, no-c-format @@ -37209,6 +37368,9 @@ msgid "" "SpecificationWorking01\">PostGIS Raster Specification for a diagram " "of this." msgstr "" +"???????? ???????????? PostGIS Raster ??? ???????????? " +"? ?????????." #. Tag: para #, no-c-format @@ -37216,6 +37378,8 @@ msgid "" ", , , " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -37223,6 +37387,8 @@ msgid "" "Returns a set of geomval (geom,val) rows, from a given raster band. If no " "band number is specified, band num defaults to 1." msgstr "" +"???????? ????? ?????? geomval (geom,val) ?? ???????? ?????????? ??????. ???? " +"????? ?????? ?? ???????, ?? ????????????? ???????????????? ????? 1." #. Tag: para #, no-c-format @@ -37232,6 +37398,10 @@ msgid "" "the union of all pixels for that band that have the same pixel value denoted " "by val." msgstr "" +"?? ???????, ?? ???????? ????? (SRF). ???? ???????? ????? ?????? geomval, " +"??????????? ?????????? (geom) ?? ????????? ????????? ?????? (val). ????? " +"???????????? ? ??'???????? ???? ???????? ??? ?????? ??????, ??? ????? " +"???????? ???????? ???????, ????????? val." #. Tag: para #, no-c-format @@ -37240,6 +37410,9 @@ msgid "" "GROUP BY in that it creates new rows. For example it can be used to expand a " "single raster into multiple POLYGONS/MULTIPOLYGONS." msgstr "" +"ST_DumpAsPolygon ???????? ??? ????????????? ???????. ??? ? ????????? ?? " +"GROUP BY, ???????? ??????? ???? ?????. ?????????, ???? ????? ??????????????? " +"??? ?????????? ?????? ?????? ?? ?????? POLYGONS/MULTIPOLYGONS." #. Tag: para #, no-c-format @@ -37247,11 +37420,13 @@ msgid "" "Changed 3.3.0, validation and fixing is disabled to improve performance. May " "result invalid geometries." msgstr "" +"??????? 3.3.0, ????????? ?? ??????????? ???????? ??? ?????????? " +"??????????????. ???? ????????? ?? ????????? ?????????." #. Tag: para #, no-c-format msgid "Availability: Requires GDAL 1.7 or higher." -msgstr "" +msgstr "???????????: ???????? ?????? GDAL 1.7 ??? ????." #. Tag: para #, no-c-format @@ -37259,6 +37434,8 @@ msgid "" "If there is a no data value set for a band, pixels with that value will not " "be returned except in the case of exclude_nodata_value=false." msgstr "" +"???? ??? ????????? ?? ??????????? ???????? ?????, ??????? ? ??? ????????? ?? " +"?????? ???????????, ?? ???????? ????????, ???? exclude_nodata_value=false." #. Tag: para #, no-c-format @@ -37266,6 +37443,8 @@ msgid "" "If you only care about count of pixels with a given value in a raster, it is " "faster to use ." msgstr "" +"???? ??? ???????? ???? ????????? ???????? ?? ??????? ????????? ? ??????, " +"?????? ???? ??????????? ." #. Tag: para #, no-c-format @@ -37273,6 +37452,8 @@ msgid "" "This is different than ST_PixelAsPolygons where one geometry is returned for " "each pixel regardless of pixel value." msgstr "" +"?? ????????????? ??? ST_PixelAsPolygons, ?? ??? ??????? ??????? ???????????? " +"???? ?????????, ????????? ??? ???????? ???????." #. Tag: para #, no-c-format @@ -37280,11 +37461,13 @@ msgid "" ", , , " ", " msgstr "" +", , , " +", " #. Tag: refpurpose #, no-c-format msgid "Returns the polygon representation of the extent of the raster." -msgstr "" +msgstr "???????? ???????, ?? ?????????? ???? ??????." #. Tag: para #, no-c-format @@ -37293,6 +37476,9 @@ msgid "" "coordinate units defined by srid. It is a float8 minimum bounding box " "represented as a polygon." msgstr "" +"???????? ???????????? ????????????? ??? ?????? ? ???????? ??????????? " +"?????????, ?????????? srid. ?? ?????????? ???????????? ????? float8, " +"???????????? ? ??????? ????????." #. Tag: para #, no-c-format @@ -37303,16 +37489,21 @@ msgid "" "varname>), (MAXX, MINY), " "(MINX, MINY))" msgstr "" +"??????? ???????????? ???????? ??????? ????????????? ????? ((MINX, MINY), (MINX, " +"MAXY), (MAXX, MAXY)" +", (MAXX, MINY), (MINX, MINY))" #. Tag: para #, no-c-format msgid ", , " -msgstr "" +msgstr ", , " #. Tag: refpurpose #, no-c-format msgid "Return the convex hull geometry of the raster excluding NODATA pixels." -msgstr "" +msgstr "????????? ????????? ??????? ???????? ??????, ?????????? ??????? NODATA." #. Tag: para #, no-c-format @@ -37320,6 +37511,8 @@ msgid "" "Return the convex hull geometry of the raster excluding NODATA pixels. If " "nband is NULL, all bands of the raster are considered." msgstr "" +"???????? ????????? ??????? ???????? ??????, ?????????? ??????? NODATA. ???? " +"nband ???????? NULL, ???????????? ??? ?????? ??????." #. Tag: para #, no-c-format @@ -37327,6 +37520,8 @@ msgid "" ", , , " "" msgstr "" +", , , " +"" #. Tag: refpurpose #, no-c-format @@ -37335,11 +37530,14 @@ msgid "" "pixel value that is not no data value. If no band number is specified, band " "num defaults to 1." msgstr "" +"???????? ??????????? ?????????, ???????? ??'???????? ????????, ???????? ???? " +"?? ???????? ????. ???? ????? ?????? ?? ???????, ?? ????????????? " +"???????????????? 1." #. Tag: para #, no-c-format msgid "Availability: 0.1.6 Requires GDAL 1.7 or higher." -msgstr "" +msgstr "???????????: 0.1.6 ??????? GDAL 1.7 ??? ????." #. Tag: para #, no-c-format @@ -37347,6 +37545,8 @@ msgid "" "Enhanced: 2.1.0 Improved Speed (fully C-Based) and the returning " "multipolygon is ensured to be valid." msgstr "" +"?????????: 2.1.0 ????????? ????????? (???????? ?? ?????? C) ?? ??????????? " +"?????????? ??????????? ?????????????." #. Tag: para #, no-c-format @@ -37354,6 +37554,8 @@ msgid "" "Changed: 2.1.0 In prior versions would sometimes return a polygon, changed " "to always return multipolygon." msgstr "" +"???????: 2.1.0 ? ?????????? ??????? ????? ?????????? ???????, ??????? ?? " +"?????? ????????? ?????????????." #. Tag: refpurpose #, no-c-format @@ -37361,6 +37563,7 @@ msgid "" "Calculates the fraction of each raster cell that is covered by a given " "geometry." msgstr "" +"???????? ?????? ?????? ????????? ???????, ??? ??????? ??????? ??????????." #. Tag: para #, no-c-format @@ -37374,16 +37577,24 @@ msgid "" "that is covered by the geometry. For linestrings, the value returned for " "each cell is the length contained in the cell." msgstr "" +"???????? ?????? ?????? ????????? ???????, ??? ??????? ??????? ??????????. " +"?????? ???????? ? ?? ?????, ???? ???????? ????????? ?????, ?? " +"???????????????? ??? ??????????. ?????? ? ?????? ??????? ?????????? ? " +"????????? ??????. ?????? ???????? ? ?? ?????????, ??? ???????????? ?? ?????, " +"? ????? ??????? ???????????? ?? ?????? ?????????? ????????? ?? ?????. ??? " +"????????? ????????, ?? ???????????? ??? ?????? ???????, ? ??????? ?? ?????, " +"??? ??????? ??????????. ??? ???????? ??'????? ????????, ?? ???????????? ??? " +"?????? ???????, ? ????????, ?? ????????? ? ???????." #. Tag: para #, no-c-format msgid "Availability: 3.6.0 Requires GEOS 3.14 or higher." -msgstr "" +msgstr "???????????: 3.6.0 ??????? GEOS 3.14 ??? ????." #. Tag: title #, no-c-format msgid "Raster Operators" -msgstr "" +msgstr "???????? ?????????" #. Tag: refpurpose #, no-c-format @@ -37391,6 +37602,8 @@ msgid "" "Returns TRUE if A's bounding box intersects B's bounding " "box." msgstr "" +"???????? TRUE, ???? ???????????? ????? A ????????????? ? " +"????????????? ?????? B." #. Tag: para #, no-c-format @@ -37399,6 +37612,9 @@ msgid "" "if the bounding box of raster/geometr A intersects the bounding box of " "raster/geometr B." msgstr "" +"???????? && ???????? TRUE, " +"???? ???????????? ????? ??????/????????? A ????????? ???????????? ????? " +"??????/????????? B." #. Tag: para #, no-c-format @@ -37406,12 +37622,16 @@ msgid "" "This operand will make use of any indexes that may be available on the " "rasters." msgstr "" +"??? ??????? ???? ??????????????? ????-??? ???????, ??? ?????? ???? ???????? " +"?? ???????." #. Tag: refpurpose #, no-c-format msgid "" "Returns TRUE if A's bounding box is to the left of B's." msgstr "" +"???????? TRUE, ???? ???????????? ????? A ??????????? " +"??????? ??? B." #. Tag: para #, no-c-format @@ -37421,12 +37641,18 @@ msgid "" "of raster B, or more accurately, overlaps or is NOT to the right of the " "bounding box of raster B." msgstr "" +"???????? &< ???????? TRUE, ???? " +"???????????? ????? ?????? A ?????????? ??? ??????????? ??????? ??? " +"????????????? ????? ?????? B, ???, ???????, ?????????? ??? ?? ??????????? " +"???????? ??? ????????????? ????? ?????? B." #. Tag: refpurpose #, no-c-format msgid "" "Returns TRUE if A's bounding box is to the right of B's." msgstr "" +"???????? TRUE, ???? ???????????? ????? A ??????????? " +"???????? ??? ????????????? ????? B." #. Tag: para #, no-c-format @@ -37436,6 +37662,10 @@ msgid "" "of raster B, or more accurately, overlaps or is NOT to the left of the " "bounding box of raster B." msgstr "" +"???????? &> ???????? TRUE, ???? " +"???????????? ????? ?????? A ?????????? ??? ??????????? ???????? ??? " +"????????????? ????? ?????? B, ???, ???????, ?????????? ??? ?? ??????????? " +"??????? ??? ????????????? ????? ?????? B." #. Tag: refpurpose #, no-c-format @@ -37443,6 +37673,8 @@ msgid "" "Returns TRUE if A's bounding box is the same as B's. Uses " "double precision bounding box." msgstr "" +"???????? TRUE, ???? ???????????? ????? A ?????????? ? " +"????????????? ?????? B. ???????????? ???????????? ????? ????????? ????????." #. Tag: para #, no-c-format @@ -37453,6 +37685,11 @@ msgid "" "perform internal orderings and comparison of rasters (ie. in a GROUP BY or " "ORDER BY clause)." msgstr "" +"???????? = ???????? TRUE, ???? " +"???????????? ????? ?????? A ?????????? ? ????????????? ?????? ?????? B. " +"PostgreSQL ???????????? ????????? =, < ?? >, ????????? ??? ???????, " +"??? ????????? ???????????? ????????????? ?? ?????????? ??????? (????? ? " +"????????? GROUP BY ??? ORDER BY). ." #. Tag: para #, no-c-format @@ -37461,6 +37698,10 @@ msgid "" "rasters. Use instead. This operator " "exists mostly so one can group by the raster column." msgstr "" +"??? ??????? ?? ????????????????? ?????? ????????, ??? ?????? ???? ???????? " +"?? ???????. ??????? ????? ?????????????? . " +"??? ???????? ????? ????????? ??? ????, ??? ????? ???? ????????? ?? ???????? " +"??????." #. Tag: refpurpose #, no-c-format @@ -37468,6 +37709,8 @@ msgid "" "Returns TRUE if A's bounding box is contained by B's. " "Uses double precision bounding box." msgstr "" +"???????? TRUE, ???? ???????????? ????? A ????????? ? " +"????????????? ????? B. ???????????? ???????????? ????? ????????? ????????." #. Tag: para #, no-c-format @@ -37476,21 +37719,24 @@ msgid "" "bounding box of raster/geometry A is contained by bounding box of raster/" "geometr B." msgstr "" +"???????? @ ???????? TRUE, ???? " +"???????????? ????? ??????/????????? A ????????? ? ????????????? ????? ??????/" +"????????? B." #. Tag: para #, no-c-format msgid "This operand will use spatial indexes on the rasters." -msgstr "" +msgstr "??? ??????? ???? ??????????????? ?????????? ??????? ?? ???????." #. Tag: para #, no-c-format msgid "Availability: 2.0.0 raster @ raster, raster @ geometry introduced" -msgstr "" +msgstr "???????????: 2.0.0 ????? @ ?????, ????? @ ????????? ???????" #. Tag: para #, no-c-format msgid "Availability: 2.0.5 geometry @ raster introduced" -msgstr "" +msgstr "???????????: 2.0.5 ????????? @ ????? ???????" #. Tag: para #, no-c-format @@ -37498,6 +37744,8 @@ msgid "" "The ~= operator returns TRUE if the " "bounding box of raster A is the same as the bounding box of raster B." msgstr "" +"???????? ~= ???????? TRUE, ???? " +"???????????? ????? ?????? A ?????????? ? ????????????? ?????? ?????? B." #. Tag: para #, no-c-format @@ -37506,11 +37754,14 @@ msgid "" "of the same chunk but represent different themes and creating a multi-band " "raster" msgstr "" +"???? ???????? ???????? ???????????? ? ?????? ???? ??????? ???????????? " +"???????, ??? ? ???????? ?????? ? ???? ? ?????????, ??? ????????????? ????? " +"????, ? ????????? ???????????????? ??????" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -37518,6 +37769,8 @@ msgid "" "Returns TRUE if A's bounding box is contains B's. Uses " "double precision bounding box." msgstr "" +"???????? TRUE, ???? ???????????? ????? A ??????? B. " +"???????????? ???????????? ????? ????????? ????????." #. Tag: para #, no-c-format @@ -37526,11 +37779,14 @@ msgid "" "bounding box of raster/geometry A is contains bounding box of raster/geometr " "B." msgstr "" +"???????? ~ ???????? TRUE, ???? " +"???????????? ????? ??????/????????? A ??????? ???????????? ????? ??????/" +"????????? B." #. Tag: title #, no-c-format msgid "Raster and Raster Band Spatial Relationships" -msgstr "" +msgstr "?????????? ????????? ??? ??????? ? ?????????? ???????" #. Tag: refpurpose #, no-c-format @@ -37539,6 +37795,8 @@ msgid "" "and at least one point of the interior of rastB lies in the interior of " "rastA." msgstr "" +"???????? true, ???? ????? ????? ?????? rastB ?? ?????? ????? ?????? rastA ? " +"????????? ???? ????? ????????? rastB ?????? ????????? rastA." #. Tag: para #, no-c-format @@ -37550,6 +37808,11 @@ msgid "" "number is provided, only those pixels with value (not NODATA) are considered " "in the test." msgstr "" +"????? rastA ??????? rastB ???? ? ?????? ????, ???? ????? ????? rastB ?? " +"?????? ????? rastA ? ????????? ???? ????? ????????? rastB ?????? ????????? " +"rastA. ???? ????? ?????? ?? ??????? (??? ??????????? ?? NULL), ? ????? " +"???????????? ?????? ?????? ???????? ??????. ???? ????? ?????? ???????, ? " +"????? ???????????? ?????? ?? ???????, ??? ????? ???????? (?? NODATA)." #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/uk/postgis-manual.po | 325 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 294 insertions(+), 31 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 3 14:48:21 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 03 Oct 2025 21:48:21 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.f5f4e969e78afe509e696086745b301b@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): Similar to #5984 perhaps, seems non-replicable or at least tightly tied to architecture and/or operating system. Doing a bisection on a system that displays the problem would be good. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 3 14:50:36 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 03 Oct 2025 21:50:36 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.b1a09ec2cb4683b1e7018664d5fbb840@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): Confirmed can reproduce. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 3 15:34:49 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 03 Oct 2025 22:34:49 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea Message-ID: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> #5996: ST_FilterHolesByArea ---------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Keywords: | ---------------------+--------------------------- For area-covering types (Polygon, CurvePolygon) remove the holes having less than the provided area. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 3 15:38:50 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 03 Oct 2025 22:38:50 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.b99592af884aaf07baa10af607925f80@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: fixed => * status: closed => reopened Comment: Uhoh, all the fixes make the minimum reproduction work, but the original failures are still there... -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Sat Oct 4 01:13:05 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 04 Oct 2025 08:13:05 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.f13378e7da10ec0f2510e8f15acf2211@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by komzpa): Can it be a mode for ST_RemoveSmallParts instead? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sat Oct 4 08:47:58 2025 From: git at osgeo.org (git at osgeo.org) Date: Sat, 4 Oct 2025 08:47:58 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-82-gac17b1d6a Message-ID: <20251004154758.EF71D160F31@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via ac17b1d6a6364a81ad7a124b2f9ae257bda51e91 (commit) from acc27445b91bd87277666e8eceb3321315e8b6ae (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ac17b1d6a6364a81ad7a124b2f9ae257bda51e91 Author: Denys Kovshun Date: Sat Oct 4 13:59:33 2025 +0000 Translated PostGIS Manual using Weblate (Ukrainian) Currently translated at 75.3% (4415 of 5857 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/uk/ diff --git a/doc/po/uk/postgis-manual.po b/doc/po/uk/postgis-manual.po index 9a257539d..2a7289932 100644 --- a/doc/po/uk/postgis-manual.po +++ b/doc/po/uk/postgis-manual.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-08-21 03:28+0000\n" -"PO-Revision-Date: 2025-10-03 19:47+0000\n" +"PO-Revision-Date: 2025-10-04 15:47+0000\n" "Last-Translator: Denys Kovshun \n" "Language-Team: Ukrainian \n" @@ -32887,7 +32887,7 @@ msgstr "" #. Tag: para #, no-c-format msgid ", , " -msgstr "" +msgstr ", , " #. Tag: refpurpose #, no-c-format @@ -32895,6 +32895,8 @@ msgid "" "Sets the georeference X and Y skew (or rotation parameter). If only one is " "passed in, sets X and Y to the same value." msgstr "" +"?????????? ????????????? X ? Y (??? ???????? ?????????). ???? ??????????? " +"?????? ???? ????????, X ? Y ?????????????? ?? ???? ? ?? ? ????????." #. Tag: para #, no-c-format @@ -32904,6 +32906,10 @@ msgid "" "href=\"http://en.wikipedia.org/wiki/World_file\">World File for more " "details." msgstr "" +"?????????? ????????????? X ? Y (??? ???????? ?????????). ???? ??????????? " +"?????? ???? ????????, X ? Y ?????????????? ?? ???? ? ?? ? ????????. " +"?????????? ?????????? ???. ? World File." #. Tag: para #, no-c-format @@ -32911,6 +32917,8 @@ msgid "" ", , , " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -32918,11 +32926,13 @@ msgid "" "Sets the SRID of a raster to a particular integer srid defined in the " "spatial_ref_sys table." msgstr "" +"?????????? SRID ?????? ?? ????? ???? ????? srid, ????????? ? ??????? " +"spatial_ref_sys." #. Tag: para #, no-c-format msgid "Sets the SRID on a raster to a particular integer value." -msgstr "" +msgstr "?????????? SRID ?? ?????? ?? ????? ???? ????????." #. Tag: para #, no-c-format @@ -32931,11 +32941,14 @@ msgid "" "data defining the spatial ref of the coordinate reference system that it's " "currently in. Useful for transformations later." msgstr "" +"?? ??????? ?????? ????? ?? ??????????? ????? ? ???? ?????? ?????????? " +"????????, ?? ?????????? ?????????? ?????????? ??????? ?????????, ? ???? ??? " +"????? ???????????. ??????? ??? ????????? ?????????????." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -32943,6 +32956,8 @@ msgid "" "Sets the value of the upper left corner of the pixel of the raster to " "projected X and Y coordinates." msgstr "" +"?????????? ???????? ????????? ?????? ???? ??????? ?????? ?? ??????????? " +"?????????? X ? Y." #. Tag: para #, no-c-format @@ -32950,11 +32965,13 @@ msgid "" "Set the value of the upper left corner of raster to the projected X and Y " "coordinates" msgstr "" +"?????????? ???????? ????????? ?????? ???? ?????? ?? ??????????? ?????????? X " +"? Y" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -32963,6 +32980,9 @@ msgid "" "arbitrary grid corner and a set of raster georeferencing attributes defined " "or borrowed from another raster." msgstr "" +"????????????????? ?????, ?????????????? ???????? ???????? ???????????, ???? " +"???????, ????????? ??? ????? ?? ????? ????????? ?????????????????? ??????, " +"?????????? ??? ??????????? ? ?????? ??????." #. Tag: para #, no-c-format @@ -32973,6 +32993,11 @@ msgid "" "borrowed from another raster. If using a reference raster, the two rasters " "must have the same SRID." msgstr "" +"??????????? ?????, ?????????????? ???????? ???????? ???????????, ???? " +"??????? (?????? ?? ??????), ??? ????? (gridx ?? gridy) ?? ????? ????????? " +"?????????????????? ?????? (scalex, scaley, skewx ?? skewy), ?????????? ??? " +"??????????? ? ?????? ??????. ???? ???????????????? ????????? ?????, ?????? " +"?????? ??????? ???? ????????? SRID." #. Tag: para #, no-c-format @@ -32980,41 +33005,43 @@ msgid "" "New pixel values are computed using one of the following resampling " "algorithms:" msgstr "" +"???? ???????? ???????? ???????????? ?? ????????? ?????? ? ????????? " +"?????????? ???????????:" #. Tag: para #, no-c-format msgid "NearestNeighbor (english or american spelling)" -msgstr "" +msgstr "NearestNeighbor (?????????? ??? ???????????? ??????????)" #. Tag: para #, no-c-format msgid "Bilinear" -msgstr "" +msgstr "Bilinear" #. Tag: para #, no-c-format msgid "Cubic" -msgstr "" +msgstr "Cubic" #. Tag: para #, no-c-format msgid "CubicSpline" -msgstr "" +msgstr "CubicSpline" #. Tag: para #, no-c-format msgid "Lanczos" -msgstr "" +msgstr "Lanczos" #. Tag: para #, no-c-format msgid "Max" -msgstr "" +msgstr "Max" #. Tag: para #, no-c-format msgid "Min" -msgstr "" +msgstr "Min" #. Tag: para #, no-c-format @@ -33022,6 +33049,8 @@ msgid "" "The default is NearestNeighbor which is the fastest but results in the worst " "interpolation." msgstr "" +"?? ????????????? ???????????????? NearestNeighbor, ???? ? ??????????, ??? " +"??? ???????? ?????????? ????????????." #. Tag: para #, no-c-format @@ -33029,6 +33058,8 @@ msgid "" "A maxerror percent of 0.125 is used if no maxerr is " "specified." msgstr "" +"???? ?? ??????? maxerr, ???????????????? ??????????? " +"??????? 0,125%." #. Tag: para #, no-c-format @@ -33036,21 +33067,25 @@ msgid "" "Refer to: GDAL Warp " "resampling methods for more details." msgstr "" +"?????????? ?????????? ???.: ?????? ????????????? GDAL Warp." #. Tag: para #, no-c-format msgid "Availability: 2.0.0 Requires GDAL 1.6.1+" -msgstr "" +msgstr "???????????: 2.0.0 ??????? GDAL 1.6.1+" #. Tag: para #, no-c-format msgid "Enhanced: 3.4.0 max and min resampling options added" msgstr "" +"?????????: ?????? ????? ????????????? ?? ???????????? ???????? ????????????? " +"3.4.0" #. Tag: para #, no-c-format msgid ", , " -msgstr "" +msgstr ", , " #. Tag: refpurpose #, no-c-format @@ -33060,6 +33095,11 @@ msgid "" "spelling), Bilinear, Cubic, CubicSpline, Lanczos, Max or Min resampling " "algorithm. Default is NearestNeighbor." msgstr "" +"??????? ?????????? ??????, ???????? ?????? ???? ??????? (??? ?????? ???????)" +". ???? ???????? ???????? ???????????? ?? ????????? ????????? ??????????? " +"NearestNeighbor (?????????? ??? ???????????? ??????????), Bilinear, Cubic, " +"CubicSpline, Lanczos, Max ??? Min. ?? ????????????? ???????????????? " +"NearestNeighbor." #. Tag: para #, no-c-format @@ -33067,6 +33107,9 @@ msgid "" "Resample a raster by adjusting only its scale (or pixel size). New pixel " "values are computed using one of the following resampling algorithms:" msgstr "" +"??????? ?????????? ??????, ???????? ?????? ???? ??????? (??? ?????? ???????)" +". ???? ???????? ???????? ???????????? ?? ????????? ?????? ? ????????? " +"?????????? ???????????:" #. Tag: para #, no-c-format @@ -33074,6 +33117,9 @@ msgid "" "scalex and scaley define the new pixel " "size. scaley must often be negative to get well oriented raster." msgstr "" +"scalex ?? scaley ?????????? ????? " +"?????? ???????. scaley ????? ??????? ???? ???'?????, ??? ???????? ????? " +"???????????? ?????." #. Tag: para #, no-c-format @@ -33083,6 +33129,10 @@ msgid "" "extent of the provided raster. If you want to be sure to retain exact input " "extent see " msgstr "" +"???? ????? scalex ??? scaley ?? ? ????????? ?????? ??? ?????? ??????, ?????? " +"?????????? ?????? ????????????, ??? ??????? ?????? ???????? ??????. ???? ?? " +"?????? ???? ????????, ?? ?????? ?????? ??????? ????? ???? ?????????, ???. " +"" #. Tag: para #, no-c-format @@ -33092,6 +33142,11 @@ msgid "" "no maxerr is specified, which is the same value used in " "GDAL gdalwarp utility. If set to zero, no approximation takes place." msgstr "" +"maxerr ? ?? ????? ??? ?????????? ???????????? ?? " +"????????? ????????? ??????????? (? ????????). ???? maxerr " +"?? ???????, ???????????????? ???????? ?? ????????????? 0,125, ??? ? ????? " +"?????, ?? ? ? ??????? GDAL gdalwarp. ???? ??????????? ??????? ????????, " +"?????????? ?? ????????????." #. Tag: para #, no-c-format @@ -33104,11 +33159,18 @@ msgid "" "the input raster. ST_SetScale do not modify the width, nor the height of the " "raster." msgstr "" +"ST_Rescale ????????????? ??? ???, ?? " +"ST_SetScale ?? ??????? ?????????? ?????? ??? ????????????? ???????? ??????. " +"ST_SetScale ???? ?????? ???????? (??? ?????????????) ??????, ??? ????????? " +"???????? ??????????? ??????? ?????????????. ST_Rescale ?????????? ?? ????, " +"?? ????? ??? ????? ?????? ? ??????, ????????? ??? ????????????? " +"????????????? ??????? ???????? ??????. ST_SetScale ?? ?????? ?? ??????, ?? " +"?????? ??????." #. Tag: para #, no-c-format msgid "Changed: 2.1.0 Works on rasters with no SRID" -msgstr "" +msgstr "???????: 2.1.0 ?????? ? ???????? ??? SRID" #. Tag: para #, no-c-format @@ -33116,6 +33178,8 @@ msgid "" "A simple example rescaling a raster from a pixel size of 0.001 degree to a " "pixel size of 0.0015 degree." msgstr "" +"??????? ??????? ????????????????? ?????? ? ??????? ??????? 0,001 ??????? ?? " +"??????? ??????? 0,0015 ???????." #. Tag: para #, no-c-format @@ -33124,6 +33188,9 @@ msgid "" ", , " msgstr "" +", , , " +", , " #. Tag: refpurpose #, no-c-format @@ -33133,6 +33200,11 @@ msgid "" "spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. " "Default is NearestNeighbor." msgstr "" +"??????? ?????????? ??????, ????????? ?????? ???? ????? (??? ????????? " +"?????????). ???? ???????? ???????? ???????????? ?? ????????? ????????? " +"??????????? NearestNeighbor (?????????? ??? ???????????? ?????????), " +"Bilinear, Cubic, CubicSpline ??? Lanczos. ?? ????????????? ???????????????? " +"NearestNeighbor." #. Tag: para #, no-c-format @@ -33143,25 +33215,34 @@ msgid "" "default is NearestNeighbor which is the fastest but results in the worst " "interpolation." msgstr "" +"??????? ?????????? ??????, ????????? ?????? ???? ????? (??? ????????? " +"?????????). ???? ???????? ???????? ???????????? ?? ????????? ????????? " +"??????????? NearestNeighbor (?????????? ??? ???????????? ?????????), " +"Bilinear, Cubic, CubicSpline ??? Lanczos. ?? ????????????? ???????????????? " +"NearestNeighbor, ???? ? ??????????, ??? ??? ???????? ????????????." #. Tag: para #, no-c-format msgid "" "skewx and skewy define the new skew." msgstr "" +"skewx ?? skewy ?????????? ????? ??? " +"??????." #. Tag: para #, no-c-format msgid "" "The extent of the new raster will encompass the extent of the provided " "raster." -msgstr "" +msgstr "?????? ?????? ?????? ???? ??????????? ??????? ???????? ??????." #. Tag: para #, no-c-format msgid "" "A maxerror percent of 0.125 if no maxerr is specified." msgstr "" +"???????? ???????????? ??????? 0,125, ???? ?? ??????? " +"maxerr." #. Tag: para #, no-c-format @@ -33174,12 +33255,18 @@ msgid "" "input raster. ST_SetSkew do not modify the width, nor the height of the " "raster." msgstr "" +"ST_Reskew ????????????? ??? ???, ?? " +"ST_SetSkew ?? ??????? ??????????? ?????? ??? ????????????? ???????? ??????. " +"ST_SetSkew ???? ?????? ???????? (??? ?????????????) ??????, ??? ????????? " +"???????? ??????????? ???????? ?????. ST_Reskew ?????????? ?? ????, ?? ????? " +"??? ????? ?????? ? ??????, ????????? ??? ????????????? ????????????? ??????? " +"???????? ??????. ST_SetSkew ?? ?????? ?? ??????, ?? ?????? ??????." #. Tag: para #, no-c-format msgid "" "A simple example reskewing a raster from a skew of 0.0 to a skew of 0.0015." -msgstr "" +msgstr "??????? ??????? ???????????? ?????? ? ??????? ??? 0,0 ?? 0,0015." #. Tag: para #, no-c-format @@ -33188,6 +33275,9 @@ msgid "" ", , " ", " msgstr "" +", , , " +", , " +", " #. Tag: refpurpose #, no-c-format @@ -33196,6 +33286,10 @@ msgid "" "using the NearestNeighbor (english or american spelling), Bilinear, Cubic, " "CubicSpline or Lanczos resampling algorithm. Default is NearestNeighbor." msgstr "" +"??????? ?????????? ??????, ????'?????? ???? ?? ?????. ???? ???????? ???????? " +"???????????? ?? ????????? ????????? ??????????? NearestNeighbor (?????????? " +"??? ???????????? ?????????), Bilinear, Cubic, CubicSpline ??? Lanczos. ?? " +"????????????? ???????????????? NearestNeighbor." #. Tag: para #, no-c-format @@ -33207,6 +33301,12 @@ msgid "" "algorithm. The default is NearestNeighbor which is the fastest but results " "in the worst interpolation." msgstr "" +"??????? ?????????? ??????, ????'?????? ???? ?? ?????, ?????????? ????????? " +"????? ??????? (gridx & gridy) ?, ?? ????????, ???????? ??????? (scalex " +"& scaley). ???? ???????? ???????? ???????????? ?? ????????? ????????? " +"????????????????? NearestNeighbor (?????????? ??? ???????????? ??????????), " +"Bilinear, Cubic, CubicSpline ??? Lanczos. ?? ????????????? ???????????????? " +"NearestNeighbor, ???? ? ??????????, ??? ??? ???????? ????????????." #. Tag: para #, no-c-format @@ -33216,6 +33316,10 @@ msgid "" "of the new raster and it does not have to be inside or on the edge of the " "new raster extent." msgstr "" +"gridx ?? gridy ?????????? ????-???? " +"????????? ?????????? ??? ????? ?????. ?? ?? ????'?????? ??????? ????? ??? " +"?????? ??????, ? ??? ?? ????'?????? ??????? ??????????? ????????? ??? ?? " +"???? ?????? ?????????? ????????." #. Tag: para #, no-c-format @@ -33223,6 +33327,8 @@ msgid "" "You can optionally define the pixel size of the new grid with " "scalex and scaley." msgstr "" +"?? ?????? ????????? ????????? ?????? ???????? ????? ????? ?? ????????? " +"scalex ?? scaley." #. Tag: para #, no-c-format @@ -33230,11 +33336,13 @@ msgid "" "Use if you need more control over the " "grid parameters." msgstr "" +"?????????????? , ???? ??? ???????? ?????? " +"???????? ??? ??????????? ?????." #. Tag: para #, no-c-format msgid "A simple example snapping a raster to a slightly different grid." -msgstr "" +msgstr "??????? ??????? ????'???? ?????? ?? ???? ????? ?????." #. Tag: para #, no-c-format @@ -33242,11 +33350,13 @@ msgid "" ", , , " "" msgstr "" +", , , " +"" #. Tag: refpurpose #, no-c-format msgid "Resize a raster to a new width/height" -msgstr "" +msgstr "??????? ?????? ?????? ?? ????? ??????/??????" #. Tag: para #, no-c-format @@ -33256,6 +33366,9 @@ msgid "" "extent of the the new raster will be the same as the extent of the provided " "raster." msgstr "" +"??????? ?????? ?????? ?? ????? ??????/??????. ???? ??????/?????? ????? " +"??????? ? ??????? ?????? ????????? ???????? ??? ???????? ??? ??????/?????? " +"??????. ?????? ?????? ?????? ???? ????? ?????, ?? ?????? ???????? ??????." #. Tag: para #, no-c-format @@ -33265,11 +33378,15 @@ msgid "" "default is NearestNeighbor which is the fastest but results in the worst " "interpolation." msgstr "" +"???? ???????? ???????? ???????????? ?? ????????? ????????? ????????????????? " +"NearestNeighbor (?????????? ??? ???????????? ?????????), Bilinear, Cubic, " +"CubicSpline ??? Lanczos. ?? ????????????? ???????????????? NearestNeighbor, " +"???? ? ??????????, ??? ??? ???????? ????????????." #. Tag: para #, no-c-format msgid "Variant 1 expects the actual width/height of the output raster." -msgstr "" +msgstr "??????? 1 ?????? ???????? ??????/?????? ????????? ??????." #. Tag: para #, no-c-format @@ -33277,6 +33394,8 @@ msgid "" "Variant 2 expects decimal values between zero (0) and one (1) indicating the " "percentage of the input raster's width/height." msgstr "" +"??????? 2 ?????? ????????? ???????? ??? ???? (0) ?? ??????? (1), ?? ???????? " +"???????? ??????/?????? ???????? ??????." #. Tag: para #, no-c-format @@ -33285,11 +33404,13 @@ msgid "" "textual percentage (\"20%\") indicating the percentage of the input raster's " "width/height." msgstr "" +"??????? 3 ??????? ??? ???????? ??????/?????? ????????? ??????, ??? ????????? " +"???????? (?20%?), ?? ?????? ???????? ??????/?????? ???????? ??????." #. Tag: para #, no-c-format msgid "Availability: 2.1.0 Requires GDAL 1.6.1+" -msgstr "" +msgstr "???????????: 2.1.0 ??????? GDAL 1.6.1+" #. Tag: para #, no-c-format @@ -33297,6 +33418,8 @@ msgid "" ", , , " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -33667,6 +33790,9 @@ msgid "" "of the sample or population. Thus, a value could be examined to be at the " "raster's 25%, 50%, 75% percentile." msgstr "" +"????????? ???????? ??? ???????? ?????? ??? ??????? ?????? ? ????????? " +"??????? ??? ??????????. ????? ?????, ???????? ???? ???? ?????????? ?? " +"????????????? 25%, 50% ?? 75% ?????????? ??????." #. Tag: para #, no-c-format @@ -33674,11 +33800,13 @@ msgid "" "If exclude_nodata_value is set to false, will also count " "pixels with no data." msgstr "" +"???? exclude_nodata_value ??????????? ?? false, ????? " +"?????? ??????????????? ??????? ??? ?????." #. Tag: para #, no-c-format msgid "Changed: 3.1.0 Removed ST_Quantile(table_name, column_name) variant." -msgstr "" +msgstr "???????: 3.1.0 ???????? ??????? ST_Quantile(table_name, column_name)." #. Tag: para #, no-c-format @@ -33687,6 +33815,8 @@ msgid "" "linkend=\"RT_ST_SummaryStatsAgg\"/>, " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -33695,6 +33825,10 @@ msgid "" "given raster band of a raster or raster coverage. Band 1 is assumed if no " "band is specified." msgstr "" +"???????? ??????? ??????????? ????, ?? ??????????? ? ?????????, ????, " +"?????????? ????????, ???????????? ??????????, ???????????? ?? ????????????? " +"??????? ??? ???????? ?????????? ?????? ?????????? ?????????? ??? ?????????? " +"????????. ???? ???????? ?? ???????, ?? ??????????, ?? ?? ????? 1." #. Tag: para #, no-c-format @@ -33703,6 +33837,11 @@ msgid "" "stddev, min, max for a given raster band of a raster or raster coverage. If " "no band is specified nband defaults to 1." msgstr "" +"???????? , ?? ??????????? ? ?????????, ????, " +"?????????? ????????, ???????????? ??????????, ???????????? ?? ????????????? " +"??????? ??? ???????? ?????????? ?????? ?????????? ?????????? ??? ?????????? " +"????????. ???? ???????? ?? ???????, nband ?? " +"????????????? ???????? 1." #. Tag: para #, no-c-format @@ -33711,6 +33850,10 @@ msgid "" "varname> value. Set exclude_nodata_value to false to get " "count of all pixels." msgstr "" +"?? ????????????? ???????????? ?????? ???????? ????????, ??? ?? ?????????? " +"???????? nodata. ?????????? " +"exclude_nodata_value ?? false, ??? ???????? ????????? " +"???? ????????." #. Tag: para #, no-c-format @@ -33718,6 +33861,8 @@ msgid "" "By default will sample all pixels. To get faster response, set " "sample_percent to lower than 1" msgstr "" +"?? ????????????? ???? ?????????? ??? ???????. ??? ???????? ?????? ?????????, " +"?????????? sample_percent ????? 1" #. Tag: para #, no-c-format @@ -33725,16 +33870,21 @@ msgid "" "Changed: 3.1.0 ST_SummaryStats(rastertable, rastercolumn, ...) variants are " "removed. Use instead." msgstr "" +"???????: 3.1.0 ???????? ST_SummaryStats(rastertable, rastercolumn, ...) " +"????????. ??????? ??? ?????????????? ." #. Tag: title #, no-c-format msgid "Example: Single raster tile" -msgstr "" +msgstr "???????: ???????? ???????? ??????" #. Tag: title #, no-c-format msgid "Example: Summarize pixels that intersect buildings of interest" msgstr "" +"???????: ?????????? ???????, ??? ??????????? ???????, ?? ????????????? " +"???????" #. Tag: para #, no-c-format @@ -33743,11 +33893,14 @@ msgid "" "Buildings and aerial Tiles (tiles each 150x150 pixels ~ 134,000 tiles), " "~102,000 building records" msgstr "" +"??? ??????? ?????? 574 ?? ?? PostGIS Windows 64-??? ? ????? ????????? " +"??????? ?? ??????????? ???????? (?????? ???????? 150x150 ???????? ~ 134 000 " +"??????), ~102 000 ??????? ??? ???????" #. Tag: title #, no-c-format msgid "Example: Raster coverage" -msgstr "" +msgstr "???????: ???????? ????????" #. Tag: para #, no-c-format @@ -33755,6 +33908,8 @@ msgid "" ", , , " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -33763,6 +33918,10 @@ msgid "" "max for a given raster band of a set of raster. Band 1 is assumed if no band " "is specified." msgstr "" +"???????. ???????? ??????? ??????????? ????, ?? ??????????? ? ?????????, " +"????, ?????????? ????????, ???????????? ??????????, ???????????? ?? " +"????????????? ??????? ??? ???????? ?????????? ?????? ?????? ???????. ???? " +"???????? ?? ???????, ?????????????? ????? 1." #. Tag: para #, no-c-format @@ -33771,6 +33930,10 @@ msgid "" "varname> value. Set exclude_nodata_value to False to get " "count of all pixels." msgstr "" +"?? ????????????? ???????????? ?????? ???????? ????????, ??? ?? ?????????? " +"???????? NODATA. ?????????? " +"exclude_nodata_value ?? False, ??? ???????? ????????? " +"???? ????????." #. Tag: para #, no-c-format @@ -33778,6 +33941,8 @@ msgid "" "By default will sample all pixels. To get faster response, set " "sample_percent to value between 0 and 1" msgstr "" +"?? ????????????? ???? ?????????? ??? ???????. ??? ???????? ?????? ?????????, " +"?????????? sample_percent ?? ???????? ??? 0 ?? 1" #. Tag: para #, no-c-format @@ -33785,6 +33950,8 @@ msgid "" ", , , " "" msgstr "" +", , , " +"" #. Tag: refpurpose #, no-c-format @@ -33795,6 +33962,12 @@ msgid "" "default nodata value pixels are not counted. and all other values in the " "pixel are output and pixel band values are rounded to the nearest integer." msgstr "" +"???????? ????? ???????, ?? ??????? ???????? ?????????? ????? ?? ????????? " +"???????? ? ???????? ?????? ?????? (??? ?????????? ????????), ??? ????? " +"??????? ????? ???????. ???? ????? ?? ???????, ?? ????????????? " +"???????????????? ????? 1. ?? ????????????? ??????? ? ????????? nodata ?? " +"????????????. ?????????? ??? ???? ???????? ???????, ? ???????? ??????? " +"?????? ???????????? ?? ??????????? ?????? ?????." #. Tag: para #, no-c-format @@ -33803,6 +33976,9 @@ msgid "" "count which contain the pixel band value and count of " "pixels in the raster tile or raster coverage of selected band." msgstr "" +"???????? ????? ??????? ?? ????????? value count, ??? ??????? ???????? ??????? ?????? ?? ????????? ???????? ? " +"????????? ?????? ??? ?????????? ???????? ????????? ??????." #. Tag: para #, no-c-format @@ -33813,26 +33989,31 @@ msgid "" "return an integer instead of records denoting the count of pixels having " "that pixel band value" msgstr "" +"???? ????? ?? ???????, nband ?? ????????????? ???????? 1. " +"???? searchvalues ?? ???????, ???????????? ??? ???????? " +"????????, ???????? ? ?????? ??? ?????????? ????????. ???? ??????? ???? " +"???????? ??????, ???????????? ???? ????? ??????? ???????, ?? ?????????? " +"????????? ????????, ??? ????? ?? ???????? ???????? ??????" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: title #, no-c-format msgid "Raster Inputs" -msgstr "" +msgstr "???????? ????????? ?????" #. Tag: refpurpose #, no-c-format msgid "Return a raster value from a Well-Known Binary (WKB) raster." -msgstr "" +msgstr "????????? ???????? ???????? ? ?????????? ????? Well-Known Binary (WKB)." #. Tag: para #, no-c-format msgid "Given a Well-Known Binary (WKB) raster, return a raster." -msgstr "" +msgstr "?? ??????? ??????? Well-Known Binary (WKB) ????????? ?????." #. Tag: para #, no-c-format @@ -33840,6 +34021,8 @@ msgid "" ", , , " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -33847,6 +34030,8 @@ msgid "" "Return a raster value from a Hex representation of Well-Known Binary (WKB) " "raster." msgstr "" +"????????? ???????? ???????? ? ???????????????? ????????????? ?????? Well-" +"Known Binary (WKB)." #. Tag: para #, no-c-format @@ -33854,6 +34039,8 @@ msgid "" "Given a Well-Known Binary (WKB) raster in Hex representation, return a " "raster." msgstr "" +"?? ??????? ??????? Well-Known Binary (WKB) ? ???????????????? ????????????? " +"????????? ?????." #. Tag: para #, no-c-format @@ -33861,16 +34048,19 @@ msgid "" ", , , " "" msgstr "" +", , , " +"" #. Tag: title #, no-c-format msgid "Raster Outputs" -msgstr "" +msgstr "????? ????????? ?????????" #. Tag: refpurpose #, no-c-format msgid "Return the Well-Known Binary (WKB) representation of the raster." msgstr "" +"????????? ????????????? ?????? ? ??????? ????? ???????? ????????? ???? (WKB)." #. Tag: para #, no-c-format @@ -33880,6 +34070,10 @@ msgid "" "RFC2-WellKnownBinaryFormat located in the PostGIS source folder for details " "of the representation." msgstr "" +"???????? ???????? ????????????? ??????. ???? outasin ??? " +"???????? TRUE, ????? out-db ???????????? ?? in-db. ???????? ????????? ??? " +"????????????? ???. ? ????? raster/doc/RFC2-WellKnownBinaryFormat, ?? " +"????????? ? ????? ?????? PostGIS." #. Tag: para #, no-c-format @@ -33887,6 +34081,8 @@ msgid "" "This is useful in binary cursors to pull data out of the database without " "converting it to a string representation." msgstr "" +"?? ??????? ? ???????? ???????? ??? ????????? ????? ? ???? ????? ??? " +"???????????? ?? ? ??????? ?????????????." #. Tag: para #, no-c-format @@ -33895,26 +34091,31 @@ msgid "" "the client does not have access to the raster file underlying an out-db " "band, set outasin to TRUE." msgstr "" +"?? ?????????????, ??????? ???? WKB ??????? ????????? ???? ?? ????? ??? ???? " +"out-db. ???? ?????? ?? ??? ??????? ?? ?????????? ?????, ?? ?????? ? ?????? " +"????? out-db, ?????????? outasin ?? TRUE." #. Tag: para #, no-c-format msgid "Enhanced: 2.1.0 Addition of outasin" -msgstr "" +msgstr "?????????: 2.1.0 ?????? outasin" #. Tag: para #, no-c-format msgid "Enhanced: 2.5.0 Addition of ST_AsWKB" -msgstr "" +msgstr "?????????: 2.5.0 ?????? ST_AsWKB" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "Return the Well-Known Binary (WKB) in Hex representation of the raster." msgstr "" +"????????? ????? ??????? ???????? ???? (WKB) ? ???????????????? ????????????? " +"??????." #. Tag: para #, no-c-format @@ -33924,6 +34125,10 @@ msgid "" "to raster/doc/RFC2-WellKnownBinaryFormat located in the PostGIS source " "folder for details of the representation." msgstr "" +"???????? ???????? ????????????? ? ???????????????? ??????? ??????. ???? " +"outasin ???????? TRUE, ????? out-db ???????????? ?? in-" +"db. ?????????? ??? ????????????? ???. raster/doc/RFC2-WellKnownBinaryFormat " +"? ????? ?????? PostGIS." #. Tag: para #, no-c-format @@ -33932,6 +34137,9 @@ msgid "" "If the client does not have access to the raster file underlying an out-db " "band, set outasin to TRUE." msgstr "" +"?? ????????????? ??????? ???? Hex WKB ??????? ????????? ???? ?? ????? ??? " +"???? out-db. ???? ?????? ?? ??? ??????? ?? ?????????? ?????, ?? ?????? ? " +"?????? ????? out-db, ?????????? outasin ?? TRUE." #. Tag: para #, no-c-format @@ -34447,6 +34655,9 @@ msgid "" "Creates a new raster of up to four 8BUI bands (grayscale, RGB, RGBA) from " "the source raster and a specified band. Band 1 is assumed if not specified." msgstr "" +"??????? ????? ????? ? ???????? ??????? ??????? 8BUI (???????? ??????, RGB, " +"RGBA) ?? ?????? ????????? ?????? ?? ???????? ?????. ???? ????? ?? ???????, " +"?? ????????????? ???????????????? ????? 1." #. Tag: para #, no-c-format @@ -37820,6 +38031,8 @@ msgid "" "This function will make use of any indexes that may be available on the " "rasters." msgstr "" +"?? ??????? ???? ??????????????? ????-??? ???????, ??? ?????? ???? ???????? " +"?? ???????." #. Tag: para #, no-c-format @@ -37828,6 +38041,9 @@ msgid "" "on the raster, e.g. ST_Contains(ST_Polygon(raster), geometry) or " "ST_Contains(geometry, ST_Polygon(raster))." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_Contains(ST_Polygon(raster), geometry) " +"??? ST_Contains(geometry, ST_Polygon(raster))." #. Tag: para #, no-c-format @@ -37835,11 +38051,13 @@ msgid "" "ST_Contains() is the inverse of ST_Within(). So, ST_Contains(rastA, rastB) " "implies ST_Within(rastB, rastA)." msgstr "" +"ST_Contains() ? ????????? ???????? ?? ST_Within(). ????, ST_Contains(rastA, " +"rastB) ??????? ST_Within(rastB, rastA)." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -37847,6 +38065,8 @@ msgid "" "Return true if rastB intersects the interior of rastA but not the boundary " "or exterior of rastA." msgstr "" +"???????? true, ???? rastB ????????? ????????? ??????? rastA, ??? ?? ???? ??? " +"???????? ??????? rastA." #. Tag: para #, no-c-format @@ -37857,11 +38077,16 @@ msgid "" "in the test. If the band number is provided, only those pixels with value " "(not NODATA) are considered in the test." msgstr "" +"????? rastA ??????? rastB, ???? rastB ????????? ????????? ??????? rastA, ??? " +"?? ???? ??? ???????? ??????? rastA. ???? ????? ?????? ?? ??????? (??? " +"??????????? ?? NULL), ? ????? ???????????? ?????? ?????? ???????? ??????. " +"???? ????? ?????? ???????, ? ????? ???????????? ?????? ?? ???????, ??? ????? " +"???????? (?? NODATA)." #. Tag: para #, no-c-format msgid "Raster rastA does not contain properly itself but does contain itself." -msgstr "" +msgstr "????? rastA ?? ??????? ??? ???? ???????? ?????, ??? ??????? ??? ????." #. Tag: para #, no-c-format @@ -37870,16 +38095,21 @@ msgid "" "on the raster, e.g. ST_ContainsProperly(ST_Polygon(raster), geometry) or " "ST_ContainsProperly(geometry, ST_Polygon(raster))." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_ContainsProperly(ST_Polygon(raster), " +"geometry) ??? ST_ContainsProperly(geometry, ST_Polygon(raster))." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "Return true if no points of raster rastB lie outside raster rastA." msgstr "" +"???????? true, ???? ????? ????? ?????? rastB ?? ?????? ?? ?????? ?????? " +"rastA." #. Tag: para #, no-c-format @@ -37890,6 +38120,11 @@ msgid "" "is provided, only those pixels with value (not NODATA) are considered in the " "test." msgstr "" +"????? rastA ???????? rastB ???? ? ?????? ????, ???? ????? ????? rastB ?? " +"?????? ?? ?????? rastA. ???? ????? ?????? ?? ??????? (??? ??????????? NULL), " +"? ????? ???????????? ?????? ?????? ???????? ??????. ???? ????? ?????? " +"???????, ? ????? ???????????? ?????? ?? ???????, ??? ????? ???????? (?? " +"NODATA)." #. Tag: para #, no-c-format @@ -37898,16 +38133,21 @@ msgid "" "on the raster, e.g. ST_Covers(ST_Polygon(raster), geometry) or " "ST_Covers(geometry, ST_Polygon(raster))." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_Covers(ST_Polygon(raster), geometry) ??? " +"ST_Covers(geometry, ST_Polygon(raster))." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "Return true if no points of raster rastA lie outside raster rastB." msgstr "" +"???????? true, ???? ????? ????? ?????? rastA ?? ?????? ?? ?????? ?????? " +"rastB." #. Tag: para #, no-c-format @@ -37918,6 +38158,11 @@ msgid "" "number is provided, only those pixels with value (not NODATA) are considered " "in the test." msgstr "" +"????? rastA ???????????? rastB ???? ? ?????? ????, ???? ????? ????? rastA ?? " +"?????? ?? ?????? rastB. ???? ????? ?????? ?? ??????? (??? ??????????? NULL), " +"? ????? ???????????? ?????? ?????? ???????? ??????. ???? ????? ?????? " +"???????, ? ????? ???????????? ?????? ?? ???????, ??? ????? ???????? (?? " +"NODATA)." #. Tag: para #, no-c-format @@ -37926,16 +38171,19 @@ msgid "" "on the raster, e.g. ST_CoveredBy(ST_Polygon(raster), geometry) or " "ST_CoveredBy(geometry, ST_Polygon(raster))." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_CoveredBy(ST_Polygon(raster), geometry) " +"??? ST_CoveredBy(geometry, ST_Polygon(raster))." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format msgid "Return true if raster rastA does not spatially intersect rastB." -msgstr "" +msgstr "???????? true, ???? ????? rastA ?? ????????????? ? ???????? ? rastB." #. Tag: para #, no-c-format @@ -37946,11 +38194,15 @@ msgid "" "provided, only those pixels with value (not NODATA) are considered in the " "test." msgstr "" +"??????? rastA ? rastB ? ???'????????, ???? ???? ?? ????? ????????? ????????. " +"???? ????? ?????? ?? ??????? (??? ??????????? ?? NULL), ? ????? ???????????? " +"???? ?????? ???????? ??????. ???? ????? ?????? ???????, ? ????? ???????????? " +"???? ?? ???????, ??? ????? ???????? (?? NODATA)." #. Tag: para #, no-c-format msgid "This function does NOT use any indexes." -msgstr "" +msgstr "?? ??????? ?? ???????????? ?????? ????????." #. Tag: para #, no-c-format @@ -37958,11 +38210,14 @@ msgid "" "To test the spatial relationship of a raster and a geometry, use ST_Polygon " "on the raster, e.g. ST_Disjoint(ST_Polygon(raster), geometry)." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_Disjoint(ST_Polygon(raster), geometry)." #. Tag: refpurpose #, no-c-format msgid "Return true if raster rastA spatially intersects raster rastB." msgstr "" +"???????? true, ???? ????? rastA ?????????? ????????????? ? ??????? rastB." #. Tag: para #, no-c-format @@ -37972,11 +38227,15 @@ msgid "" "is considered in the test. If the band number is provided, only those pixels " "with value (not NODATA) are considered in the test." msgstr "" +"???????? true, ???? ????? rastA ?????????? ????????? ????? rastB. ???? ????? " +"?????? ?? ??????? (??? ??????????? NULL), ? ????? ???????????? ???? ?????? " +"???????? ??????. ???? ????? ????? ???????, ? ????? ???????????? ???? ?? " +"???????, ??? ????? ???????? (?? NODATA)." #. Tag: para #, no-c-format msgid "Enhanced: 2.0.0 support raster/raster intersects was introduced." -msgstr "" +msgstr "?????????: 2.0.0 ?????? ????????? ?????????/????????? ?????????." #. Tag: para #, no-c-format @@ -37984,11 +38243,13 @@ msgid "" "Changed: 2.1.0 The behavior of the ST_Intersects(raster, geometry) variants " "changed to match that of ST_Intersects(geometry, raster)." msgstr "" +"???????: 2.1.0 ????????? ????????? ST_Intersects(raster, geometry) ???????, " +"??? ??????????? ????????? ST_Intersects(geometry, raster)." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -37996,6 +38257,8 @@ msgid "" "Return true if raster rastA and rastB intersect but one does not completely " "contain the other." msgstr "" +"???????? true, ???? ?????? rastA ? rastB ?????????????, ??? ???? ?? ???????? " +"??????? ?????." #. Tag: para #, no-c-format @@ -38006,6 +38269,11 @@ msgid "" "the raster is considered in the test. If the band number is provided, only " "those pixels with value (not NODATA) are considered in the test." msgstr "" +"???????? true, ???? ????? rastA ?????????? ?????????? ????? rastB. ?? " +"???????, ?? rastA ? rastB ?????????????, ??? ???? ?? ??????? ???????? ?????. " +"???? ????? ?????? ?? ??????? (??? ??????????? NULL), ? ????? ???????????? " +"?????? ?????? ???????? ??????. ???? ????? ?????? ???????, ? ????? " +"???????????? ?????? ?? ???????, ??? ????? ???????? (?? NODATA)." #. Tag: para #, no-c-format @@ -38013,6 +38281,8 @@ msgid "" "To test the spatial relationship of a raster and a geometry, use ST_Polygon " "on the raster, e.g. ST_Overlaps(ST_Polygon(raster), geometry)." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_Overlaps(ST_Polygon(raster), geometry)." #. Tag: refpurpose #, no-c-format @@ -38020,6 +38290,8 @@ msgid "" "Return true if raster rastA and rastB have at least one point in common but " "their interiors do not intersect." msgstr "" +"???????? true, ???? ???????? ?????????? rastA ? rastB ????? ????????? ???? " +"??????? ?????, ??? ?? ????????? ??????? ?? ?????????????." #. Tag: para #, no-c-format @@ -38031,6 +38303,12 @@ msgid "" "provided, only those pixels with value (not NODATA) are considered in the " "test." msgstr "" +"???????? true, ???? ????? rastA ?????????? ?????????? ?????? rastB. ?? " +"???????, ?? rastA ? rastB ????? ????????? ???? ??????? ?????, ??? ?? " +"????????? ??????? ?? ?????????????. ???? ????? ?????? ?? ??????? (??? " +"??????????? ?? NULL), ? ????? ???????????? ???? ?????? ???????? ??????. ???? " +"????? ?????? ???????, ? ????? ???????????? ???? ?? ???????, ??? ????? " +"???????? (?? NODATA)." #. Tag: para #, no-c-format @@ -38038,6 +38316,8 @@ msgid "" "To test the spatial relationship of a raster and a geometry, use ST_Polygon " "on the raster, e.g. ST_Touches(ST_Polygon(raster), geometry)." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_Touches(ST_Polygon(raster), geometry)." #. Tag: refpurpose #, no-c-format @@ -38046,6 +38326,10 @@ msgid "" "(pixels can be put on same grid without cutting into pixels) and false if " "they don't with notice detailing issue." msgstr "" +"???????? ???????? true, ???? ?????? ????? ????????? ?????, ???????, " +"?????????? ????'???? ?? ???????? (??????? ????? ?????????? ?? ????? ????? " +"??? ?????????? ?? ???????), ? false, ???? ???? ?? ???????????? ??? " +"?????????, ? ?????????????, ?? ???????? ?????? ????????." #. Tag: para #, no-c-format @@ -38057,6 +38341,12 @@ msgid "" "of the other raster. Returns false if they don't and a NOTICE detailing the " "alignment issue." msgstr "" +"???????????? ?????? (???????? 1 ? 2): ???????? ???????? true, ???? ??? " +"?????? (?????? ????????????? ??? ???????? ? ????????????? ??????? upperleft, " +"scale, skew ? srid) ????? ????????? ???????, ?????, srid ? ????????? ???? ? " +"???????? ????? ????-????? ??????? ?????? ?????? ???????? ?? ????-???? ??? " +"????? ?????? ??????. ???????? false, ???? ???? ?? ?????, ? ???????????? ? " +"????????? ??????????? ??? ???????? ????????????." #. Tag: para #, no-c-format @@ -38066,16 +38356,20 @@ msgid "" "\"aggregate\" function in the terminology of PostgreSQL. That means that it " "operates on rows of data, in the same way the SUM() and AVG() functions do." msgstr "" +"????????? ?????? (??????? 3): ? ?????? ??????? ???????? ???????? true, ???? " +"??? ?????? ? ?????? ?????????. ??????? ST_SameAlignment() ? ???????????? " +"???????? ? ???????????? PostgreSQL. ?? ???????, ?? ???? ?????? ??????? ????? " +"??? ????, ?? ??????? SUM() ? AVG()." #. Tag: para #, no-c-format msgid "Enhanced: 2.1.0 addition of Aggregate variant" -msgstr "" +msgstr "?????????: 2.1.0 ????????? ???????? Aggregate" #. Tag: title #, no-c-format msgid "Examples: Rasters" -msgstr "" +msgstr "????????: ??????" #. Tag: para #, no-c-format @@ -38083,6 +38377,8 @@ msgid "" ", , " msgstr "" +", , " #. Tag: refpurpose #, no-c-format @@ -38090,6 +38386,8 @@ msgid "" "Returns text stating if rasters are aligned and if not aligned, " "a reason why." msgstr "" +"???????? ?????, ?? ??????, ?? ????????? ??????, ? ???? ??, ?? " +"??????? ?????." #. Tag: para #, no-c-format @@ -38097,6 +38395,8 @@ msgid "" "Returns text stating if rasters are aligned and if not aligned, a " "reason why." msgstr "" +"???????? ?????, ?? ??????, ?? ?????? ?????????, ? ???? ??, ?? ??????? " +"?????." #. Tag: para #, no-c-format @@ -38104,11 +38404,13 @@ msgid "" "If there are several reasons why the rasters are not aligned, only one " "reason (the first test to fail) will be returned." msgstr "" +"???? ????? ?????? ??????, ????? ??? ?????? ?? ?????????, ???? ????????? ???? " +"???? ??????? (?????? ????, ???? ?? ???????)." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -38117,6 +38419,8 @@ msgid "" "and at least one point of the interior of rastA lies in the interior of " "rastB." msgstr "" +"???????? true, ???? ????? ????? ?????? rastA ?? ?????? ????? ?????? rastB ? " +"????????? ???? ????? ????????? rastA ?????? ????????? rastB." #. Tag: para #, no-c-format @@ -38128,6 +38432,12 @@ msgid "" "number is provided, only those pixels with value (not NODATA) are considered " "in the test." msgstr "" +"????? rastA ??????????? ? ????? rastB ???? ? ?????? ????, ???? ????? ????? " +"rastA ?? ?????? ?? ?????? rastB ? ????????? ???? ????? ??????????? ??????? " +"rastA ?????? ? ?????????? ??????? rastB. ???? ????? ?????? ?? ??????? (??? " +"??????????? ?? NULL), ? ????? ???????????? ?????? ?????? ???????? ??????. " +"???? ????? ?????? ???????, ? ????? ???????????? ?????? ?? ???????, ??? ????? " +"???????? (?? NODATA)." #. Tag: para #, no-c-format @@ -38136,6 +38446,9 @@ msgid "" "on the raster, e.g. ST_Within(ST_Polygon(raster), geometry) or " "ST_Within(geometry, ST_Polygon(raster))." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_Within(ST_Polygon(raster), geometry) ??? " +"ST_Within(geometry, ST_Polygon(raster))." #. Tag: para #, no-c-format @@ -38143,6 +38456,8 @@ msgid "" "ST_Within() is the inverse of ST_Contains(). So, ST_Within(rastA, rastB) " "implies ST_Contains(rastB, rastA)." msgstr "" +"ST_Within() ? ????????? ???????? ?? ST_Contains(). ????, ST_Within(rastA, " +"rastB) ??????? ST_Contains(rastB, rastA)." #. Tag: para #, no-c-format @@ -38150,6 +38465,8 @@ msgid "" ", , , " "" msgstr "" +", , , " +"" #. Tag: refpurpose #, no-c-format @@ -38157,6 +38474,8 @@ msgid "" "Return true if rasters rastA and rastB are within the specified distance of " "each other." msgstr "" +"???????? true, ???? ?????? rastA ? rastB ??????????? ?? ??????? ???????? " +"???? ??? ??????." #. Tag: para #, no-c-format @@ -38167,6 +38486,10 @@ msgid "" "provided, only those pixels with value (not NODATA) are considered in the " "test." msgstr "" +"???????? true, ???? ?????? rastA ? rastB ??????????? ?? ??????? ???????? " +"???? ??? ??????. ???? ????? ?????? ?? ??????? (??? ??????????? NULL), ? " +"????? ???????????? ?????? ?????? ???????? ??????. ???? ????? ?????? ???????, " +"? ????? ???????????? ?????? ?? ???????, ??? ????? ???????? (?? NODATA)." #. Tag: para #, no-c-format @@ -38175,6 +38498,9 @@ msgid "" "of the rasters. For this function to make sense, the source rasters must " "both be of the same coordinate projection, having the same SRID." msgstr "" +"???????? ?????????? ? ????????, ?????????? ???????? ??????????? ????????? " +"???????. ??? ?? ??????? ???? ????, ??????? ?????? ??????? ???? ???????? " +"???????? ????????? ? ????????? SRID." #. Tag: para #, no-c-format @@ -38182,11 +38508,13 @@ msgid "" "To test the spatial relationship of a raster and a geometry, use ST_Polygon " "on the raster, e.g. ST_DWithin(ST_Polygon(raster), geometry)." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_DWithin(ST_Polygon(raster), geometry)." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -38194,6 +38522,8 @@ msgid "" "Return true if rasters rastA and rastB are fully within the specified " "distance of each other." msgstr "" +"???????? ???????? true, ???? ?????? rastA ? rastB ???????? ??????????? ?? " +"??????? ???????? ???? ??? ??????." #. Tag: para #, no-c-format @@ -38204,6 +38534,11 @@ msgid "" "number is provided, only those pixels with value (not NODATA) are considered " "in the test." msgstr "" +"???????? true, ???? ?????? rastA ? rastB ???????? ??????????? ?? ??????? " +"???????? ???? ??? ??????. ???? ????? ?????? ?? ??????? (??? ??????????? NULL)" +", ? ????? ???????????? ?????? ?????? ???????? ??????. ???? ????? ?????? " +"???????, ? ????? ???????????? ?????? ?? ???????, ??? ????? ???????? (?? " +"NODATA)." #. Tag: para #, no-c-format @@ -38211,32 +38546,37 @@ msgid "" "To test the spatial relationship of a raster and a geometry, use ST_Polygon " "on the raster, e.g. ST_DFullyWithin(ST_Polygon(raster), geometry)." msgstr "" +"??? ?????????? ?????????? ????????? ??? ??????? ? ??????????, ?????????????? " +"ST_Polygon ?? ??????, ????????? ST_DFullyWithin(ST_Polygon(raster), " +"geometry)." #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: title #, no-c-format msgid "Raster Tips" -msgstr "" +msgstr "?????? ???? ??????" #. Tag: para #, no-c-format msgid "" "This section documents various gotchas and tips related to PostGIS Raster." msgstr "" +"? ????? ??????? ??????? ????? ???????? ?????? ?? ??????, ???'????? ? PostGIS " +"Raster." #. Tag: title #, no-c-format msgid "Out-DB Rasters" -msgstr "" +msgstr "?????? Out-DB" #. Tag: title #, no-c-format msgid "Directory containing many files" -msgstr "" +msgstr "???????, ?? ??????? ?????? ??????" #. Tag: para #, no-c-format @@ -38246,6 +38586,11 @@ msgid "" "thousands, millions), opening that file becomes extremely slow (especially " "if that file happens to be on a network drive such as NFS)." msgstr "" +"???? GDAL ????????? ????, GDAL ???????? ?????? ??????? ????? ?????, ??? " +"???????? ??????? ????? ??????. ???? ??? ??????? ??????? ?????? ?????? (" +"?????????, ??????, ????????), ????????? ????? ????? ???? ??????????? " +"????????? (???????? ???? ??? ???? ??????????? ?? ?????????? ?????, ?????? ?? " +"NFS)." #. Tag: para #, no-c-format @@ -38256,6 +38601,11 @@ msgid "" "GDAL_DISABLE_READDIR_ON_OPEN to TRUE " "to disable directory scanning." msgstr "" +"??? ???????? ???? ????????? GDAL ????? ???????? ?????? ??????????: GDAL_DISABLE_READDIR_ON_OPEN. " +"?????????? GDAL_DISABLE_READDIR_ON_OPEN ?? TRUE, ??? ???????? ?????????? ?????????." #. Tag: para #, no-c-format @@ -38267,11 +38617,17 @@ msgid "" "is the name of the cluster, e.g. maindb). You can also set PostGIS " "environment variables here as well." msgstr "" +"? Ubuntu (? ???? ?? ?????????????? ?????? PostgreSQL ??? Ubuntu), " +"GDAL_DISABLE_READDIR_ON_OPEN ????? ?????????? ? " +"/etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/environment (?? POSTGRESQL_VERSION ? ?? ?????? PostgreSQL, ????????? 9.6, ? " +"CLUSTER_NAME ? ?? ????? ????????, ????????? maindb). ??? ????? ????? " +"?????????? ?????? ?????????? PostGIS." #. Tag: title #, no-c-format msgid "Maximum Number of Open Files" -msgstr "" +msgstr "??????????? ????????? ????????? ??????" #. Tag: para #, no-c-format @@ -38284,6 +38640,13 @@ msgid "" "temperatures and we want to know the absolute min and max value for a pixel " "in that dataset)." msgstr "" +"??????????? ????????? ????????? ??????, ????????? Linux ? PostgreSQL, " +"???????? ? ?????????????? (???????? 1024 ????????? ?????? ?? ??????), " +"???????? ? ??????????, ?? ??????? ???????????????? ??????. ??? ??????? Out-" +"DB ???? ??????? ????? ???? ????? ?????????? ??? ????? (?????????, ????? " +"????? ?? 10 ????? ? ????? ??????? ??? ??????? ???, ?? ??????? ?????????? ?? " +"??????????? ???????????, ? ?? ?????? ????? ????????? ?????????? ?? " +"??????????? ???????? ??? ??????? ? ????? ?????? ?????)." #. Tag: para #, no-c-format @@ -38298,6 +38661,16 @@ msgid "" "/etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/postgresql.conf in Ubuntu environments)." msgstr "" +"???????????? ?????? ? ???????? ???????????? PostgreSQL: max_files_per_process. ?? " +"????????????? ??????????? ???????? 1000, ?? ? ??????? ??????? ??? Out-DB " +"Rasters. ????????? ?????????? ????????? ???? ???? 65536, ??? ?? ????????? " +"???????? ??? ????? ??????? ????? ? ???????, ?? ??????????? ??? ??? ??????? " +"?????. ?? ???????????? ????? ???????? ?????? ??? ??? ??????? ??????? ?, " +"????????, ?????? ? ????? ???????????? PostgreSQL (?????????, /etc/" +"postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/postgresql.conf ? " +"??????????? Ubuntu)." #. Tag: para #, no-c-format @@ -38305,21 +38678,23 @@ msgid "" "The major change to make is the Linux kernel's open files limits. There are " "two parts to this:" msgstr "" +"??????? ?????, ??? ???????? ??????, ?????????? ???????? ????????? ?????? " +"???? Linux. ???? ??????????? ? ???? ??????:" #. Tag: para #, no-c-format msgid "Maximum number of open files for the entire system" -msgstr "" +msgstr "??????????? ????????? ????????? ?????? ??? ????? ???????" #. Tag: para #, no-c-format msgid "Maximum number of open files per process" -msgstr "" +msgstr "??????????? ????????? ????????? ?????? ?? ??????" #. Tag: title #, no-c-format msgid "Maximum number of open files for the entire system" -msgstr "" +msgstr "??????????? ????????? ????????? ?????? ??? ????? ???????" #. Tag: para #, no-c-format @@ -38327,6 +38702,8 @@ msgid "" "You can inspect the current maximum number of open files for the entire " "system with the following example:" msgstr "" +"?? ?????? ?????????? ??????? ??????????? ????????? ????????? ?????? ??? " +"????? ??????? ?? ????????? ?????????? ????????:" #. Tag: para #, no-c-format @@ -38334,11 +38711,13 @@ msgid "" "If the value returned is not large enough, add a file to /etc/" "sysctl.d/ as per the following example:" msgstr "" +"???? ????????? ???????? ??????????? ??????, ??????? ???? ?? /etc/" +"sysctl.d/ ?????????? ?? ?????????? ????????:" #. Tag: title #, no-c-format msgid "Maximum number of open files per process" -msgstr "" +msgstr "??????????? ????????? ????????? ?????? ?? ??????" #. Tag: para #, no-c-format @@ -38346,6 +38725,8 @@ msgid "" "We need to increase the maximum number of open files per process for the " "PostgreSQL server processes." msgstr "" +"??? ???????? ????????? ??????????? ????????? ????????? ?????? ?? ?????? ??? " +"???????? ??????? PostgreSQL." #. Tag: para #, no-c-format @@ -38354,6 +38735,9 @@ msgid "" "number of open files, do as per the following example (make sure to have " "PostgreSQL running):" msgstr "" +"??? ????????, ??? ????????? ????????? ?????? ?????????????? ??????? ??????? " +"?????? PostgreSQL, ????????? ???????? ??? (?????????????, ?? PostgreSQL " +"??????):" #. Tag: para #, no-c-format @@ -38362,6 +38746,10 @@ msgid "" "It doesn't matter which PostgreSQL process, any of them will do. The " "response we are interested in is Max open files." msgstr "" +"? ?????????? ???? ???????? ?? ?????????? ????????? ????????? ?????? ??? " +"??????? 31718. ?? ??? ????????, ???? ???? ?????? PostgreSQL, ????-???? ? ??? " +"???????. ?????????, ??? ??? ????????, ? ?? ??????????? ????????? " +"????????? ??????." #. Tag: para #, no-c-format @@ -38372,6 +38760,12 @@ msgid "" "max_files_per_process. In our example, we set " "max_files_per_process to 65536." msgstr "" +"?? ?????? ????????? ?'??? ????????? ?? " +"??????? ????????? ??? ???????????? ????????? " +"????????? ??????, ??? ???? ???? ???????? ?? ????????, ??? ?? " +"??????? ??? ???????????? PostgreSQL max_files_per_process. ? ?????? ???????? ?? ?????????? max_files_per_process ?? 65536." #. Tag: para #, no-c-format @@ -38382,6 +38776,11 @@ msgid "" "postgresql (SysV) or /lib/systemd/" "system/postgresql*.service (systemd)." msgstr "" +"? Ubuntu (? ???????????, ?? ?? ?????????????? ?????? PostgreSQL ??? Ubuntu), " +"???????????? ?????? ??????? Soft Limit ?? " +"Hard Limit ? ?? ????????????? /etc/init.d/postgresql (SysV) ??? /lib/" +"systemd/system/postgresql*.service (systemd)." #. Tag: para #, no-c-format @@ -38391,6 +38790,10 @@ msgid "" "role=\"strong\">ulimit -n 131072 to /" "etc/init.d/postgresql." msgstr "" +"???????? ?????????? ??????? SysV Ubuntu, ?? ?? ??????? ulimit -H -n 262144 ?? ulimit -n 131072 ?? /etc/init.d/" +"postgresql." #. Tag: para #, no-c-format @@ -38400,12 +38803,16 @@ msgid "" "role=\"strong\">/lib/systemd/system/postgresql*.service file in " "the [Service] section." msgstr "" +"????? ?????????? ??????? systemd Ubuntu. ?? ?????? LimitNOFILE=131072 ?? ??????? ????? /" +"lib/systemd/system/postgresql*.service ? ??????? [Service]." #. Tag: para #, no-c-format msgid "" "After making the necessary systemd changes, make sure to reload the daemon" -msgstr "" +msgstr "????? ???????? ?????????? ???? ?? systemd ?????????????? ?????" #. Tag: title #, no-c-format @@ -38415,12 +38822,12 @@ msgstr "?????????? ?????????" #. Tag: para #, no-c-format msgid "These functions determine spatial relationships between geometries." -msgstr "" +msgstr "?? ??????? ?????????? ?????????? ????????? ??? ???????????." #. Tag: title #, no-c-format msgid "Topological Relationships" -msgstr "" +msgstr "??????????? ?????????" #. Tag: refpurpose #, no-c-format @@ -38428,6 +38835,8 @@ msgid "" "Tests if two geometries spatially intersect in 3D - only for points, " "linestrings, polygons, polyhedral surface (area)" msgstr "" +"?????????, ?? ??? ????????? ????????????? ? ???????? 3D - ?????? ??? ?????, " +"???????? ?????????, ?????????, ????????????? ????????? (????)" #. Tag: para #, no-c-format @@ -38436,11 +38845,14 @@ msgid "" "aforementioned returns true, then the geometries also spatially intersect. " "Disjoint implies false for spatial intersection." msgstr "" +"??????????, ??????, ????????? ??? ????????? ?????????? ???????. ???? ????-" +"??? ? ?????????????? ???????? ???????? true, ?? ????????? ????? ?????????? " +"?????????????. ???'????????? ??????? false ??? ???????????? ????????." #. Tag: para #, no-c-format msgid "&index_aware;" -msgstr "" +msgstr "&index_aware;" #. Tag: para #, no-c-format @@ -38451,21 +38863,26 @@ msgid "" "kind of issues where a distance of a centimeter you want to just consider as " "intersecting, use ." msgstr "" +"????? ??????? ????????? ????????? ????????? ?? ?????? ????????????? ???, ?? " +"?? ???????? ????? ???????????? ???????. ?????????, ????????? ????? ?? ????? " +"?? ????????? ???? ?? ?????? ?? ?????. ??? ????? ????????, ???? ???????? ? " +"???? ????????? ?? ?????? ??????? ?????????, ?????????????? ." #. Tag: para #, no-c-format msgid "Changed: 3.0.0 SFCGAL backend removed, GEOS backend supports TINs." -msgstr "" +msgstr "???????: 3.0.0 ???????? ?????? SFCGAL, ?????? GEOS ????????? TIN." #. Tag: title #, no-c-format msgid "TIN Examples" -msgstr "" +msgstr "???????? TIN" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -38473,6 +38890,8 @@ msgid "" "Tests if every point of B lies in A, and their interiors have a point in " "common" msgstr "" +"?????????, ?? ????? ????? B ?????? ? A, ? ?? ????? ???? ????????? ??????? " +"??????? ?????" #. Tag: para #, no-c-format @@ -38482,6 +38901,10 @@ msgid "" "equivalently, no points of B lie in the exterior of A), and the interiors of " "A and B have at least one point in common." msgstr "" +"???????? TRUE, ???? ????????? A ??????? ????????? B. A ??????? B ???? ? " +"?????? ????, ???? ??? ????? B ?????? ????????? (????? ? ?????????? ??????? " +"??? ?? ????) A (???, ?? ????????????, ????? ????? B ?? ?????? ???? ?????? A)" +", ? ????????? ??????? A ? B ????? ????????? ???? ??????? ?????." #. Tag: para #, no-c-format @@ -38489,6 +38912,8 @@ msgid "" "In mathematical terms: ST_Contains(A, B) ? (A ? B = B) ? (Int(A) ? " "Int(B) ? ?) " msgstr "" +"? ???????????? ????????: ST_Contains(A, B) ? (A ? B = B) ? (Int(A) " +"? Int(B) ? ?) " #. Tag: para #, no-c-format @@ -38500,6 +38925,12 @@ msgid "" "ST_Contains(B,A) = true, then the two geometries must be " "topologically equal (ST_Equals(A,B) = true)." msgstr "" +"?????????? ????????? ? ????????????: ????? ????????? ??????? ???? ????. (?? " +"??????? ??? ?????, ? ????????? " +"????????? ?? ??????? ???? ???? ???????? ?????). " +"?????????? ? ???????????????: ???? ST_Contains(A,B) = true ? " +"ST_Contains(B,A) = true, ?? ??? ????????? ??????? ???? " +"??????????? ??????? (ST_Equals(A,B) = true)." #. Tag: para #, no-c-format @@ -38507,6 +38938,8 @@ msgid "" "ST_Contains is the converse of . So, " "ST_Contains(A,B) = ST_Within(B,A)." msgstr "" +"ST_Contains ? ????????? ?? . ????, " +"ST_Contains(A,B) = ST_Within(B,A)." #. Tag: para #, no-c-format @@ -38519,6 +38952,13 @@ msgid "" " predicate provides a more inclusive " "relationship." msgstr "" +"???????? ????????? ??????? ??????? ???? ??????? ?????, ???????? ?????????? " +"??????? ? ????, ?? ???????? ?? ????? ?? ??????? ????? " +"?? ?????, ?? ???????? ?????? ? ????? ?????. ??? ????????? ?????????? " +"?????????? ???. ??????? OGC Covers, Contains, " +"Within. ???????? ?????????? ????? " +"????????? ??????????." #. Tag: para #, no-c-format @@ -38526,6 +38966,8 @@ msgid "" "&index_aware; To avoid index use, use the function _ST_Contains." msgstr "" +"&index_aware; ??? ???????? ???????????? ???????, ?????????????? ??????? " +"_ST_Contains." #. Tag: para #, no-c-format @@ -38533,12 +38975,16 @@ msgid "" "Enhanced: 2.3.0 Enhancement to PIP short-circuit extended to support " "MultiPoints with few points. Prior versions only supported point in polygon." msgstr "" +"?????????: 2.3.0 ?????????? ????????? ????????? PIP ????????? ??? ????????? " +"MultiPoints ? ????????? ????????? ?????. ????????? ?????? ???????????? " +"?????? ????? ? ?????????????." #. Tag: para #, no-c-format msgid "" "Enhanced: 3.0.0 enabled support for GEOMETRYCOLLECTION" msgstr "" +"?????????: 3.0.0 ???????? ????????? ??? GEOMETRYCOLLECTION" #. Tag: para #, no-c-format @@ -38546,6 +38992,8 @@ msgid "" "Do not use this function with invalid geometries. You will get unexpected " "results." msgstr "" +"?? ?????????????? ?? ??????? ? ?????????? ???????????. ?? ????????? " +"??????????? ??????????." #. Tag: para #, no-c-format @@ -38553,6 +39001,8 @@ msgid "" "NOTE: this is the \"allowable\" version that returns a boolean, not an " "integer." msgstr "" +"????????: ?? ??????????? ??????, ??? ???????? ??????? ????????, ? ?? ???? " +"?????." #. Tag: para #, no-c-format @@ -38560,11 +39010,13 @@ msgid "" "&sfs_compliant; s2.1.1.2 // s2.1.13.3 - same as within(geometry B, geometry " "A)" msgstr "" +"&sfs_compliant; s2.1.1.2 // s2.1.13.3 - ?? ????, ?? ? ? (geometry B, " +"geometry A)" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 5.1.31" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 5.1.31" #. Tag: para #, no-c-format @@ -38572,26 +39024,28 @@ msgid "" "ST_Contains returns TRUE in the " "following situations:" msgstr "" +"ST_Contains ???????? TRUE ? ????? " +"????????:" #. Tag: para #, no-c-format msgid "LINESTRING / MULTIPOINT" -msgstr "" +msgstr "LINESTRING / MULTIPOINT" #. Tag: para #, no-c-format msgid "POLYGON / POINT" -msgstr "" +msgstr "POLYGON / POINT" #. Tag: para #, no-c-format msgid "POLYGON / LINESTRING" -msgstr "" +msgstr "POLYGON / LINESTRING" #. Tag: para #, no-c-format msgid "POLYGON / POLYGON" -msgstr "" +msgstr "POLYGON / POLYGON" #. Tag: para #, no-c-format @@ -38599,11 +39053,13 @@ msgid "" "ST_Contains returns FALSE in the " "following situations:" msgstr "" +"ST_Contains ???????? FALSE ? ????? " +"?????????:" #. Tag: para #, no-c-format msgid "POLYGON / MULTIPOINT" -msgstr "" +msgstr "POLYGON / MULTIPOINT" #. Tag: para #, no-c-format @@ -38612,11 +39068,14 @@ msgid "" "returns FALSE in the following situations (whereas " "ST_Covers returns TRUE):" msgstr "" +"????? ????? ???????????? ???????? ST_Contains ???????? " +"FALSE ? ????? ????????? (???? ?? ST_Covers ???????? TRUE):" #. Tag: para #, no-c-format msgid "LINESTRING / POINT" -msgstr "" +msgstr "LINESTRING / POINT" #. Tag: para #, no-c-format @@ -38625,11 +39084,14 @@ msgid "" ", , " msgstr "" +", , , " +", , " #. Tag: refpurpose #, no-c-format msgid "Tests if every point of B lies in the interior of A" -msgstr "" +msgstr "?????????, ?? ????? ????? B ?????? ? ?????????? ??????? A" #. Tag: para #, no-c-format @@ -38637,6 +39099,9 @@ msgid "" "Returns true if every point of B lies in the interior of " "A (or equivalently, no point of B lies in the the boundary or exterior of A)." msgstr "" +"???????? true, ???? ????? ????? B ?????? ? ?????????? " +"??????? A (???, ?? ????????????, ????? ????? B ?? ?????? ?? ???? ??? ????? " +"A)." #. Tag: para #, no-c-format @@ -38644,6 +39109,8 @@ msgid "" "In mathematical terms: ST_ContainsProperly(A, B) ? Int(A) ? B = B " "" msgstr "" +"? ???????????? ????????: ST_ContainsProperly(A, B) ? Int(A) ? B = " +"B " #. Tag: para #, no-c-format @@ -38651,11 +39118,13 @@ msgid "" "A contains B properly if the DE-9IM Intersection Matrix for the two " "geometries matches [T**FF*FF*]" msgstr "" +"A ??????? B ???????? ?????, ???? ??????? ???????? DE-9IM ??? ???? ????????? " +"?????????? [T**FF*FF*]" #. Tag: para #, no-c-format msgid "A does not properly contain itself, but does contain itself." -msgstr "" +msgstr "A ?? ??????? ???? ???????? ?????, ??? ??????? ????." #. Tag: para #, no-c-format @@ -38666,6 +39135,11 @@ msgid "" "out test geometries which lie fully inside the area. In these cases the " "intersection is known a priori to be exactly the original test geometry." msgstr "" +"??? ???????? ???????????????? ??? ?????????? ????????? ?????? ????????? ? " +"??????? ????????????? ??????????. ???????? ??????? ? ?????? ????????? " +"?????????, ??????????? ??????????????? containsProperly ??? ??????????????? " +"???????? ?????????, ??? ???????? ?????? ????????? ???????. ? ??? ???????? " +"??????? ??????? ??????? ?? ????? ??????????? ??????? ?????????." #. Tag: para #, no-c-format @@ -38673,6 +39147,8 @@ msgid "" "&index_aware; To avoid index use, use the function " "_ST_ContainsProperly." msgstr "" +"&index_aware; ??? ???????? ???????????? ???????, ?????????????? ??????? " +"_ST_ContainsProperly." #. Tag: para #, no-c-format @@ -38681,6 +39157,9 @@ msgid "" " is that it can be computed more " "efficiently, with no need to compute topology at individual points." msgstr "" +"???????? ????? ????????? ??? ?? ??????? ? ????, ?? ???? ????? ??????????? " +"???????????, ??? ???????????? ??????????? ????????? ? ??????? ??????." #. Tag: para #, no-c-format @@ -38690,11 +39169,14 @@ msgid "" "linkend=\"ST_Equals\"/>, , " msgstr "" +", , , , , , , " #. Tag: refpurpose #, no-c-format msgid "Tests if every point of A lies in B" -msgstr "" +msgstr "?????????, ?? ????? ????? A ?????? ? B" #. Tag: para #, no-c-format @@ -38703,12 +39185,17 @@ msgid "" "inside (i.e. intersects the interior or boundary of) Geometry/Geography B. " "Equivalently, tests that no point of A lies outside (in the exterior of) B." msgstr "" +"???????? true, ???? ????? ????? ? ?????????/????????? A " +"?????? ????????? (????? ????????? ????????? ??????? ??? ????) ?????????/" +"????????? B. ????????????, ?????????, ?? ????? ????? A ?? ?????? ???? (?????)" +" B." #. Tag: para #, no-c-format msgid "" "In mathematical terms: ST_CoveredBy(A, B) ? A ? B = A " msgstr "" +"? ???????????? ????????: ST_CoveredBy(A, B) ? A ? B = A " #. Tag: para #, no-c-format @@ -38897,22 +39384,22 @@ msgstr "" #. Tag: para #, no-c-format msgid "MULTIPOINT / LINESTRING" -msgstr "" +msgstr "MULTIPOINT / LINESTRING" #. Tag: para #, no-c-format msgid "MULTIPOINT / POLYGON" -msgstr "" +msgstr "MULTIPOINT / POLYGON" #. Tag: para #, no-c-format msgid "LINESTRING / POLYGON" -msgstr "" +msgstr "LINESTRING / POLYGON" #. Tag: para #, no-c-format msgid "LINESTRING / LINESTRING" -msgstr "" +msgstr "LINESTRING / LINESTRING" #. Tag: para #, no-c-format @@ -39010,12 +39497,12 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sfs_compliant; s2.1.1.2" -msgstr "" +msgstr "&sfs_compliant; s2.1.1.2" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 5.1.24" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 5.1.24" #. Tag: para #, no-c-format @@ -39030,6 +39517,8 @@ msgid "" ", , , " "" msgstr "" +", , , " +"" #. Tag: refpurpose #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/uk/postgis-manual.po | 643 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 566 insertions(+), 77 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Sun Oct 5 06:36:25 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 5 Oct 2025 06:36:25 -0700 (PDT) Subject: [SCM] postgis.net branch website updated. clarity-final-154-gbb591e9 Message-ID: <20251005133625.D198F16E348@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "postgis.net". The branch, website has been updated via bb591e9a3960d374defdfd24e83a11ccd196d840 (commit) from f5cbaf238ca17148bbb679581efacb2abc5bee90 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bb591e9a3960d374defdfd24e83a11ccd196d840 Author: Regina Obe Date: Sun Oct 5 09:36:19 2025 -0400 Update to reflect release of PostgreSQL 18 3.6.0 bundle diff --git a/content/documentation/getting_started/install_windows/released_versions.md b/content/documentation/getting_started/install_windows/released_versions.md index d86457b..9b24042 100644 --- a/content/documentation/getting_started/install_windows/released_versions.md +++ b/content/documentation/getting_started/install_windows/released_versions.md @@ -1,20 +1,21 @@ --- title: Latest Released Version -date: 2024-09-28 +date: 2025-10-05 weight: 10 geekdocHidden: true geekdocHiddenTocTree: false --- -PostGIS 3.5.3 came out May 17th, 2025. Windows PostGIS Bundle 3.5.3 installers for PostgreSQL 13-17 was released June 5th 2025. +PostGIS 3.6.0 came out Sept 2nd, 2025. Windows PostGIS Bundle 3.6.0 installers for PostgreSQL 18 was released Sept 2nd 2025. -Binaries for versions of PostgreSQL 13-17 (64-bit) available in `Unreleased PostGIS Versions` and [OSGeo downloads][5]). Installers for 13-17(64-bit) available on [OSGeo downloads][5] and application stackbuilder. +Binaries for versions of PostgreSQL 13-18 (64-bit) available in `Unreleased PostGIS Versions` and [OSGeo downloads][5]). Installers for 18(64-bit) available on [OSGeo downloads][5] and application stackbuilder. +Installers for PostgreSQL 13-17 will be available later. -PostGIS 3.5.3 bundle includes: +PostGIS 3.6.0 bundle includes: - * PostGIS 3.5.3 with MVT support, with raster, [GEOS](https://github.com/libgeos/geos/blob/3.13.1/NEWS.md) 3.13.1, [PROJ](https://proj.org/download.html#past-releases) 8.2.1, [SFCGAL](http://sfcgal.org) support (1.5.2), address_standardizer, topology + * PostGIS 3.6.0 with MVT support, with raster, [GEOS](https://libgeos.org/posts/2025-08-21-geos-3-14-released/) 3.14.0, [PROJ](https://proj.org/download.html#past-releases) 8.2.1, [SFCGAL](http://sfcgal.org) support (2.2.0), address_standardizer, topology * PostGIS Tiger geocoder extension - Tiger 2024 - * pgRouting 3.8 [pgRouting 3.8.0](https://docs.pgrouting.org/3.8/en/index.html) + * pgRouting 4.0 [pgRouting 4.0.0-alpha](https://docs.pgrouting.org/4.0/en/index.html) * Commandline raster loader (raster2pgsql), shapefile import/export (shp2pgsql,pgsql2shp) * Commandline [osm2pgrouting 2.3.8](https://github.com/pgRouting/osm2pgrouting/wiki/Documentation-for-osm2pgrouting-v2.3) for loading data from .osm files into pgRouting routable format * GUI: shp2pgsql-gui which has both import and export support for geometry/geography @@ -27,7 +28,7 @@ PostGIS 3.5.3 bundle includes: for querying LIDAR point cloud and in/out functions to convert to PostGIS geometry * [h3-pg](https://github.com/zachasme/h3-pg) 4.1.4 for using Uber h3 api and converting h3 index representations to postgis geometry/geography/raster (raster support is new in this release). - * [MobilityDB](https://mobilitydb.com) [v1.2.0](https://github.com/MobilityDB/MobilityDB/releases/tag/v1.2.0) + * [MobilityDB](https://mobilitydb.com) [v1.3.0-alpha](https://github.com/MobilityDB/MobilityDB/releases/tag/v1.3.0-alpha) for managing trajectories. Includes many temporal spatial types and functions for them. Refer to [Enabling PostGIS Extensions: MobilityDb](../enabling_postgis/#mobilitydb) for guidance. The simplest way to get PostGIS on Windows for the EnterpriseDb Windows PostgreSQL distribution is using the StackBuilder. ----------------------------------------------------------------------- Summary of changes: .../getting_started/install_windows/released_versions.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) hooks/post-receive -- postgis.net From git at osgeo.org Sun Oct 5 06:56:02 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 5 Oct 2025 06:56:02 -0700 (PDT) Subject: [SCM] postgis.net branch website updated. clarity-final-155-g270c679 Message-ID: <20251005135602.4AE6816E908@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "postgis.net". The branch, website has been updated via 270c679d3dd4ed57d45dbffdf92f6b0c81f9854f (commit) from bb591e9a3960d374defdfd24e83a11ccd196d840 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 270c679d3dd4ed57d45dbffdf92f6b0c81f9854f Author: Regina Obe Date: Sun Oct 5 09:55:57 2025 -0400 Fix release date of PG18 installers diff --git a/content/documentation/getting_started/install_windows/released_versions.md b/content/documentation/getting_started/install_windows/released_versions.md index 9b24042..b2e93bd 100644 --- a/content/documentation/getting_started/install_windows/released_versions.md +++ b/content/documentation/getting_started/install_windows/released_versions.md @@ -6,7 +6,7 @@ geekdocHidden: true geekdocHiddenTocTree: false --- -PostGIS 3.6.0 came out Sept 2nd, 2025. Windows PostGIS Bundle 3.6.0 installers for PostgreSQL 18 was released Sept 2nd 2025. +PostGIS 3.6.0 came out Sept 2nd, 2025. Windows PostGIS Bundle 3.6.0 installers for PostgreSQL 18 was released Oct 5th 2025. Binaries for versions of PostgreSQL 13-18 (64-bit) available in `Unreleased PostGIS Versions` and [OSGeo downloads][5]). Installers for 18(64-bit) available on [OSGeo downloads][5] and application stackbuilder. Installers for PostgreSQL 13-17 will be available later. ----------------------------------------------------------------------- Summary of changes: .../documentation/getting_started/install_windows/released_versions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- postgis.net From trac at osgeo.org Mon Oct 6 09:18:26 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 16:18:26 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.c9871b948b205b9097cdc9b7bbc8a5cd@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): OK, this is a "representation-of-5-as-double" kind of issue, combined with a design decision in GEOS ClipByRect. ClipByRect assumes that points on the boundary should be discarded. The variability in the result seems to be a "representation-of-5-as-double" issue. There is an existing test that checks {{{ /// Point on boundary template<> template<> void object::test<3>() { checkClipByRect( "POINT(15 10)", 10, 10, 20, 20, "POINT EMPTY" ); } }}} So, I can fix this problem in general by allowing boundary points to be part of the clip result, but only by changing existing behaviour. This would be more consistent than the current tests, which are being confused by cases that are boundary issues (the rectangle boundary checker is very complex). I wish this was just a bug. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Mon Oct 6 11:09:13 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 18:09:13 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.a89ce7429350a4700a3ad41bacc9ea38@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): Oh, duh, so the inconsistency is in the box short cut. The GEOS code enforces strict containment as the rule, but the PostGIS calling code has a box shortcut that is accepting the whole object if its bbox is covered by the rectangle. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Mon Oct 6 12:14:06 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 19:14:06 -0000 Subject: [PostGIS] #5997: Pg19 Crash Message-ID: <049.ad26eed4b7b2f3ecc6b1d3e58c09c996@osgeo.org> #5997: Pg19 Crash ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: critical | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Keywords: | ----------------------+--------------------------- As of a recent update to Pg19, our use of window functions is causing a crash. Reproduce: {{{ CREATE TEMPORARY TABLE cluster_inputs (id int, geom geometry); INSERT INTO cluster_inputs VALUES (1, 'LINESTRING (0 0, 1 1)'), (2, 'LINESTRING (5 5, 4 4)'), (3, NULL), (4, 'LINESTRING (0 0, -1 -1)'), (5, 'LINESTRING (6 6, 7 7)'), (6, 'POLYGON EMPTY'), (7, 'POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))'); SELECT 't5', id, ST_AsText(geom), ST_ClusterWithinWin(geom, 1.4) OVER () AS cluster FROM cluster_inputs; }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Mon Oct 6 12:38:57 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 19:38:57 -0000 Subject: [PostGIS] #5997: Pg19 Crash In-Reply-To: <049.ad26eed4b7b2f3ecc6b1d3e58c09c996@osgeo.org> References: <049.ad26eed4b7b2f3ecc6b1d3e58c09c996@osgeo.org> Message-ID: <064.3262ab30a2b513517bf69b9f0dca699d@osgeo.org> #5997: Pg19 Crash -----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: critical | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: -----------------------+--------------------------- Comment (by pramsey): Tracked it down, not our fault. https://github.com/postgres/postgres/commit/25a30bbd4235a49c854036c84fe90f2bc5a87652#r167294738 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 12:49:27 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 12:49:27 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-83-g389eaee28 Message-ID: <20251006194928.4DD246A6@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 389eaee2863b5b1d06a33670621f98bf56438680 (commit) from ac17b1d6a6364a81ad7a124b2f9ae257bda51e91 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 389eaee2863b5b1d06a33670621f98bf56438680 Author: Paul Ramsey Date: Mon Oct 6 12:49:11 2025 -0700 Make PostGIS and GEOS consistent in handling clipping at the border of the rectangle (both now clip boundary vertices) References #5962 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 16ee36e89..339214f0d 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1546,8 +1546,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } diff --git a/regress/core/tickets.sql b/regress/core/tickets.sql index 46490a912..4b580b003 100644 --- a/regress/core/tickets.sql +++ b/regress/core/tickets.sql @@ -1613,3 +1613,13 @@ CREATE TABLE test5987 (geom geometry(Geometry,4326)); INSERT INTO test5987 VALUES('LINESTRING(20 20,20.1 20,20.2 19.9)'::geometry); SELECT '#5987', ST_AsText(geom), ST_AsText(ST_GeometryN(geom, 1)) FROM test5987; DROP TABLE IF EXISTS test5987; + +-- ------------------------------------------------------------------------------------- +-- #5962 +SELECT '#5962', + ST_AsText(ST_ClipByBox2D( + ST_GeomFromText('MULTIPOINT((1 1),(3 4),(5 4))'), + ST_MakeEnvelope(0, 0, 5, 5)), 2), + ST_AsText(ST_ClipByBox2D( + ST_GeomFromText('MULTIPOINT((1 1),(6 4),(5 4))'), + ST_MakeEnvelope(0, 0, 5, 5 )), 2); diff --git a/regress/core/tickets_expected b/regress/core/tickets_expected index dd5538e62..0f2bf2f39 100644 --- a/regress/core/tickets_expected +++ b/regress/core/tickets_expected @@ -491,3 +491,4 @@ public|test5829|geom|2|4326|GEOMETRY public|test5978|geometry|2|4326|POINT public|test5978|shape|2|4326|POINT #5987|LINESTRING(20 20,20.1 20,20.2 19.9)|LINESTRING(20 20,20.1 20,20.2 19.9) +#5962|MULTIPOINT((1 1),(3 4))|POINT(1 1) ----------------------------------------------------------------------- Summary of changes: postgis/lwgeom_geos.c | 5 +++-- regress/core/tickets.sql | 10 ++++++++++ regress/core/tickets_expected | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 12:49:35 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 19:49:35 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.555683ffca0331cc49156712d4b8a981@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"389eaee2863b5b1d06a33670621f98bf56438680/git" 389eaee/git]: {{{#!CommitTicketReference repository="git" revision="389eaee2863b5b1d06a33670621f98bf56438680" Make PostGIS and GEOS consistent in handling clipping at the border of the rectangle (both now clip boundary vertices) References #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 14:36:54 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 14:36:54 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-84-g489825052 Message-ID: <20251006213654.69ED31571@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 489825052c458022fe8fe3b698e7d812461688fc (commit) from 389eaee2863b5b1d06a33670621f98bf56438680 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 489825052c458022fe8fe3b698e7d812461688fc Author: Paul Ramsey Date: Mon Oct 6 14:36:46 2025 -0700 Support build under Pg19devel diff --git a/postgis/lwgeom_transform.c b/postgis/lwgeom_transform.c index df9cf4e4d..58bbac8d6 100644 --- a/postgis/lwgeom_transform.c +++ b/postgis/lwgeom_transform.c @@ -22,13 +22,16 @@ * **********************************************************************/ +#include "../postgis_config.h" #include "postgres.h" #include "fmgr.h" #include "funcapi.h" +#if POSTGIS_PGSQL_VERSION >= 190 +#include "access/htup_details.h" +#endif #include "utils/builtins.h" -#include "../postgis_config.h" #include "liblwgeom.h" #include "lwgeodetic.h" #include "stringbuffer.h" ----------------------------------------------------------------------- Summary of changes: postgis/lwgeom_transform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Mon Oct 6 14:37:40 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 14:37:40 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-85-g419aa9519 Message-ID: <20251006213740.3A0CC2425@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 419aa9519f970de44b1bd1ed770f5932f53c0c36 (commit) from 489825052c458022fe8fe3b698e7d812461688fc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 419aa9519f970de44b1bd1ed770f5932f53c0c36 Author: Paul Ramsey Date: Mon Oct 6 14:37:27 2025 -0700 Fix raycast for linestrings, references #5989 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 58e7cb4ba..c95bf21e1 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -89,6 +89,14 @@ static void test_mindistance2d_tolerance(void) double zero_accepted_error = 0.0; + /* + * CurvePolygon and Point, #5989 + */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE((129296 142584,94722 100435,91618 97138,57306 60686,26874 28357,13059 34228,14572 65506,14593 65948,14616 66389),CIRCULARSTRING(14616 66389,17955 101124,24417 135415,24655 136418,24895 137421),(24895 137421,25472 139809,19354 141285,0 0,148000 142000,129296 142584)))", + "POINT(19925 112376)", + 199.655, 0.001); + /* ** Simple case. */ diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index a2cb2b037..5cb90a04c 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -107,25 +107,11 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) } int -lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P) { - // Check if the point is within the bounding box of the segment - if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || - p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) - { - return LW_FALSE; - } - - // Check for collinearity using the 2D cross-product. - // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) - double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); - - if (fabs(cross_product) < DBL_EPSILON) - { - return LW_TRUE; // Point is collinear and within the bounding box - } - - return LW_TRUE; + int side = lw_segment_side(A1, A2, P); + if (side != 0) return LW_FALSE; + return lw_pt_in_seg(P, A1, A2); } /** ----------------------------------------------------------------------- Summary of changes: liblwgeom/cunit/cu_measures.c | 8 ++++++++ liblwgeom/lwalgorithm.c | 22 ++++------------------ 2 files changed, 12 insertions(+), 18 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 14:37:41 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 21:37:41 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.73e339cb25d7b48dd687920d0ec9efb9@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"419aa9519f970de44b1bd1ed770f5932f53c0c36/git" 419aa951/git]: {{{#!CommitTicketReference repository="git" revision="419aa9519f970de44b1bd1ed770f5932f53c0c36" Fix raycast for linestrings, references #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 14:37:53 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 14:37:53 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-14-gbd6c4c16d Message-ID: <20251006213753.3C0D531AD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via bd6c4c16dc8d3d6a2bc9332efc052867097f3ff3 (commit) from e185d2dfae4fad62ac4b9da87ab2e1a9f4ddfb48 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bd6c4c16dc8d3d6a2bc9332efc052867097f3ff3 Author: Paul Ramsey Date: Mon Oct 6 14:26:43 2025 -0700 Fix raycast for linestrings, references #5989 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 58e7cb4ba..c95bf21e1 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -89,6 +89,14 @@ static void test_mindistance2d_tolerance(void) double zero_accepted_error = 0.0; + /* + * CurvePolygon and Point, #5989 + */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE((129296 142584,94722 100435,91618 97138,57306 60686,26874 28357,13059 34228,14572 65506,14593 65948,14616 66389),CIRCULARSTRING(14616 66389,17955 101124,24417 135415,24655 136418,24895 137421),(24895 137421,25472 139809,19354 141285,0 0,148000 142000,129296 142584)))", + "POINT(19925 112376)", + 199.655, 0.001); + /* ** Simple case. */ diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index a2cb2b037..5cb90a04c 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -107,25 +107,11 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) } int -lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P) { - // Check if the point is within the bounding box of the segment - if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || - p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) - { - return LW_FALSE; - } - - // Check for collinearity using the 2D cross-product. - // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) - double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); - - if (fabs(cross_product) < DBL_EPSILON) - { - return LW_TRUE; // Point is collinear and within the bounding box - } - - return LW_TRUE; + int side = lw_segment_side(A1, A2, P); + if (side != 0) return LW_FALSE; + return lw_pt_in_seg(P, A1, A2); } /** ----------------------------------------------------------------------- Summary of changes: liblwgeom/cunit/cu_measures.c | 8 ++++++++ liblwgeom/lwalgorithm.c | 22 ++++------------------ 2 files changed, 12 insertions(+), 18 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 14:37:54 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 21:37:54 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.bf864cf65c8dcd32831493956f3d629c@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"bd6c4c16dc8d3d6a2bc9332efc052867097f3ff3/git" bd6c4c1/git]: {{{#!CommitTicketReference repository="git" revision="bd6c4c16dc8d3d6a2bc9332efc052867097f3ff3" Fix raycast for linestrings, references #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 14:48:51 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 14:48:51 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-65-g17b3a4ac3 Message-ID: <20251006214851.B033C3046@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 17b3a4ac3d1eff3a22eba4bbb88e9f358479d4f1 (commit) from ad84988e23da71ad8dcda1e878641c18f3a1113a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 17b3a4ac3d1eff3a22eba4bbb88e9f358479d4f1 Author: Paul Ramsey Date: Mon Oct 6 14:26:43 2025 -0700 Fix raycast for linestrings, references #5989 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 58e7cb4ba..c95bf21e1 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -89,6 +89,14 @@ static void test_mindistance2d_tolerance(void) double zero_accepted_error = 0.0; + /* + * CurvePolygon and Point, #5989 + */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE((129296 142584,94722 100435,91618 97138,57306 60686,26874 28357,13059 34228,14572 65506,14593 65948,14616 66389),CIRCULARSTRING(14616 66389,17955 101124,24417 135415,24655 136418,24895 137421),(24895 137421,25472 139809,19354 141285,0 0,148000 142000,129296 142584)))", + "POINT(19925 112376)", + 199.655, 0.001); + /* ** Simple case. */ diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index ea59575d3..ad0150e20 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -107,25 +107,11 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) } int -lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P) { - // Check if the point is within the bounding box of the segment - if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || - p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) - { - return LW_FALSE; - } - - // Check for collinearity using the 2D cross-product. - // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) - double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); - - if (fabs(cross_product) < DBL_EPSILON) - { - return LW_TRUE; // Point is collinear and within the bounding box - } - - return LW_TRUE; + int side = lw_segment_side(A1, A2, P); + if (side != 0) return LW_FALSE; + return lw_pt_in_seg(P, A1, A2); } /** ----------------------------------------------------------------------- Summary of changes: liblwgeom/cunit/cu_measures.c | 8 ++++++++ liblwgeom/lwalgorithm.c | 22 ++++------------------ 2 files changed, 12 insertions(+), 18 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 14:48:53 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 21:48:53 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.efbc608ff1be105f4abe4bca4ace4fd3@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"17b3a4ac3d1eff3a22eba4bbb88e9f358479d4f1/git" 17b3a4a/git]: {{{#!CommitTicketReference repository="git" revision="17b3a4ac3d1eff3a22eba4bbb88e9f358479d4f1" Fix raycast for linestrings, references #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 14:48:56 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 14:48:56 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-58-gff86b0204 Message-ID: <20251006214856.4508A3047@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via ff86b0204c253be159154cc718f49bce3c5a8e08 (commit) via e0b431b6dcf0394da7bad09ee531d6098bdd99d3 (commit) from ceb807b1c4ebd8c00179707738aad8fc09f490d1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ff86b0204c253be159154cc718f49bce3c5a8e08 Author: Paul Ramsey Date: Mon Oct 6 14:26:43 2025 -0700 Fix raycast for linestrings, references #5989 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 58e7cb4ba..c95bf21e1 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -89,6 +89,14 @@ static void test_mindistance2d_tolerance(void) double zero_accepted_error = 0.0; + /* + * CurvePolygon and Point, #5989 + */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE((129296 142584,94722 100435,91618 97138,57306 60686,26874 28357,13059 34228,14572 65506,14593 65948,14616 66389),CIRCULARSTRING(14616 66389,17955 101124,24417 135415,24655 136418,24895 137421),(24895 137421,25472 139809,19354 141285,0 0,148000 142000,129296 142584)))", + "POINT(19925 112376)", + 199.655, 0.001); + /* ** Simple case. */ diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index 331d4c14d..cd2295975 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -99,25 +99,11 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) } int -lw_pt_on_segment(const POINT2D* p1, const POINT2D* p2, const POINT2D* p) +lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P) { - // Check if the point is within the bounding box of the segment - if (p->x < FP_MIN(p1->x, p2->x) || p->x > FP_MAX(p1->x, p2->x) || - p->y < FP_MIN(p1->y, p2->y) || p->y > FP_MAX(p1->y, p2->y)) - { - return LW_FALSE; - } - - // Check for collinearity using the 2D cross-product. - // (p.y - p1.y) * (p2.x - p1.x) - (p.x - p1.x) * (p2.y - p1.y) - double cross_product = (p->y - p1->y) * (p2->x - p1->x) - (p->x - p1->x) * (p2->y - p1->y); - - if (fabs(cross_product) < DBL_EPSILON) - { - return LW_TRUE; // Point is collinear and within the bounding box - } - - return LW_TRUE; + int side = lw_segment_side(A1, A2, P); + if (side != 0) return LW_FALSE; + return lw_pt_in_seg(P, A1, A2); } /** commit e0b431b6dcf0394da7bad09ee531d6098bdd99d3 Author: Paul Ramsey Date: Fri Oct 3 10:08:26 2025 -0700 Pg19 build support diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h index 151138a8c..d7706ff52 100644 --- a/libpgcommon/lwgeom_pg.h +++ b/libpgcommon/lwgeom_pg.h @@ -88,13 +88,23 @@ void pg_install_lwgeom_handlers(void); /* Argument handling macros */ #define PG_GETARG_GSERIALIZED_P(varno) ((GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(varno))) + #define PG_GETARG_GSERIALIZED_P_COPY(varno) ((GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(varno))) + #define PG_GSERIALIZED_DATUM_NEEDS_DETOAST(datum) \ (VARATT_IS_EXTENDED((datum)) || VARATT_IS_EXTERNAL((datum)) || VARATT_IS_COMPRESSED((datum))) + +#if POSTGIS_PGSQL_VERSION >= 190 +#define PG_GETARG_GSERIALIZED_HEADER(varno) \ + PG_GSERIALIZED_DATUM_NEEDS_DETOAST(DatumGetPointer(PG_GETARG_DATUM(varno))) \ + ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ + : ((GSERIALIZED *)(PG_GETARG_POINTER(varno))) +#else #define PG_GETARG_GSERIALIZED_HEADER(varno) \ PG_GSERIALIZED_DATUM_NEEDS_DETOAST(PG_GETARG_DATUM(varno)) \ ? ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size())) \ : ((GSERIALIZED *)(PG_GETARG_DATUM(varno))) +#endif /* Debugging macros */ #if POSTGIS_DEBUG_LEVEL > 0 ----------------------------------------------------------------------- Summary of changes: liblwgeom/cunit/cu_measures.c | 8 ++++++++ liblwgeom/lwalgorithm.c | 22 ++++------------------ libpgcommon/lwgeom_pg.h | 10 ++++++++++ 3 files changed, 22 insertions(+), 18 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 14:48:57 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 21:48:57 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.28c5d33fd970e1547ce1632ca06f41c9@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"ff86b0204c253be159154cc718f49bce3c5a8e08/git" ff86b02/git]: {{{#!CommitTicketReference repository="git" revision="ff86b0204c253be159154cc718f49bce3c5a8e08" Fix raycast for linestrings, references #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 16:39:17 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 16:39:17 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-15-g190595e66 Message-ID: <20251006233917.47F6C3232@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via 190595e666d97bcc20f514f74f8b857509f226c6 (commit) from bd6c4c16dc8d3d6a2bc9332efc052867097f3ff3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 190595e666d97bcc20f514f74f8b857509f226c6 Author: Paul Ramsey Date: Mon Oct 6 16:38:56 2025 -0700 Consistent clipping of MULTI/POINT (Paul Ramsey) References #5962 diff --git a/NEWS b/NEWS index a3cd68d68..f60416789 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PostGIS 3.6.1 - #5991, CircularString distance error (Paul Ramsey) - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) - #5998, ST_Distance error on CurvePolygon (Paul Ramsey) + - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) PostGIS 3.6.0 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 16ee36e89..339214f0d 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1546,8 +1546,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/lwgeom_geos.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 16:39:31 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 23:39:31 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.a27b93b1b37ae8ab757ec4ac40c7dce1@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"190595e666d97bcc20f514f74f8b857509f226c6/git" 190595e/git]: {{{#!CommitTicketReference repository="git" revision="190595e666d97bcc20f514f74f8b857509f226c6" Consistent clipping of MULTI/POINT (Paul Ramsey) References #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 16:41:08 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 16:41:08 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-66-g89ebcc501 Message-ID: <20251006234108.6E6313511@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 89ebcc501e570813f576d7aae785f7e88e395db9 (commit) from 17b3a4ac3d1eff3a22eba4bbb88e9f358479d4f1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 89ebcc501e570813f576d7aae785f7e88e395db9 Author: Paul Ramsey Date: Mon Oct 6 16:41:01 2025 -0700 Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 diff --git a/NEWS b/NEWS index 14a0e8674..b41abc6a1 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. - #5991, CircularString distance error (Paul Ramsey) - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) - #5989, ST_Distance error on CurvePolygon (Paul Ramsey) +- #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) PostGIS 3.5.3 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 717a597e4..a1d07df36 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1546,8 +1546,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/lwgeom_geos.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 16:41:19 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 23:41:19 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.ce010c8a96842654306e7996f4565d8f@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"89ebcc501e570813f576d7aae785f7e88e395db9/git" 89ebcc50/git]: {{{#!CommitTicketReference repository="git" revision="89ebcc501e570813f576d7aae785f7e88e395db9" Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 16:41:48 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 16:41:48 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-59-gf9dbfd1a8 Message-ID: <20251006234149.0B4D13515@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via f9dbfd1a801b47f4ec0ca8f9438b3bfa11bff470 (commit) from ff86b0204c253be159154cc718f49bce3c5a8e08 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f9dbfd1a801b47f4ec0ca8f9438b3bfa11bff470 Author: Paul Ramsey Date: Mon Oct 6 16:41:43 2025 -0700 Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 diff --git a/NEWS b/NEWS index 53f01c3bf..e1500842a 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,7 @@ Proj 6.1+ required. - #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) - #5991, CircularString distance error (Paul Ramsey) - #5989, ST_Distance error on CurvePolygon (Paul Ramsey) + - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) PostGIS 3.4.4 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 77d8f5f0e..c008df184 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1615,8 +1615,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/lwgeom_geos.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 16:41:50 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 23:41:50 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.e498ec821ad6e8f88bd89429397e575f@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"f9dbfd1a801b47f4ec0ca8f9438b3bfa11bff470/git" f9dbfd1a/git]: {{{#!CommitTicketReference repository="git" revision="f9dbfd1a801b47f4ec0ca8f9438b3bfa11bff470" Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 16:43:12 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 16:43:12 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.2 updated. 3.2.7-52-gf42e6f14b Message-ID: <20251006234312.30E61358A@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.2 has been updated via f42e6f14b23de1971059efff3cf37c8e659ad770 (commit) from a5bf611dc7ee92674b0882a7c1bbd404bd9d32e5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f42e6f14b23de1971059efff3cf37c8e659ad770 Author: Paul Ramsey Date: Mon Oct 6 16:43:05 2025 -0700 Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 diff --git a/NEWS b/NEWS index a6ec3149d..e04537370 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,7 @@ Proj 4.9+ required. - #5909, ST_ValueCount crashes on empty table (Paul Ramsey) - #5917, ST_Relate becomes unresponsive (Paul Ramsey) - #5991, CircularString distance error (Paul Ramsey) + - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) PostGIS 3.2.8 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 27b7de311..30be9a363 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1518,8 +1518,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/lwgeom_geos.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 16:43:13 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 23:43:13 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.33c1bd766bab73aa81d4e8ea3116eb4c@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"f42e6f14b23de1971059efff3cf37c8e659ad770/git" f42e6f14/git]: {{{#!CommitTicketReference repository="git" revision="f42e6f14b23de1971059efff3cf37c8e659ad770" Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 6 16:43:48 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 6 Oct 2025 16:43:48 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.1 updated. 3.1.11-43-g422163cfb Message-ID: <20251006234348.B7F03328C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.1 has been updated via 422163cfb7af7c6a534cd479fbbd9f5de63ab01c (commit) from 50b214e52432bc39aa3cfd20038c696433626b67 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 422163cfb7af7c6a534cd479fbbd9f5de63ab01c Author: Paul Ramsey Date: Mon Oct 6 16:43:43 2025 -0700 Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 diff --git a/NEWS b/NEWS index 32dd7f80d..ec9f6bd22 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ YYYY/MM/DD - #5909, ST_ValueCount crashes on empty table (Paul Ramsey) - #5917, ST_Relate becomes unresponsive (Paul Ramsey) - #5991, CircularString distance error (Paul Ramsey) + - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) PostGIS 3.1.12 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index f69509008..d0d832531 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1583,8 +1583,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/lwgeom_geos.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 6 16:43:50 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 23:43:50 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.dfcc4bb842d0ce4984dd211ce8a27a1c@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"422163cfb7af7c6a534cd479fbbd9f5de63ab01c/git" 422163cf/git]: {{{#!CommitTicketReference repository="git" revision="422163cfb7af7c6a534cd479fbbd9f5de63ab01c" Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Mon Oct 6 16:44:40 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 06 Oct 2025 23:44:40 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.8a66de1c93898eef3b190243b0cde99b@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: closed Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 02:47:17 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 09:47:17 -0000 Subject: [PostGIS] #5688: Allow 0-tolerance topology loading In-Reply-To: <046.4325684cbbc21e167034a6e979d08945@osgeo.org> References: <046.4325684cbbc21e167034a6e979d08945@osgeo.org> Message-ID: <061.8319597b711c7850fbd55cee17764999@osgeo.org> #5688: Allow 0-tolerance topology loading --------------------------+--------------------------- Reporter: strk | Owner: strk Type: enhancement | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: topology | Version: master Resolution: | Keywords: --------------------------+--------------------------- Description changed by strk: Old description: > Currently not available as a value of 0 passed to the topology population > functions mean "use the precision found in the topology.topology record" > and a 0 in the topology.topology record means "use a computed precision > based on input geometry". > > A WIP to add proper 0-tolerance support (to avoid snapping) is here: > https://git.osgeo.org/gitea/postgis/postgis/pulls/6 New description: Currently not available as a value of 0 passed to the topology population functions mean "use the precision found in the topology.topology record" and a 0 in the topology.topology record means "use a computed precision based on input geometry". A WIP to add proper 0-tolerance support (to avoid snapping) is here: https://gitea.osgeo.org/postgis/postgis/pulls/271 -- -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 11:53:01 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 11:53:01 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-87-g22cc67618 Message-ID: <20251007185301.65973133CDF@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 22cc676181c68cb32bc932e1570c2766964ff847 (commit) via 2b76117f390b19cfd21daed40fb150322e8802c1 (commit) from 419aa9519f970de44b1bd1ed770f5932f53c0c36 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 22cc676181c68cb32bc932e1570c2766964ff847 Merge: 419aa9519 2b76117f3 Author: Paul Ramsey Date: Tue Oct 7 11:52:57 2025 -0700 Merge branch 'ProjectMutilation-fix-memleak' commit 2b76117f390b19cfd21daed40fb150322e8802c1 Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:02:03 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:02:03 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-88-g7dbb676e8 Message-ID: <20251007190203.EDF27134E4F@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 7dbb676e8901f39bb0318939a0317f9042b897be (commit) from 22cc676181c68cb32bc932e1570c2766964ff847 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7dbb676e8901f39bb0318939a0317f9042b897be Author: Paul Ramsey Date: Tue Oct 7 12:01:41 2025 -0700 Fix definition of ST_CoverageClean parameter order diff --git a/doc/reference_coverage.xml b/doc/reference_coverage.xml index 304d7c2e8..a98c58427 100644 --- a/doc/reference_coverage.xml +++ b/doc/reference_coverage.xml @@ -328,10 +328,10 @@ MULTIPOLYGON (((10 150, 80 190, 110 150, 140 80, 120 10, 10 10, 10 150), (50 60, geometry ST_CoverageClean geometry winset geom - float8 - snappingDistance = -1 float8 gapMaximumWidth = 0 + float8 + snappingDistance = -1 text overlapMergeStrategy = 'MERGE_LONGEST_BORDER' ----------------------------------------------------------------------- Summary of changes: doc/reference_coverage.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:02:22 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:02:22 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-16-gdde0f5518 Message-ID: <20251007190222.B8145135DC2@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via dde0f5518a0941e207a7ac5faecd1385c38c6737 (commit) from 190595e666d97bcc20f514f74f8b857509f226c6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dde0f5518a0941e207a7ac5faecd1385c38c6737 Author: Paul Ramsey Date: Tue Oct 7 12:01:41 2025 -0700 Fix definition of ST_CoverageClean parameter order diff --git a/doc/reference_coverage.xml b/doc/reference_coverage.xml index 304d7c2e8..a98c58427 100644 --- a/doc/reference_coverage.xml +++ b/doc/reference_coverage.xml @@ -328,10 +328,10 @@ MULTIPOLYGON (((10 150, 80 190, 110 150, 140 80, 120 10, 10 10, 10 150), (50 60, geometry ST_CoverageClean geometry winset geom - float8 - snappingDistance = -1 float8 gapMaximumWidth = 0 + float8 + snappingDistance = -1 text overlapMergeStrategy = 'MERGE_LONGEST_BORDER' ----------------------------------------------------------------------- Summary of changes: doc/reference_coverage.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:07:32 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:07:32 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.7-60-g71b0a452e Message-ID: <20251007190732.C548913627A@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via 71b0a452ea5a3869ad05249e3b0b4f92644858e6 (commit) via 27c003d95479c54b145d5ad88cd503bb569d7580 (commit) from 9c7b4d441b4470dbaef1ca869ee2eeb0f7d59bed (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 71b0a452ea5a3869ad05249e3b0b4f92644858e6 Author: Paul Ramsey Date: Tue Oct 7 12:07:16 2025 -0700 Update distance calculations for CurvePolygon, references #5989 diff --git a/NEWS b/NEWS index fa76e6db1..610253a33 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ Proj 4.9+ required. - #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) - #5991, CircularString distance error (Paul Ramsey) - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) + - #5989, CurvePolygon distance error (Paul Ramsey) PostGIS 3.3.8 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index 610b2a593..9713bf653 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -88,6 +88,13 @@ static void test_mindistance2d_tolerance(void) double default_accepted_error = 0.00001; double zero_accepted_error = 0.0; + /* + * CurvePolygon and Point, #5989 + */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE((129296 142584,94722 100435,91618 97138,57306 60686,26874 28357,13059 34228,14572 65506,14593 65948,14616 66389),CIRCULARSTRING(14616 66389,17955 101124,24417 135415,24655 136418,24895 137421),(24895 137421,25472 139809,19354 141285,0 0,148000 142000,129296 142584)))", + "POINT(19925 112376)", + 199.655, 0.001); /* ** Simple case. diff --git a/liblwgeom/cunit/cu_ptarray.c b/liblwgeom/cunit/cu_ptarray.c index 3b6cec8fc..48d6a3b24 100644 --- a/liblwgeom/cunit/cu_ptarray.c +++ b/liblwgeom/cunit/cu_ptarray.c @@ -554,7 +554,7 @@ static void test_ptarrayarc_contains_point() cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); //printf("%s\n", cu_error_msg); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg); + ASSERT_STRING_EQUAL("ptarrayarc_raycast_intersections called with even number of points", cu_error_msg); /*** Unclosed ring ***/ lwline_free(lwline); diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index 8fae3a8e6..cb3565c71 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -433,6 +433,7 @@ int lw_arc_side(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, const P int lw_arc_calculate_gbox_cartesian_2d(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, GBOX *gbox); double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result); int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2); +int lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P); int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); double lw_seg_length(const POINT2D *A1, const POINT2D *A2); @@ -442,6 +443,8 @@ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); +int ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); +int ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt); int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt); diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index 5d2fffb17..a9f68f084 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -49,10 +49,8 @@ p3d_same(const POINT3D *p1, const POINT3D *p2) int p2d_same(const POINT2D *p1, const POINT2D *p2) { - if( FP_EQUALS(p1->x,p2->x) && FP_EQUALS(p1->y,p2->y) ) - return LW_TRUE; - else - return LW_FALSE; + return FP_EQUALS(p1->x, p2->x) + && FP_EQUALS(p1->y, p2->y); } /** @@ -85,7 +83,9 @@ lw_seg_length(const POINT2D *A1, const POINT2D *A2) int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3) { - return lw_segment_side(A1, A3, A2) == lw_segment_side(A1, A3, P); + int pt_side = lw_segment_side(A1, A3, P); + int arc_side = lw_segment_side(A1, A3, A2); + return pt_side == 0 || pt_side == arc_side; } /** @@ -99,6 +99,14 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) ((A1->y <= P->y && P->y < A2->y) || (A1->y >= P->y && P->y > A2->y)); } +int +lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P) +{ + int side = lw_segment_side(A1, A2, P); + if (side != 0) return LW_FALSE; + return lw_pt_in_seg(P, A1, A2); +} + /** * Returns true if arc A is actually a point (all vertices are the same) . */ diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c index 03f4201cd..f7363d069 100644 --- a/liblwgeom/lwcompound.c +++ b/liblwgeom/lwcompound.c @@ -141,63 +141,49 @@ int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) return LW_FAILURE; } + +/* + * Use a ray-casting count to determine if the point + * is inside or outside of the compound curve. Ray-casting + * is run against each component of the overall arc, and + * the even/odd test run against the total of all components. + * Returns LW_INSIDE / LW_BOUNDARY / LW_OUTSIDE + */ int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { - uint32_t i; - LWLINE *lwline; - LWCIRCSTRING *lwcirc; - int wn = 0; - int winding_number = 0; - int result; + int intersections = 0; - for ( i = 0; i < comp->ngeoms; i++ ) + if (lwgeom_is_empty(lwcompound_as_lwgeom(comp))) + return LW_OUTSIDE; + + for (uint32_t j = 0; j < comp->ngeoms; j++) { - LWGEOM *lwgeom = comp->geoms[i]; - if ( lwgeom->type == LINETYPE ) + int on_boundary = LW_FALSE; + const LWGEOM *sub = comp->geoms[j]; + if (sub->type == LINETYPE) { - lwline = lwgeom_as_lwline(lwgeom); - if ( comp->ngeoms == 1 ) - { - return ptarray_contains_point(lwline->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); - } + LWLINE *lwline = lwgeom_as_lwline(sub); + intersections += ptarray_raycast_intersections(lwline->points, pt, &on_boundary); + } + else if (sub->type == CIRCSTRINGTYPE) + { + LWCIRCSTRING *lwcirc = lwgeom_as_lwcircstring(sub); + intersections += ptarrayarc_raycast_intersections(lwcirc->points, pt, &on_boundary); } else { - lwcirc = lwgeom_as_lwcircstring(lwgeom); - if ( ! lwcirc ) { - lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); - return 0; - } - if ( comp->ngeoms == 1 ) - { - return ptarrayarc_contains_point(lwcirc->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); - } + lwerror("%s: unsupported type %s", __func__, lwtype_name(sub->type)); } - - /* Propogate boundary condition */ - if ( result == LW_BOUNDARY ) + if (on_boundary) return LW_BOUNDARY; - - wn += winding_number; } - /* Outside */ - if (wn == 0) - return LW_OUTSIDE; - - /* Inside */ - return LW_INSIDE; + /* + * Odd number of intersections means inside. + * Even means outside. + */ + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } LWCOMPOUND * diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index a2353965a..69e5ed494 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1552,25 +1552,154 @@ int lw_dist2d_arc_arc_concentric(const POINT2D *A1, const POINT2D *CENTER, DISTPTS *dl); -int -lw_dist2d_arc_arc(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - DISTPTS *dl) + +/** + * @brief Calculates the intersection points of a circle and line. + * + * This function assumes the center and test point are distinct. + * Finds the line between the circle center and test point, and + * the two intersection points on the circle defined by that line. + * If those points fall within the provided arc (A1,A2,A3) then + * the points are added to the provided array (I) and the array + * length counter is incremented. + * + * @param A1 Point of arc + * @param A2 Point of arc + * @param A3 Point of arc + * @param center_A Center of arc A circle + * @param radius_A Radius of arc A circle + * @param P Point to use in calculating intersection line + * @param I [out] Pointer to an return value array + * @param ni [out] Pointer to return array size counter + * @return int + */ +static int +lw_dist2d_circle_intersections( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *center_A, + double radius_A, + const POINT2D *P, + POINT2D *I, + uint32_t *ni) { - POINT2D CA, CB; /* Center points of arcs A and B */ + POINT2D R; + + // If the test point is on the center of the other + // arc, some other point has to be closer, by definition. + if (p2d_same(center_A, P)) + return 0; + + // Calculate vector from the center to the pt + double dir_x = center_A->x - P->x; + double dir_y = center_A->y - P->y; + double dist = sqrt(dir_x * dir_x + dir_y * dir_y); + + // Normalize the direction vector to get a unit vector (length = 1) + double unit_x = dir_x / dist; + double unit_y = dir_y / dist; + + // Calculate the two intersection points on the circle + // Point 1: Move from center_A along the unit vector by distance radius_A + R.x = center_A->x + unit_x * radius_A; + R.y = center_A->y + unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + // Point 2: Move from center_A against the unit vector by distance radius_A + R.x = center_A->x - unit_x * radius_A; + R.y = center_A->y - unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + return 0; +} + + +/** + * @brief Calculates the intersection points of two overlapping circles. + * + * This function assumes the circles are known to intersect at one or two points. + * Specifically, the distance 'd' between their centers must satisfy: + * d < (rA + rB) and d > fabs(rA - rB) + * If these conditions are not met, the results are undefined. + * + * @param cA [in] Pointer to the center point of the first circle (A). + * @param rA [in] The radius of the first circle (A). + * @param cB [in] Pointer to the center point of the second circle (B). + * @param rB [in] The radius of the second circle (B). + * @param I [out] Pointer to an array of at least 2 POINT2D structs to store the results. + * I[0] will contain the first intersection point. + * If a second exists, it will be in I[1]. + * @return int The number of intersection points found (1 or 2). Returns 0 if + * the centers are coincident or another error occurs. + */ +static uint32_t +lw_dist2d_circle_circle_intersections( + const POINT2D *cA, double rA, + const POINT2D *cB, double rB, + POINT2D *I) +{ + // Vector from center A to center B + double dx = cB->x - cA->x; + double dy = cB->y - cA->y; + + // Distance between the centers + double d = sqrt(dx * dx + dy * dy); + + // 'a' is the distance from the center of circle A to the point P, + // which is the base of the right triangle formed by cA, P, and an intersection point. + double a = (rA * rA - rB * rB + d * d) / (2.0 * d); + + // 'h' is the height of that right triangle. + double h_squared = rA * rA - a * a; + + // Due to floating point errors, h_squared can be slightly negative. + // This happens when the circles are perfectly tangent. Clamp to 0. + if (h_squared < 0.0) + h_squared = 0.0; + + double h = sqrt(h_squared); + + // Find the coordinates of point P + double Px = cA->x + a * (dx / d); + double Py = cA->y + a * (dy / d); + + // The two intersection points are found by moving from P by a distance 'h' + // in directions perpendicular to the line connecting the centers. + // The perpendicular vector to (dx, dy) is (-dy, dx). + + // Intersection point 1 + I[0].x = Px - h * (dy / d); + I[0].y = Py + h * (dx / d); + + // If h is very close to 0, the circles are tangent and there's only one intersection point. + if (FP_IS_ZERO(h)) + return 1; + + // Intersection point 2 + I[1].x = Px + h * (dy / d); + I[1].y = Py - h * (dx / d); + + return 2; +} + +int +lw_dist2d_arc_arc( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, + DISTPTS *dl) +{ + POINT2D pts_A[16]; /* Points on A that might be the nearest */ + POINT2D pts_B[16]; /* Points on B that might be the nearest */ + uint32_t ai = 0, bi = 0; /* Number of points in pts_A and pts_B */ + POINT2D center_A, center_B; /* Center points of arcs A and B */ double radius_A, radius_B, d; /* Radii of arcs A and B */ - POINT2D D; /* Mid-point between the centers CA and CB */ - int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */ + int is_disjoint, is_overlapping, is_contained, is_same_center; + POINT2D intersectionPts[2]; if (dl->mode != DIST_MIN) lwerror("lw_dist2d_arc_arc only supports mindistance"); - /* TODO: Handle case where arc is closed circle (A1 = A3) */ - /* What if one or both of our "arcs" is actually a point? */ if (lw_arc_is_pt(B1, B2, B3) && lw_arc_is_pt(A1, A2, A3)) return lw_dist2d_pt_pt(B1, A1, dl); @@ -1580,8 +1709,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, return lw_dist2d_pt_arc(A1, B1, B2, B3, dl); /* Calculate centers and radii of circles. */ - radius_A = lw_arc_center(A1, A2, A3, &CA); - radius_B = lw_arc_center(B1, B2, B3, &CB); + radius_A = lw_arc_center(A1, A2, A3, ¢er_A); + radius_B = lw_arc_center(B1, B2, B3, ¢er_B); /* Two co-linear arcs?!? That's two segments. */ if (radius_A < 0 && radius_B < 0) @@ -1595,275 +1724,112 @@ lw_dist2d_arc_arc(const POINT2D *A1, if (radius_B < 0) return lw_dist2d_seg_arc(B1, B3, A1, A2, A3, dl); - /* Center-center distance */ - d = distance2d_pt_pt(&CA, &CB); + /* Circle relationships */ + d = distance2d_pt_pt(¢er_A, ¢er_B); + is_disjoint = (d > (radius_A + radius_B)); + is_contained = (d < fabs(radius_A - radius_B)); + is_same_center = p2d_same(¢er_A, ¢er_B); + is_overlapping = ! (is_disjoint || is_contained || is_same_center); - /* Concentric arcs */ - if (FP_EQUALS(d, 0.0)) - return lw_dist2d_arc_arc_concentric(A1, A2, A3, radius_A, B1, B2, B3, radius_B, &CA, dl); + /* + * Prime the array of potential closest points with the + * arc end points, which frequently participate in closest + * points. + */ + pts_A[ai++] = *A1; + pts_A[ai++] = *A3; + pts_B[bi++] = *B1; + pts_B[bi++] = *B3; - /* Make sure that arc "A" has the bigger radius */ - if (radius_B > radius_A) + /* + * Overlapping circles might have a zero distance + * case if the circle intersection points are inside both + * arcs. + */ + if (is_overlapping) { - const POINT2D *tmp; - POINT2D TP; /* Temporary point P */ - double td; - tmp = B1; - B1 = A1; - A1 = tmp; - tmp = B2; - B2 = A2; - A2 = tmp; - tmp = B3; - B3 = A3; - A3 = tmp; - TP = CB; - CB = CA; - CA = TP; - td = radius_B; - radius_B = radius_A; - radius_A = td; - } - - /* Circles touch at a point. Is that point within the arcs? */ - if (d == (radius_A + radius_B)) - { - D.x = CA.x + (CB.x - CA.x) * radius_A / d; - D.y = CA.y + (CB.y - CA.y) * radius_A / d; - - pt_in_arc_A = lw_pt_in_arc(&D, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&D, B1, B2, B3); - - /* Arcs do touch at D, return it */ - if (pt_in_arc_A && pt_in_arc_B) + /* + * Find the two points the circles intersect at. + */ + uint32_t npoints = lw_dist2d_circle_circle_intersections( + ¢er_A, radius_A, + ¢er_B, radius_B, + intersectionPts); + for (uint32_t i = 0; i < npoints; i++) { - lw_dist2d_distpts_set(dl, 0.0, &D, &D); - return LW_TRUE; + /* + * If an intersection point is contained in both + * arcs, that is a location of zero distance, so + * we are done calculating. + */ + if (lw_pt_in_arc(&intersectionPts[i], A1, A2, A3) && + lw_pt_in_arc(&intersectionPts[i], B1, B2, B3)) + { + lw_dist2d_distpts_set(dl, 0.0, &intersectionPts[i], &intersectionPts[i]); + return LW_TRUE; + } } } - /* Disjoint or contained circles don't intersect. Closest point may be on */ - /* the line joining CA to CB. */ - else if (d > (radius_A + radius_B) /* Disjoint */ || d < (radius_A - radius_B) /* Contained */) + + /* + * Join the circle centers and find the places that + * line intersects the circles. Where those places + * are in the arcs, they are potential sites of the + * closest points. + */ + if (is_disjoint || is_contained || is_overlapping) { - POINT2D XA, XB; /* Points where the line from CA to CB cross their circle bounds */ - - /* Calculate hypothetical nearest points, the places on the */ - /* two circles where the center-center line crosses. If both */ - /* arcs contain their hypothetical points, that's the crossing distance */ - XA.x = CA.x + (CB.x - CA.x) * radius_A / d; - XA.y = CA.y + (CB.y - CA.y) * radius_A / d; - XB.x = CB.x + (CA.x - CB.x) * radius_B / d; - XB.y = CB.y + (CA.y - CB.y) * radius_B / d; - - pt_in_arc_A = lw_pt_in_arc(&XA, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&XB, B1, B2, B3); - - /* If the nearest points are both within the arcs, that's our answer */ - /* the shortest distance is at the nearest points */ - if (pt_in_arc_A && pt_in_arc_B) + if (!is_same_center) { - return lw_dist2d_pt_pt(&XA, &XB, dl); - } - } - /* Circles cross at two points, are either of those points in both arcs? */ - /* http://paulbourke.net/geometry/2circle/ */ - else if (d < (radius_A + radius_B)) - { - POINT2D E, F; /* Points where circle(A) and circle(B) cross */ - /* Distance from CA to D */ - double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d); - /* Distance from D to E or F */ - double h = sqrt(radius_A * radius_A - a * a); + /* Add points on A that intersect line from center_A to center_B */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, ¢er_B, + pts_A, &ai); - /* Location of D */ - D.x = CA.x + (CB.x - CA.x) * a / d; - D.y = CA.y + (CB.y - CA.y) * a / d; - - /* Start from D and project h units perpendicular to CA-D to get E */ - E.x = D.x + (D.y - CA.y) * h / a; - E.y = D.y + (D.x - CA.x) * h / a; - - /* Crossing point E contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&E, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&E, B1, B2, B3); - - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &E, &E); - return LW_TRUE; + /* Add points on B that intersect line from center_B to center_A */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, ¢er_A, + pts_B, &bi); } - /* Start from D and project h units perpendicular to CA-D to get F */ - F.x = D.x - (D.y - CA.y) * h / a; - F.y = D.y - (D.x - CA.x) * h / a; + /* Add points on A that intersect line to B1 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B1, + pts_A, &ai); - /* Crossing point F contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&F, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&F, B1, B2, B3); + /* Add points on A that intersect line to B3 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B3, + pts_A, &ai); - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &F, &F); - return LW_TRUE; - } - } - else - { - lwerror("lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!"); - return LW_FALSE; + /* Add points on B that intersect line to A1 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A1, + pts_B, &bi); + + /* Add points on B that intersect line to A3 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A3, + pts_B, &bi); } - /* Closest point is in the arc A, but not in the arc B, so */ - /* one of the B end points must be the closest. */ - if (pt_in_arc_A && !pt_in_arc_B) - { - lw_dist2d_pt_arc(B1, A1, A2, A3, dl); - lw_dist2d_pt_arc(B3, A1, A2, A3, dl); - return LW_TRUE; - } - /* Closest point is in the arc B, but not in the arc A, so */ - /* one of the A end points must be the closest. */ - else if (pt_in_arc_B && !pt_in_arc_A) - { - lw_dist2d_pt_arc(A1, B1, B2, B3, dl); - lw_dist2d_pt_arc(A3, B1, B2, B3, dl); - return LW_TRUE; - } - /* Finally, one of the end-point to end-point combos is the closest. */ - else - { - lw_dist2d_pt_pt(A1, B1, dl); - lw_dist2d_pt_pt(A1, B3, dl); - lw_dist2d_pt_pt(A3, B1, dl); - lw_dist2d_pt_pt(A3, B3, dl); - return LW_TRUE; - } + /* + * Now just brute force check all pairs of participating + * points, to find the pair that is closest together. + */ + for (uint32_t i = 0; i < ai; i++) + for (uint32_t j = 0; j < bi; j++) + lw_dist2d_pt_pt(&pts_A[i], &pts_B[j], dl); return LW_TRUE; } -int -lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl) -{ - int seg_size; - double dist_sqr, shortest_sqr; - const POINT2D *P1; - const POINT2D *P2; - POINT2D proj; - - if (radius_A == radius_B) - { - /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */ - seg_size = lw_segment_side(A1, A3, A2); - if (seg_size == lw_segment_side(A1, A3, B1)) - { - lw_dist2d_distpts_set(dl, 0.0, B1, B1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(A1, A3, B3)) - { - lw_dist2d_distpts_set(dl, 0.0, B3, B3); - return LW_TRUE; - } - /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */ - seg_size = lw_segment_side(B1, B3, B2); - if (seg_size == lw_segment_side(B1, B3, A1)) - { - lw_dist2d_distpts_set(dl, 0.0, A1, A1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(B1, B3, A3)) - { - lw_dist2d_distpts_set(dl, 0.0, A3, A3); - return LW_TRUE; - } - } - else - { - /* Check if any projection of B ends are in A*/ - seg_size = lw_segment_side(A1, A3, A2); - - /* B1 */ - proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B; - - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B1); - return LW_TRUE; - } - /* B3 */ - proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B; - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B3); - return LW_TRUE; - } - - /* Now check projections of A in B */ - seg_size = lw_segment_side(B1, B3, B2); - - /* A1 */ - proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A1); - return LW_TRUE; - } - - /* A3 */ - proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A3); - return LW_TRUE; - } - } - - /* Check the shortest between the distances of the 4 ends */ - shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1); - P1 = A1; - P2 = B1; - - dist_sqr = distance2d_sqr_pt_pt(A1, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A1; - P2 = B3; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B1); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B1; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B3; - } - - lw_dist2d_distpts_set(dl, sqrt(shortest_sqr), P1, P2); - return LW_TRUE; -} /** Finds the shortest distance between two segments. diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 9adf88f54..e106d2372 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -733,13 +733,284 @@ ptarray_is_closed_z(const POINTARRAY *in) } /** -* Return 1 if the point is inside the POINTARRAY, -1 if it is outside, -* and 0 if it is on the boundary. -*/ + * The following is based on the "Fast Winding Number Inclusion of a Point + * in a Polygon" algorithm by Dan Sunday. + * http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number + * + * Return: + * - LW_INSIDE (1) if the point is inside the POINTARRAY + * - LW_BOUNDARY (0) if it is on the boundary. + * - LW_OUTSIDE (-1) if it is outside + */ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarray_contains_point_partial(pa, pt, LW_TRUE, NULL); + const POINT2D *seg1, *seg2; + int wn = 0; + + seg1 = getPoint2d_cp(pa, 0); + seg2 = getPoint2d_cp(pa, pa->npoints-1); + if (!p2d_same(seg1, seg2)) + lwerror("ptarray_contains_point called on unclosed ring"); + + for (uint32_t i = 1; i < pa->npoints; i++) + { + double side, ymin, ymax; + + seg2 = getPoint2d_cp(pa, i); + + /* Zero length segments are ignored. */ + if (p2d_same(seg1, seg2)) + { + seg1 = seg2; + continue; + } + + ymin = FP_MIN(seg1->y, seg2->y); + ymax = FP_MAX(seg1->y, seg2->y); + + /* Only test segments in our vertical range */ + if (pt->y > ymax || pt->y < ymin) + { + seg1 = seg2; + continue; + } + + side = lw_segment_side(seg1, seg2, pt); + + /* + * A point on the boundary of a ring is not contained. + * WAS: if (fabs(side) < 1e-12), see #852 + */ + if ((side == 0) && lw_pt_in_seg(pt, seg1, seg2)) + { + return LW_BOUNDARY; + } + + /* + * If the point is to the left of the line, and it's rising, + * then the line is to the right of the point and + * circling counter-clockwise, so increment. + */ + if ((side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y)) + { + wn++; + } + + /* + * If the point is to the right of the line, and it's falling, + * then the line is to the right of the point and circling + * clockwise, so decrement. + */ + else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) ) + { + wn--; + } + + seg1 = seg2; + } + + /* wn == 0 => Outside, wn != 0 => Inside */ + return wn == 0 ? LW_OUTSIDE : LW_INSIDE; +} + +int +ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + // A valid linestring must have at least 2 point + if (pa->npoints < 2) + lwerror("%s called on invalid linestring", __func__); + + int intersections = 0; + double px = p->x; + double py = p->y; + + // Iterate through each edge of the polygon + for (uint32_t i = 0; i < pa->npoints-1; ++i) + { + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + + /* Skip zero-length edges */ + if (p2d_same(p1, p2)) + continue; + + /* --- Step 1: Check if the point is ON the boundary edge --- */ + if (lw_pt_on_segment(p1, p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + /* --- Step 2: Perform the Ray Casting intersection test --- */ + + /* + * Check if the horizontal ray from p intersects the edge (p1, p2). + * This is the core condition for handling vertices correctly: + * - One vertex must be strictly above the ray (py < vertex.y) + * - The other must be on or below the ray (py >= vertex.y) + */ + if (((p1->y <= py) && (py < p2->y)) || ((p2->y <= py) && (py < p1->y))) + { + /* + * Calculate the x-coordinate where the edge intersects the ray's horizontal line. + * Formula: x = x1 + (y - y1) * (x2 - x1) / (y2 - y1) + */ + double x_intersection = p1->x + (py - p1->y) * (p2->x - p1->x) / (p2->y - p1->y); + + /* + * If the intersection point is to the right of our test point, + * it's a valid "crossing". + */ + if (x_intersection > px) + { + intersections++; + } + } + } + + return intersections; +} + + +/** + * @brief Calculates the intersection points of a circle and a horizontal line. + * + * The equation of a circle is (x - cx)^2 + (y - cy)^2 = r^2. + * The equation of the horizontal line is y = y_line. + * Substituting y_line into the circle equation gives: + * (x - cx)^2 = r^2 - (y_line - cy)^2 + * This function solves for x. + * + * @param center A pointer to the center point of the circle. + * @param radius The radius of the circle. + * @param ray The y-coordinate of the horizontal line. + * @param i0 A pointer to a POINT2D to store the first intersection point. + * @param i1 A pointer to a POINT2D to store the second intersection point. + * + * @return The number of intersection points found (0, 1, or 2). + */ +static int +circle_raycast_intersections(const POINT2D *center, double radius, double ray, POINT2D *i0, POINT2D *i1) +{ + // Calculate the vertical distance from the circle's center to the horizontal line. + double dy = ray - center->y; + + // If the absolute vertical distance is greater than the radius, there are no intersections. + if (fabs(dy) > radius) + return 0; + + // Use the Pythagorean theorem to find the horizontal distance (dx) from the + // center's x-coordinate to the intersection points. + // dx^2 + dy^2 = radius^2 => dx^2 = radius^2 - dy^2 + double dx_squared = radius * radius - dy * dy; + + // Case 1: One intersection (tangent) + // This occurs when the line just touches the top or bottom of the circle. + // dx_squared will be zero. We check against a small epsilon for floating-point safety. + if (FP_EQUALS(dx_squared, 0.0)) + { + i0->x = center->x; + i0->y = ray; + return 1; + } + + // Case 2: Two intersections + // The line cuts through the circle. + double dx = sqrt(dx_squared); + + // The first intersection point has the smaller x-value. + i0->x = center->x - dx; + i0->y = ray; + + // The second intersection point has the larger x-value. + i1->x = center->x + dx; + i1->y = ray; + + return 2; +} + + +int +ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + int intersections = 0; + double px = p->x; + double py = p->y; + + assert(on_boundary); + + // A valid circular arc must have at least 3 vertices (circle). + if (pa->npoints < 3) + lwerror("%s called on invalid circularstring", __func__); + + if (pa->npoints % 2 == 0) + lwerror("%s called with even number of points", __func__); + + // Iterate through each arc of the circularstring + for (uint32_t i = 1; i < pa->npoints-1; i +=2) + { + const POINT2D* p0 = getPoint2d_cp(pa, i-1); + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + POINT2D center = {0,0}; + double radius, d; + GBOX gbox; + + // Skip zero-length arc + if (lw_arc_is_pt(p0, p1, p2)) + continue; + + // --- Step 1: Check if the point is ON the boundary edge --- + if (p2d_same(p0, p) || p2d_same(p1, p) || p2d_same(p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // Calculate some important pieces + radius = lw_arc_center(p0, p1, p2, ¢er); + + d = distance2d_pt_pt(p, ¢er); + if (FP_EQUALS(d, radius) && lw_pt_in_arc(p, p0, p1, p2)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // --- Step 2: Perform the Ray Casting intersection test --- + + // Only process arcs that our ray crosses + lw_arc_calculate_gbox_cartesian_2d(p0, p1, p2, &gbox); + if ((gbox.ymin <= py) && (py < gbox.ymax)) + { + // Point of intersection on the circle that defines the arc + POINT2D i0, i1; + + // How many points of intersection are there + int iCount = circle_raycast_intersections(¢er, radius, py, &i0, &i1); + + // Nothing to see here + if (iCount == 0) + continue; + + // Cannot think of a case where a grazing is not a + // no-op + if (iCount == 1) + continue; + + // So we must have 2 intersections + // Only increment the counter for intersections to the right + // of the test point + if (i0.x > px && lw_pt_in_arc(&i0, p0, p1, p2)) + intersections++; + + if (i1.x > px && lw_pt_in_arc(&i1, p0, p1, p2)) + intersections++; + } + } + + return intersections; } int @@ -838,7 +1109,16 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarrayarc_contains_point_partial(pa, pt, LW_TRUE /* Check closed*/, NULL); + int on_boundary = LW_FALSE; + int intersections; + if (!ptarray_is_closed_2d(pa)) + lwerror("%s called on unclosed ring", __func__); + + intersections = ptarrayarc_raycast_intersections(pa, pt, &on_boundary); + if (on_boundary) + return LW_BOUNDARY; + else + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } int commit 27c003d95479c54b145d5ad88cd503bb569d7580 Author: Paul Ramsey Date: Mon Oct 6 16:42:32 2025 -0700 Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 diff --git a/NEWS b/NEWS index 49ef32aa0..fa76e6db1 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,7 @@ Proj 4.9+ required. - #5917, ST_Relate becomes unresponsive (Paul Ramsey) - #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) - #5991, CircularString distance error (Paul Ramsey) + - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) PostGIS 3.3.8 diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index cb3e5b4e2..e54a48e18 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1491,8 +1491,9 @@ Datum ST_ClipByBox2d(PG_FUNCTION_ARGS) bbox2 = (GBOX *)PG_GETARG_POINTER(box2d_idx); bbox2->flags = 0; - /* if bbox1 is covered by bbox2, return lwgeom1 */ - if (gbox_contains_2d(bbox2, &bbox1)) + /* If bbox1 is strictly contained by bbox2, return input geometry */ + if (bbox2->xmin < bbox1.xmin && bbox2->xmax > bbox1.xmax && + bbox2->ymin < bbox1.ymin && bbox2->ymax > bbox1.ymax) { PG_RETURN_DATUM(PG_GETARG_DATUM(geom_idx)); } ----------------------------------------------------------------------- Summary of changes: NEWS | 2 + liblwgeom/cunit/cu_measures.c | 7 + liblwgeom/cunit/cu_ptarray.c | 2 +- liblwgeom/liblwgeom_internal.h | 3 + liblwgeom/lwalgorithm.c | 18 +- liblwgeom/lwcompound.c | 74 +++--- liblwgeom/measures.c | 496 +++++++++++++++++++---------------------- liblwgeom/ptarray.c | 290 +++++++++++++++++++++++- postgis/lwgeom_geos.c | 5 +- 9 files changed, 575 insertions(+), 322 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 12:07:34 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:07:34 -0000 Subject: [PostGIS] #5962: Inconsistent results in multipoint clipping In-Reply-To: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> References: <047.d4193a7a87c6acc2d59807f3d2c17f94@osgeo.org> Message-ID: <062.d37d6aaaf5b79263589ac00cea77eafd@osgeo.org> #5962: Inconsistent results in multipoint clipping ----------------------+--------------------------- Reporter: bradh | Owner: pramsey Type: defect | Status: closed Priority: low | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"27c003d95479c54b145d5ad88cd503bb569d7580/git" 27c003d9/git]: {{{#!CommitTicketReference repository="git" revision="27c003d95479c54b145d5ad88cd503bb569d7580" Consistent clipping of MULTI/POINT (Paul Ramsey), references #5962 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 12:07:34 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:07:34 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.c9e54d292d50eedb1126d3b6a84cf049@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"71b0a452ea5a3869ad05249e3b0b4f92644858e6/git" 71b0a45/git]: {{{#!CommitTicketReference repository="git" revision="71b0a452ea5a3869ad05249e3b0b4f92644858e6" Update distance calculations for CurvePolygon, references #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 12:07:39 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:07:39 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.2 updated. 3.2.7-54-gbd71a9ffe Message-ID: <20251007190739.8A3BB1360C0@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.2 has been updated via bd71a9ffef92c6dd34f80d3af03463604695b860 (commit) via f29425e4cfe9a8358a0a09d2f7a7192be8233e8e (commit) from f42e6f14b23de1971059efff3cf37c8e659ad770 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bd71a9ffef92c6dd34f80d3af03463604695b860 Author: Paul Ramsey Date: Tue Oct 7 12:06:31 2025 -0700 News item for f29425e4c diff --git a/NEWS b/NEWS index e04537370..3832d8c37 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ Proj 4.9+ required. - #5917, ST_Relate becomes unresponsive (Paul Ramsey) - #5991, CircularString distance error (Paul Ramsey) - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) + - #5989, CurvePolygon distance error (Paul Ramsey) PostGIS 3.2.8 commit f29425e4cfe9a8358a0a09d2f7a7192be8233e8e Author: Paul Ramsey Date: Tue Oct 7 11:35:59 2025 -0700 Update distance calculations for CurvePolygon, references #5989 diff --git a/liblwgeom/cunit/cu_measures.c b/liblwgeom/cunit/cu_measures.c index a72ab3def..c7e44facc 100644 --- a/liblwgeom/cunit/cu_measures.c +++ b/liblwgeom/cunit/cu_measures.c @@ -88,6 +88,13 @@ static void test_mindistance2d_tolerance(void) double default_accepted_error = 0.00001; double zero_accepted_error = 0.0; + /* + * CurvePolygon and Point, #5989 + */ + DIST2DTEST( + "CURVEPOLYGON(COMPOUNDCURVE((129296 142584,94722 100435,91618 97138,57306 60686,26874 28357,13059 34228,14572 65506,14593 65948,14616 66389),CIRCULARSTRING(14616 66389,17955 101124,24417 135415,24655 136418,24895 137421),(24895 137421,25472 139809,19354 141285,0 0,148000 142000,129296 142584)))", + "POINT(19925 112376)", + 199.655, 0.001); /* ** Simple case. diff --git a/liblwgeom/cunit/cu_ptarray.c b/liblwgeom/cunit/cu_ptarray.c index c5bc7c260..0ae4a43fd 100644 --- a/liblwgeom/cunit/cu_ptarray.c +++ b/liblwgeom/cunit/cu_ptarray.c @@ -554,7 +554,7 @@ static void test_ptarrayarc_contains_point() cu_error_msg_reset(); rv = ptarrayarc_contains_point(pa, &pt); //printf("%s\n", cu_error_msg); - ASSERT_STRING_EQUAL("ptarrayarc_contains_point called with even number of points", cu_error_msg); + ASSERT_STRING_EQUAL("ptarrayarc_raycast_intersections called with even number of points", cu_error_msg); /*** Unclosed ring ***/ lwline_free(lwline); diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index 4fa50ddc3..769822058 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -424,6 +424,7 @@ int lw_arc_side(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, const P int lw_arc_calculate_gbox_cartesian_2d(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, GBOX *gbox); double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result); int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2); +int lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P); int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3); double lw_seg_length(const POINT2D *A1, const POINT2D *A2); @@ -433,6 +434,8 @@ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt); int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number); +int ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); +int ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary); int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt); int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt); diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index 5d2fffb17..a9f68f084 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -49,10 +49,8 @@ p3d_same(const POINT3D *p1, const POINT3D *p2) int p2d_same(const POINT2D *p1, const POINT2D *p2) { - if( FP_EQUALS(p1->x,p2->x) && FP_EQUALS(p1->y,p2->y) ) - return LW_TRUE; - else - return LW_FALSE; + return FP_EQUALS(p1->x, p2->x) + && FP_EQUALS(p1->y, p2->y); } /** @@ -85,7 +83,9 @@ lw_seg_length(const POINT2D *A1, const POINT2D *A2) int lw_pt_in_arc(const POINT2D *P, const POINT2D *A1, const POINT2D *A2, const POINT2D *A3) { - return lw_segment_side(A1, A3, A2) == lw_segment_side(A1, A3, P); + int pt_side = lw_segment_side(A1, A3, P); + int arc_side = lw_segment_side(A1, A3, A2); + return pt_side == 0 || pt_side == arc_side; } /** @@ -99,6 +99,14 @@ lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2) ((A1->y <= P->y && P->y < A2->y) || (A1->y >= P->y && P->y > A2->y)); } +int +lw_pt_on_segment(const POINT2D* A1, const POINT2D* A2, const POINT2D* P) +{ + int side = lw_segment_side(A1, A2, P); + if (side != 0) return LW_FALSE; + return lw_pt_in_seg(P, A1, A2); +} + /** * Returns true if arc A is actually a point (all vertices are the same) . */ diff --git a/liblwgeom/lwcompound.c b/liblwgeom/lwcompound.c index 03f4201cd..f7363d069 100644 --- a/liblwgeom/lwcompound.c +++ b/liblwgeom/lwcompound.c @@ -141,63 +141,49 @@ int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt) return LW_FAILURE; } + +/* + * Use a ray-casting count to determine if the point + * is inside or outside of the compound curve. Ray-casting + * is run against each component of the overall arc, and + * the even/odd test run against the total of all components. + * Returns LW_INSIDE / LW_BOUNDARY / LW_OUTSIDE + */ int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt) { - uint32_t i; - LWLINE *lwline; - LWCIRCSTRING *lwcirc; - int wn = 0; - int winding_number = 0; - int result; + int intersections = 0; - for ( i = 0; i < comp->ngeoms; i++ ) + if (lwgeom_is_empty(lwcompound_as_lwgeom(comp))) + return LW_OUTSIDE; + + for (uint32_t j = 0; j < comp->ngeoms; j++) { - LWGEOM *lwgeom = comp->geoms[i]; - if ( lwgeom->type == LINETYPE ) + int on_boundary = LW_FALSE; + const LWGEOM *sub = comp->geoms[j]; + if (sub->type == LINETYPE) { - lwline = lwgeom_as_lwline(lwgeom); - if ( comp->ngeoms == 1 ) - { - return ptarray_contains_point(lwline->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number); - } + LWLINE *lwline = lwgeom_as_lwline(sub); + intersections += ptarray_raycast_intersections(lwline->points, pt, &on_boundary); + } + else if (sub->type == CIRCSTRINGTYPE) + { + LWCIRCSTRING *lwcirc = lwgeom_as_lwcircstring(sub); + intersections += ptarrayarc_raycast_intersections(lwcirc->points, pt, &on_boundary); } else { - lwcirc = lwgeom_as_lwcircstring(lwgeom); - if ( ! lwcirc ) { - lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type)); - return 0; - } - if ( comp->ngeoms == 1 ) - { - return ptarrayarc_contains_point(lwcirc->points, pt); - } - else - { - /* Don't check closure while doing p-i-p test */ - result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number); - } + lwerror("%s: unsupported type %s", __func__, lwtype_name(sub->type)); } - - /* Propogate boundary condition */ - if ( result == LW_BOUNDARY ) + if (on_boundary) return LW_BOUNDARY; - - wn += winding_number; } - /* Outside */ - if (wn == 0) - return LW_OUTSIDE; - - /* Inside */ - return LW_INSIDE; + /* + * Odd number of intersections means inside. + * Even means outside. + */ + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } LWCOMPOUND * diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index f13bcbcdc..192aa3c69 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -1541,25 +1541,154 @@ int lw_dist2d_arc_arc_concentric(const POINT2D *A1, const POINT2D *CENTER, DISTPTS *dl); -int -lw_dist2d_arc_arc(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - DISTPTS *dl) + +/** + * @brief Calculates the intersection points of a circle and line. + * + * This function assumes the center and test point are distinct. + * Finds the line between the circle center and test point, and + * the two intersection points on the circle defined by that line. + * If those points fall within the provided arc (A1,A2,A3) then + * the points are added to the provided array (I) and the array + * length counter is incremented. + * + * @param A1 Point of arc + * @param A2 Point of arc + * @param A3 Point of arc + * @param center_A Center of arc A circle + * @param radius_A Radius of arc A circle + * @param P Point to use in calculating intersection line + * @param I [out] Pointer to an return value array + * @param ni [out] Pointer to return array size counter + * @return int + */ +static int +lw_dist2d_circle_intersections( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *center_A, + double radius_A, + const POINT2D *P, + POINT2D *I, + uint32_t *ni) { - POINT2D CA, CB; /* Center points of arcs A and B */ + POINT2D R; + + // If the test point is on the center of the other + // arc, some other point has to be closer, by definition. + if (p2d_same(center_A, P)) + return 0; + + // Calculate vector from the center to the pt + double dir_x = center_A->x - P->x; + double dir_y = center_A->y - P->y; + double dist = sqrt(dir_x * dir_x + dir_y * dir_y); + + // Normalize the direction vector to get a unit vector (length = 1) + double unit_x = dir_x / dist; + double unit_y = dir_y / dist; + + // Calculate the two intersection points on the circle + // Point 1: Move from center_A along the unit vector by distance radius_A + R.x = center_A->x + unit_x * radius_A; + R.y = center_A->y + unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + // Point 2: Move from center_A against the unit vector by distance radius_A + R.x = center_A->x - unit_x * radius_A; + R.y = center_A->y - unit_y * radius_A; + if (lw_pt_in_arc(&R, A1, A2, A3)) + I[(*ni)++] = R; + + return 0; +} + + +/** + * @brief Calculates the intersection points of two overlapping circles. + * + * This function assumes the circles are known to intersect at one or two points. + * Specifically, the distance 'd' between their centers must satisfy: + * d < (rA + rB) and d > fabs(rA - rB) + * If these conditions are not met, the results are undefined. + * + * @param cA [in] Pointer to the center point of the first circle (A). + * @param rA [in] The radius of the first circle (A). + * @param cB [in] Pointer to the center point of the second circle (B). + * @param rB [in] The radius of the second circle (B). + * @param I [out] Pointer to an array of at least 2 POINT2D structs to store the results. + * I[0] will contain the first intersection point. + * If a second exists, it will be in I[1]. + * @return int The number of intersection points found (1 or 2). Returns 0 if + * the centers are coincident or another error occurs. + */ +static uint32_t +lw_dist2d_circle_circle_intersections( + const POINT2D *cA, double rA, + const POINT2D *cB, double rB, + POINT2D *I) +{ + // Vector from center A to center B + double dx = cB->x - cA->x; + double dy = cB->y - cA->y; + + // Distance between the centers + double d = sqrt(dx * dx + dy * dy); + + // 'a' is the distance from the center of circle A to the point P, + // which is the base of the right triangle formed by cA, P, and an intersection point. + double a = (rA * rA - rB * rB + d * d) / (2.0 * d); + + // 'h' is the height of that right triangle. + double h_squared = rA * rA - a * a; + + // Due to floating point errors, h_squared can be slightly negative. + // This happens when the circles are perfectly tangent. Clamp to 0. + if (h_squared < 0.0) + h_squared = 0.0; + + double h = sqrt(h_squared); + + // Find the coordinates of point P + double Px = cA->x + a * (dx / d); + double Py = cA->y + a * (dy / d); + + // The two intersection points are found by moving from P by a distance 'h' + // in directions perpendicular to the line connecting the centers. + // The perpendicular vector to (dx, dy) is (-dy, dx). + + // Intersection point 1 + I[0].x = Px - h * (dy / d); + I[0].y = Py + h * (dx / d); + + // If h is very close to 0, the circles are tangent and there's only one intersection point. + if (FP_IS_ZERO(h)) + return 1; + + // Intersection point 2 + I[1].x = Px + h * (dy / d); + I[1].y = Py - h * (dx / d); + + return 2; +} + +int +lw_dist2d_arc_arc( + const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, + const POINT2D *B1, const POINT2D *B2, const POINT2D *B3, + DISTPTS *dl) +{ + POINT2D pts_A[16]; /* Points on A that might be the nearest */ + POINT2D pts_B[16]; /* Points on B that might be the nearest */ + uint32_t ai = 0, bi = 0; /* Number of points in pts_A and pts_B */ + POINT2D center_A, center_B; /* Center points of arcs A and B */ double radius_A, radius_B, d; /* Radii of arcs A and B */ - POINT2D D; /* Mid-point between the centers CA and CB */ - int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */ + int is_disjoint, is_overlapping, is_contained, is_same_center; + POINT2D intersectionPts[2]; if (dl->mode != DIST_MIN) lwerror("lw_dist2d_arc_arc only supports mindistance"); - /* TODO: Handle case where arc is closed circle (A1 = A3) */ - /* What if one or both of our "arcs" is actually a point? */ if (lw_arc_is_pt(B1, B2, B3) && lw_arc_is_pt(A1, A2, A3)) return lw_dist2d_pt_pt(B1, A1, dl); @@ -1569,8 +1698,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, return lw_dist2d_pt_arc(A1, B1, B2, B3, dl); /* Calculate centers and radii of circles. */ - radius_A = lw_arc_center(A1, A2, A3, &CA); - radius_B = lw_arc_center(B1, B2, B3, &CB); + radius_A = lw_arc_center(A1, A2, A3, ¢er_A); + radius_B = lw_arc_center(B1, B2, B3, ¢er_B); /* Two co-linear arcs?!? That's two segments. */ if (radius_A < 0 && radius_B < 0) @@ -1584,275 +1713,112 @@ lw_dist2d_arc_arc(const POINT2D *A1, if (radius_B < 0) return lw_dist2d_seg_arc(B1, B3, A1, A2, A3, dl); - /* Center-center distance */ - d = distance2d_pt_pt(&CA, &CB); + /* Circle relationships */ + d = distance2d_pt_pt(¢er_A, ¢er_B); + is_disjoint = (d > (radius_A + radius_B)); + is_contained = (d < fabs(radius_A - radius_B)); + is_same_center = p2d_same(¢er_A, ¢er_B); + is_overlapping = ! (is_disjoint || is_contained || is_same_center); - /* Concentric arcs */ - if (FP_EQUALS(d, 0.0)) - return lw_dist2d_arc_arc_concentric(A1, A2, A3, radius_A, B1, B2, B3, radius_B, &CA, dl); + /* + * Prime the array of potential closest points with the + * arc end points, which frequently participate in closest + * points. + */ + pts_A[ai++] = *A1; + pts_A[ai++] = *A3; + pts_B[bi++] = *B1; + pts_B[bi++] = *B3; - /* Make sure that arc "A" has the bigger radius */ - if (radius_B > radius_A) + /* + * Overlapping circles might have a zero distance + * case if the circle intersection points are inside both + * arcs. + */ + if (is_overlapping) { - const POINT2D *tmp; - POINT2D TP; /* Temporary point P */ - double td; - tmp = B1; - B1 = A1; - A1 = tmp; - tmp = B2; - B2 = A2; - A2 = tmp; - tmp = B3; - B3 = A3; - A3 = tmp; - TP = CB; - CB = CA; - CA = TP; - td = radius_B; - radius_B = radius_A; - radius_A = td; - } - - /* Circles touch at a point. Is that point within the arcs? */ - if (d == (radius_A + radius_B)) - { - D.x = CA.x + (CB.x - CA.x) * radius_A / d; - D.y = CA.y + (CB.y - CA.y) * radius_A / d; - - pt_in_arc_A = lw_pt_in_arc(&D, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&D, B1, B2, B3); - - /* Arcs do touch at D, return it */ - if (pt_in_arc_A && pt_in_arc_B) + /* + * Find the two points the circles intersect at. + */ + uint32_t npoints = lw_dist2d_circle_circle_intersections( + ¢er_A, radius_A, + ¢er_B, radius_B, + intersectionPts); + for (uint32_t i = 0; i < npoints; i++) { - lw_dist2d_distpts_set(dl, 0.0, &D, &D); - return LW_TRUE; + /* + * If an intersection point is contained in both + * arcs, that is a location of zero distance, so + * we are done calculating. + */ + if (lw_pt_in_arc(&intersectionPts[i], A1, A2, A3) && + lw_pt_in_arc(&intersectionPts[i], B1, B2, B3)) + { + lw_dist2d_distpts_set(dl, 0.0, &intersectionPts[i], &intersectionPts[i]); + return LW_TRUE; + } } } - /* Disjoint or contained circles don't intersect. Closest point may be on */ - /* the line joining CA to CB. */ - else if (d > (radius_A + radius_B) /* Disjoint */ || d < (radius_A - radius_B) /* Contained */) + + /* + * Join the circle centers and find the places that + * line intersects the circles. Where those places + * are in the arcs, they are potential sites of the + * closest points. + */ + if (is_disjoint || is_contained || is_overlapping) { - POINT2D XA, XB; /* Points where the line from CA to CB cross their circle bounds */ - - /* Calculate hypothetical nearest points, the places on the */ - /* two circles where the center-center line crosses. If both */ - /* arcs contain their hypothetical points, that's the crossing distance */ - XA.x = CA.x + (CB.x - CA.x) * radius_A / d; - XA.y = CA.y + (CB.y - CA.y) * radius_A / d; - XB.x = CB.x + (CA.x - CB.x) * radius_B / d; - XB.y = CB.y + (CA.y - CB.y) * radius_B / d; - - pt_in_arc_A = lw_pt_in_arc(&XA, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&XB, B1, B2, B3); - - /* If the nearest points are both within the arcs, that's our answer */ - /* the shortest distance is at the nearest points */ - if (pt_in_arc_A && pt_in_arc_B) + if (!is_same_center) { - return lw_dist2d_pt_pt(&XA, &XB, dl); - } - } - /* Circles cross at two points, are either of those points in both arcs? */ - /* http://paulbourke.net/geometry/2circle/ */ - else if (d < (radius_A + radius_B)) - { - POINT2D E, F; /* Points where circle(A) and circle(B) cross */ - /* Distance from CA to D */ - double a = (radius_A * radius_A - radius_B * radius_B + d * d) / (2 * d); - /* Distance from D to E or F */ - double h = sqrt(radius_A * radius_A - a * a); + /* Add points on A that intersect line from center_A to center_B */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, ¢er_B, + pts_A, &ai); - /* Location of D */ - D.x = CA.x + (CB.x - CA.x) * a / d; - D.y = CA.y + (CB.y - CA.y) * a / d; - - /* Start from D and project h units perpendicular to CA-D to get E */ - E.x = D.x + (D.y - CA.y) * h / a; - E.y = D.y + (D.x - CA.x) * h / a; - - /* Crossing point E contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&E, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&E, B1, B2, B3); - - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &E, &E); - return LW_TRUE; + /* Add points on B that intersect line from center_B to center_A */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, ¢er_A, + pts_B, &bi); } - /* Start from D and project h units perpendicular to CA-D to get F */ - F.x = D.x - (D.y - CA.y) * h / a; - F.y = D.y - (D.x - CA.x) * h / a; + /* Add points on A that intersect line to B1 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B1, + pts_A, &ai); - /* Crossing point F contained in arcs? */ - pt_in_arc_A = lw_pt_in_arc(&F, A1, A2, A3); - pt_in_arc_B = lw_pt_in_arc(&F, B1, B2, B3); + /* Add points on A that intersect line to B3 */ + lw_dist2d_circle_intersections( + A1, A2, A3, + ¢er_A, radius_A, B3, + pts_A, &ai); - if (pt_in_arc_A && pt_in_arc_B) - { - lw_dist2d_distpts_set(dl, 0.0, &F, &F); - return LW_TRUE; - } - } - else - { - lwerror("lw_dist2d_arc_arc: arcs neither touch, intersect nor are disjoint! INCONCEIVABLE!"); - return LW_FALSE; + /* Add points on B that intersect line to A1 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A1, + pts_B, &bi); + + /* Add points on B that intersect line to A3 */ + lw_dist2d_circle_intersections( + B1, B2, B3, + ¢er_B, radius_B, A3, + pts_B, &bi); } - /* Closest point is in the arc A, but not in the arc B, so */ - /* one of the B end points must be the closest. */ - if (pt_in_arc_A && !pt_in_arc_B) - { - lw_dist2d_pt_arc(B1, A1, A2, A3, dl); - lw_dist2d_pt_arc(B3, A1, A2, A3, dl); - return LW_TRUE; - } - /* Closest point is in the arc B, but not in the arc A, so */ - /* one of the A end points must be the closest. */ - else if (pt_in_arc_B && !pt_in_arc_A) - { - lw_dist2d_pt_arc(A1, B1, B2, B3, dl); - lw_dist2d_pt_arc(A3, B1, B2, B3, dl); - return LW_TRUE; - } - /* Finally, one of the end-point to end-point combos is the closest. */ - else - { - lw_dist2d_pt_pt(A1, B1, dl); - lw_dist2d_pt_pt(A1, B3, dl); - lw_dist2d_pt_pt(A3, B1, dl); - lw_dist2d_pt_pt(A3, B3, dl); - return LW_TRUE; - } + /* + * Now just brute force check all pairs of participating + * points, to find the pair that is closest together. + */ + for (uint32_t i = 0; i < ai; i++) + for (uint32_t j = 0; j < bi; j++) + lw_dist2d_pt_pt(&pts_A[i], &pts_B[j], dl); return LW_TRUE; } -int -lw_dist2d_arc_arc_concentric(const POINT2D *A1, - const POINT2D *A2, - const POINT2D *A3, - double radius_A, - const POINT2D *B1, - const POINT2D *B2, - const POINT2D *B3, - double radius_B, - const POINT2D *CENTER, - DISTPTS *dl) -{ - int seg_size; - double dist_sqr, shortest_sqr; - const POINT2D *P1; - const POINT2D *P2; - POINT2D proj; - - if (radius_A == radius_B) - { - /* Check if B1 or B3 are in the same side as A2 in the A1-A3 arc */ - seg_size = lw_segment_side(A1, A3, A2); - if (seg_size == lw_segment_side(A1, A3, B1)) - { - lw_dist2d_distpts_set(dl, 0.0, B1, B1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(A1, A3, B3)) - { - lw_dist2d_distpts_set(dl, 0.0, B3, B3); - return LW_TRUE; - } - /* Check if A1 or A3 are in the same side as B2 in the B1-B3 arc */ - seg_size = lw_segment_side(B1, B3, B2); - if (seg_size == lw_segment_side(B1, B3, A1)) - { - lw_dist2d_distpts_set(dl, 0.0, A1, A1); - return LW_TRUE; - } - if (seg_size == lw_segment_side(B1, B3, A3)) - { - lw_dist2d_distpts_set(dl, 0.0, A3, A3); - return LW_TRUE; - } - } - else - { - /* Check if any projection of B ends are in A*/ - seg_size = lw_segment_side(A1, A3, A2); - - /* B1 */ - proj.x = CENTER->x + (B1->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B1->y - CENTER->y) * radius_A / radius_B; - - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B1); - return LW_TRUE; - } - /* B3 */ - proj.x = CENTER->x + (B3->x - CENTER->x) * radius_A / radius_B; - proj.y = CENTER->y + (B3->y - CENTER->y) * radius_A / radius_B; - if (seg_size == lw_segment_side(A1, A3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, B3); - return LW_TRUE; - } - - /* Now check projections of A in B */ - seg_size = lw_segment_side(B1, B3, B2); - - /* A1 */ - proj.x = CENTER->x + (A1->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A1->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A1); - return LW_TRUE; - } - - /* A3 */ - proj.x = CENTER->x + (A3->x - CENTER->x) * radius_B / radius_A; - proj.y = CENTER->y + (A3->y - CENTER->y) * radius_B / radius_A; - if (seg_size == lw_segment_side(B1, B3, &proj)) - { - lw_dist2d_distpts_set(dl, fabs(radius_A - radius_B), &proj, A3); - return LW_TRUE; - } - } - - /* Check the shortest between the distances of the 4 ends */ - shortest_sqr = dist_sqr = distance2d_sqr_pt_pt(A1, B1); - P1 = A1; - P2 = B1; - - dist_sqr = distance2d_sqr_pt_pt(A1, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A1; - P2 = B3; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B1); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B1; - } - - dist_sqr = distance2d_sqr_pt_pt(A3, B3); - if (dist_sqr < shortest_sqr) - { - shortest_sqr = dist_sqr; - P1 = A3; - P2 = B3; - } - - lw_dist2d_distpts_set(dl, sqrt(shortest_sqr), P1, P2); - return LW_TRUE; -} /** Finds the shortest distance between two segments. diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 9adf88f54..e106d2372 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -733,13 +733,284 @@ ptarray_is_closed_z(const POINTARRAY *in) } /** -* Return 1 if the point is inside the POINTARRAY, -1 if it is outside, -* and 0 if it is on the boundary. -*/ + * The following is based on the "Fast Winding Number Inclusion of a Point + * in a Polygon" algorithm by Dan Sunday. + * http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number + * + * Return: + * - LW_INSIDE (1) if the point is inside the POINTARRAY + * - LW_BOUNDARY (0) if it is on the boundary. + * - LW_OUTSIDE (-1) if it is outside + */ int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarray_contains_point_partial(pa, pt, LW_TRUE, NULL); + const POINT2D *seg1, *seg2; + int wn = 0; + + seg1 = getPoint2d_cp(pa, 0); + seg2 = getPoint2d_cp(pa, pa->npoints-1); + if (!p2d_same(seg1, seg2)) + lwerror("ptarray_contains_point called on unclosed ring"); + + for (uint32_t i = 1; i < pa->npoints; i++) + { + double side, ymin, ymax; + + seg2 = getPoint2d_cp(pa, i); + + /* Zero length segments are ignored. */ + if (p2d_same(seg1, seg2)) + { + seg1 = seg2; + continue; + } + + ymin = FP_MIN(seg1->y, seg2->y); + ymax = FP_MAX(seg1->y, seg2->y); + + /* Only test segments in our vertical range */ + if (pt->y > ymax || pt->y < ymin) + { + seg1 = seg2; + continue; + } + + side = lw_segment_side(seg1, seg2, pt); + + /* + * A point on the boundary of a ring is not contained. + * WAS: if (fabs(side) < 1e-12), see #852 + */ + if ((side == 0) && lw_pt_in_seg(pt, seg1, seg2)) + { + return LW_BOUNDARY; + } + + /* + * If the point is to the left of the line, and it's rising, + * then the line is to the right of the point and + * circling counter-clockwise, so increment. + */ + if ((side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y)) + { + wn++; + } + + /* + * If the point is to the right of the line, and it's falling, + * then the line is to the right of the point and circling + * clockwise, so decrement. + */ + else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) ) + { + wn--; + } + + seg1 = seg2; + } + + /* wn == 0 => Outside, wn != 0 => Inside */ + return wn == 0 ? LW_OUTSIDE : LW_INSIDE; +} + +int +ptarray_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + // A valid linestring must have at least 2 point + if (pa->npoints < 2) + lwerror("%s called on invalid linestring", __func__); + + int intersections = 0; + double px = p->x; + double py = p->y; + + // Iterate through each edge of the polygon + for (uint32_t i = 0; i < pa->npoints-1; ++i) + { + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + + /* Skip zero-length edges */ + if (p2d_same(p1, p2)) + continue; + + /* --- Step 1: Check if the point is ON the boundary edge --- */ + if (lw_pt_on_segment(p1, p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + /* --- Step 2: Perform the Ray Casting intersection test --- */ + + /* + * Check if the horizontal ray from p intersects the edge (p1, p2). + * This is the core condition for handling vertices correctly: + * - One vertex must be strictly above the ray (py < vertex.y) + * - The other must be on or below the ray (py >= vertex.y) + */ + if (((p1->y <= py) && (py < p2->y)) || ((p2->y <= py) && (py < p1->y))) + { + /* + * Calculate the x-coordinate where the edge intersects the ray's horizontal line. + * Formula: x = x1 + (y - y1) * (x2 - x1) / (y2 - y1) + */ + double x_intersection = p1->x + (py - p1->y) * (p2->x - p1->x) / (p2->y - p1->y); + + /* + * If the intersection point is to the right of our test point, + * it's a valid "crossing". + */ + if (x_intersection > px) + { + intersections++; + } + } + } + + return intersections; +} + + +/** + * @brief Calculates the intersection points of a circle and a horizontal line. + * + * The equation of a circle is (x - cx)^2 + (y - cy)^2 = r^2. + * The equation of the horizontal line is y = y_line. + * Substituting y_line into the circle equation gives: + * (x - cx)^2 = r^2 - (y_line - cy)^2 + * This function solves for x. + * + * @param center A pointer to the center point of the circle. + * @param radius The radius of the circle. + * @param ray The y-coordinate of the horizontal line. + * @param i0 A pointer to a POINT2D to store the first intersection point. + * @param i1 A pointer to a POINT2D to store the second intersection point. + * + * @return The number of intersection points found (0, 1, or 2). + */ +static int +circle_raycast_intersections(const POINT2D *center, double radius, double ray, POINT2D *i0, POINT2D *i1) +{ + // Calculate the vertical distance from the circle's center to the horizontal line. + double dy = ray - center->y; + + // If the absolute vertical distance is greater than the radius, there are no intersections. + if (fabs(dy) > radius) + return 0; + + // Use the Pythagorean theorem to find the horizontal distance (dx) from the + // center's x-coordinate to the intersection points. + // dx^2 + dy^2 = radius^2 => dx^2 = radius^2 - dy^2 + double dx_squared = radius * radius - dy * dy; + + // Case 1: One intersection (tangent) + // This occurs when the line just touches the top or bottom of the circle. + // dx_squared will be zero. We check against a small epsilon for floating-point safety. + if (FP_EQUALS(dx_squared, 0.0)) + { + i0->x = center->x; + i0->y = ray; + return 1; + } + + // Case 2: Two intersections + // The line cuts through the circle. + double dx = sqrt(dx_squared); + + // The first intersection point has the smaller x-value. + i0->x = center->x - dx; + i0->y = ray; + + // The second intersection point has the larger x-value. + i1->x = center->x + dx; + i1->y = ray; + + return 2; +} + + +int +ptarrayarc_raycast_intersections(const POINTARRAY *pa, const POINT2D *p, int *on_boundary) +{ + int intersections = 0; + double px = p->x; + double py = p->y; + + assert(on_boundary); + + // A valid circular arc must have at least 3 vertices (circle). + if (pa->npoints < 3) + lwerror("%s called on invalid circularstring", __func__); + + if (pa->npoints % 2 == 0) + lwerror("%s called with even number of points", __func__); + + // Iterate through each arc of the circularstring + for (uint32_t i = 1; i < pa->npoints-1; i +=2) + { + const POINT2D* p0 = getPoint2d_cp(pa, i-1); + const POINT2D* p1 = getPoint2d_cp(pa, i); + const POINT2D* p2 = getPoint2d_cp(pa, i+1); + POINT2D center = {0,0}; + double radius, d; + GBOX gbox; + + // Skip zero-length arc + if (lw_arc_is_pt(p0, p1, p2)) + continue; + + // --- Step 1: Check if the point is ON the boundary edge --- + if (p2d_same(p0, p) || p2d_same(p1, p) || p2d_same(p2, p)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // Calculate some important pieces + radius = lw_arc_center(p0, p1, p2, ¢er); + + d = distance2d_pt_pt(p, ¢er); + if (FP_EQUALS(d, radius) && lw_pt_in_arc(p, p0, p1, p2)) + { + *on_boundary = LW_TRUE; + return 0; + } + + // --- Step 2: Perform the Ray Casting intersection test --- + + // Only process arcs that our ray crosses + lw_arc_calculate_gbox_cartesian_2d(p0, p1, p2, &gbox); + if ((gbox.ymin <= py) && (py < gbox.ymax)) + { + // Point of intersection on the circle that defines the arc + POINT2D i0, i1; + + // How many points of intersection are there + int iCount = circle_raycast_intersections(¢er, radius, py, &i0, &i1); + + // Nothing to see here + if (iCount == 0) + continue; + + // Cannot think of a case where a grazing is not a + // no-op + if (iCount == 1) + continue; + + // So we must have 2 intersections + // Only increment the counter for intersections to the right + // of the test point + if (i0.x > px && lw_pt_in_arc(&i0, p0, p1, p2)) + intersections++; + + if (i1.x > px && lw_pt_in_arc(&i1, p0, p1, p2)) + intersections++; + } + } + + return intersections; } int @@ -838,7 +1109,16 @@ ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int chec int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt) { - return ptarrayarc_contains_point_partial(pa, pt, LW_TRUE /* Check closed*/, NULL); + int on_boundary = LW_FALSE; + int intersections; + if (!ptarray_is_closed_2d(pa)) + lwerror("%s called on unclosed ring", __func__); + + intersections = ptarrayarc_raycast_intersections(pa, pt, &on_boundary); + if (on_boundary) + return LW_BOUNDARY; + else + return (intersections % 2) ? LW_INSIDE : LW_OUTSIDE; } int ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + liblwgeom/cunit/cu_measures.c | 7 + liblwgeom/cunit/cu_ptarray.c | 2 +- liblwgeom/liblwgeom_internal.h | 3 + liblwgeom/lwalgorithm.c | 18 +- liblwgeom/lwcompound.c | 74 +++--- liblwgeom/measures.c | 496 +++++++++++++++++++---------------------- liblwgeom/ptarray.c | 290 +++++++++++++++++++++++- 8 files changed, 571 insertions(+), 320 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 12:07:41 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:07:41 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.ebcf3135902e2b4770fc313f1cb2d2d5@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"f29425e4cfe9a8358a0a09d2f7a7192be8233e8e/git" f29425e4/git]: {{{#!CommitTicketReference repository="git" revision="f29425e4cfe9a8358a0a09d2f7a7192be8233e8e" Update distance calculations for CurvePolygon, references #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 12:10:39 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:10:39 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-17-gba2639c51 Message-ID: <20251007191039.7164013644D@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via ba2639c5145af2647fb9d70a4730f45cf9c07bcb (commit) from dde0f5518a0941e207a7ac5faecd1385c38c6737 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ba2639c5145af2647fb9d70a4730f45cf9c07bcb Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:10:48 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:10:48 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-67-g4991a8dd1 Message-ID: <20251007191048.9582C13612D@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 4991a8dd1cf17db8afa5391a8dfe668b0182b6a2 (commit) from 89ebcc501e570813f576d7aae785f7e88e395db9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4991a8dd1cf17db8afa5391a8dfe668b0182b6a2 Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:10:56 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:10:56 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-60-g7fbd2bc8d Message-ID: <20251007191057.12B0A135D5A@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via 7fbd2bc8d07a3f541f95593e77749cda2c5fd74f (commit) from f9dbfd1a801b47f4ec0ca8f9438b3bfa11bff470 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7fbd2bc8d07a3f541f95593e77749cda2c5fd74f Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:11:05 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:11:05 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.7-61-gab19387a3 Message-ID: <20251007191105.442D713619F@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via ab19387a34ea20e7edb1eabbd6591f366995faf6 (commit) from 71b0a452ea5a3869ad05249e3b0b4f92644858e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ab19387a34ea20e7edb1eabbd6591f366995faf6 Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:11:12 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:11:12 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.2 updated. 3.2.7-55-gdd98c6f88 Message-ID: <20251007191112.35958136485@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.2 has been updated via dd98c6f88026cf6f2504bfc2afb88bbd02b530fd (commit) from bd71a9ffef92c6dd34f80d3af03463604695b860 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dd98c6f88026cf6f2504bfc2afb88bbd02b530fd Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 12:11:39 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:11:39 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.1 updated. 3.1.11-44-g147d127ff Message-ID: <20251007191140.0A407136486@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.1 has been updated via 147d127fff7667c1c2f915d6ef3f37c7ea60d8a0 (commit) from 422163cfb7af7c6a534cd479fbbd9f5de63ab01c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 147d127fff7667c1c2f915d6ef3f37c7ea60d8a0 Author: Maksim Korotkov Date: Tue Oct 7 15:46:55 2025 +0300 address_standardizer: fixed memory leak The memory was not released in case of error handling. Found by PostgresPro with Svace static analyzer Fixes: c6091a4bb ("Prep to move address_standardizer into extensions folder") Signed-off-by: Maksim Korotkov diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index 8a4b9abe1..4fe63e3ed 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -623,6 +623,7 @@ STAND_PARAM *init_stand_context(PAGC_GLOBAL *__pagc_global__,ERR_PARAM *__err_pa PAGC_CALLOC_STRUC(__stand_param__,STAND_PARAM,1,__err_param__,NULL) ; if ((__stand_param__->stz_info = create_segments(__err_param__)) == NULL) { + FREE_AND_NULL(__stand_param__); return NULL ; } PAGC_CALLOC_2D_ARRAY(__stand_param__->standard_fields, char, MAXOUTSYM, MAXFLDLEN, __err_param__, NULL) ; ----------------------------------------------------------------------- Summary of changes: extensions/address_standardizer/standard.c | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 12:29:31 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:29:31 -0000 Subject: [PostGIS] #5994: null pointer dereference in ST_AsGeoJsonRow In-Reply-To: <049.a8f65297f16623a5866ccf55bcdacc5d@osgeo.org> References: <049.a8f65297f16623a5866ccf55bcdacc5d@osgeo.org> Message-ID: <064.b3f2122c052622cea219e997b5f39afb@osgeo.org> #5994: null pointer dereference in ST_AsGeoJsonRow ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.5.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"1b003421b5f4b0a74432b6dd8a79156d677c1887/git" 1b003421/git]: {{{#!CommitTicketReference repository="git" revision="1b003421b5f4b0a74432b6dd8a79156d677c1887" Fix null pointer in ST_AsGeoJsonRow, references #5994 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 12:29:31 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:29:31 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.3a7b5d139a9e2716bd8c244a9eb2162e@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: reopened Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"9979912be010137e0cee0b111e68eec938d516ca/git" 9979912/git]: {{{#!CommitTicketReference repository="git" revision="9979912be010137e0cee0b111e68eec938d516ca" Fix arc/arc distance to handle more cases such as contained, circular, and other interesting arc/arc alignments that come up rarely in ordinary GIS data. Fix compoundcurve distance calculations, in particular the containment test, which was failing for some cases. Replaced containment test with a ray casting algorithm that makes more sense for circularstrings that the winding order algorithm did. References #5989 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 12:33:14 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 12:33:14 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-120-g56c2cc850 Message-ID: <20251007193315.17D601371AB@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 56c2cc85083f125e9d5f623b9de1b20370d558ef (commit) from c0bc117e91fd015468fd37975c42f382070b52f4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 56c2cc85083f125e9d5f623b9de1b20370d558ef Author: Paul Ramsey Date: Tue Oct 7 12:33:07 2025 -0700 Clarify single sided buffering a little. From Peter Nguyen diff --git a/doc/reference_processing.xml b/doc/reference_processing.xml index 8144058a4..80c16af3f 100644 --- a/doc/reference_processing.xml +++ b/doc/reference_processing.xml @@ -85,8 +85,8 @@ providing a list of blank-separated key=value pairs as follows: 'mitre_limit=#.#' : mitre ratio limit (only affects mitered join style). 'miter_limit' is accepted as a synonym for 'mitre_limit'. -'side=both|left|right' : 'left' or 'right' performs a single-sided buffer on the geometry, with the buffered side relative to the direction of the line. -This is only applicable to LINESTRING geometry and does not affect POINT or POLYGON geometries. By default end caps are square. +'side=both|left|right' : defaults to 'both'. 'left' or 'right' performs a single-sided buffer on the geometry, with the buffered side relative to the direction of the line. +This is only applicable to LINESTRING geometry and does not affect POINT or POLYGON geometries. By default end caps are square when 'left' or 'right' are specified. ----------------------------------------------------------------------- Summary of changes: doc/reference_processing.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 12:46:41 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:46:41 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.503248c26f534dc1bdf03975347ab9cc@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.2.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: reopened => closed Comment: Finished back-patch to 3.3. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 12:46:49 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:46:49 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.27ba36ab9aa76dbfc8b7c40c0bf25381@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.3.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * version: 3.2.x => 3.3.x -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 12:47:00 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 19:47:00 -0000 Subject: [PostGIS] #5989: ST_Distance error on CurvePolygon In-Reply-To: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> References: <049.160f5b03509401c2e12090c58b6e5840@osgeo.org> Message-ID: <064.c42f63228c41eed8f84537727f244e06@osgeo.org> #5989: ST_Distance error on CurvePolygon ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.3.9 Component: postgis | Version: 3.3.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * milestone: PostGIS 3.5.4 => PostGIS 3.3.9 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 13:03:39 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 20:03:39 -0000 Subject: [PostGIS] #5997: Pg19 Crash In-Reply-To: <049.ad26eed4b7b2f3ecc6b1d3e58c09c996@osgeo.org> References: <049.ad26eed4b7b2f3ecc6b1d3e58c09c996@osgeo.org> Message-ID: <064.56f68432c3193270894350b670559bbf@osgeo.org> #5997: Pg19 Crash -----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: critical | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: fixed | Keywords: -----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed Comment: Should be patched shortly. https://www.postgresql.org/message- id/20251007.112832.740065769089328041.ishii%40postgresql.org -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 13:05:07 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 20:05:07 -0000 Subject: [PostGIS] #5988: ST_ConcaveHull makes pg crash In-Reply-To: <052.43c2f5afd07a6ecd656aab94ceadb24a@osgeo.org> References: <052.43c2f5afd07a6ecd656aab94ceadb24a@osgeo.org> Message-ID: <067.6d0eab3dbb1a40da298332e857b5acb3@osgeo.org> #5988: ST_ConcaveHull makes pg crash -------------------------+---------------------------- Reporter: severingeo | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: ST_ConcaveHull -------------------------+---------------------------- Changes (by pramsey): * resolution: => invalid * status: new => closed Comment: Closing until reporter adds a reproduction case. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 13:05:55 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 20:05:55 -0000 Subject: [PostGIS] #5965: PG19 compile is spitting out warnings about PG_GSERIALIZED_DATUM_NEEDS_DETOAST In-Reply-To: <046.15962c34b0928e353b65fe98f8107652@osgeo.org> References: <046.15962c34b0928e353b65fe98f8107652@osgeo.org> Message-ID: <061.ef7c3a11a90a3788f0dc709e09bd608c@osgeo.org> #5965: PG19 compile is spitting out warnings about PG_GSERIALIZED_DATUM_NEEDS_DETOAST ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: closed Priority: blocker | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed Comment: To my knowledge things are working as of now. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 14:27:44 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 21:27:44 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.80d04afd35a0d55526a96094f5cdfdd7@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): Erm, once you start adding extra params onto an existing function, the "might as well have a new function" starts to kick in; bonus points if the other mode involves a completely separate code line. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 7 15:34:36 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 22:34:36 -0000 Subject: [PostGIS] #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension Message-ID: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension ----------------------------+---------------------------- Reporter: robe | Owner: robe Type: patch | Status: new Priority: medium | Milestone: PostGIS 3.0.12 Component: tiger geocoder | Version: 3.5.x Keywords: | ----------------------------+---------------------------- This is a security patch provided by the Yandex group to address the possibility that a rogue user might create tables in tiger schema before create extension is done and then apply triggers to the table that could be triggered on insert of data by the extension. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 15:38:26 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 15:38:26 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-122-g115ee04ba Message-ID: <20251007223826.AC0BE1600DC@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 115ee04ba2263ff714bd4f66b77cc3be1d5c35e1 (commit) via 1ee415c1a24238ca26f0608d80707c649349b713 (commit) from 56c2cc85083f125e9d5f623b9de1b20370d558ef (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 115ee04ba2263ff714bd4f66b77cc3be1d5c35e1 Author: Regina Obe Date: Tue Oct 7 18:27:17 2025 -0400 TIGER EXTENSION SECURITY fix - Ensure tables are created by tiger extension and bale if not. Patch provided by Andrey Borodin (Yandex) Closes #5998 for PostGIS 3.7.0 diff --git a/extras/tiger_geocoder/geocode_settings.sql b/extras/tiger_geocoder/geocode_settings.sql index e126f825b..e5c09b8c2 100644 --- a/extras/tiger_geocoder/geocode_settings.sql +++ b/extras/tiger_geocoder/geocode_settings.sql @@ -22,10 +22,16 @@ BEGIN IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'geocode_settings') THEN CREATE TABLE geocode_settings(name text primary key, setting text, unit text, category text, short_desc text); GRANT SELECT ON geocode_settings TO public; + ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS geocode_settings(name text primary key, setting text, unit text, category text, short_desc text); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'geocode_settings_default') THEN CREATE TABLE geocode_settings_default(name text primary key, setting text, unit text, category text, short_desc text); GRANT SELECT ON geocode_settings_default TO public; + ELSE + -- Same as above. + CREATE TABLE IF NOT EXISTS geocode_settings_default(name text primary key, setting text, unit text, category text, short_desc text); END IF; --recreate defaults TRUNCATE TABLE geocode_settings_default; diff --git a/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql b/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql index ff78fc8f8..da6fc91a9 100644 --- a/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql +++ b/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql @@ -11,14 +11,23 @@ BEGIN IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_gaz') THEN CREATE TABLE pagc_gaz (id serial NOT NULL primary key ,seq integer ,word text, stdword text, token integer,is_custom boolean NOT NULL default true); GRANT SELECT ON pagc_gaz TO public; + ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS pagc_gaz (id serial NOT NULL primary key ,seq integer ,word text, stdword text, token integer,is_custom boolean NOT NULL default true); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_lex') THEN CREATE TABLE pagc_lex (id serial NOT NULL primary key,seq integer,word text,stdword text,token integer,is_custom boolean NOT NULL default true); GRANT SELECT ON pagc_lex TO public; + ELSE + -- Same as above. + CREATE TABLE IF NOT EXISTS pagc_lex (id serial NOT NULL primary key,seq integer,word text,stdword text,token integer,is_custom boolean NOT NULL default true); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_rules') THEN CREATE TABLE pagc_rules (id serial NOT NULL primary key,rule text, is_custom boolean DEFAULT true); GRANT SELECT ON pagc_rules TO public; + ELSE + -- Same as above. + CREATE TABLE IF NOT EXISTS pagc_rules (id serial NOT NULL primary key,rule text, is_custom boolean DEFAULT true); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_gaz' AND data_type='text') THEN -- its probably old table structure change type of lex and gaz columns diff --git a/extras/tiger_geocoder/tiger_loader_2012.sql b/extras/tiger_geocoder/tiger_loader_2012.sql index c4d6da1b7..00593ecf5 100644 --- a/extras/tiger_geocoder/tiger_loader_2012.sql +++ b/extras/tiger_geocoder/tiger_loader_2012.sql @@ -57,18 +57,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -125,9 +121,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -138,8 +132,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -149,7 +142,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2013.sql b/extras/tiger_geocoder/tiger_loader_2013.sql index d42f60ea2..8b6e0d166 100644 --- a/extras/tiger_geocoder/tiger_loader_2013.sql +++ b/extras/tiger_geocoder/tiger_loader_2013.sql @@ -56,18 +56,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -124,9 +120,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -137,8 +131,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -148,7 +141,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2014.sql b/extras/tiger_geocoder/tiger_loader_2014.sql index bedb84051..8726e5afe 100644 --- a/extras/tiger_geocoder/tiger_loader_2014.sql +++ b/extras/tiger_geocoder/tiger_loader_2014.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -212,9 +274,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -225,8 +285,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -236,7 +295,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2015.sql b/extras/tiger_geocoder/tiger_loader_2015.sql index fe0bdf62f..3311be2e7 100644 --- a/extras/tiger_geocoder/tiger_loader_2015.sql +++ b/extras/tiger_geocoder/tiger_loader_2015.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -212,9 +274,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -225,8 +285,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -236,7 +295,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2016.sql b/extras/tiger_geocoder/tiger_loader_2016.sql index 0cb93e442..39dd37f0a 100644 --- a/extras/tiger_geocoder/tiger_loader_2016.sql +++ b/extras/tiger_geocoder/tiger_loader_2016.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2017.sql b/extras/tiger_geocoder/tiger_loader_2017.sql index 9a7c6a726..5644a4d53 100644 --- a/extras/tiger_geocoder/tiger_loader_2017.sql +++ b/extras/tiger_geocoder/tiger_loader_2017.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2018.sql b/extras/tiger_geocoder/tiger_loader_2018.sql index 61e68797a..33697e785 100644 --- a/extras/tiger_geocoder/tiger_loader_2018.sql +++ b/extras/tiger_geocoder/tiger_loader_2018.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2019.sql b/extras/tiger_geocoder/tiger_loader_2019.sql index 12a395b60..9485011cf 100644 --- a/extras/tiger_geocoder/tiger_loader_2019.sql +++ b/extras/tiger_geocoder/tiger_loader_2019.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2020.sql b/extras/tiger_geocoder/tiger_loader_2020.sql index 6afce151a..01c81f26a 100644 --- a/extras/tiger_geocoder/tiger_loader_2020.sql +++ b/extras/tiger_geocoder/tiger_loader_2020.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -165,18 +231,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -232,9 +294,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -245,8 +305,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -256,7 +315,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2021.sql b/extras/tiger_geocoder/tiger_loader_2021.sql index 0cdd7ee5a..675bff9cd 100644 --- a/extras/tiger_geocoder/tiger_loader_2021.sql +++ b/extras/tiger_geocoder/tiger_loader_2021.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -172,18 +238,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -239,9 +301,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -252,8 +312,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -263,7 +322,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2022.sql b/extras/tiger_geocoder/tiger_loader_2022.sql index af4b9ee25..991ce2255 100644 --- a/extras/tiger_geocoder/tiger_loader_2022.sql +++ b/extras/tiger_geocoder/tiger_loader_2022.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -175,18 +241,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -242,9 +304,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -255,8 +315,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -266,7 +325,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2023.sql b/extras/tiger_geocoder/tiger_loader_2023.sql index 691176236..65c497ce2 100644 --- a/extras/tiger_geocoder/tiger_loader_2023.sql +++ b/extras/tiger_geocoder/tiger_loader_2023.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -175,18 +241,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -242,9 +304,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -255,8 +315,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -266,7 +325,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2024.sql b/extras/tiger_geocoder/tiger_loader_2024.sql index f6d7f0b85..1c9b87830 100644 --- a/extras/tiger_geocoder/tiger_loader_2024.sql +++ b/extras/tiger_geocoder/tiger_loader_2024.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tiger.tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tiger.tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tiger.bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -175,18 +241,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -242,9 +304,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -255,8 +315,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -266,7 +325,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; commit 1ee415c1a24238ca26f0608d80707c649349b713 Author: Regina Obe Date: Tue Oct 7 18:26:13 2025 -0400 Fix winnie scripts diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh index 10aa48c0e..229a16ed1 100644 --- a/ci/winnie/regress_postgis.sh +++ b/ci/winnie/regress_postgis.sh @@ -68,11 +68,11 @@ if [ $INCLUDE_MINOR_LIB == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --with-library-minor-version" fi -if [ $REGRESS_WITHOUT_TOPOLOGY == "1" ]; then +if [ $REGRESS_WITHOUT_TOPOLOGY == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-topology" fi -if [ $REGRESS_WITHOUT_RASTER == "1" ]; then +if [ $REGRESS_WITHOUT_RASTER == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-raster" fi @@ -103,9 +103,9 @@ make -j 4 make install # don't run tests twice. Only run regular if extension test is not asked for -if [ "$MAKE_EXTENSION" == "" ]; then +if [ "$MAKE_EXTENSION" == "0" ]; then make check RUNTESTFLAGS=-v -fi +fi if [ "$MAKE_EXTENSION" == "1" ]; then @@ -117,13 +117,13 @@ if [ "$MAKE_EXTENSION" == "1" ]; then #strip raster/rt_pg/postgis_raster-*.dll #strip sfcgal/*.dll - if [ $REGRESS_WITHOUT_TOPOLOGY == "" ]; then + if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then cp -r topology/*.dll ${PGPATHEDB}/lib fi cp postgis/postgis*.dll ${PGPATHEDB}/lib cp sfcgal/*.dll ${PGPATHEDB}/lib - if [ $REGRESS_WITHOUT_RASTER == "" ]; then + if [ $REGRESS_WITHOUT_RASTER == "0" ]; then cp raster/rt_pg/postgis_raster-*.dll ${PGPATHEDB}/lib fi @@ -141,18 +141,18 @@ export UPGRADEABLE_VERSIONS=$value export WIN_RELEASED_VERSIONS="2.0.0 2.0.1 2.0.3 2.0.4 2.0.6 2.1.4 2.1.7 2.1.8 2.2.0 2.2.3 2.3.0 2.3.7 2.4.0 2.4.4" export extensions_to_install="postgis postgis_sfcgal postgis_tiger_geocoder address_standardizer" -if [ $REGRESS_WITHOUT_TOPOLOGY == "" ]; then +if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then extensions_to_install="${extensions_to_install} postgis_topology" fi -if [ $REGRESS_WITHOUT_RASTER == "" ]; then +if [ $REGRESS_WITHOUT_RASTER == "0" ]; then extensions_to_install="${extensions_to_install} postgis_raster" fi #echo "Versions are: $UPGRADEABLE_VERSIONS" for EXTNAME in $extensions_to_install; do - + cp extensions/$EXTNAME/sql/* ${PGPATHEDB}/share/extension cp extensions/$EXTNAME/sql/$EXTNAME--TEMPLATED--TO--ANY.sql ${PGPATHEDB}/share/extension/$EXTNAME--$POSTGIS_MICRO_VER--${POSTGIS_MINOR_MAX_VER}.sql; diff --git a/ci/winnie/winnie_common.sh b/ci/winnie/winnie_common.sh index e81b946f0..d375cbec6 100644 --- a/ci/winnie/winnie_common.sh +++ b/ci/winnie/winnie_common.sh @@ -65,6 +65,18 @@ fi; echo "LZ4_VER ${LZ4_VER}" +if [[ "${REGRESS_WITHOUT_TOPOLOGY}" == '' ]] ; then + export REGRESS_WITHOUT_TOPOLOGY=0 +fi; + +if [[ "${REGRESS_WITHOUT_RASTER}" == '' ]] ; then + export REGRESS_WITHOUT_RASTER=0 +fi; + +if [[ "${MAKE_EXTENSION}" == '' ]] ; then + export MAKE_EXTENSION=0 +fi; + #set to something even if override is on but not set if [[ "${ZLIB_VER}" == '' ]] ; then ----------------------------------------------------------------------- Summary of changes: ci/winnie/regress_postgis.sh | 18 ++--- ci/winnie/winnie_common.sh | 12 ++++ extras/tiger_geocoder/geocode_settings.sql | 6 ++ .../tiger_geocoder/pagc_normalize/pagc_tables.sql | 9 +++ extras/tiger_geocoder/tiger_loader_2012.sql | 16 ++--- extras/tiger_geocoder/tiger_loader_2013.sql | 16 ++--- extras/tiger_geocoder/tiger_loader_2014.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2015.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2016.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2017.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2018.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2019.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2020.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2021.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2022.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2023.sql | 82 ++++++++++++++++++---- extras/tiger_geocoder/tiger_loader_2024.sql | 82 ++++++++++++++++++---- 17 files changed, 814 insertions(+), 165 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 15:38:43 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 07 Oct 2025 22:38:43 -0000 Subject: [PostGIS] #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension In-Reply-To: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> References: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> Message-ID: <061.94c76831913c819d75d39a69e88a845a@osgeo.org> #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension -----------------------------+---------------------------- Reporter: robe | Owner: robe Type: patch | Status: closed Priority: medium | Milestone: PostGIS 3.0.12 Component: tiger geocoder | Version: 3.5.x Resolution: fixed | Keywords: -----------------------------+---------------------------- Changes (by Regina Obe ): * resolution: => fixed * status: new => closed Comment: In [changeset:"115ee04ba2263ff714bd4f66b77cc3be1d5c35e1/git" 115ee04b/git]: {{{#!CommitTicketReference repository="git" revision="115ee04ba2263ff714bd4f66b77cc3be1d5c35e1" TIGER EXTENSION SECURITY fix - Ensure tables are created by tiger extension and bale if not. Patch provided by Andrey Borodin (Yandex) Closes #5998 for PostGIS 3.7.0 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 17:46:40 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 17:46:40 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-123-gc3325a32c Message-ID: <20251008004640.514D0162500@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via c3325a32c85604bf56f280c41bdf83f619500b4b (commit) from 115ee04ba2263ff714bd4f66b77cc3be1d5c35e1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c3325a32c85604bf56f280c41bdf83f619500b4b Author: Nikolai B Date: Wed Sep 24 14:05:19 2025 +0100 doc(St_Subdivide) mention potential changes in geography Closes https://github.com/postgis/postgis/pull/831 for PostGIS 3.7.0 Patch provided by Nikolai Berkoff diff --git a/doc/reference_overlay.xml b/doc/reference_overlay.xml index a380b6447..7225cea18 100644 --- a/doc/reference_overlay.xml +++ b/doc/reference_overlay.xml @@ -654,6 +654,11 @@ SELECT ST_AsText( ST_Split( ST_Snap(line, point, 1), point)) AS snapped_split, The "hit" cases are faster because the spatial operations executed by the index recheck process fewer points. + + When casting a subdivided geometry to geography, the resulting geography may differ from the original. + Subdivision adds vertices in planar (geometry) space. If vertices are inserted along the boundary, they will alter the geographical representation, where edges are interpreted as geodesic segments. + To minimize distortion, first densify the geography using to add geodesic vertices, then cast to geometry before subdivision. + This is a set-returning function (SRF) that return a set of rows containing single geometry values. @@ -703,6 +708,8 @@ SELECT row_number() OVER() As rn, ST_AsText(geom) As wkt Example: Densify a long geography line using ST_Segmentize(geography, distance), and use ST_Subdivide to split the resulting line into sublines of 8 vertices. + Densification minimizes the impact of changes to the geography representation of a geometry + when subdividing. ----------------------------------------------------------------------- Summary of changes: doc/reference_overlay.xml | 7 +++++++ 1 file changed, 7 insertions(+) hooks/post-receive -- PostGIS From git at osgeo.org Tue Oct 7 18:05:15 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 18:05:15 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-124-g598acb624 Message-ID: <20251008010515.8BB1E163124@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 598acb6241df31b6f77f115b7af796e1226424ab (commit) from c3325a32c85604bf56f280c41bdf83f619500b4b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 598acb6241df31b6f77f115b7af796e1226424ab Author: Regina Obe Date: Tue Oct 7 21:00:44 2025 -0400 Get rid of creation of tiger_data schema It really shouldn't be part of the extension and is created on initial load. The user can also overwrite the schema name before load. References #5998 for PostGIS 3.7.0 diff --git a/extras/tiger_geocoder/tiger_loader_2024.sql b/extras/tiger_geocoder/tiger_loader_2024.sql index 1c9b87830..5af42e84a 100644 --- a/extras/tiger_geocoder/tiger_loader_2024.sql +++ b/extras/tiger_geocoder/tiger_loader_2024.sql @@ -245,12 +245,6 @@ BEGIN END $$ LANGUAGE 'plpgsql'; -DO -$$ -BEGIN - CREATE SCHEMA IF NOT EXISTS tiger_data; -END -$$ LANGUAGE 'plpgsql'; DELETE FROM loader_platform WHERE os IN ('sh', 'windows'); GRANT SELECT ON TABLE loader_platform TO public; ----------------------------------------------------------------------- Summary of changes: extras/tiger_geocoder/tiger_loader_2024.sql | 6 ------ 1 file changed, 6 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 18:05:17 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 01:05:17 -0000 Subject: [PostGIS] #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension In-Reply-To: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> References: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> Message-ID: <061.5cd2026e6f7baa9c4c3aeae9b6249cd1@osgeo.org> #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension -----------------------------+---------------------------- Reporter: robe | Owner: robe Type: patch | Status: closed Priority: medium | Milestone: PostGIS 3.0.12 Component: tiger geocoder | Version: 3.5.x Resolution: fixed | Keywords: -----------------------------+---------------------------- Comment (by Regina Obe ): In [changeset:"598acb6241df31b6f77f115b7af796e1226424ab/git" 598acb6/git]: {{{#!CommitTicketReference repository="git" revision="598acb6241df31b6f77f115b7af796e1226424ab" Get rid of creation of tiger_data schema It really shouldn't be part of the extension and is created on initial load. The user can also overwrite the schema name before load. References #5998 for PostGIS 3.7.0 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 7 20:14:33 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 7 Oct 2025 20:14:33 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-18-g03737df1d Message-ID: <20251008031433.CCF7A1644AF@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via 03737df1dec03f07453218573d2489d9b8d2622c (commit) from ba2639c5145af2647fb9d70a4730f45cf9c07bcb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 03737df1dec03f07453218573d2489d9b8d2622c Author: Nikolai B Date: Wed Sep 24 14:05:19 2025 +0100 doc(St_Subdivide) mention potential changes in geography Closes https://github.com/postgis/postgis/pull/831 for PostGIS 3.6.1 Patch provided by Nikolai Berkoff diff --git a/doc/introduction.xml b/doc/introduction.xml index 209707e05..983f01f64 100644 --- a/doc/introduction.xml +++ b/doc/introduction.xml @@ -316,6 +316,7 @@ Mike Toews Nathan Wagner Nathaniel Clay + Nikolai Berkoff Nikita Shulga Norman Vine Patricia Tozer diff --git a/doc/reference_overlay.xml b/doc/reference_overlay.xml index a380b6447..7225cea18 100644 --- a/doc/reference_overlay.xml +++ b/doc/reference_overlay.xml @@ -654,6 +654,11 @@ SELECT ST_AsText( ST_Split( ST_Snap(line, point, 1), point)) AS snapped_split, The "hit" cases are faster because the spatial operations executed by the index recheck process fewer points. + + When casting a subdivided geometry to geography, the resulting geography may differ from the original. + Subdivision adds vertices in planar (geometry) space. If vertices are inserted along the boundary, they will alter the geographical representation, where edges are interpreted as geodesic segments. + To minimize distortion, first densify the geography using to add geodesic vertices, then cast to geometry before subdivision. + This is a set-returning function (SRF) that return a set of rows containing single geometry values. @@ -703,6 +708,8 @@ SELECT row_number() OVER() As rn, ST_AsText(geom) As wkt Example: Densify a long geography line using ST_Segmentize(geography, distance), and use ST_Subdivide to split the resulting line into sublines of 8 vertices. + Densification minimizes the impact of changes to the geography representation of a geometry + when subdividing. ----------------------------------------------------------------------- Summary of changes: doc/introduction.xml | 1 + doc/reference_overlay.xml | 7 +++++++ 2 files changed, 8 insertions(+) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 7 23:19:07 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 06:19:07 -0000 Subject: [PostGIS] #5965: PG19 compile is spitting out warnings about PG_GSERIALIZED_DATUM_NEEDS_DETOAST In-Reply-To: <046.15962c34b0928e353b65fe98f8107652@osgeo.org> References: <046.15962c34b0928e353b65fe98f8107652@osgeo.org> Message-ID: <061.a10ab7a66093e080b147082083709fc0@osgeo.org> #5965: PG19 compile is spitting out warnings about PG_GSERIALIZED_DATUM_NEEDS_DETOAST ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: closed Priority: blocker | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Laurenz Albe): I can confirm that building against PostgreSQL v19 works now. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 00:08:33 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 07:08:33 -0000 Subject: [PostGIS] #5999: PostGIS doesn't compile against PG19 Message-ID: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> #5999: PostGIS doesn't compile against PG19 ---------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Keywords: | ---------------------+--------------------------- Just had debbie rebuild from postgres master branch and getting this error now during compile https://github.com/postgis/postgis/actions/runs/18332638595/job/52221466442 {{{ rep -v '^#' legacy.sql.tmp | /usr/bin/perl -lpe "s'MODULE_PATHNAME'\$libdir/postgis-3'g;s'@extschema@\.''g" > legacy.sql grep -v '^#' legacy_minimal.sql.tmp | /usr/bin/perl -lpe "s'MODULE_PATHNAME'\$libdir/postgis-3'g;s'@extschema@\.''g" > legacy_minimal.sql grep -v '^#' postgis.sql.tmp | /usr/bin/perl -lpe "s'MODULE_PATHNAME'\$libdir/postgis-3'g;s'@extschema@\.''g" > postgis.sql grep -v '^#' legacy_gist.sql.tmp | /usr/bin/perl -lpe "s'MODULE_PATHNAME'\$libdir/postgis-3'g;s'@extschema@\.''g" > legacy_gist.sql rm -f legacy.sql.tmp rm -f legacy_minimal.sql.tmp /usr/bin/perl ../utils/create_uninstall.pl legacy.sql 190 > uninstall_legacy.sql rm -f legacy_gist.sql.tmp rm -f postgis.sql.tmp /usr/bin/perl ../utils/create_uninstall.pl postgis.sql 190 > uninstall_postgis.sql /usr/bin/perl ../utils/create_upgrade.pl postgis.sql > postgis_upgrade.sql.in echo "BEGIN;" > postgis_upgrade.sql cat common_before_upgrade.sql postgis_before_upgrade.sql postgis_upgrade.sql.in postgis_after_upgrade.sql common_after_upgrade.sql >> postgis_upgrade.sql echo "COMMIT;" >> postgis_upgrade.sql lwgeom_transform.c: In function 'srs_tuple_from_entry': lwgeom_transform.c:402:17: error: implicit declaration of function 'heap_form_tuple'; did you mean 'brin_form_tuple'? [-Wimplicit-function- declaration] 402 | tuple = heap_form_tuple(tuple_desc, tuple_data, tuple_null); | ^~~~~~~~~~~~~~~ | brin_form_tuple lwgeom_transform.c:402:15: error: assignment to 'HeapTuple' {aka 'HeapTupleData *'} from 'int' makes pointer from integer without a cast [-Wint-conversion] 402 | tuple = heap_form_tuple(tuple_desc, tuple_data, tuple_null); | ^ make[1]: *** [: lwgeom_transform.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make[1]: Leaving directory '/src/postgis/postgis' make: *** [GNUmakefile:36: all] Error 1 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 00:53:22 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 07:53:22 -0000 Subject: [PostGIS] #5983: Potential data corruption in topology.topoelement after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.1b7b89944049d73bcb5324224441a8f0@osgeo.org> #5983: Potential data corruption in topology.topoelement after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by francoisb): The `topology.topogeometry` composite type appears to be affected too, probably with the same root cause. I can file a separate ticket if applicable. One observation about the "garbage" values, which are not entirely random. Consider: - Topology `topo_1` with topology ID 1 - Table `table_1` with a column `topogeom` of type `topology.topogeometry` - Layer ID 1 of `topo_1` of type poly (type 3), is deployed in column `topogeom` After the 3.6.0 upgrade, the `relation` table for the topology looks all good: {{{ SELECT topogeo_id, array_agg(element_id ORDER BY element_id) AS element_ids FROM topo_1.relation GROUP BY 1; }}} Output limited to one example topogeometry: {{{ ? topogeo_id ? element_ids ? ? 57 ? {134,138} ? }}} However, the `topogeom` column has garbage in all `id` and `type` subfields: {{{ SELECT topogeom FROM table_1; }}} Output limited to the row corresponding to the example topogeo_id = 57 from above: {{{ ? topogeom ? ? (1,1,12884901945,262144) ? }}} Expected is: (1,1,57,3) Selecting subfields individually or with `.*` doesn't change the behavior: {{{ SELECT (topogeom).id FROM table_1; }}} {{{ ? id ? ? 12884901945 ? }}} {{{ SELECT (topogeom).* FROM table_1; }}} {{{ ? topology_id ? layer_id ? id ? type ? ? 1 ? 1 ? 12884901945 ? 0 ? }}} The value for `type` is truely random and inconsistent. It doesn't change if the same query is executed immediately after (presumably memory contents doesn't change), but it will change if other queries are run in between, or across different sessions; a hint that it depends on some unrelated memory contents. The value for `id`, however, is consistently the same and predictable. The hex representation for `12884901945` as 64-bit: 00000003 00000039 - `3` appears in the 32 most significant bits, the expected `type` value - `57` (in decimal, or `39` in hex) appears in the 32 least significant bits, the expected `id` value Clearly, the actual bytes for `id` are 32-bit in reality, but the PostgreSQL/PostGIS code is incorrectly trying to read 64-bit. The extra 32-bit read are from the `type`, because this field happens to be contiguous in the topogeometry composite type. One could programmatically compute the correct `topogeometry` values, with a single SQL UPDATE query, by parsing the bytes of the garbage `id`, to recover correct `id` and `type`. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 02:07:07 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 09:07:07 -0000 Subject: [PostGIS] #6000: Dereference of NULL Message-ID: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> #6000: Dereference of NULL -----------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Keywords: | -----------------------+--------------------------- liblwgeom/measures.c: Function lw_dist2d_check_overlap() if (!lwg1->bbox) lwgeom_calculate_gbox(lwg1, lwg1->bbox); if (!lwg2->bbox) lwgeom_calculate_gbox(lwg2, lwg2->bbox); Inside lwgeom_calculate_gbox() the NULL pointers lwg1->bbox and lwg2->bbox are dereferenced -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 07:18:43 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 14:18:43 -0000 Subject: [PostGIS] #5999: PostGIS doesn't compile against PG19 In-Reply-To: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> References: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> Message-ID: <061.dab82ac7a4931359cc4a1ce07f10b521@osgeo.org> #5999: PostGIS doesn't compile against PG19 ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: ----------------------+--------------------------- Changes (by robe): * resolution: => invalid * status: new => closed Comment: nevermind. Not sure what I was looking at maybe an old log. Was fine on debbie and I see it green now. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 07:20:42 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 14:20:42 -0000 Subject: [PostGIS] #5999: PostGIS doesn't compile against PG19 In-Reply-To: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> References: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> Message-ID: <061.a5d8e0919a372e4a6f6c1f9401962245@osgeo.org> #5999: PostGIS doesn't compile against PG19 ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: reopened Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by robe): * resolution: invalid => * status: closed => reopened Comment: Okay not user error. Seems to be failing just on stable-3.6. Master is fine so perhaps something we fixed in master we didn't backport to 3.6 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 07:21:00 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 14:21:00 -0000 Subject: [PostGIS] #5999: PostGIS 3.6 doesn't compile against PG19 (was: PostGIS doesn't compile against PG19) In-Reply-To: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> References: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> Message-ID: <061.5ad939448d218a423feac194c06d5dc4@osgeo.org> #5999: PostGIS 3.6 doesn't compile against PG19 ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: reopened Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by robe): * summary: PostGIS doesn't compile against PG19 => PostGIS 3.6 doesn't compile against PG19 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 08:51:20 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 08:51:20 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-125-g747d7732b Message-ID: <20251008155121.4619316AB76@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 747d7732b009ee6821501f290a3f729e56a9634d (commit) from 598acb6241df31b6f77f115b7af796e1226424ab (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 747d7732b009ee6821501f290a3f729e56a9634d Author: Regina Obe Date: Wed Oct 8 11:50:27 2025 -0400 Winnie try to fix path issue in binary regress diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh index 229a16ed1..5a86e8db9 100644 --- a/ci/winnie/regress_postgis.sh +++ b/ci/winnie/regress_postgis.sh @@ -39,10 +39,10 @@ echo PATH AFTER: $PATH echo WORKSPACE IS $WORKSPACE #mkdir ${PROJECTS}/postgis/tmp -export PGIS_REG_TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_MICRO_VER}_pg${PG_VER}_geos${GEOS_VER}_gdal${GDAL_VER}w${OS_BUILD} -rm -rf ${PGIS_REG_TMPDIR} -mkdir ${PGIS_REG_TMPDIR} -export TMPDIR=${PGIS_REG_TMPDIR} +#export PGIS_REG_TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_MICRO_VER}_pg${PG_VER}_geos${GEOS_VER}_gdal${GDAL_VER}w${OS_BUILD} +#rm -rf ${PGIS_REG_TMPDIR} +#mkdir ${PGIS_REG_TMPDIR} +#export TMPDIR=${PGIS_REG_TMPDIR} #rm -rf ${PGIS_REG_TMPDIR} #TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_VER}_${PG_VER}_${GEOS_VERSION}_${PROJ_VER} @@ -99,7 +99,7 @@ LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${LZ4_PATH}/lib -L${PROJECTS #patch liblwgeom generated make to get rid of dynamic linking #sed -i 's/LDFLAGS += -no-undefined//g' liblwgeom/Makefile -make -j 4 +make -j 2 make install # don't run tests twice. Only run regular if extension test is not asked for ----------------------------------------------------------------------- Summary of changes: ci/winnie/regress_postgis.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 09:30:32 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 16:30:32 -0000 Subject: [PostGIS] #5889: Include location in topology errors In-Reply-To: <046.3c240c50e31de7a47e9aae513347842f@osgeo.org> References: <046.3c240c50e31de7a47e9aae513347842f@osgeo.org> Message-ID: <061.07e226b64b604680a136c982d06c043f@osgeo.org> #5889: Include location in topology errors -----------------------+--------------------------- Reporter: strk | Owner: ankoure Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.5.4 Component: topology | Version: master Resolution: | Keywords: -----------------------+--------------------------- Changes (by ankoure): * owner: strk => ankoure * status: new => assigned -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 11:12:00 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 11:12:00 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-19-g6f86c539c Message-ID: <20251008181201.0176C16BC6C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via 6f86c539c13f461553f414bcf5f86dfa3c5001f2 (commit) from 03737df1dec03f07453218573d2489d9b8d2622c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6f86c539c13f461553f414bcf5f86dfa3c5001f2 Author: Paul Ramsey Date: Wed Oct 8 11:11:53 2025 -0700 Add in headers for Pg19 build diff --git a/postgis/lwgeom_transform.c b/postgis/lwgeom_transform.c index df9cf4e4d..58bbac8d6 100644 --- a/postgis/lwgeom_transform.c +++ b/postgis/lwgeom_transform.c @@ -22,13 +22,16 @@ * **********************************************************************/ +#include "../postgis_config.h" #include "postgres.h" #include "fmgr.h" #include "funcapi.h" +#if POSTGIS_PGSQL_VERSION >= 190 +#include "access/htup_details.h" +#endif #include "utils/builtins.h" -#include "../postgis_config.h" #include "liblwgeom.h" #include "lwgeodetic.h" #include "stringbuffer.h" ----------------------------------------------------------------------- Summary of changes: postgis/lwgeom_transform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 8 11:12:12 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 11:12:12 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-68-gb33ea0a6d Message-ID: <20251008181212.C0FBB16BC6E@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via b33ea0a6df77f4a37396fd00c248f34da32910cc (commit) from 4991a8dd1cf17db8afa5391a8dfe668b0182b6a2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b33ea0a6df77f4a37396fd00c248f34da32910cc Author: Paul Ramsey Date: Wed Oct 8 11:12:07 2025 -0700 Add in headers for Pg19 build diff --git a/postgis/lwgeom_transform.c b/postgis/lwgeom_transform.c index df9cf4e4d..58bbac8d6 100644 --- a/postgis/lwgeom_transform.c +++ b/postgis/lwgeom_transform.c @@ -22,13 +22,16 @@ * **********************************************************************/ +#include "../postgis_config.h" #include "postgres.h" #include "fmgr.h" #include "funcapi.h" +#if POSTGIS_PGSQL_VERSION >= 190 +#include "access/htup_details.h" +#endif #include "utils/builtins.h" -#include "../postgis_config.h" #include "liblwgeom.h" #include "lwgeodetic.h" #include "stringbuffer.h" ----------------------------------------------------------------------- Summary of changes: postgis/lwgeom_transform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 12:41:38 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 19:41:38 -0000 Subject: [PostGIS] #6001: ST_MakeLine support MultiLineString Message-ID: <049.2cfcc5fcdf597bd45c4bec3fb6f5040a@osgeo.org> #6001: ST_MakeLine support MultiLineString -------------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: enhancement | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Keywords: | -------------------------+--------------------------- ST_MakeLine can consume points, multipoint and linestrings, why not multilinestring? Just stick them onto the output in the order the subelements occur in the collection. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 13:28:26 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 13:28:26 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-126-g0383bab91 Message-ID: <20251008202826.6C90816C5C4@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 0383bab91e5f2eb7ac418fc661d473d3b87f5330 (commit) from 747d7732b009ee6821501f290a3f729e56a9634d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0383bab91e5f2eb7ac418fc661d473d3b87f5330 Author: Paul Ramsey Date: Wed Oct 8 13:27:52 2025 -0700 Support MultiLineString as input to ST_MakeLine. Handle each sub-geometry in order it appears in the collection. Closes #6001 diff --git a/NEWS b/NEWS index f07ea83e1..69d76e147 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ xxxx/xx/xx - #5993, [topology] Add max_edges parameter to TopoGeo_AddLinestring (Sandro Santilli) - + - #6001, support MultiLineString in ST_MakeLine (Paul Ramsey) PostGIS 3.6.0 diff --git a/doc/reference_constructor.xml b/doc/reference_constructor.xml index 819527f6b..e849926c5 100644 --- a/doc/reference_constructor.xml +++ b/doc/reference_constructor.xml @@ -1,70 +1,70 @@
- Geometry Constructors + Geometry Constructors - - - ST_Collect - Creates a GeometryCollection or Multi* geometry from a set of geometries. - + + + ST_Collect + Creates a GeometryCollection or Multi* geometry from a set of geometries. + - - - - geometry ST_Collect - geometry g1 - geometry g2 - - - geometry ST_Collect - geometry[] g1_array - - - geometry ST_Collect - geometry set g1field - - - + + + + geometry ST_Collect + geometry g1 + geometry g2 + + + geometry ST_Collect + geometry[] g1_array + + + geometry ST_Collect + geometry set g1field + + + - - Description - Collects geometries into a geometry collection. - The result is either a Multi* or a - GeometryCollection, depending on whether the input geometries have the same or different types - (homogeneous or heterogeneous). - The input geometries are left unchanged within the collection. - + + Description + Collects geometries into a geometry collection. + The result is either a Multi* or a + GeometryCollection, depending on whether the input geometries have the same or different types + (homogeneous or heterogeneous). + The input geometries are left unchanged within the collection. + - Variant 1: accepts two input geometries - Variant 2: accepts an array of geometries - Variant 3: aggregate function accepting a rowset of geometries. + Variant 1: accepts two input geometries + Variant 2: accepts an array of geometries + Variant 3: aggregate function accepting a rowset of geometries. - - If any of the input geometries are collections (Multi* or GeometryCollection) - ST_Collect returns a GeometryCollection (since that is the only type - which can contain nested collections). - To prevent this, use in a subquery to expand the - input collections to their atomic elements (see example below). - + + If any of the input geometries are collections (Multi* or GeometryCollection) + ST_Collect returns a GeometryCollection (since that is the only type + which can contain nested collections). + To prevent this, use in a subquery to expand the + input collections to their atomic elements (see example below). + - ST_Collect and appear similar, but in fact operate quite differently. - ST_Collect aggregates geometries into a collection without changing them in any way. - ST_Union geometrically merges geometries where they overlap, - and splits linestrings at intersections. - It may return single geometries when it dissolves boundaries. - + ST_Collect and appear similar, but in fact operate quite differently. + ST_Collect aggregates geometries into a collection without changing them in any way. + ST_Union geometrically merges geometries where they overlap, + and splits linestrings at intersections. + It may return single geometries when it dissolves boundaries. + - Availability: 1.4.0 - ST_Collect(geomarray) was introduced. ST_Collect was enhanced to handle more geometries faster. - &Z_support; - &curve_support; - + Availability: 1.4.0 - ST_Collect(geomarray) was introduced. ST_Collect was enhanced to handle more geometries faster. + &Z_support; + &curve_support; + - - Examples - Two-input variant - Collect 2D points. + + Examples - Two-input variant + Collect 2D points. SELECT ST_AsText( ST_Collect( ST_GeomFromText('POINT(1 2)'), - ST_GeomFromText('POINT(-2 3)') )); + ST_GeomFromText('POINT(-2 3)') )); st_astext ---------- @@ -74,9 +74,9 @@ MULTIPOINT((1 2),(-2 3)) Collect 3D points. SELECT ST_AsEWKT( ST_Collect( ST_GeomFromEWKT('POINT(1 2 3)'), - ST_GeomFromEWKT('POINT(1 2 4)') ) ); + ST_GeomFromEWKT('POINT(1 2 4)') ) ); - st_asewkt + st_asewkt ------------------------- MULTIPOINT(1 2 3,1 2 4) @@ -84,15 +84,15 @@ SELECT ST_AsEWKT( ST_Collect( ST_GeomFromEWKT('POINT(1 2 3)'), Collect curves. SELECT ST_AsText( ST_Collect( 'CIRCULARSTRING(220268 150415,220227 150505,220227 150406)', - 'CIRCULARSTRING(220227 150406,2220227 150407,220227 150406)')); + 'CIRCULARSTRING(220227 150406,2220227 150407,220227 150406)')); - st_astext + st_astext ------------------------------------------------------------------------------------ MULTICURVE(CIRCULARSTRING(220268 150415,220227 150505,220227 150406), CIRCULARSTRING(220227 150406,2220227 150407,220227 150406)) - - + + Examples - Array variant Using an array constructor for a subquery. @@ -101,186 +101,188 @@ SELECT ST_Collect( ARRAY( SELECT geom FROM sometable ) ); Using an array constructor for values. SELECT ST_AsText( ST_Collect( - ARRAY[ ST_GeomFromText('LINESTRING(1 2, 3 4)'), - ST_GeomFromText('LINESTRING(3 4, 4 5)') ] )) As wktcollect; + ARRAY[ ST_GeomFromText('LINESTRING(1 2, 3 4)'), + ST_GeomFromText('LINESTRING(3 4, 4 5)') ] )) As wktcollect; --wkt collect -- MULTILINESTRING((1 2,3 4),(3 4,4 5)) - - - Examples - Aggregate variant - Creating multiple collections by grouping geometries in a table. + + + Examples - Aggregate variant + Creating multiple collections by grouping geometries in a table. SELECT stusps, ST_Collect(f.geom) as geom - FROM (SELECT stusps, (ST_Dump(geom)).geom As geom - FROM - somestatetable ) As f - GROUP BY stusps + FROM (SELECT stusps, (ST_Dump(geom)).geom As geom + FROM + somestatetable ) As f + GROUP BY stusps - - - See Also - , - - + + + See Also + , + + - - - ST_LineFromMultiPoint + + + ST_LineFromMultiPoint - Creates a LineString from a MultiPoint geometry. - + Creates a LineString from a MultiPoint geometry. + - - - - geometry ST_LineFromMultiPoint - geometry aMultiPoint - - - + + + + geometry ST_LineFromMultiPoint + geometry aMultiPoint + + + - - Description + + Description - Creates a LineString from a MultiPoint geometry. + Creates a LineString from a MultiPoint geometry. - Use to create lines from Point or LineString inputs. + Use to create lines from Point or LineString inputs. - &Z_support; + &Z_support; - + - - Examples - Create a 3D line string from a 3D MultiPoint - + + Examples + Create a 3D line string from a 3D MultiPoint + SELECT ST_AsEWKT( ST_LineFromMultiPoint('MULTIPOINT(1 2 3, 4 5 6, 7 8 9)') ); --result-- LINESTRING(1 2 3,4 5 6,7 8 9) - + - - - See Also + + + See Also - , - - + , + + - - - ST_MakeEnvelope + + + ST_MakeEnvelope - Creates a rectangular Polygon from minimum and maximum coordinates. - + Creates a rectangular Polygon from minimum and maximum coordinates. + - - - - geometry ST_MakeEnvelope - float xmin - float ymin - float xmax - float ymax - integer srid=unknown - - - + + + + geometry ST_MakeEnvelope + float xmin + float ymin + float xmax + float ymax + integer srid=unknown + + + - - Description + + Description - Creates a rectangular Polygon from the minimum and maximum values for X and Y. - Input values must be in the spatial reference system specified by the SRID. - If no SRID is specified the unknown spatial reference system (SRID 0) is used. + Creates a rectangular Polygon from the minimum and maximum values for X and Y. + Input values must be in the spatial reference system specified by the SRID. + If no SRID is specified the unknown spatial reference system (SRID 0) is used. - Availability: 1.5 - Enhanced: 2.0: Ability to specify an envelope without specifying an SRID was introduced. + Availability: 1.5 + Enhanced: 2.0: Ability to specify an envelope without specifying an SRID was introduced. - + - - Example: Building a bounding box polygon - + + Example: Building a bounding box polygon + SELECT ST_AsText( ST_MakeEnvelope(10, 10, 11, 11, 4326) ); st_asewkt ----------- POLYGON((10 10, 10 11, 11 11, 11 10, 10 10)) - - - See Also - , , , - - + + + See Also + , , , + + - - - ST_MakeLine + + + ST_MakeLine - Creates a LineString from Point, MultiPoint, or LineString geometries. - + Creates a LineString from Point, MultiPoint, or LineString geometries. + - - - - geometry ST_MakeLine - geometry geom1 - geometry geom2 - + + + + geometry ST_MakeLine + geometry geom1 + geometry geom2 + - - geometry ST_MakeLine - geometry[] geoms_array - + + geometry ST_MakeLine + geometry[] geoms_array + - - geometry ST_MakeLine - geometry set geoms - - - + + geometry ST_MakeLine + geometry set geoms + + + - - Description + + Description - Creates a LineString containing the points of Point, MultiPoint, or LineString geometries. - Other geometry types cause an error. - - Variant 1: accepts two input geometries - Variant 2: accepts an array of geometries - Variant 3: aggregate function accepting a rowset of geometries. - To ensure the order of the input geometries use ORDER BY in the function call, - or a subquery with an ORDER BY clause. + Creates a LineString containing the points of Point, MultiPoint, or LineString geometries. + Other geometry types cause an error. + + Variant 1: accepts two input geometries + Variant 2: accepts an array of geometries + Variant 3: aggregate function accepting a rowset of geometries. + To ensure the order of the input geometries use ORDER BY in the function call, + or a subquery with an ORDER BY clause. - - Repeated nodes at the beginning of input LineStrings are collapsed to a single point. - Repeated points in Point and MultiPoint inputs are not collapsed. - can be used to collapse repeated points from the output LineString. - + + Repeated nodes at the beginning of input LineStrings are collapsed to a single point. + Repeated points in Point and MultiPoint inputs are not collapsed. + Components of MultiLineString are handled in the order they appear in the collection. + can be used to collapse repeated points from the output LineString. + - &Z_support; + &Z_support; - Availability: 2.3.0 - Support for MultiPoint input elements was introduced - Availability: 2.0.0 - Support for LineString input elements was introduced - Availability: 1.4.0 - ST_MakeLine(geomarray) was introduced. ST_MakeLine aggregate functions was enhanced to handle more points faster. + Availability: 3.7.0 - Support for MultiLineString input elements was introduced + Availability: 2.3.0 - Support for MultiPoint input elements was introduced + Availability: 2.0.0 - Support for LineString input elements was introduced + Availability: 1.4.0 - ST_MakeLine(geomarray) was introduced. ST_MakeLine aggregate functions was enhanced to handle more points faster. - + - - Examples: Two-input variant + + Examples: Two-input variant Create a line composed of two points. SELECT ST_AsText( ST_MakeLine(ST_Point(1,2), ST_Point(3,4)) ); - st_astext + st_astext --------------------- LINESTRING(1 2,3 4) @@ -289,7 +291,7 @@ SELECT ST_AsText( ST_MakeLine(ST_Point(1,2), ST_Point(3,4)) ); SELECT ST_AsEWKT( ST_MakeLine(ST_MakePoint(1,2,3), ST_MakePoint(3,4,5) )); - st_asewkt + st_asewkt ------------------------- LINESTRING(1 2 3,3 4 5) @@ -302,123 +304,123 @@ SELECT ST_AsEWKT( ST_MakeLine(ST_MakePoint(1,2,3), ST_MakePoint(3,4,5) )); ----------------------------- LINESTRING(0 0,1 1,2 2,3 3) - + - - Examples: Array variant + + Examples: Array variant - Create a line from an array formed by a subquery with ordering. + Create a line from an array formed by a subquery with ordering. SELECT ST_MakeLine( ARRAY( SELECT ST_Centroid(geom) FROM visit_locations ORDER BY visit_time) ); - Create a 3D line from an array of 3D points + Create a 3D line from an array of 3D points SELECT ST_AsEWKT( ST_MakeLine( ARRAY[ ST_MakePoint(1,2,3), ST_MakePoint(3,4,5), ST_MakePoint(6,6,6) ] )); - st_asewkt + st_asewkt ------------------------- LINESTRING(1 2 3,3 4 5,6 6 6) - + - - Examples: Aggregate variant - This example queries time-based sequences of GPS points from a set of tracks - and creates one record for each track. - The result geometries are LineStrings composed of the GPS track points in the order of travel. + + Examples: Aggregate variant + This example queries time-based sequences of GPS points from a set of tracks + and creates one record for each track. + The result geometries are LineStrings composed of the GPS track points in the order of travel. Using aggregate ORDER BY provides a correctly-ordered LineString. - + SELECT gps.track_id, ST_MakeLine(gps.geom ORDER BY gps_time) As geom - FROM gps_points As gps - GROUP BY track_id; + FROM gps_points As gps + GROUP BY track_id; Prior to PostgreSQL 9, ordering in a subquery can be used. However, sometimes the query plan may not respect the order of the subquery. - + SELECT gps.track_id, ST_MakeLine(gps.geom) As geom - FROM ( SELECT track_id, gps_time, geom - FROM gps_points ORDER BY track_id, gps_time ) As gps - GROUP BY track_id; - + FROM ( SELECT track_id, gps_time, geom + FROM gps_points ORDER BY track_id, gps_time ) As gps + GROUP BY track_id; + - - See Also - , + + See Also + , , , , , - - + + - - - ST_MakePoint + + + ST_MakePoint - Creates a 2D, 3DZ or 4D Point. - + Creates a 2D, 3DZ or 4D Point. + - - - - geometry ST_MakePoint - float x - float y - - - - - geometry ST_MakePoint - float x - float y - float z - - - - - geometry ST_MakePoint - float x - float y - float z - float m - - - + + + + geometry ST_MakePoint + float x + float y + + + + + geometry ST_MakePoint + float x + float y + float z + + + + + geometry ST_MakePoint + float x + float y + float z + float m + + + - - Description + + Description - Creates a 2D XY, 3D XYZ or 4D XYZM Point geometry. - Use to make points with XYM coordinates. + Creates a 2D XY, 3D XYZ or 4D XYZM Point geometry. + Use to make points with XYM coordinates. - Use to specify a SRID for the created point. + Use to specify a SRID for the created point. - - While not OGC-compliant, ST_MakePoint is - faster than - and . - It is also easier to use for numeric coordinate values. + + While not OGC-compliant, ST_MakePoint is + faster than + and . + It is also easier to use for numeric coordinate values. - For geodetic coordinates, X is longitude and Y is latitude + For geodetic coordinates, X is longitude and Y is latitude - - The functions - , , , and - can be used to create points with a given SRID. - + + The functions + , , , and + can be used to create points with a given SRID. + - &Z_support; - + &Z_support; + - - Examples - -- Create a point with unknown SRID + + Examples + -- Create a point with unknown SRID SELECT ST_MakePoint(-71.1043443253471, 42.3150676015829); -- Create a point in the WGS 84 geodetic CRS @@ -432,62 +434,62 @@ SELECT ST_Z(ST_MakePoint(1, 2,1.5)); result ------- 1.5 - - - See Also - - , , , , - , , , - - - + + + See Also + + , , , , + , , , + + + - - - ST_MakePointM + + + ST_MakePointM - Creates a Point from X, Y and M values. - + Creates a Point from X, Y and M values. + - - - - geometry ST_MakePointM - float x - float y - float m - - - + + + + geometry ST_MakePointM + float x + float y + float m + + + - - Description + + Description - Creates a point with X, Y and M (measure) ordinates. - Use to make points with XY, XYZ, or XYZM coordinates. + Creates a point with X, Y and M (measure) ordinates. + Use to make points with XY, XYZ, or XYZM coordinates. - Use to specify a SRID for the created point. + Use to specify a SRID for the created point. - For geodetic coordinates, X is longitude and Y is latitude + For geodetic coordinates, X is longitude and Y is latitude - - The functions - , and - can be used to create points with an M value and a given SRID. - + + The functions + , and + can be used to create points with an M value and a given SRID. + - + - - Examples - is used for text output - because does not support M values. + + Examples + is used for text output + because does not support M values. - Create point with unknown SRID. - + Create point with unknown SRID. + SELECT ST_AsEWKT( ST_MakePointM(-71.1043443253471, 42.3150676015829, 10) ); - st_asewkt + st_asewkt ----------------------------------------------- POINTM(-71.1043443253471 42.3150676015829 10) @@ -496,7 +498,7 @@ SELECT ST_AsEWKT( ST_MakePointM(-71.1043443253471, 42.3150676015829, 10) ); SELECT ST_AsEWKT( ST_SetSRID( ST_MakePointM(-71.104, 42.315, 10), 4326)); - st_asewkt + st_asewkt --------------------------------------------------------- SRID=4326;POINTM(-71.104 42.315 10) @@ -509,59 +511,59 @@ result ------- 10 - - - See Also - , , - , - - + + + See Also + , , + , + + - - - ST_MakePolygon + + + ST_MakePolygon - Creates a Polygon from a shell and optional list of holes. - + Creates a Polygon from a shell and optional list of holes. + - - - - geometry ST_MakePolygon - geometry linestring - - - - - geometry ST_MakePolygon - geometry outerlinestring - geometry[] interiorlinestrings - - - + + + + geometry ST_MakePolygon + geometry linestring + + + + + geometry ST_MakePolygon + geometry outerlinestring + geometry[] interiorlinestrings + + + - - Description + + Description - Creates a Polygon formed by the given shell and optional array of holes. - Input geometries must be closed LineStrings (rings). + Creates a Polygon formed by the given shell and optional array of holes. + Input geometries must be closed LineStrings (rings). - Variant 1: Accepts one shell LineString. - Variant 2: Accepts a shell LineString and an array of - inner (hole) LineStrings. A geometry array can be constructed using the PostgreSQL array_agg(), ARRAY[] or - ARRAY() constructs. + Variant 1: Accepts one shell LineString. + Variant 2: Accepts a shell LineString and an array of + inner (hole) LineStrings. A geometry array can be constructed using the PostgreSQL array_agg(), ARRAY[] or + ARRAY() constructs. - This function does not accept MultiLineStrings. - Use to generate a LineString, or to extract LineStrings. - + This function does not accept MultiLineStrings. + Use to generate a LineString, or to extract LineStrings. + - &Z_support; - + &Z_support; + - - Examples: Single input variant - Create a Polygon from a 2D LineString. - + + Examples: Single input variant + Create a Polygon from a 2D LineString. + SELECT ST_MakePolygon( ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)')); @@ -589,18 +591,18 @@ st_asewkt ---------- POLYGONM((75.15 29.53 1,77 29 1,77.6 29.5 2,75.15 29.53 2)) - - - Examples: Outer shell with inner holes variant + + + Examples: Outer shell with inner holes variant - Create a donut Polygon with an extra hole - + Create a donut Polygon with an extra hole + SELECT ST_MakePolygon( ST_ExteriorRing( ST_Buffer(ring.line,10)), - ARRAY[ ST_Translate(ring.line, 1, 1), - ST_ExteriorRing(ST_Buffer(ST_Point(20,20),1)) ] - ) + ARRAY[ ST_Translate(ring.line, 1, 1), + ST_ExteriorRing(ST_Buffer(ST_Point(20,20),1)) ] + ) FROM (SELECT ST_ExteriorRing( - ST_Buffer(ST_Point(10,10),10,10)) AS line ) AS ring; + ST_Buffer(ST_Point(10,10),10,10)) AS line ) AS ring; Create a set of province boundaries with holes representing lakes. The input is a table of @@ -618,20 +620,20 @@ FROM (SELECT ST_ExteriorRing( The CASE construct is used because passing a null array into ST_MakePolygon results in a NULL return value. - + SELECT p.gid, p.province_name, - CASE WHEN array_agg(w.geom) IS NULL - THEN p.geom - ELSE ST_MakePolygon( ST_LineMerge(ST_Boundary(p.geom)), + CASE WHEN array_agg(w.geom) IS NULL + THEN p.geom + ELSE ST_MakePolygon( ST_LineMerge(ST_Boundary(p.geom)), array_agg(w.geom)) END FROM - provinces p LEFT JOIN waterlines w - ON (ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom)) + provinces p LEFT JOIN waterlines w + ON (ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom)) GROUP BY p.gid, p.province_name, p.geom; - Another technique is to utilize a correlated subquery - and the ARRAY() constructor that converts a row set to an array. + Another technique is to utilize a correlated subquery + and the ARRAY() constructor that converts a row set to an array. SELECT p.gid, p.province_name, CASE WHEN EXISTS( SELECT w.geom @@ -648,31 +650,31 @@ SELECT p.gid, p.province_name, END AS geom FROM provinces p; - - - See Also - - - - - - + + + See Also + + + + + + - - - ST_Point + + + ST_Point - Creates a Point with X, Y and SRID values. - + Creates a Point with X, Y and SRID values. + - - - - geometry ST_Point - float x - float y - - + + + + geometry ST_Point + float x + float y + + geometry ST_Point @@ -681,38 +683,38 @@ FROM provinces p; integer srid=unknown - + - - Description + + Description - Returns a Point with the given X and Y coordinate values. This is the SQL-MM equivalent for that takes just X and Y. + Returns a Point with the given X and Y coordinate values. This is the SQL-MM equivalent for that takes just X and Y. - For geodetic coordinates, X is longitude and Y is latitude + For geodetic coordinates, X is longitude and Y is latitude - Enhanced: 3.2.0 srid as an extra optional argument was added. Older installs require combining with ST_SetSRID to mark the srid on the geometry. - &sqlmm_compliant; SQL-MM 3: 6.1.2 + Enhanced: 3.2.0 srid as an extra optional argument was added. Older installs require combining with ST_SetSRID to mark the srid on the geometry. + &sqlmm_compliant; SQL-MM 3: 6.1.2 - + - - Examples: Geometry + + Examples: Geometry SELECT ST_Point( -71.104, 42.315); Creating a point with SRID specified: - SELECT ST_Point( -71.104, 42.315, 4326); + SELECT ST_Point( -71.104, 42.315, 4326); Alternative way of specifying SRID: SELECT ST_SetSRID( ST_Point( -71.104, 42.315), 4326); - + - - Examples: Geography + + Examples: Geography - Create geography points using the :: cast syntax: - SELECT ST_Point( -71.104, 42.315, 4326)::geography; + Create geography points using the :: cast syntax: + SELECT ST_Point( -71.104, 42.315, 4326)::geography; Pre-PostGIS 3.2 code, using CAST: SELECT CAST( ST_SetSRID(ST_Point( -71.104, 42.315), 4326) AS geography); @@ -723,17 +725,17 @@ In this example a point in Pennsylvania State Plane feet (SRID 2273) is projected to WGS84 (SRID 4326). SELECT ST_Transform( ST_Point( 3637510, 3014852, 2273), 4326)::geography; - + - - - See Also + + + See Also - , - , , , - , - - + , + , , , + , + + @@ -849,49 +851,49 @@ SELECT ST_Transform( ST_Point( 3637510, 3014852, 2273), 4326)::geography; - - - ST_Polygon - Creates a Polygon from a LineString with a specified SRID. - + + + ST_Polygon + Creates a Polygon from a LineString with a specified SRID. + - - - - geometry ST_Polygon - geometry lineString - integer srid - - - + + + + geometry ST_Polygon + geometry lineString + integer srid + + + - - Description + + Description - Returns a polygon built from the given LineString - and sets the spatial reference system from the srid. + Returns a polygon built from the given LineString + and sets the spatial reference system from the srid. - ST_Polygon is similar to Variant 1 - with the addition of setting the SRID. - To create polygons with holes - use Variant 2 and then . - + ST_Polygon is similar to Variant 1 + with the addition of setting the SRID. + To create polygons with holes + use Variant 2 and then . + - This function does not accept MultiLineStrings. - Use to generate a LineString, or to extract LineStrings. - + This function does not accept MultiLineStrings. + Use to generate a LineString, or to extract LineStrings. + - &sfs_compliant; - &sqlmm_compliant; SQL-MM 3: 8.3.2 - &Z_support; + &sfs_compliant; + &sqlmm_compliant; SQL-MM 3: 8.3.2 + &Z_support; - + - - Examples + + Examples Create a 2D polygon. - + SELECT ST_AsText( ST_Polygon('LINESTRING(75 29, 77 29, 77 29, 75 29)'::geometry, 4326) ); -- result -- @@ -904,40 +906,40 @@ SELECT ST_AsEWKT( ST_Polygon( ST_GeomFromEWKT('LINESTRING(75 29 1, 77 29 2, 77 2 -- result -- SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1)) - + - - - See Also + + + See Also - , , , , , - - + , , , , , + + - - - ST_TileEnvelope - Creates a rectangular Polygon in Web Mercator (SRID:3857) using the XYZ tile system. - + + + ST_TileEnvelope + Creates a rectangular Polygon in Web Mercator (SRID:3857) using the XYZ tile system. + - - - - geometry ST_TileEnvelope - integer tileZoom - integer tileX - integer tileY - geometry bounds=SRID=3857;LINESTRING(-20037508.342789 -20037508.342789,20037508.342789 20037508.342789) - float margin=0.0 - - - + + + + geometry ST_TileEnvelope + integer tileZoom + integer tileX + integer tileY + geometry bounds=SRID=3857;LINESTRING(-20037508.342789 -20037508.342789,20037508.342789 20037508.342789) + float margin=0.0 + + + - - Description + + Description - Creates a rectangular Polygon + Creates a rectangular Polygon giving the extent of a tile in the XYZ tile system. The tile is specified by the zoom level Z and the XY index of the tile in the grid at that level. Can be used to define the tile bounds required by to convert geometry @@ -949,7 +951,7 @@ SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1)) The optional bounds parameter can be used to generate tiles in any coordinate system. It is a geometry that has the SRID and extent of the "Zoom Level zero" square within which the XYZ tile system is inscribed. - The optional margin parameter can be used to expand a tile by the given percentage. + The optional margin parameter can be used to expand a tile by the given percentage. E.g. margin=0.125 expands the tile by 12.5%, which is equivalent to buffer=512 when the tile extent size is 4096, as used in . This is useful to create a tile buffer to include data lying outside of the tile's visible area, but whose existence affects the tile rendering. For example, a city name (a point) could be near an edge of a tile, so its label should be rendered on two tiles, even though the point is located in the visible area of just one tile. @@ -958,13 +960,13 @@ SRID=4326;POLYGON((75 29 1, 77 29 2, 77 29 3, 75 29 1)) Do not specify a margin when using with ST_AsMVTGeom. See the example for . - Enhanced: 3.1.0 Added margin parameter. - Availability: 3.0.0 - + Enhanced: 3.1.0 Added margin parameter. + Availability: 3.0.0 + - - Example: Building a tile envelope - SELECT ST_AsText( ST_TileEnvelope(2, 1, 1) ); + + Example: Building a tile envelope + SELECT ST_AsText( ST_TileEnvelope(2, 1, 1) ); st_astext ------------------------------ @@ -976,64 +978,64 @@ SELECT ST_AsText( ST_TileEnvelope(3, 1, 1, ST_MakeEnvelope(-180, -90, 180, 90, 4 ------------------------------------------------------ POLYGON((-135 45,-135 67.5,-90 67.5,-90 45,-135 45)) - - - See Also - - - + + + See Also + + + - - - ST_HexagonGrid - Returns a set of hexagons and cell indices that completely cover the bounds of the geometry argument. - + + + ST_HexagonGrid + Returns a set of hexagons and cell indices that completely cover the bounds of the geometry argument. + - - - - setof record ST_HexagonGrid - float8 size - geometry bounds - - - + + + + setof record ST_HexagonGrid + float8 size + geometry bounds + + + - - Description + + Description - Starts with the concept of a hexagon tiling of the plane. - (Not a hexagon tiling of the globe, this is not the - H3 tiling scheme.) - For a given planar SRS, and a given edge size, starting at the origin of the SRS, - there is one unique hexagonal tiling of the plane, Tiling(SRS, Size). - This function answers the question: what hexagons in a given Tiling(SRS, Size) - overlap with a given bounds. + Starts with the concept of a hexagon tiling of the plane. + (Not a hexagon tiling of the globe, this is not the + H3 tiling scheme.) + For a given planar SRS, and a given edge size, starting at the origin of the SRS, + there is one unique hexagonal tiling of the plane, Tiling(SRS, Size). + This function answers the question: what hexagons in a given Tiling(SRS, Size) + overlap with a given bounds. - - - + + + - The SRS for the output hexagons is the SRS provided by the bounds geometry. - Doubling or tripling the edge size of the hexagon generates a new parent tiling that - fits with the origin tiling. Unfortunately, it is not possible to generate parent - hexagon tilings that the child tiles perfectly fit inside. + The SRS for the output hexagons is the SRS provided by the bounds geometry. + Doubling or tripling the edge size of the hexagon generates a new parent tiling that + fits with the origin tiling. Unfortunately, it is not possible to generate parent + hexagon tilings that the child tiles perfectly fit inside. - - - + + + - Availability: 3.1.0 + Availability: 3.1.0 - + - - Example: Counting points in hexagons - To do a point summary against a hexagonal tiling, generate a hexagon grid using the - extent of the points as the bounds, then spatially join to that grid. - SELECT COUNT(*), hexes.geom + + Example: Counting points in hexagons + To do a point summary against a hexagonal tiling, generate a hexagon grid using the + extent of the points as the bounds, then spatially join to that grid. + SELECT COUNT(*), hexes.geom FROM ST_HexagonGrid( 10000, @@ -1045,16 +1047,16 @@ FROM GROUP BY hexes.geom; - Example: Generating hex coverage of polygons - If we generate a set of hexagons for each polygon boundary and filter - out those that do not intersect their hexagons, we end up with a tiling for - each polygon. - - - - Tiling states results in a hexagon coverage of each state, and multiple - hexagons overlapping at the borders between states. - The LATERAL keyword is implied for set-returning functions when referring to a prior table in the FROM list. So CROSS JOIN LATERAL, CROSS JOIN, or just plain , are equivalent constructs for this example. + Example: Generating hex coverage of polygons + If we generate a set of hexagons for each polygon boundary and filter + out those that do not intersect their hexagons, we end up with a tiling for + each polygon. + + + + Tiling states results in a hexagon coverage of each state, and multiple + hexagons overlapping at the borders between states. + The LATERAL keyword is implied for set-returning functions when referring to a prior table in the FROM list. So CROSS JOIN LATERAL, CROSS JOIN, or just plain , are equivalent constructs for this example. SELECT admin1.gid, hex.geom FROM admin1 @@ -1069,41 +1071,41 @@ WHERE See Also , , , - + - - - ST_Hexagon - Returns a single hexagon, using the provided edge size and - cell coordinate within the hexagon grid space. - + + + ST_Hexagon + Returns a single hexagon, using the provided edge size and + cell coordinate within the hexagon grid space. + - - - - geometry ST_Hexagon - float8 size - integer cell_i - integer cell_j - geometry origin - - - + + + + geometry ST_Hexagon + float8 size + integer cell_i + integer cell_j + geometry origin + + + - - Description + + Description - Uses the same hexagon tiling concept as , but generates just one hexagon at the desired cell coordinate. Optionally, - can adjust origin coordinate of the tiling, the default origin is at 0,0. - - Hexagons are generated with no SRID set, so use to set the SRID to the one you expect. + Uses the same hexagon tiling concept as , but generates just one hexagon at the desired cell coordinate. Optionally, + can adjust origin coordinate of the tiling, the default origin is at 0,0. + + Hexagons are generated with no SRID set, so use to set the SRID to the one you expect. - Availability: 3.1.0 - + Availability: 3.1.0 + - - Example: Creating a hexagon at the origin - SELECT ST_AsText(ST_SetSRID(ST_Hexagon(1.0, 0, 0), 3857)); + + Example: Creating a hexagon at the origin + SELECT ST_AsText(ST_SetSRID(ST_Hexagon(1.0, 0, 0), 3857)); POLYGON((-1 0,-0.5 -0.866025403784439,0.5 @@ -1111,12 +1113,12 @@ POLYGON((-1 0,-0.5 0,0.5 0.866025403784439,-0.5 0.866025403784439,-1 0)) - - - See Also - , , - - + + + See Also + , , + + @@ -1203,51 +1205,51 @@ FROM admin0 WHERE name = 'Canada' - - - ST_Square - Returns a single square, using the provided edge size and - cell coordinate within the square grid space. - + + + ST_Square + Returns a single square, using the provided edge size and + cell coordinate within the square grid space. + - - - - geometry ST_Square - float8 size - integer cell_i - integer cell_j - geometry origin='POINT(0 0)' - - - + + + + geometry ST_Square + float8 size + integer cell_i + integer cell_j + geometry origin='POINT(0 0)' + + + - - Description + + Description - Uses the same square tiling concept as , but generates just one square at the desired cell coordinate. Optionally, - can adjust origin coordinate of the tiling, the default origin is at 0,0. - + Uses the same square tiling concept as , but generates just one square at the desired cell coordinate. Optionally, + can adjust origin coordinate of the tiling, the default origin is at 0,0. + - + Squares are generated with the SRID of the given origin. Use to set the SRID if the given origin has an unknown SRID (as is the case by default). - Availability: 3.1.0 - + Availability: 3.1.0 + - - Example: Creating a square at the origin - SELECT ST_AsText(ST_SetSRID(ST_Square(1.0, 0, 0), 3857)); + + Example: Creating a square at the origin + SELECT ST_AsText(ST_SetSRID(ST_Square(1.0, 0, 0), 3857)); POLYGON((0 0,0 1,1 1,1 0,0 0)) - - - See Also - , , - - + + + See Also + , , + + diff --git a/liblwgeom/lwline.c b/liblwgeom/lwline.c index 999927fea..50185f510 100644 --- a/liblwgeom/lwline.c +++ b/liblwgeom/lwline.c @@ -192,6 +192,16 @@ lwline_from_lwgeom_array(int32_t srid, uint32_t ngeoms, LWGEOM **geoms) */ ptarray_append_ptarray(pa, ((LWLINE*)g)->points, -1); } + else if ( g->type == MULTILINETYPE ) + { + LWMLINE *mline = lwgeom_as_lwmline(g); + for ( uint32_t j = 0; j < mline->ngeoms; j++ ) + { + LWLINE *line = mline->geoms[j]; + if (lwline_is_empty(line)) continue; + ptarray_append_ptarray(pa, line->points, -1); + } + } else if ( g->type == MULTIPOINTTYPE ) { it = lwpointiterator_create(g); diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 507e2283d..4bf5816e9 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -184,7 +184,7 @@ ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance) /* Check for pathology */ if( ! pa1 || ! pa2 ) { - lwerror("ptarray_append_ptarray: null input"); + lwerror("%s: null input", __func__); return LW_FAILURE; } @@ -194,13 +194,13 @@ ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance) if( FLAGS_GET_READONLY(pa1->flags) ) { - lwerror("ptarray_append_ptarray: target pointarray is read-only"); + lwerror("%s: target pointarray is read-only", __func__); return LW_FAILURE; } if( FLAGS_GET_ZM(pa1->flags) != FLAGS_GET_ZM(pa2->flags) ) { - lwerror("ptarray_append_ptarray: appending mixed dimensionality is not allowed"); + lwerror("%s: appending mixed dimensionality is not allowed", __func__); return LW_FAILURE; } @@ -209,17 +209,17 @@ ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance) /* Check for duplicate end point */ if ( pa1->npoints ) { - POINT2D tmp1, tmp2; - getPoint2d_p(pa1, pa1->npoints-1, &tmp1); - getPoint2d_p(pa2, 0, &tmp2); + const POINT2D *tmp1, *tmp2; + tmp1 = getPoint2d_cp(pa1, pa1->npoints-1); + tmp2 = getPoint2d_cp(pa2, 0); /* If the end point and start point are the same, then don't copy start point */ - if (p2d_same(&tmp1, &tmp2)) { + if (p2d_same(tmp1, tmp2)) { poff = 1; --npoints; } - else if ( gap_tolerance == 0 || ( gap_tolerance > 0 && - distance2d_pt_pt(&tmp1, &tmp2) > gap_tolerance ) ) + else if ((gap_tolerance == 0) || + (gap_tolerance > 0 && distance2d_pt_pt(tmp1, tmp2) > gap_tolerance) ) { lwerror("Second line start point too far from first line end point"); return LW_FAILURE; diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c index 1e126ce82..06ea00934 100644 --- a/postgis/lwgeom_functions_basic.c +++ b/postgis/lwgeom_functions_basic.c @@ -1467,8 +1467,10 @@ Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS) geom = (GSERIALIZED *)DatumGetPointer(value); - if (gserialized_get_type(geom) != POINTTYPE && gserialized_get_type(geom) != LINETYPE && - gserialized_get_type(geom) != MULTIPOINTTYPE) + if (gserialized_get_type(geom) != POINTTYPE && + gserialized_get_type(geom) != MULTIPOINTTYPE && + gserialized_get_type(geom) != LINETYPE && + gserialized_get_type(geom) != MULTILINETYPE) { continue; } diff --git a/regress/core/ctors.sql b/regress/core/ctors.sql index 2af13ae92..d4038d44e 100644 --- a/regress/core/ctors.sql +++ b/regress/core/ctors.sql @@ -36,3 +36,11 @@ select ST_makebox2d('POINT(0 0)', 'SRID=3;POINT(1 1)'); select ST_3DMakeBox('SRID=3;POINT(0 0)', 'SRID=3;POINT(1 1)'); select ST_3DMakeBox('POINT(0 0)', 'SRID=3;POINT(1 1)'); + +SELECT 'ST_MakeLine2', ST_AsText(ST_MakeLine(geom)) +FROM ( + VALUES + ('LINESTRING(0 0, 1 1)'), + ('MULTILINESTRING((1 1, 2 2), (2 2, 3 3))'), + ('MULTILINESTRING(EMPTY, (4 4, 5 5))') + ) AS geoms(geom); diff --git a/regress/core/ctors_expected b/regress/core/ctors_expected index a459f433a..d18c7100c 100644 --- a/regress/core/ctors_expected +++ b/regress/core/ctors_expected @@ -9,3 +9,4 @@ BOX(0 0,1 1) ERROR: BOX2D_construct: Operation on mixed SRID geometries (Point, 0) != (Point, 3) BOX3D(0 0 0,1 1 0) ERROR: BOX3D_construct: Operation on mixed SRID geometries (Point, 0) != (Point, 3) +ST_MakeLine2|LINESTRING(0 0,1 1,2 2,3 3,4 4,5 5) ----------------------------------------------------------------------- Summary of changes: NEWS | 2 +- doc/reference_constructor.xml | 1408 +++++++++++++++++++------------------- liblwgeom/lwline.c | 10 + liblwgeom/ptarray.c | 18 +- postgis/lwgeom_functions_basic.c | 6 +- regress/core/ctors.sql | 8 + regress/core/ctors_expected | 1 + 7 files changed, 738 insertions(+), 715 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 13:28:46 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 20:28:46 -0000 Subject: [PostGIS] #6001: ST_MakeLine support MultiLineString In-Reply-To: <049.2cfcc5fcdf597bd45c4bec3fb6f5040a@osgeo.org> References: <049.2cfcc5fcdf597bd45c4bec3fb6f5040a@osgeo.org> Message-ID: <064.57e7a6044418f9d0f3251b5c1ddc4d53@osgeo.org> #6001: ST_MakeLine support MultiLineString --------------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: fixed | Keywords: --------------------------+--------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"0383bab91e5f2eb7ac418fc661d473d3b87f5330/git" 0383bab/git]: {{{#!CommitTicketReference repository="git" revision="0383bab91e5f2eb7ac418fc661d473d3b87f5330" Support MultiLineString as input to ST_MakeLine. Handle each sub-geometry in order it appears in the collection. Closes #6001 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 14:05:09 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:05:09 -0000 Subject: [PostGIS] #5999: PostGIS 3.6 doesn't compile against PG19 In-Reply-To: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> References: <046.e4e26bfd5c7a374ff8b0433706e29bb1@osgeo.org> Message-ID: <061.6d48d3384598b680b0dc34f0d353cd8e@osgeo.org> #5999: PostGIS 3.6 doesn't compile against PG19 ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: reopened => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:20:08 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:08 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-127-gc57e094f7 Message-ID: <20251008212009.3021016D474@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via c57e094f73819eee5ffea672ee185c391e655ffe (commit) from 0383bab91e5f2eb7ac418fc661d473d3b87f5330 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c57e094f73819eee5ffea672ee185c391e655ffe Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 62e2a3586..cc3ea6800 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -276,6 +276,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -313,6 +329,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -330,6 +348,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -529,26 +549,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Oct 8 14:20:15 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:15 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-20-ge5cc9ae7a Message-ID: <20251008212015.7059616DE86@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via e5cc9ae7a1806acc8d18b0ee4f4ee7d4b9e29c7c (commit) from 6f86c539c13f461553f414bcf5f86dfa3c5001f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e5cc9ae7a1806acc8d18b0ee4f4ee7d4b9e29c7c Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 62e2a3586..cc3ea6800 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -276,6 +276,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -313,6 +329,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -330,6 +348,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -529,26 +549,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:20:21 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:21 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.4ef5a9d05dbcb825c85e20c3d9292f5b@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"c57e094f73819eee5ffea672ee185c391e655ffe/git" c57e094/git]: {{{#!CommitTicketReference repository="git" revision="c57e094f73819eee5ffea672ee185c391e655ffe" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 14:20:21 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:21 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.42df069cc494896d7f993c781f0de2b7@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"e5cc9ae7a1806acc8d18b0ee4f4ee7d4b9e29c7c/git" e5cc9ae/git]: {{{#!CommitTicketReference repository="git" revision="e5cc9ae7a1806acc8d18b0ee4f4ee7d4b9e29c7c" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:20:23 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:23 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-69-g64bf79d69 Message-ID: <20251008212023.6605316DEA5@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 64bf79d69cd9730511fae2bab10e328350cdea41 (commit) from b33ea0a6df77f4a37396fd00c248f34da32910cc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 64bf79d69cd9730511fae2bab10e328350cdea41 Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 14202917a..b96e7bf62 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -276,6 +276,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -313,6 +329,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -330,6 +348,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -529,26 +549,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:20:25 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:25 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.6ae4471171db777080f678a5898ee8ae@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"64bf79d69cd9730511fae2bab10e328350cdea41/git" 64bf79d6/git]: {{{#!CommitTicketReference repository="git" revision="64bf79d69cd9730511fae2bab10e328350cdea41" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:20:32 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:32 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-61-g68f53711c Message-ID: <20251008212032.F062316DE5B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via 68f53711ce18a7a93cbed1b6b315d35fc715e481 (commit) from 7fbd2bc8d07a3f541f95593e77749cda2c5fd74f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 68f53711ce18a7a93cbed1b6b315d35fc715e481 Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index e2b3154cf..613a217bf 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -276,6 +276,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -313,6 +329,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -330,6 +348,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -529,26 +549,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:20:34 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:34 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.01da1a673b4af54c956713ecd33a6976@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"68f53711ce18a7a93cbed1b6b315d35fc715e481/git" 68f53711/git]: {{{#!CommitTicketReference repository="git" revision="68f53711ce18a7a93cbed1b6b315d35fc715e481" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:20:40 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:40 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.7-62-g7288ef04d Message-ID: <20251008212040.97D0416E894@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via 7288ef04d22ee6828e9811bed19c5b91068fb1a9 (commit) from ab19387a34ea20e7edb1eabbd6591f366995faf6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7288ef04d22ee6828e9811bed19c5b91068fb1a9 Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 69e5ed494..2fd217e90 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -276,6 +276,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -313,6 +329,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -330,6 +348,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -529,26 +549,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:20:42 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:42 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.e7ea6bba67a04c8cabcc2516e12b153a@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"7288ef04d22ee6828e9811bed19c5b91068fb1a9/git" 7288ef04/git]: {{{#!CommitTicketReference repository="git" revision="7288ef04d22ee6828e9811bed19c5b91068fb1a9" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:20:46 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:46 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.2 updated. 3.2.7-56-g6e2102f01 Message-ID: <20251008212046.83CEC16E773@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.2 has been updated via 6e2102f01c0f9019c53ba5ca7a975834805326e5 (commit) from dd98c6f88026cf6f2504bfc2afb88bbd02b530fd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6e2102f01c0f9019c53ba5ca7a975834805326e5 Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index 192aa3c69..2fd00f944 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -273,6 +273,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -310,6 +326,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -327,6 +345,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -524,26 +544,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:20:47 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:47 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.8b67d0f9860fbdcd274f06e029b2e773@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"6e2102f01c0f9019c53ba5ca7a975834805326e5/git" 6e2102f0/git]: {{{#!CommitTicketReference repository="git" revision="6e2102f01c0f9019c53ba5ca7a975834805326e5" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:20:54 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:20:54 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.1 updated. 3.1.11-45-g741aaa589 Message-ID: <20251008212054.B831516E610@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.1 has been updated via 741aaa5891fb8064cc40f29eceb0362289c5ba8f (commit) from 147d127fff7667c1c2f915d6ef3f37c7ea60d8a0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 741aaa5891fb8064cc40f29eceb0362289c5ba8f Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index f13bcbcdc..43b7ffd47 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -273,6 +273,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -310,6 +326,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -327,6 +345,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -524,26 +544,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:20:56 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:20:56 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.12d0089056852d6ce1a4b9239f10b28c@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"741aaa5891fb8064cc40f29eceb0362289c5ba8f/git" 741aaa58/git]: {{{#!CommitTicketReference repository="git" revision="741aaa5891fb8064cc40f29eceb0362289c5ba8f" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 14:21:03 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 14:21:03 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.0 updated. 3.0.11-20-g58ef17e4f Message-ID: <20251008212103.C8C0416E612@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.0 has been updated via 58ef17e4fc45651f8b3e92ea9cefc34942f35e71 (commit) from 98992aa72c3358aff5fc6ee4f30984c8f2a289e4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 58ef17e4fc45651f8b3e92ea9cefc34942f35e71 Author: Paul Ramsey Date: Wed Oct 8 14:17:23 2025 -0700 Avoid possible null pointer dereference. Closes #6000 diff --git a/liblwgeom/measures.c b/liblwgeom/measures.c index ac2ddac46..eb95ef750 100644 --- a/liblwgeom/measures.c +++ b/liblwgeom/measures.c @@ -261,6 +261,22 @@ lw_dist2d_is_collection(const LWGEOM *g) } } + +/* Check for overlapping bboxes */ +static int +lw_dist2d_check_overlap(const LWGEOM *lwg1, const LWGEOM *lwg2) +{ + assert(lwg1 && lwg2 && lwg1->bbox && lwg2->bbox); + + /* Check if the geometries intersect. */ + if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || + lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) + { + return LW_FALSE; + } + return LW_TRUE; +} + /** This is a recursive function delivering every possible combination of subgeometries */ @@ -298,6 +314,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g1 = (LWGEOM *)lwg1; + if (!g1) continue; + if (lwgeom_is_empty(g1)) continue; @@ -315,6 +333,8 @@ lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl) else g2 = (LWGEOM *)lwg2; + if (!g2) continue; + if (lw_dist2d_is_collection(g2)) { LWDEBUG(3, "Found collection inside second geometry collection, recursing"); @@ -512,26 +532,6 @@ lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS return LW_FALSE; } -/* Check for overlapping bboxes */ -int -lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2) -{ - LWDEBUG(2, "lw_dist2d_check_overlap is called"); - if (!lwg1->bbox) - lwgeom_calculate_gbox(lwg1, lwg1->bbox); - if (!lwg2->bbox) - lwgeom_calculate_gbox(lwg2, lwg2->bbox); - - /* Check if the geometries intersect. */ - if ((lwg1->bbox->xmax < lwg2->bbox->xmin || lwg1->bbox->xmin > lwg2->bbox->xmax || - lwg1->bbox->ymax < lwg2->bbox->ymin || lwg1->bbox->ymin > lwg2->bbox->ymax)) - { - LWDEBUG(3, "geometries bboxes did not overlap"); - return LW_FALSE; - } - LWDEBUG(3, "geometries bboxes overlap"); - return LW_TRUE; -} /** Geometries are distributed for the new faster distance-calculations */ int diff --git a/liblwgeom/measures.h b/liblwgeom/measures.h index 9cf0fb958..fc3f34bfe 100644 --- a/liblwgeom/measures.h +++ b/liblwgeom/measures.h @@ -69,7 +69,6 @@ typedef struct int lw_dist2d_comp(const LWGEOM *lw1, const LWGEOM *lw2, DISTPTS *dl); int lw_dist2d_distribute_bruteforce(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); int lw_dist2d_recursive(const LWGEOM *lwg1, const LWGEOM *lwg2, DISTPTS *dl); -int lw_dist2d_check_overlap(LWGEOM *lwg1, LWGEOM *lwg2); int lw_dist2d_distribute_fast(LWGEOM *lwg1, LWGEOM *lwg2, DISTPTS *dl); /* ----------------------------------------------------------------------- Summary of changes: liblwgeom/measures.c | 40 ++++++++++++++++++++-------------------- liblwgeom/measures.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 14:21:05 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 08 Oct 2025 21:21:05 -0000 Subject: [PostGIS] #6000: Dereference of NULL In-Reply-To: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> References: <051.61dd8a3c8e10d1d808a6e3e0649ad971@osgeo.org> Message-ID: <066.fd63c65a1c30a69fc88fab1ca7ee0521@osgeo.org> #6000: Dereference of NULL ------------------------+--------------------------- Reporter: mkorotkov | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.6.x Resolution: fixed | Keywords: ------------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"58ef17e4fc45651f8b3e92ea9cefc34942f35e71/git" 58ef17e/git]: {{{#!CommitTicketReference repository="git" revision="58ef17e4fc45651f8b3e92ea9cefc34942f35e71" Avoid possible null pointer dereference. Closes #6000 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 8 20:11:00 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 8 Oct 2025 20:11:00 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-128-g9e3d20753 Message-ID: <20251009031100.AB8211897F2@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 9e3d207534699a2d43608b1f51c00780883126a1 (commit) from c57e094f73819eee5ffea672ee185c391e655ffe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9e3d207534699a2d43608b1f51c00780883126a1 Author: Regina Obe Date: Wed Oct 8 23:08:46 2025 -0400 Fix winnie gtk check condition [skip ci] diff --git a/ci/winnie/package_postgis.sh b/ci/winnie/package_postgis.sh index bb4f1fc4c..bcaa2435e 100644 --- a/ci/winnie/package_postgis.sh +++ b/ci/winnie/package_postgis.sh @@ -12,7 +12,7 @@ DWN=${WEB}/download #export PG_VER=9.2beta2 if [ -n "$SOURCE_FOLDER" ]; then - export POSTGIS_SRC=${PROJECTS}/postgis/$SOURCE_FOLDER + export POSTGIS_SRC=${PROJECTS}/postgis/$SOURCE_FOLDER cd $POSTGIS_SRC fi @@ -55,7 +55,7 @@ cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libstdc++-6.dll $outdir/bi cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libgcc*.dll $outdir/bin # don't package postgisgui if we don't have gtk2 -if [ -n "${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}" ]; then +if [ -d "${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}" ]; then mkdir $outdir/bin/postgisgui mkdir $outdir/bin/postgisgui/share mkdir $outdir/bin/postgisgui/lib ----------------------------------------------------------------------- Summary of changes: ci/winnie/package_postgis.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 8 21:34:08 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 04:34:08 -0000 Subject: [PostGIS] #5983: Potential data corruption in topology.topoelement after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.dcd5af66ee2c90a70d7c3b5c9b6a38b3@osgeo.org> #5983: Potential data corruption in topology.topoelement after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Replying to [comment:8 francoisb]: > The `topology.topogeometry` composite type appears to be affected too, probably with the same root cause. I can file a separate ticket if applicable. > It's fine to have it all here. We should take care of it as a single fix. Just need to relabel the bug. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 21:34:36 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 04:34:36 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 (was: Potential data corruption in topology.topoelement after upgrade to 3.6.0) In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.fe20792d7c5f4d329ece6e20e4c379d9@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Changes (by robe): * summary: Potential data corruption in topology.topoelement after upgrade to 3.6.0 => Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 22:02:23 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 05:02:23 -0000 Subject: [PostGIS] #3651: ST_Orientation crashes the backend In-Reply-To: <053.eddda6c7c6b527b9efa247c07629950c@osgeo.org> References: <053.eddda6c7c6b527b9efa247c07629950c@osgeo.org> Message-ID: <068.6eb620c13aaa7a868bfa0a3dc13beae4@osgeo.org> #3651: ST_Orientation crashes the backend --------------------------+----------------------------- Reporter: postgispaul | Owner: Lo?c Bartoletti Type: defect | Status: new Priority: high | Milestone: PostGIS SFCGAL Component: sfcgal | Version: 2.3.x Resolution: | Keywords: windows --------------------------+----------------------------- Changes (by robe): * owner: robe => Lo?c Bartoletti Comment: Just retested crash.sql using sfcgal 2.2.0 compiled with msys2/mingw64 gcc 13.2 and still crashes. {{{ PostgreSQL 18.0 on x86_64-windows, compiled by msvc-19.44.35215, 64-bit POSTGIS="3.6.0 3.6.0" [EXTENSION] PGSQL="180" GEOS="3.14.0-CAPI-1.20.4" SFCGAL="SFCGAL 2.2.0, CGAL 6.0.1, BOOST 1.88.0" PROJ="8.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=C:\Users\lr\AppData\Local/proj DATABASE_PATH=C:\ming64\projects\proj\rel- proj-8.2.1w64/share/proj/proj.db" (compiled against PROJ 8.2.1) LIBXML="2.12.5" LIBJSON="0.12" LIBPROTOBUF="1.2.1" WAGYU="0.5.0 (Internal)" }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 22:03:25 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 05:03:25 -0000 Subject: [PostGIS] #4931: commit mails are lacking change info In-Reply-To: <046.90cfd22563770bc5841f2df49983d892@osgeo.org> References: <046.90cfd22563770bc5841f2df49983d892@osgeo.org> Message-ID: <061.ce580ae5530a05f3e9fe6eb4e642f51c@osgeo.org> #4931: commit mails are lacking change info -------------------------+-------------------- Reporter: strk | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: Component: management | Version: Resolution: wontfix | Keywords: -------------------------+-------------------- Changes (by robe): * resolution: => wontfix * status: new => closed Comment: I can't even remember what this was about. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 22:06:55 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 05:06:55 -0000 Subject: [PostGIS] #5675: WARN Module "hugo-geekdoc" is not compatible with this Hugo version In-Reply-To: <046.f7d6f66f1b7e3e11895d69a31e4ed30e@osgeo.org> References: <046.f7d6f66f1b7e3e11895d69a31e4ed30e@osgeo.org> Message-ID: <061.b6c35d02badace1f7f9fb6f7714880fe@osgeo.org> #5675: WARN Module "hugo-geekdoc" is not compatible with this Hugo version ----------------------+-------------------------------------- Reporter: strk | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: Website Management, Bots Component: website | Version: Resolution: fixed | Keywords: ----------------------+-------------------------------------- Changes (by robe): * resolution: => fixed * status: new => closed Comment: The bots aren't complaining anymore since we upgraded their hugo. In fact they are newer now than what debbie is running and I had to remove some deprecated code no longer supported in new hugo. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 8 22:10:05 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 05:10:05 -0000 Subject: [PostGIS] #2106: Add spatialite and rasterlite to windows distributed gdal binary In-Reply-To: <046.6f9319bd4e7e130f76aeb0af228cc9a3@osgeo.org> References: <046.6f9319bd4e7e130f76aeb0af228cc9a3@osgeo.org> Message-ID: <061.fcd3cdb52866fda6fa88b255b57d259b@osgeo.org> #2106: Add spatialite and rasterlite to windows distributed gdal binary --------------------------+----------------------------- Reporter: robe | Owner: robe Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: packages | Version: master Resolution: wontfix | Keywords: windows --------------------------+----------------------------- Changes (by robe): * resolution: => wontfix * status: new => closed Comment: These are just for use with postgis raster and ogrfdw. They are not meant to be full purpose gdal. For full purpose gdal, I think using the QGIS gdal windows shell is best. I'm going to close this out cause I don't think there is high demand for it within postgis raster use and it does add some extra dependencies. I do have sqlite now as an additional dependency so in theory rasterlite and spatialite at least the non-spatial part can be ready with ogr_fdw. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 9 08:44:14 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 15:44:14 -0000 Subject: [PostGIS] #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension In-Reply-To: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> References: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> Message-ID: <061.2e62806bb410fca3c2aa8f15bd0e0380@osgeo.org> #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension -----------------------------+---------------------------- Reporter: robe | Owner: robe Type: patch | Status: reopened Priority: medium | Milestone: PostGIS 3.0.12 Component: tiger geocoder | Version: 3.5.x Resolution: | Keywords: -----------------------------+---------------------------- Changes (by robe): * resolution: fixed => * status: closed => reopened Comment: still need to backport. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 9 08:52:37 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 9 Oct 2025 08:52:37 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-23-gaca123684 Message-ID: <20251009155238.675496584@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via aca123684d92189659756a00d93a97398447f229 (commit) via abd2fda84e22c81d8279b6e25dabd8e3f76db32e (commit) via ad0444b02c4ca00a388d1be03305571b71c5563e (commit) from e5cc9ae7a1806acc8d18b0ee4f4ee7d4b9e29c7c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aca123684d92189659756a00d93a97398447f229 Author: Regina Obe Date: Thu Oct 9 11:52:29 2025 -0400 Add credits. References #5998 for PostGIS 3.6.1 diff --git a/NEWS b/NEWS index f60416789..476d10cfe 100644 --- a/NEWS +++ b/NEWS @@ -5,11 +5,14 @@ PostGIS 3.6.1 * Fixes * - #5978, geometry_columns needs to still parse table constraints (Paul Ramsey) - - #5987, ST_GeometryN fails for non-collections (Paul Ramsey) + - #5987, ST_GeometryN fails for non-collections (Paul Ramsey) - #5991, CircularString distance error (Paul Ramsey) - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) - #5998, ST_Distance error on CurvePolygon (Paul Ramsey) - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) + - #5998, [tiger_geocoder] [security] CVE-2022-2625, make sure tables requires + by extension are owned by extension + authored: Andrey Borodin (Yandex), reported by Sergey Bobrov (Kaspersky) PostGIS 3.6.0 commit abd2fda84e22c81d8279b6e25dabd8e3f76db32e Author: Regina Obe Date: Tue Oct 7 18:27:17 2025 -0400 TIGER EXTENSION SECURITY fix - Ensure tables are created by tiger extension and bale if not. Patch provided by Andrey Borodin (Yandex) - Don't create tiger_data as that gets created on first load of data and shouldn't be part of the extension References #5998 for PostGIS 3.6.1 diff --git a/extras/tiger_geocoder/geocode_settings.sql b/extras/tiger_geocoder/geocode_settings.sql index e126f825b..e5c09b8c2 100644 --- a/extras/tiger_geocoder/geocode_settings.sql +++ b/extras/tiger_geocoder/geocode_settings.sql @@ -22,10 +22,16 @@ BEGIN IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'geocode_settings') THEN CREATE TABLE geocode_settings(name text primary key, setting text, unit text, category text, short_desc text); GRANT SELECT ON geocode_settings TO public; + ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS geocode_settings(name text primary key, setting text, unit text, category text, short_desc text); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'geocode_settings_default') THEN CREATE TABLE geocode_settings_default(name text primary key, setting text, unit text, category text, short_desc text); GRANT SELECT ON geocode_settings_default TO public; + ELSE + -- Same as above. + CREATE TABLE IF NOT EXISTS geocode_settings_default(name text primary key, setting text, unit text, category text, short_desc text); END IF; --recreate defaults TRUNCATE TABLE geocode_settings_default; diff --git a/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql b/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql index ff78fc8f8..da6fc91a9 100644 --- a/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql +++ b/extras/tiger_geocoder/pagc_normalize/pagc_tables.sql @@ -11,14 +11,23 @@ BEGIN IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_gaz') THEN CREATE TABLE pagc_gaz (id serial NOT NULL primary key ,seq integer ,word text, stdword text, token integer,is_custom boolean NOT NULL default true); GRANT SELECT ON pagc_gaz TO public; + ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS pagc_gaz (id serial NOT NULL primary key ,seq integer ,word text, stdword text, token integer,is_custom boolean NOT NULL default true); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_lex') THEN CREATE TABLE pagc_lex (id serial NOT NULL primary key,seq integer,word text,stdword text,token integer,is_custom boolean NOT NULL default true); GRANT SELECT ON pagc_lex TO public; + ELSE + -- Same as above. + CREATE TABLE IF NOT EXISTS pagc_lex (id serial NOT NULL primary key,seq integer,word text,stdword text,token integer,is_custom boolean NOT NULL default true); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_rules') THEN CREATE TABLE pagc_rules (id serial NOT NULL primary key,rule text, is_custom boolean DEFAULT true); GRANT SELECT ON pagc_rules TO public; + ELSE + -- Same as above. + CREATE TABLE IF NOT EXISTS pagc_rules (id serial NOT NULL primary key,rule text, is_custom boolean DEFAULT true); END IF; IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_schema = 'tiger' AND table_name = 'pagc_gaz' AND data_type='text') THEN -- its probably old table structure change type of lex and gaz columns diff --git a/extras/tiger_geocoder/tiger_loader_2012.sql b/extras/tiger_geocoder/tiger_loader_2012.sql index c4d6da1b7..00593ecf5 100644 --- a/extras/tiger_geocoder/tiger_loader_2012.sql +++ b/extras/tiger_geocoder/tiger_loader_2012.sql @@ -57,18 +57,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -125,9 +121,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -138,8 +132,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -149,7 +142,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2013.sql b/extras/tiger_geocoder/tiger_loader_2013.sql index d42f60ea2..8b6e0d166 100644 --- a/extras/tiger_geocoder/tiger_loader_2013.sql +++ b/extras/tiger_geocoder/tiger_loader_2013.sql @@ -56,18 +56,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -124,9 +120,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -137,8 +131,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -148,7 +141,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2014.sql b/extras/tiger_geocoder/tiger_loader_2014.sql index bedb84051..8726e5afe 100644 --- a/extras/tiger_geocoder/tiger_loader_2014.sql +++ b/extras/tiger_geocoder/tiger_loader_2014.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -212,9 +274,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -225,8 +285,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -236,7 +295,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2015.sql b/extras/tiger_geocoder/tiger_loader_2015.sql index fe0bdf62f..3311be2e7 100644 --- a/extras/tiger_geocoder/tiger_loader_2015.sql +++ b/extras/tiger_geocoder/tiger_loader_2015.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -212,9 +274,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -225,8 +285,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -236,7 +295,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2016.sql b/extras/tiger_geocoder/tiger_loader_2016.sql index 0cb93e442..39dd37f0a 100644 --- a/extras/tiger_geocoder/tiger_loader_2016.sql +++ b/extras/tiger_geocoder/tiger_loader_2016.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2017.sql b/extras/tiger_geocoder/tiger_loader_2017.sql index 9a7c6a726..5644a4d53 100644 --- a/extras/tiger_geocoder/tiger_loader_2017.sql +++ b/extras/tiger_geocoder/tiger_loader_2017.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2018.sql b/extras/tiger_geocoder/tiger_loader_2018.sql index 61e68797a..33697e785 100644 --- a/extras/tiger_geocoder/tiger_loader_2018.sql +++ b/extras/tiger_geocoder/tiger_loader_2018.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2019.sql b/extras/tiger_geocoder/tiger_loader_2019.sql index 12a395b60..9485011cf 100644 --- a/extras/tiger_geocoder/tiger_loader_2019.sql +++ b/extras/tiger_geocoder/tiger_loader_2019.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -144,18 +210,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -211,9 +273,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -224,8 +284,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -235,7 +294,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2020.sql b/extras/tiger_geocoder/tiger_loader_2020.sql index 6afce151a..01c81f26a 100644 --- a/extras/tiger_geocoder/tiger_loader_2020.sql +++ b/extras/tiger_geocoder/tiger_loader_2020.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -165,18 +231,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -232,9 +294,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -245,8 +305,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -256,7 +315,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2021.sql b/extras/tiger_geocoder/tiger_loader_2021.sql index 0cdd7ee5a..675bff9cd 100644 --- a/extras/tiger_geocoder/tiger_loader_2021.sql +++ b/extras/tiger_geocoder/tiger_loader_2021.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -172,18 +238,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -239,9 +301,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -252,8 +312,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -263,7 +322,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2022.sql b/extras/tiger_geocoder/tiger_loader_2022.sql index af4b9ee25..991ce2255 100644 --- a/extras/tiger_geocoder/tiger_loader_2022.sql +++ b/extras/tiger_geocoder/tiger_loader_2022.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -175,18 +241,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -242,9 +304,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -255,8 +315,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -266,7 +325,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2023.sql b/extras/tiger_geocoder/tiger_loader_2023.sql index 691176236..65c497ce2 100644 --- a/extras/tiger_geocoder/tiger_loader_2023.sql +++ b/extras/tiger_geocoder/tiger_loader_2023.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -175,18 +241,14 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE SCHEMA IF NOT EXISTS tiger_data; END $$ LANGUAGE 'plpgsql'; @@ -242,9 +304,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -255,8 +315,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -266,7 +325,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; diff --git a/extras/tiger_geocoder/tiger_loader_2024.sql b/extras/tiger_geocoder/tiger_loader_2024.sql index f6d7f0b85..75db83e0f 100644 --- a/extras/tiger_geocoder/tiger_loader_2024.sql +++ b/extras/tiger_geocoder/tiger_loader_2024.sql @@ -89,6 +89,72 @@ IF NOT EXISTS(SELECT table_name FROM information_schema.columns WHERE table_sche CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) ); COMMENT ON TABLE tiger.bg IS 'block groups'; +ELSE + -- Insist on invoking Postgres logic of owning table by extension. This prevent attacks like CVE-2022-2625. + CREATE TABLE IF NOT EXISTS tiger.tract + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + tract_id varchar(11) PRIMARY KEY, + name varchar(7), + namelsad varchar(20), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tiger.tabblock + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blockce varchar(4), + tabblock_id varchar(16) PRIMARY KEY, + name varchar(20), + mtfcc varchar(5), + ur varchar(1), + uace varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); + + CREATE TABLE IF NOT EXISTS tiger.bg + ( + gid serial NOT NULL, + statefp varchar(2), + countyfp varchar(3), + tractce varchar(6), + blkgrpce varchar(1), + bg_id varchar(12) PRIMARY KEY, + namelsad varchar(13), + mtfcc varchar(5), + funcstat varchar(1), + aland double precision, + awater double precision, + intptlat varchar(11), + intptlon varchar(12), + the_geom geometry, + CONSTRAINT enforce_dims_geom CHECK (st_ndims(the_geom) = 2), + CONSTRAINT enforce_geotype_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL), + CONSTRAINT enforce_srid_geom CHECK (st_srid(the_geom) = 4269) + ); END IF; IF EXISTS(SELECT * FROM information_schema.columns WHERE table_schema = 'tiger' AND column_name = 'tabblock_id' AND table_name = 'tabblock' AND character_maximum_length < 16) THEN -- size of name and tabblock_id fields need to be increased @@ -175,18 +241,7 @@ $$ DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_platform' AND table_schema = 'tiger') THEN - CREATE TABLE loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); - END IF; -END -$$ LANGUAGE 'plpgsql'; - -DO -$$ -BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = 'tiger_data') THEN - CREATE SCHEMA tiger_data; - END IF; + CREATE TABLE IF NOT EXISTS loader_platform(os varchar(50) PRIMARY KEY, declare_sect text, pgbin text, wget text, unzip_command text, psql text, path_sep text, loader text, environ_set_command text, county_process_command text); END $$ LANGUAGE 'plpgsql'; @@ -242,9 +297,7 @@ done'); -- variables table DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_variables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); - END IF; + CREATE TABLE IF NOT EXISTS loader_variables(tiger_year varchar(4) PRIMARY KEY, website_root text, staging_fold text, data_schema text, staging_schema text); END $$ LANGUAGE 'plpgsql'; @@ -255,8 +308,7 @@ GRANT SELECT ON TABLE loader_variables TO public; DO $$ BEGIN - IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'loader_lookuptables' AND table_schema = 'tiger') THEN - CREATE TABLE loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, + CREATE TABLE IF NOT EXISTS loader_lookuptables(process_order integer NOT NULL DEFAULT 1000, lookup_name text primary key, table_name text, single_mode boolean NOT NULL DEFAULT true, load boolean NOT NULL DEFAULT true, @@ -266,7 +318,6 @@ BEGIN post_load_process text, single_geom_mode boolean DEFAULT false, insert_mode char(1) NOT NULL DEFAULT 'c', pre_load_process text,columns_exclude text[], website_root_override text); - END IF; END $$ LANGUAGE 'plpgsql'; commit ad0444b02c4ca00a388d1be03305571b71c5563e Author: Regina Obe Date: Thu Oct 9 11:39:48 2025 -0400 Cleanup winnie ci building diff --git a/ci/winnie/package_postgis.sh b/ci/winnie/package_postgis.sh index bb4f1fc4c..bcaa2435e 100644 --- a/ci/winnie/package_postgis.sh +++ b/ci/winnie/package_postgis.sh @@ -12,7 +12,7 @@ DWN=${WEB}/download #export PG_VER=9.2beta2 if [ -n "$SOURCE_FOLDER" ]; then - export POSTGIS_SRC=${PROJECTS}/postgis/$SOURCE_FOLDER + export POSTGIS_SRC=${PROJECTS}/postgis/$SOURCE_FOLDER cd $POSTGIS_SRC fi @@ -55,7 +55,7 @@ cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libstdc++-6.dll $outdir/bi cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libgcc*.dll $outdir/bin # don't package postgisgui if we don't have gtk2 -if [ -n "${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}" ]; then +if [ -d "${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}" ]; then mkdir $outdir/bin/postgisgui mkdir $outdir/bin/postgisgui/share mkdir $outdir/bin/postgisgui/lib diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh index 10aa48c0e..5a86e8db9 100644 --- a/ci/winnie/regress_postgis.sh +++ b/ci/winnie/regress_postgis.sh @@ -39,10 +39,10 @@ echo PATH AFTER: $PATH echo WORKSPACE IS $WORKSPACE #mkdir ${PROJECTS}/postgis/tmp -export PGIS_REG_TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_MICRO_VER}_pg${PG_VER}_geos${GEOS_VER}_gdal${GDAL_VER}w${OS_BUILD} -rm -rf ${PGIS_REG_TMPDIR} -mkdir ${PGIS_REG_TMPDIR} -export TMPDIR=${PGIS_REG_TMPDIR} +#export PGIS_REG_TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_MICRO_VER}_pg${PG_VER}_geos${GEOS_VER}_gdal${GDAL_VER}w${OS_BUILD} +#rm -rf ${PGIS_REG_TMPDIR} +#mkdir ${PGIS_REG_TMPDIR} +#export TMPDIR=${PGIS_REG_TMPDIR} #rm -rf ${PGIS_REG_TMPDIR} #TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_VER}_${PG_VER}_${GEOS_VERSION}_${PROJ_VER} @@ -68,11 +68,11 @@ if [ $INCLUDE_MINOR_LIB == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --with-library-minor-version" fi -if [ $REGRESS_WITHOUT_TOPOLOGY == "1" ]; then +if [ $REGRESS_WITHOUT_TOPOLOGY == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-topology" fi -if [ $REGRESS_WITHOUT_RASTER == "1" ]; then +if [ $REGRESS_WITHOUT_RASTER == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-raster" fi @@ -99,13 +99,13 @@ LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${LZ4_PATH}/lib -L${PROJECTS #patch liblwgeom generated make to get rid of dynamic linking #sed -i 's/LDFLAGS += -no-undefined//g' liblwgeom/Makefile -make -j 4 +make -j 2 make install # don't run tests twice. Only run regular if extension test is not asked for -if [ "$MAKE_EXTENSION" == "" ]; then +if [ "$MAKE_EXTENSION" == "0" ]; then make check RUNTESTFLAGS=-v -fi +fi if [ "$MAKE_EXTENSION" == "1" ]; then @@ -117,13 +117,13 @@ if [ "$MAKE_EXTENSION" == "1" ]; then #strip raster/rt_pg/postgis_raster-*.dll #strip sfcgal/*.dll - if [ $REGRESS_WITHOUT_TOPOLOGY == "" ]; then + if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then cp -r topology/*.dll ${PGPATHEDB}/lib fi cp postgis/postgis*.dll ${PGPATHEDB}/lib cp sfcgal/*.dll ${PGPATHEDB}/lib - if [ $REGRESS_WITHOUT_RASTER == "" ]; then + if [ $REGRESS_WITHOUT_RASTER == "0" ]; then cp raster/rt_pg/postgis_raster-*.dll ${PGPATHEDB}/lib fi @@ -141,18 +141,18 @@ export UPGRADEABLE_VERSIONS=$value export WIN_RELEASED_VERSIONS="2.0.0 2.0.1 2.0.3 2.0.4 2.0.6 2.1.4 2.1.7 2.1.8 2.2.0 2.2.3 2.3.0 2.3.7 2.4.0 2.4.4" export extensions_to_install="postgis postgis_sfcgal postgis_tiger_geocoder address_standardizer" -if [ $REGRESS_WITHOUT_TOPOLOGY == "" ]; then +if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then extensions_to_install="${extensions_to_install} postgis_topology" fi -if [ $REGRESS_WITHOUT_RASTER == "" ]; then +if [ $REGRESS_WITHOUT_RASTER == "0" ]; then extensions_to_install="${extensions_to_install} postgis_raster" fi #echo "Versions are: $UPGRADEABLE_VERSIONS" for EXTNAME in $extensions_to_install; do - + cp extensions/$EXTNAME/sql/* ${PGPATHEDB}/share/extension cp extensions/$EXTNAME/sql/$EXTNAME--TEMPLATED--TO--ANY.sql ${PGPATHEDB}/share/extension/$EXTNAME--$POSTGIS_MICRO_VER--${POSTGIS_MINOR_MAX_VER}.sql; diff --git a/ci/winnie/winnie_common.sh b/ci/winnie/winnie_common.sh index e81b946f0..d375cbec6 100644 --- a/ci/winnie/winnie_common.sh +++ b/ci/winnie/winnie_common.sh @@ -65,6 +65,18 @@ fi; echo "LZ4_VER ${LZ4_VER}" +if [[ "${REGRESS_WITHOUT_TOPOLOGY}" == '' ]] ; then + export REGRESS_WITHOUT_TOPOLOGY=0 +fi; + +if [[ "${REGRESS_WITHOUT_RASTER}" == '' ]] ; then + export REGRESS_WITHOUT_RASTER=0 +fi; + +if [[ "${MAKE_EXTENSION}" == '' ]] ; then + export MAKE_EXTENSION=0 +fi; + #set to something even if override is on but not set if [[ "${ZLIB_VER}" == '' ]] ; then ----------------------------------------------------------------------- Summary of changes: NEWS | 5 +- ci/winnie/package_postgis.sh | 4 +- ci/winnie/regress_postgis.sh | 28 +++---- ci/winnie/winnie_common.sh | 12 +++ extras/tiger_geocoder/geocode_settings.sql | 6 ++ .../tiger_geocoder/pagc_normalize/pagc_tables.sql | 9 +++ extras/tiger_geocoder/tiger_loader_2012.sql | 16 +--- extras/tiger_geocoder/tiger_loader_2013.sql | 16 +--- extras/tiger_geocoder/tiger_loader_2014.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2015.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2016.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2017.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2018.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2019.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2020.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2021.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2022.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2023.sql | 82 +++++++++++++++++--- extras/tiger_geocoder/tiger_loader_2024.sql | 87 +++++++++++++++++----- 19 files changed, 824 insertions(+), 179 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 9 08:52:50 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 15:52:50 -0000 Subject: [PostGIS] #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension In-Reply-To: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> References: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> Message-ID: <061.07e397948b938d07c868524c4c66e4df@osgeo.org> #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension -----------------------------+---------------------------- Reporter: robe | Owner: robe Type: patch | Status: reopened Priority: medium | Milestone: PostGIS 3.0.12 Component: tiger geocoder | Version: 3.5.x Resolution: | Keywords: -----------------------------+---------------------------- Comment (by Regina Obe ): In [changeset:"abd2fda84e22c81d8279b6e25dabd8e3f76db32e/git" abd2fda8/git]: {{{#!CommitTicketReference repository="git" revision="abd2fda84e22c81d8279b6e25dabd8e3f76db32e" TIGER EXTENSION SECURITY fix - Ensure tables are created by tiger extension and bale if not. Patch provided by Andrey Borodin (Yandex) - Don't create tiger_data as that gets created on first load of data and shouldn't be part of the extension References #5998 for PostGIS 3.6.1 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 9 08:52:50 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 15:52:50 -0000 Subject: [PostGIS] #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension In-Reply-To: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> References: <046.5656718946f98b4130c49108ab22f1a5@osgeo.org> Message-ID: <061.924952686a51784442e8da78d38eff03@osgeo.org> #5998: Ensure postgis_tiger_geocoder packaged tables are created by the extension -----------------------------+---------------------------- Reporter: robe | Owner: robe Type: patch | Status: reopened Priority: medium | Milestone: PostGIS 3.0.12 Component: tiger geocoder | Version: 3.5.x Resolution: | Keywords: -----------------------------+---------------------------- Comment (by Regina Obe ): In [changeset:"aca123684d92189659756a00d93a97398447f229/git" aca1236/git]: {{{#!CommitTicketReference repository="git" revision="aca123684d92189659756a00d93a97398447f229" Add credits. References #5998 for PostGIS 3.6.1 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 9 09:52:32 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 9 Oct 2025 09:52:32 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-129-gbe67fc40a Message-ID: <20251009165233.046E36FAF@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via be67fc40ac8afd864b6276919b9b7b62d16ad26e (commit) from 9e3d207534699a2d43608b1f51c00780883126a1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be67fc40ac8afd864b6276919b9b7b62d16ad26e Author: Regina Obe Date: Thu Oct 9 12:51:55 2025 -0400 WOODPECKER-CI changes - turn off interrupt tests - get rid of duplicate enable-lto line diff --git a/.woodpecker/regress.yml b/.woodpecker/regress.yml index 87c1b47f7..b331edcb3 100644 --- a/.woodpecker/regress.yml +++ b/.woodpecker/regress.yml @@ -24,7 +24,7 @@ variables: - $${SRCDIR}/configure --with-library-minor-version --enable-lto - --enable-lto + --without-interrupt-tests CFLAGS="-O2 -Wall -fno-omit-frame-pointer -Werror" - make -j steps-pg-test-preinstall: &steps-pg-test-preinstall ----------------------------------------------------------------------- Summary of changes: .woodpecker/regress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 9 13:52:39 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 09 Oct 2025 20:52:39 -0000 Subject: [PostGIS] #5889: Include location in topology errors In-Reply-To: <046.3c240c50e31de7a47e9aae513347842f@osgeo.org> References: <046.3c240c50e31de7a47e9aae513347842f@osgeo.org> Message-ID: <061.3b9b161c1db787dd2e2b13f759396896@osgeo.org> #5889: Include location in topology errors --------------------------+--------------------------- Reporter: strk | Owner: ankoure Type: enhancement | Status: assigned Priority: medium | Milestone: PostGIS 3.7.0 Component: topology | Version: master Resolution: | Keywords: --------------------------+--------------------------- Changes (by strk): * milestone: PostGIS 3.5.4 => PostGIS 3.7.0 * type: defect => enhancement -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 9 22:27:04 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 9 Oct 2025 22:27:04 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-130-g58374818b Message-ID: <20251010052705.375F4166579@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 58374818b0c985b5a825fdd18dbee1238c0cc83a (commit) from be67fc40ac8afd864b6276919b9b7b62d16ad26e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: NEWS | 7 +++++ doc/extras_topology.xml | 20 ++++++++------ liblwgeom/topo/lwgeom_topo.c | 6 ++-- topology/postgis_topology.c | 32 +++++++++++----------- topology/sql/manage/CreateTopology.sql.in | 5 +--- topology/sql/populate.sql.in | 17 ++++++++---- topology/sql/topogeometry/totopogeom.sql.in | 4 +-- topology/test/regress/topogeo_addlinestring.sql | 16 +++++------ .../test/regress/topogeo_addpoint_merge_edges.sql | 4 +-- 9 files changed, 61 insertions(+), 50 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 9 22:27:10 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 10 Oct 2025 05:27:10 -0000 Subject: [PostGIS] #5688: Allow 0-tolerance topology loading In-Reply-To: <046.4325684cbbc21e167034a6e979d08945@osgeo.org> References: <046.4325684cbbc21e167034a6e979d08945@osgeo.org> Message-ID: <061.439f3a95f4e106d7e00b1ff66948caa7@osgeo.org> #5688: Allow 0-tolerance topology loading --------------------------+--------------------------- Reporter: strk | Owner: strk Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: topology | Version: master Resolution: fixed | Keywords: --------------------------+--------------------------- Changes (by Sandro Santilli ): * resolution: => fixed * status: new => closed Comment: In [changeset:"58374818b0c985b5a825fdd18dbee1238c0cc83a/git" 5837481/git]: {{{#!CommitTicketReference repository="git" revision="58374818b0c985b5a825fdd18dbee1238c0cc83a" Add 0-tolerance (no snapping) support in topology population functions Retains the default of automatic computation, which is now obtained by passing -1 as the tolerance Document default tolerance value Update tests to adapt to the breaking change. Closes #5688 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 9 23:00:45 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 10 Oct 2025 06:00:45 -0000 Subject: [PostGIS] #5180: Batch edges removal function In-Reply-To: <046.ddc64c3d7abeb0f46be2e25390beb522@osgeo.org> References: <046.ddc64c3d7abeb0f46be2e25390beb522@osgeo.org> Message-ID: <061.eb34f631af85dbd60b4a9bc3fa3d9743@osgeo.org> #5180: Batch edges removal function --------------------------+----------------------------- Reporter: strk | Owner: strk Type: enhancement | Status: new Priority: medium | Milestone: PostGIS Fund Me Component: topology | Version: Resolution: | Keywords: --------------------------+----------------------------- Comment (by strk): A real world use case showing how we could speed removal of many edges by 10x: https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/issues/110#note_2811975706 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 10 12:39:57 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 10 Oct 2025 12:39:57 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-131-g11337be06 Message-ID: <20251010193957.712CC197745@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 11337be06b6937bd23caa889af1f9a5a319a62c6 (commit) from 58374818b0c985b5a825fdd18dbee1238c0cc83a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 11337be06b6937bd23caa889af1f9a5a319a62c6 Author: Sandro Santilli Date: Fri Oct 10 21:39:28 2025 +0200 Add fixing of smart quote characters in fix_broken_xml.sh script diff --git a/doc/po/fix_broken_xml.sh b/doc/po/fix_broken_xml.sh index d62d6373d..6f3f23644 100755 --- a/doc/po/fix_broken_xml.sh +++ b/doc/po/fix_broken_xml.sh @@ -9,3 +9,9 @@ perl -pi -e 's/<[^[>\\]*!\[CDATA\[/ This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 87f1ded8cf25763cdf9f15142bb1219abcce2a57 (commit) from 11337be06b6937bd23caa889af1f9a5a319a62c6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 87f1ded8cf25763cdf9f15142bb1219abcce2a57 Author: Sandro Santilli Date: Fri Oct 10 21:47:09 2025 +0200 Fix Ukrainan translation Please do not translate tags and do not use smart quotes ! diff --git a/doc/po/uk/postgis-manual.po b/doc/po/uk/postgis-manual.po index 2a7289932..029bc5b24 100644 --- a/doc/po/uk/postgis-manual.po +++ b/doc/po/uk/postgis-manual.po @@ -31038,9 +31038,9 @@ msgid "" "is string 'GDAL' or 'ESRI'." msgstr "" "???????? ???????? ?????????????, ????????? ?????????? ???????, ? ??????? " -"GDAL ??? ESRI, ?? ?? ???????? ?????? ? ????? world. ?? ????????????? ???????????????? " -"GDAL, ???? ??? ?? ???????. ??? ? ?? ????? ?GDAL? ??? ?ESRI?." +"GDAL ??? ESRI, ?? ?? ???????? ?????? ? ????? world. ?? ????????????? ???????????????? " +"GDAL, ???? ??? ?? ???????. ??? ? ?? ????? \"GDAL\" ??? \"ESRI\"." #. Tag: para #, no-c-format @@ -31263,7 +31263,7 @@ msgid "" "World_file\">World File for more details." msgstr "" "???????? ????????? X ?????? ??????? ? ???????? ??????? ?????????. ?????????? " -"?????????? ???. ? World File." #. Tag: para @@ -31286,8 +31286,8 @@ msgid "" "wiki/World_file\">World File for more details." msgstr "" "???????? ????????? Y ?????? ??????? ? ???????? ??????? ?????????. ???? ???? " -"???'?????. ?????????? ?????????? ???. ? World File." +"???'?????. ?????????? ?????????? ???. ? World File." #. Tag: para #, no-c-format @@ -32089,8 +32089,8 @@ msgid "" ">, val double precision, x " "integer, y integers." msgstr "" -"?????? ?????? ??????????: geom , val ???????? ????????, x " +"?????? ?????? ??????????: geom , val ???????? ????????, x " "???? ?????, y ???? ?????." #. Tag: para @@ -32321,10 +32321,10 @@ msgid "" "wiki/Bilinear_interpolation\">bilinear interpolation to estimate the " "value between pixel centers." msgstr "" -"??????????? ?????????? ????????? resample ? ?nearest?, ?? " -"??????? ?????????? ????????????? ?? ?????????? ???????, ?? ?bilinear?, ?? " -"??????? ????????? ???????????? ??? ?????? ???????? " +"??????????? ?????????? ????????? resample ? \"nearest\", ?? " +"??????? ?????????? ????????????? ?? ?????????? ???????, ?? \"bilinear\", ?? " +"??????? ????????? ???????????? ??? ?????? ???????? " "??? ???????? ????????." #. Tag: para @@ -32442,10 +32442,10 @@ msgid "" "Bilinear_interpolation\">bilinear interpolation to calculate a value " "that takes neighboring cells into account also." msgstr "" -"???????? resample ????? ?????????? ?? ???????? ?nearest?, " +"???????? resample ????? ?????????? ?? ???????? \"nearest\", " "??? ?????????? ???????? ? ???????, ? ??? ????????? ????? ???????, ??? " -"?bilinear?, ??? ??????????????? ????????? ???????????? ??? ?????????? " +"\"bilinear\", ??? ??????????????? ????????? ???????????? ??? ?????????? " "????????, ??? ????? ???????? ??????? ???????." #. Tag: para @@ -32790,7 +32790,7 @@ msgid "" "provided will return null." msgstr "" "?????????? ????????????? 6 ?????????? ????????????? ?? ???? ??????. ??????? " -"?????? ???? ? ??????? ?GDAL? ??? ?ESRI?. ?? ????????????? ???????????????? " +"?????? ???? ? ??????? \"GDAL\" ??? \"ESRI\". ?? ????????????? ???????????????? " "GDAL. ???? 6 ????????? ?? ???????, ???????????? ??????? ????????." #. Tag: para @@ -32834,7 +32834,7 @@ msgid "" "details." msgstr "" "?????????? ???????? ?????. ??????? ??????????? ? ????????. ?????????? " -"?????????? ???. ? World File." #. Tag: refpurpose @@ -32908,8 +32908,8 @@ msgid "" msgstr "" "?????????? ????????????? X ? Y (??? ???????? ?????????). ???? ??????????? " "?????? ???? ????????, X ? Y ?????????????? ?? ???? ? ?? ? ????????. " -"?????????? ?????????? ???. ? World File." +"?????????? ?????????? ???. ? World File." #. Tag: para #, no-c-format @@ -33067,8 +33067,8 @@ msgid "" "Refer to: GDAL Warp " "resampling methods for more details." msgstr "" -"?????????? ?????????? ???.: ?????? ????????????? GDAL Warp." +"?????????? ?????????? ???.: ?????? ????????????? GDAL Warp." #. Tag: para #, no-c-format @@ -33405,7 +33405,7 @@ msgid "" "width/height." msgstr "" "??????? 3 ??????? ??? ???????? ??????/?????? ????????? ??????, ??? ????????? " -"???????? (?20%?), ?? ?????? ???????? ??????/?????? ???????? ??????." +"???????? (\"20%\"), ?? ?????? ???????? ??????/?????? ???????? ??????." #. Tag: para #, no-c-format @@ -34174,8 +34174,8 @@ msgid "" "supported by your library." msgstr "" "?????? format ??? ??????. ?? ???????? ??? ?????????, " -"?????????????? ? ????? ?????????? libgdal. ???????? ???????? ??????? ?JPEG?, " -"?GTIff?, ?PNG?. ?????????????? , ??? " +"?????????????? ? ????? ?????????? libgdal. ???????? ???????? ??????? \"JPEG\", " +"\"GTIff\", \"PNG\". ?????????????? , ??? " "???????? ?????? ????????, ??? ????????? ???? ??????????." #. Tag: para @@ -34187,7 +34187,7 @@ msgid "" msgstr "" "options ????????? ????? ????? GDAL. ????????? ????? " "???????? ??? ???????. ?????????? ?????????? ???. ? ??????? ????? ??????? GDAL " +"xlink:href=\"http://www.gdal.org/frmt_various.html\">????? ??????? GDAL " "Raster." #. Tag: para @@ -34224,7 +34224,7 @@ msgid "" "the server file system." msgstr "" "???? ?? ???????? ???????????? ????? ? ????? ?????? ? ?? ???????????? ??????? ???????? ??????? ??'????? PostgreSQL. ?? ????????? " "?????????? ???????, ??? ????? ????????? ???????. ???????? ?????, ?? ??? " "????? ??? ??????????? ?????? ???????????????? ?? ???? ?????, ???????? " @@ -34314,8 +34314,8 @@ msgstr "" "???. create_options ??? JPEG ). ??? " "JPEG ???????? ? PROGRESSIVE ON ??? OFF ? " "QUALITY ? ????????? ??? 0 ?? 100, ? ?? ????????????? ? " -"75. ?????????? ?????????? ???. ? ????????? ??????? GDAL Raster." +"75. ?????????? ?????????? ???. ? ????????? ??????? GDAL Raster." #. Tag: title #, no-c-format @@ -34399,9 +34399,9 @@ msgstr "" "options ????? ????? ????? GDAL, ?? ????????? ??? PNG (" "???????? create_options ??? PNG ? ). " "??? PNG ??????? ? ?????? ZLEVEL (????????? ????, ?? ???????????? ?? " -"????????? ? ?? ????????????? 6), ????????? ARRAY[?ZLEVEL=9?]. WORLDFILE ?? " +"????????? ? ?? ????????????? 6), ????????? ARRAY[\"ZLEVEL=9\"]. WORLDFILE ?? " "????????????, ???????? ??????? ??????? ???????? ??? ??????????. ?????????? " -"?????????? ???. ? ????????? ??????? GDAL Raster." #. Tag: para @@ -34475,8 +34475,8 @@ msgid "" msgstr "" "options ????? ????? ????? ????????? GDAL, ?? ????????? " "??? GTiff (???????? create_options ??? GTiff ? ). ??? ???????? ????? ??????? GDAL Raster ??? ????? ????????? " +"\"RT_ST_GDALDrivers\"/>). ??? ???????? ????? ??????? GDAL Raster ??? ????? ????????? " "??????????." #. Tag: para @@ -34597,8 +34597,8 @@ msgid "" "imagery\">MassGIS Aerial Orthos." msgstr "" "? ????????? ????????? ???????????????? ?????????????? ????? ???????????, " -"???????? ?? ????? MassGIS MassGIS Aerial " +"???????? ?? ????? MassGIS MassGIS Aerial " "Orthos." #. Tag: title @@ -34750,8 +34750,8 @@ msgstr "" "?????????? ?????????, ????????, ??????? ?? ????? (?????????? ??????? ??? 0 " "?? 255). ??????? ??????? ???????? ????? ??????????????? ????????? ????????, " "?? 0% ? 100% ? ??????????? ? ???????????? ??????????, ?? ????????????? ? " -"?????????? ??????. ???????? ????? ????????? ?????? (?,?), ??????????, " -"?????????? (?:?) ??/??? ?????????. ???????? ??????? ????? ?????????? ?? " +"?????????? ??????. ???????? ????? ????????? ?????? (\",\"), ??????????, " +"?????????? (\":\") ??/??? ?????????. ???????? ??????? ????? ?????????? ?? " "nv, null ??? nodata ??? ???????? NODATA. ??????? ???????? ?????." @@ -34763,8 +34763,8 @@ msgid "" "html#gdaldem_color_relief\">gdaldem." msgstr "" "????????? colormap ?????? ?? ????????? ?????? ??????????? " -"??????? GDAL gdaldem." +"??????? GDAL gdaldem." #. Tag: para #, no-c-format @@ -34806,8 +34806,8 @@ msgid "" "A great reference for colormaps is ColorBrewer." msgstr "" -"??????? ???????? ?????????? ??? ??????? ????? ? ColorBrewer." +"??????? ???????? ?????????? ??? ??????? ????? ? ColorBrewer." #. Tag: para #, no-c-format @@ -34976,7 +34976,7 @@ msgid "" "the end of the expression. e.g. (ST_Intersection(rast, geom)).geom" msgstr "" "?? ?????? ???????? ?????? ?? ????????? ?? ??????? ??????????????? ?????? " -"geomval, ????????? ?? ? ????? ?? ??????? ?.geom? ??? ?.val? ? ????? ??????. " +"geomval, ????????? ?? ? ????? ?? ??????? \".geom\" ??? \".val\" ? ????? ??????. " "?????????, (ST_Intersection(rast, geom)).geom" #. Tag: para @@ -35002,7 +35002,7 @@ msgid "" "value pixel in the result." msgstr "" "???? ?????????? ?????? ???????????? ????????????? ???????? ???? ??? ??????. " -"????????? ????? ??????? ?????? ?BAND1?, ?BAND2? ??? ?BOTH?, ?????????? ?? " +"????????? ????? ??????? ?????? \"BAND1\", \"BAND2\" ??? \"BOTH\", ?????????? ?? " "????, ?? ??????????? ?? ???????? returnband. ??????? ? " "????????? nodata, ???????? ? ????-???? ?????, ?????????? ?? ????? ???????? ? " "????????? nodata ? ???? ?????? ??????????. ?????? ???????, ????-???? " @@ -35027,7 +35027,7 @@ msgstr "" "?????????? ??? ????????, ?? ?? ?????????????. ?? ?????? ????????? ??? " "???????? ???????? nodata ??? ????-????? ?????????? ??????, ??????? ????? " "nodataval[] ? ????? ??? ????? ?????????? nodata, ??????? " -"??? ????, ?? ?? ????????? ?????? ?BAND1?, ?BAND2? ??? ?BOTH?. ????? ???????? " +"??? ????, ?? ?? ????????? ?????? \"BAND1\", \"BAND2\" ??? \"BOTH\". ????? ???????? " "? ?????? ??????? ???????? nodata ? ??????? ??????, ? ????? ???????? ??????? " "???????? nodata ? ??????? ??????. ???? ???? ??????? ????? ?? ??? ??????????? " "???????? nodata ? ????? ???????? ?? ??????? ? ??????, ???? ??????????? ?? " @@ -35328,9 +35328,9 @@ msgid "" "current/static/xfunc-sql.html\">Query Language (SQL) Functions." msgstr "" "??? ????????? ?????????? ?????????? ??? ??????? ????? VARIADIC ?????????? ?? " -"???????????? PostgreSQL ?? ??????? ???????? SQL ?? ??????? ????????? " -"??????????? ? ??????? ???? ??????? (SQL)." +"???????????? PostgreSQL ?? ??????? \"??????? SQL ?? ??????? ????????? " +"??????????\" ? ??????? ???? ??????? (SQL)." #. Tag: para #, no-c-format @@ -35542,7 +35542,7 @@ msgstr "" msgid "" "[rast.y] - 1-based pixel row of the pixel of interest" msgstr "" -"[rast.y] - ??? ????????, ?? ??????????? ? 1, " +"[rast.y] - ??? ????????, ?? ??????????? ? 1, " "???? ??????????? ???????, ?? ??? ????????" #. Tag: title @@ -35876,8 +35876,8 @@ msgstr "" "????????? ??????? ?? ???????? ???? ????????. ???? ?????? ??????? ?? ???????, " "?? ?? ????????????? ???????????????? ????? 1 ??????? ??????. ???????????? " "????? ???? ?????????? (???????, ????? ? ???? ????????) ?? ?????, ?????????? " -"?????? ???????, ? ???? ?????? ???? ?????????? ?????????? ?extenttype?. " -"???????? ??? ?extenttype? ?????? ????: INTERSECTION, UNION, FIRST, SECOND." +"?????? ???????, ? ???? ?????? ???? ?????????? ?????????? \"extenttype\". " +"???????? ??? \"extenttype\" ?????? ????: INTERSECTION, UNION, FIRST, SECOND." #. Tag: para #, no-c-format @@ -36031,7 +36031,7 @@ msgstr "" "???????? ???? float, ???????????? ????? ????? ????? ?? ????? ?????? ? " "??????? ????????? ?????????. ?????? ???????? ? ?? ???????? ??????? ??????? " "?????? (????????? ??? ???? ????? ??????). ?????? ???????? ? ?? ??????? " -"???????? ???????????? ??????? ? ??????? ?{x,y}?. ?????? ???????? ??????, ?? " +"???????? ???????????? ??????? ? ??????? \"{x,y}\". ?????? ???????? ??????, ?? " "??? ???? ????????? ??? ????? ???? " "???????? ?? userfunction." @@ -36173,7 +36173,7 @@ msgstr "" "??????? ??????? ?????? ? rast1 (????????? ??? ???? ????? " "??????). ?????? ???????? ? ?? ???????? ??????? ??????? ?????? ? " "rast2. ?????? ???????? ? ?? ??????? ???????? ??????? " -"??????? ? ????? ?{x,y}?. ????????? ???????? ??????, ?? ??? ???? ????????? " +"??????? ? ????? \"{x,y}\". ????????? ???????? ??????, ?? ??? ???? ????????? " "????? ???? ???????? ?? " "tworastuserfunc." @@ -36311,7 +36311,7 @@ msgid "" "the computation -- this flag must be sent to the user callback function, and " "the user function decides how to ignore it." msgstr "" -"?ignore?: ????-??? ???????? NODATA, ?? ????????????? ? ????????, ??????????? " +"\"ignore\": ????-??? ???????? NODATA, ?? ????????????? ? ????????, ??????????? " "??? ??? ?????????? ? ??? ?????? ??????? ???? ?????????? ?? ??????? " "?????????? ??????? ???????????, ? ??????? ??????????? ???????, ?? ???? " "??????????." @@ -36323,7 +36323,7 @@ msgid "" "resulting pixel to be NULL -- the user callback function is skipped in this " "case." msgstr "" -"?NULL?: ????-??? ???????? NODATA, ?? ????????????? ? ????????, ?????????? ?? " +"\"NULL\": ????-??? ???????? NODATA, ?? ????????????? ? ????????, ?????????? ?? " "????, ?? ???????????? ??????? ???? NULL ? ? ????? ??????? ??????? ?????????? " "??????? ??????????? ?????????????." @@ -36335,9 +36335,9 @@ msgid "" "if this value is NODATA, the behavior is the same as 'NULL' (for the " "affected neighborhood)" msgstr "" -"?value?: ????-??? ???????? NODATA, ?? ????????????? ? ????????, ??????????? " +"\"value\": ????-??? ???????? NODATA, ?? ????????????? ? ????????, ??????????? " "????????-?????????? (???, ?? ??????????? ? ?????? ????????). ???????? ?????, " -"?? ???? ?? ???????? ? NODATA, ????????? ???? ????? ?, ?? ? ??? ?NULL? (??? " +"?? ???? ?? ???????? ? NODATA, ????????? ???? ????? ?, ?? ? ??? \"NULL\" (??? " "???????????? ????????)" #. Tag: para @@ -36353,9 +36353,9 @@ msgid "" "html\">https://gdal.org/user/drivers/raster/postgisraster.html and " "then prepared in the examples" msgstr "" -"???????? ?????????????? ????? ?katrina?, ???????????? ?? ??????? ????????, " -"???????? ? https://gdal.org/user/drivers/raster/postgisraster.htmlhttps://gdal.org/user/drivers/raster/postgisraster.html, ? ????? ????????????? ? ????????? " #. Tag: para @@ -37012,9 +37012,9 @@ msgid "" msgstr "" "??? ????????? ?????????? ?????????? ??? ???????, ?????????? ?? ??????? " "????????? ???. ESRI - ?? ?????? ??????? " -"????????? ?? ESRI - ?? ?????? ??????? " +"????????? ?? ???????? ???????? ERDAS - ?????????? ????????." #. Tag: para @@ -37135,8 +37135,8 @@ msgid "" "TopicName=How%20Hillshade%20works\">How hillshade works." msgstr "" "??? ????????? ?????????? ?????????? ??? Hillshade, ???? ?????, ?????????? ?? " -"?? ?????? hillshade." +"?? ?????? hillshade." #. Tag: para #, no-c-format @@ -37161,7 +37161,7 @@ msgstr "" #. Tag: refpurpose #, no-c-format msgid "Returns a raster with the calculated \"roughness\" of a DEM." -msgstr "???????? ????? ? ?????????? ???????????? ???????? ?????? ??????? (DEM)." +msgstr "???????? ????? ? ?????????? \"??????????\" ???????? ?????? ??????? (DEM)." #. Tag: para #, no-c-format @@ -37169,7 +37169,7 @@ msgid "" "Calculates the \"roughness\" of a DEM, by subtracting the maximum from the " "minimum for a given area." msgstr "" -"???????? ???????????? ???????? ?????? ??????? (DEM), ?????????? ??????????? " +"???????? \"??????????\" ???????? ?????? ??????? (DEM), ?????????? ??????????? " "???????? ??? ???????????? ??? ??????? ???????." #. Tag: para @@ -37233,9 +37233,9 @@ msgid "" msgstr "" "??? ????????? ?????????? ?????????? ??? ?????, ?????????? ?? ??????? " "????????? ???. ESRI - ?? ?????? ??????? " -"????????? ?? ESRI - ?? ?????? ??????? " +"????????? ?? ???????? ???????? ERDAS - ?????????? ??????." #. Tag: para @@ -37347,10 +37347,10 @@ msgstr "" "Z ????? ? ?? ?????? ????????. ???????? ?'??? ?????????? ????????????: " "???????? ????????, ???????? ???????? ??????????? ??????, ?????? ???????, " "?????????? ????? ? ??????? ????????????. ????? ???????? ?????????? ??? " -"????????? ?? ???? ????????? ???. ? ???????????? gdal_grid???????????? gdal_grid. ?????? ?????????? ??? ??, ?? ???????????? ????????????, ???. ???????? ? ?????? " +"xlink:href=\"https://gdal.org/tutorials/gdal_grid_tut.html\">???????? ? ?????? " "? ?????? GDAL." #. Tag: para @@ -37376,8 +37376,8 @@ msgid "" "interpolation with a smoothing of 2, you would use \"invdist:smoothing=2.0\"" msgstr "" "?????, ?? ???????? ???????? ?? ????????? ?????????, ? ???????, ???? " -"???????????????? gdal_grid. ?????????, ??? ???????????? ? " +"???????????????? gdal_grid. ?????????, ??? ???????????? ? " "????????? ????????? ?? ????????????? 2 ???? ??????????????? \"invdist" ":smoothing=2.0\"" @@ -37463,7 +37463,7 @@ msgid "" "normally zero, but could be different. To generate 10m contours at 5, 15, " "25, ... the LEVEL_BASE would be 5." msgstr "" -"??????, ???????? ???? ?????????????? ????????? ????????, ???????? ???????? " +"\"????\", ???????? ???? ?????????????? ????????? ????????, ???????? ???????? " "????, ??? ???? ???? ?????. ??? ???????? 10-??????? ??????? ?? 5, 15, 25, ... " "LEVEL_BASE ????????????? 5." @@ -37579,8 +37579,8 @@ msgid "" "SpecificationWorking01\">PostGIS Raster Specification for a diagram " "of this." msgstr "" -"???????? ???????????? PostGIS Raster ??? ???????????? " +"???????? ???????????? PostGIS Raster ??? ???????????? " "? ?????????." #. Tag: para @@ -38357,7 +38357,7 @@ msgid "" "operates on rows of data, in the same way the SUM() and AVG() functions do." msgstr "" "????????? ?????? (??????? 3): ? ?????? ??????? ???????? ???????? true, ???? " -"??? ?????? ? ?????? ?????????. ??????? ST_SameAlignment() ? ???????????? " +"??? ?????? ? ?????? ?????????. ??????? ST_SameAlignment() ? \"??????????\" " "???????? ? ???????????? PostgreSQL. ?? ???????, ?? ???? ?????? ??????? ????? " "??? ????, ?? ??????? SUM() ? AVG()." @@ -38602,8 +38602,8 @@ msgid "" "to disable directory scanning." msgstr "" "??? ???????? ???? ????????? GDAL ????? ???????? ?????? ??????????: GDAL_DISABLE_READDIR_ON_OPEN. " +"xlink:href=\"https://gdal.org/user/configoptions.html#config-" +"GDAL_DISABLE_READDIR_ON_OPEN\">GDAL_DISABLE_READDIR_ON_OPEN. " "?????????? GDAL_DISABLE_READDIR_ON_OPEN ?? TRUE, ??? ???????? ?????????? ?????????." @@ -38662,8 +38662,8 @@ msgid "" "emphasis> in Ubuntu environments)." msgstr "" "???????????? ?????? ? ???????? ???????????? PostgreSQL: max_files_per_process. ?? " +"xlink:href=\"https://www.postgresql.org/docs/current/static/runtime-config-" +"resource.html#GUC-MAX-FILES-PER-PROCESS\">max_files_per_process. ?? " "????????????? ??????????? ???????? 1000, ?? ? ??????? ??????? ??? Out-DB " "Rasters. ????????? ?????????? ????????? ???? ???? 65536, ??? ?? ????????? " "???????? ??? ????? ??????? ????? ? ???????, ?? ??????????? ??? ??? ??????? " @@ -38925,7 +38925,7 @@ msgid "" "ST_Contains(B,A) = true, then the two geometries must be " "topologically equal (ST_Equals(A,B) = true)." msgstr "" -"?????????? ????????? ? ????????????: ????? ????????? ??????? ???? ????. (?? " +"?????????? \"???????\" ? ????????????: ????? ????????? ??????? ???? ????. (?? " "??????? ??? ?????, ? ????????? " "????????? ?? ??????? ???? ???? ???????? ?????). " "?????????? ? ???????????????: ???? ST_Contains(A,B) = true ? " @@ -38955,8 +38955,8 @@ msgstr "" "???????? ????????? ??????? ??????? ???? ??????? ?????, ???????? ?????????? " "??????? ? ????, ?? ???????? ?? ????? ?? ??????? ????? " "?? ?????, ?? ???????? ?????? ? ????? ?????. ??? ????????? ?????????? " -"?????????? ???. ??????? OGC Covers, Contains, " +"?????????? ???. ??????? OGC Covers, Contains, " "Within. ???????? ?????????? ????? " "????????? ??????????." @@ -39001,7 +39001,7 @@ msgid "" "NOTE: this is the \"allowable\" version that returns a boolean, not an " "integer." msgstr "" -"????????: ?? ??????????? ??????, ??? ???????? ??????? ????????, ? ?? ???? " +"????????: ?? \"?????????\" ??????, ??? ???????? ??????? ????????, ? ?? ???? " "?????." #. Tag: para ----------------------------------------------------------------------- Summary of changes: doc/po/uk/postgis-manual.po | 170 ++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 85 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Oct 10 13:02:35 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 10 Oct 2025 13:02:35 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-133-gd1c28c62c Message-ID: <20251010200235.E645819913F@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via d1c28c62c4c5de585a11c6b07cd34e7576546d09 (commit) from 87f1ded8cf25763cdf9f15142bb1219abcce2a57 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d1c28c62c4c5de585a11c6b07cd34e7576546d09 Author: Sandro Santilli Date: Fri Oct 10 21:59:20 2025 +0200 Be safe about expanding $@ diff --git a/doc/po/fix_broken_xml.sh b/doc/po/fix_broken_xml.sh index 6f3f23644..34590d651 100755 --- a/doc/po/fix_broken_xml.sh +++ b/doc/po/fix_broken_xml.sh @@ -1,17 +1,17 @@ #!/bin/sh # Fix malformed entities -perl -pi -e 's/&([#a-z_0-9]+)[^#a-z0-9;]+;/&\1;/g' $@ +perl -pi -e 's/&([#a-z_0-9]+)[^#a-z0-9;]+;/&\1;/g' "$@" # Fix malformed CDATA -perl -pi -e 's/<[^[>\\]*!\[CDATA\[/\\]*!\[CDATA\[/ References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.accd8688dde41a7c0ef9279404ac2d0b@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): Oh, does this do the same thing with ST_Intersects? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 10 13:49:55 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 10 Oct 2025 20:49:55 -0000 Subject: [PostGIS] #5974: Add matching finishGEOS() to all initGEOS() In-Reply-To: <050.80d7c2bb0a0771a25af4668425153a09@osgeo.org> References: <050.80d7c2bb0a0771a25af4668425153a09@osgeo.org> Message-ID: <065.16b22527d0d5596dadf3e44b4c735e7b@osgeo.org> #5974: Add matching finishGEOS() to all initGEOS() --------------------------+--------------------------- Reporter: ezimanyi | Owner: pramsey Type: enhancement | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: --------------------------+--------------------------- Comment (by pramsey): No, the initGEOS() call checks the global "handle" and if it's non-null is creates one on the heap. Subsequent calls find a non-null value and do not bother. So that first initialization is shared by all subsequent calls to initGEOS by that backend. Which could be a lot of calls. This is why sticking a finishGEOS at the end of every function call is not necessarily a grand idea. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 10 22:49:53 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 11 Oct 2025 05:49:53 -0000 Subject: [PostGIS] #6002: PostGIS 3.6 and 3.5 PDF mauals giving a 404 Message-ID: <046.945d71078d52e97fb078534d3791bcc0@osgeo.org> #6002: PostGIS 3.6 and 3.5 PDF mauals giving a 404 ---------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: new Priority: medium | Milestone: Website Management, Bots Component: documentation | Version: 3.5.x Keywords: | ---------------------------+-------------------------------------- As noted in https://lists.osgeo.org/pipermail/postgis- users/2025-October/046928.html https://postgis.net/documentation/manual/ The pdf links for 3.5 and 3.6 point at https://postgis.net/stuff/postgis-3.6.pdf and https://postgis.net/stuff/postgis-3.5.pdf They should be pointing at https://postgis.net/stuff/postgis-3.6-en.pdf https://postgis.net/stuff/postgis-3.5-en.pdf or we can put in a redirect I guess so the reference without en redirects to en. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Sat Oct 11 12:44:57 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 11 Oct 2025 19:44:57 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.202d66a2e043ffc8ecd61b6eecd3aff2@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------- Reporter: nti | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------- Comment (by endafarrell): Hi all. I too was affected by this. We had created a "standardizer" for our usage of the data as we often create GeoJSON, and we have points, linestrings, polygons and multi-variants of all, and so we had this function in our app: {{{ CREATE OR REPLACE FUNCTION public.App_AsText(geom geometry) RETURNS text LANGUAGE 'plpgsql' IMMUTABLE LEAKPROOF PARALLEL SAFE AS $BODY$ BEGIN RETURN ST_AsText(ST_ForcePolygonCCW(ST_Force2D(geom)), 6) END $BODY$; }}} An example of what happens is this linestring: {{{ LINESTRING(13.2786 52.50159,13.27841 52.50167,13.27812 52.50174,13.27782 52.50179,13.27747 52.50181,13.27721 52.50164) }}} is reversed: {{{ spatialindex=> select ST_AsText(st_forcepolygonccw('LINESTRING(13.2786 52.50159,13.27841 52.50167,13.27812 52.50174,13.27782 52.50179,13.27747 52.50181,13.27721 52.50164)')); st_astext ------------------------------------------------------------------------------------------------------------------------ LINESTRING(13.27721 52.50164,13.27747 52.50181,13.27782 52.50179,13.27812 52.50174,13.27841 52.50167,13.2786 52.50159) (1 row) spatialindex=> }}} We're still on last year's versions: {{{ spatialindex=> select version(); version ---------------------------------------------------------------------------------------------------------------- PostgreSQL 17.6 on aarch64-unknown-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit (1 row) spatialindex=> select postgis_version(); postgis_version --------------------------------------- 3.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1 (1 row) }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Sat Oct 11 15:58:13 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 11 Oct 2025 22:58:13 -0000 Subject: [PostGIS] #6003: unknown conversion warning in lwgeom under mingw64/msys2 gcc 13.2 Message-ID: <046.af1e8163b07c9a3c6d2c1916c460f2e6@osgeo.org> #6003: unknown conversion warning in lwgeom under mingw64/msys2 gcc 13.2 ---------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Keywords: windows | ---------------------+--------------------------- I'm noticing these warnings. They might have been there with my old chain too, maybe I'm just paying more attention now to these since upgrading my chain. {{{ ptarray.c: In function 'ptarray_addPoint': ptarray.c:541:75: warning: unknown conversion type character 'z' in format [-Wformat=] 541 | lwerror("ptarray_addPoint: point dimension out of range (%zu)", | ^ ptarray.c:541:25: warning: too many arguments for format [-Wformat-extra- args] 541 | lwerror("ptarray_addPoint: point dimension out of range (%zu)", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lwgeom_api.c: In function 'printPA': lwgeom_api.c:455:56: warning: unknown conversion type character 'z' in format [-Wformat=] 455 | lwnotice(" ndims=%i, ptsize=%zu", | ^ lwgeom_api.c:455:18: warning: too many arguments for format [-Wformat- extra-args] 455 | lwnotice(" ndims=%i, ptsize=%zu", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }}} All tests regress even topology ones so not sure it's anything to worry about -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Sat Oct 11 16:05:14 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 11 Oct 2025 23:05:14 -0000 Subject: [PostGIS] #6003: unknown conversion warning in lwgeom under mingw64/msys2 gcc 13.2 In-Reply-To: <046.af1e8163b07c9a3c6d2c1916c460f2e6@osgeo.org> References: <046.af1e8163b07c9a3c6d2c1916c460f2e6@osgeo.org> Message-ID: <061.0ddc6ec064d45bee8256c417e09555da@osgeo.org> #6003: unknown conversion warning in lwgeom under mingw64/msys2 gcc 13.2 ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: low | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: windows ----------------------+--------------------------- Comment (by robe): This seems to be a common issue with mingw64. So other references to the issue in other projects such as in QT- https://bugreports.qt.io/browse/QTBUG-70030 VHDL compiler and simulator -- https://github.com/nickg/nvc/issues/525 The suggestion is it has to do with msvcrt which is pegged at c89 or some such thing and can be worked around by forcing __USE_MINGW_ANSI_STDIO 1. I haven't given that a try to see if it resolves the issue. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sat Oct 11 16:12:04 2025 From: git at osgeo.org (git at osgeo.org) Date: Sat, 11 Oct 2025 16:12:04 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-134-g5dc95f1bc Message-ID: <20251011231205.2F08516AD6A@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 5dc95f1bc3047b048128616d4543b603b8bbdca7 (commit) from d1c28c62c4c5de585a11c6b07cd34e7576546d09 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5dc95f1bc3047b048128616d4543b603b8bbdca7 Author: Regina Obe Date: Sat Oct 11 19:11:57 2025 -0400 Winnie upgrade default json and pcre2 versions diff --git a/ci/winnie/winnie_common.sh b/ci/winnie/winnie_common.sh index d375cbec6..e9876a684 100644 --- a/ci/winnie/winnie_common.sh +++ b/ci/winnie/winnie_common.sh @@ -21,18 +21,21 @@ if [[ "${OVERRIDE}" == '' ]] ; then export ZLIB_VER=1.2.13 export PROTOBUF_VER=3.2.0 export PROTOBUFC_VER=1.2.1 - export JSON_VER=0.12 + export JSON_VER=0.16 export PROJSO=libproj_8_2.dll export LZ4_VER=1.9.3 fi; if [[ ${PCRE_VER} == '' ]]; then - PCRE_VER=10.40 + PCRE_VER=10.42 fi; export PROTOBUF_VER=3.2.0 export PROTOBUFC_VER=1.2.1 -export JSON_VER=0.12 + +if [[ ${JSON_VER} == '' ]]; then + export JSON_VER=0.16 +fi; ----------------------------------------------------------------------- Summary of changes: ci/winnie/winnie_common.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Sun Oct 12 15:49:46 2025 From: trac at osgeo.org (PostGIS) Date: Sun, 12 Oct 2025 22:49:46 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.d165d951ab1ca07031347799d312aa42@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by pramsey): * milestone: => PostGIS 3.4.5 * priority: medium => high -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sun Oct 12 22:16:53 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 12 Oct 2025 22:16:53 -0700 (PDT) Subject: [SCM] postgis.net branch website updated. clarity-final-156-gb76b285 Message-ID: <20251013051653.BC54019D415@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "postgis.net". The branch, website has been updated via b76b2855c927dc8fa370b5f5a53616e87373c5b2 (commit) from 270c679d3dd4ed57d45dbffdf92f6b0c81f9854f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b76b2855c927dc8fa370b5f5a53616e87373c5b2 Author: Regina Obe Date: Mon Oct 13 01:16:08 2025 -0400 Fix for doc pds 3.5+ links now having lang tab Closes https://trac.osgeo.org/postgis/ticket/6002 diff --git a/layouts/shortcodes/doclinks.html b/layouts/shortcodes/doclinks.html index f4dc882..429f0ee 100644 --- a/layouts/shortcodes/doclinks.html +++ b/layouts/shortcodes/doclinks.html @@ -42,7 +42,7 @@  {{ . }} {{ end }} - +
  • tiger_geocoder:  {{ range $.Site.Params.docLanguages }}  {{ . }} @@ -56,7 +56,7 @@ {{ if ( and (ne .is_dev true) (eq $ver "stable") (ne .eol true ) ) }}
  • PostGIS {{ $key }} ( HTML - | PDF + | PDF | EPUB )
  • {{ end }} ----------------------------------------------------------------------- Summary of changes: layouts/shortcodes/doclinks.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- postgis.net From trac at osgeo.org Sun Oct 12 22:21:23 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 13 Oct 2025 05:21:23 -0000 Subject: [PostGIS] #6002: PostGIS 3.6 and 3.5 PDF mauals giving a 404 In-Reply-To: <046.945d71078d52e97fb078534d3791bcc0@osgeo.org> References: <046.945d71078d52e97fb078534d3791bcc0@osgeo.org> Message-ID: <061.58a3bbeedf68324be035b8c858895202@osgeo.org> #6002: PostGIS 3.6 and 3.5 PDF mauals giving a 404 ----------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: Website Management, Bots Component: documentation | Version: 3.5.x Resolution: fixed | Keywords: ----------------------------+-------------------------------------- Changes (by robe): * resolution: => fixed * status: new => closed Comment: Revised to do a hugo conditional so it tacks on an -en for postgis 3.5 and above. Committed at https://gitea.osgeo.org/postgis/postgis.net/commit/b76b2855c927dc8fa370b5f5a53616e87373c5b2 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Sun Oct 12 22:30:21 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 13 Oct 2025 05:30:21 -0000 Subject: [PostGIS] #5974: Add matching finishGEOS() to all initGEOS() In-Reply-To: <050.80d7c2bb0a0771a25af4668425153a09@osgeo.org> References: <050.80d7c2bb0a0771a25af4668425153a09@osgeo.org> Message-ID: <065.0b125c353c5813ccc086a5e4425b4846@osgeo.org> #5974: Add matching finishGEOS() to all initGEOS() --------------------------+--------------------------- Reporter: ezimanyi | Owner: pramsey Type: enhancement | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: --------------------------+--------------------------- Comment (by robe): @ezimanyi Perhaps we need to rename this ticket as https://github.com/postgis/postgis/pull/826 doesn't seem to have anything to do with initGEOS finishGEOS or at least not anymore and there is no other PR from you just a pointing at your branch commit https://github.com/MobilityDB/postgis/commit/923c304394755ea31392970aaf38ea1d4d934d86 which doesn't count as a pull request or was your intent to have this as a pull request? At anyrate I think as @pramsey mentioned initGEOS/finishGEOS is a no go. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sun Oct 12 23:19:02 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 12 Oct 2025 23:19:02 -0700 (PDT) Subject: [SCM] postgis.net branch website updated. clarity-final-157-g582c905 Message-ID: <20251013061902.AC37119EA17@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "postgis.net". The branch, website has been updated via 582c9058567f96623dbbef8eef56342bd22e0f67 (commit) from b76b2855c927dc8fa370b5f5a53616e87373c5b2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 582c9058567f96623dbbef8eef56342bd22e0f67 Author: Regina Obe Date: Mon Oct 13 02:18:56 2025 -0400 Notes about release of PostGIS 3.6.0 bundle for postgresql 18 diff --git a/content/documentation/getting_started/install_windows/released_versions.md b/content/documentation/getting_started/install_windows/released_versions.md index b2e93bd..bb6d0d8 100644 --- a/content/documentation/getting_started/install_windows/released_versions.md +++ b/content/documentation/getting_started/install_windows/released_versions.md @@ -6,10 +6,12 @@ geekdocHidden: true geekdocHiddenTocTree: false --- -PostGIS 3.6.0 came out Sept 2nd, 2025. Windows PostGIS Bundle 3.6.0 installers for PostgreSQL 18 was released Oct 5th 2025. +PostGIS 3.6.0 came out Sept 2nd, 2025. Windows PostGIS Bundle 3.6.0 installers for PostgreSQL 18 was last released Oct 13th 2025. Binaries for versions of PostgreSQL 13-18 (64-bit) available in `Unreleased PostGIS Versions` and [OSGeo downloads][5]). Installers for 18(64-bit) available on [OSGeo downloads][5] and application stackbuilder. -Installers for PostgreSQL 13-17 will be available later. +Installers for PostgreSQL 13-17 will be available when PostGIS 3.6.1 comes out. + +Note that this version does not include shp2pgsql-gui. We plan to include this in the 3.6.1 release after fixing some issues. PostGIS 3.6.0 bundle includes: @@ -17,11 +19,9 @@ PostGIS 3.6.0 bundle includes: * PostGIS Tiger geocoder extension - Tiger 2024 * pgRouting 4.0 [pgRouting 4.0.0-alpha](https://docs.pgrouting.org/4.0/en/index.html) * Commandline raster loader (raster2pgsql), shapefile import/export (shp2pgsql,pgsql2shp) - * Commandline [osm2pgrouting 2.3.8](https://github.com/pgRouting/osm2pgrouting/wiki/Documentation-for-osm2pgrouting-v2.3) for loading data from .osm files into pgRouting routable format - * GUI: shp2pgsql-gui which has both import and export support for geometry/geography + * Commandline [osm2pgrouting main](https://github.com/pgRouting/osm2pgrouting/wiki/Documentation-for-osm2pgrouting-v2.3) for loading data from .osm files into pgRouting routable format * [ogrfdw 1.1.7](https://github.com/pramsey/pgsql-ogr-fdw/releases/tag/v1.1.7) - spatial foreign data wrapper for reading both spatial (spatial columns become postgis geometry) and non-spatial data. [IMPORT FOREIGN SCHEMA](http://www.postgresonline.com/journal/archives/359-Import-Foreign-Schema-for-ogr_fdw-for-PostgreSQL-9.5.html) support - New features in 1.1 - `character_encoding` option and utility functions `ogr_fdw_drivers()`, `ogr_fdw_version()`. * [GDAL 3.9.2](https://gdal.org/download.html#current-releases) with OpenJPEG 2.5.20 (JPEG 2000), ODBC, Curl, SQLite3 (for GeoPackage and OSM support), excel (XLS) (via FreeXL 1.0.6), libreoffice, XLSX spreadsheet (via expat), Arrow 13.0 for Arrow, Parquet, and GeoParquet support (used by both PostGIS raster and ogrfdw) * [pgpointcloud](https://github.com/pgpointcloud/pointcloud) 1.2.5 ----------------------------------------------------------------------- Summary of changes: .../getting_started/install_windows/released_versions.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- postgis.net From trac at osgeo.org Tue Oct 14 06:32:41 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 14 Oct 2025 13:32:41 -0000 Subject: [PostGIS] #5974: Add matching finishGEOS() to all initGEOS() In-Reply-To: <050.80d7c2bb0a0771a25af4668425153a09@osgeo.org> References: <050.80d7c2bb0a0771a25af4668425153a09@osgeo.org> Message-ID: <065.4c1b28ff18cd32330f6bfe7e57c1e2bb@osgeo.org> #5974: Add matching finishGEOS() to all initGEOS() --------------------------+--------------------------- Reporter: ezimanyi | Owner: pramsey Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: --------------------------+--------------------------- Changes (by ezimanyi): * resolution: => invalid * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 07:10:20 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 14 Oct 2025 14:10:20 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.e73f1ee48af9b71457083803a447e260@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by dbaston): I was thinking of adding "remove small parts" to GEOS, it's commonly- needed as a follow-up to aggressive coverage simplification: [[Image(https://private-user- images.githubusercontent.com/6318931/500986049-4b4caec7-823d-4697-a5a8-05dd625113b2.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NjA0NTExNTUsIm5iZiI6MTc2MDQ1MDg1NSwicGF0aCI6Ii82MzE4OTMxLzUwMDk4NjA0OS00YjRjYWVjNy04MjNkLTQ2OTctYTVhOC0wNWRkNjI1MTEzYjIucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MTAxNCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTEwMTRUMTQwNzM1WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZDFmYjQ0MzEyZmRiOTA2ZDE5MzM2ODI3OWFjN2NmOWQ4ZWE1YWVlNTFhNDk4NWZkZTg5ZjYxNzYxNDI3MDA0MiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.6uTAVnhxvp46QUokBh6XXGHuZ229J6mfouyS6RYSFzo)]] Hole removal would really need to be integrated into coverage simplification itself, since we need to know if some other polygon is occupying the hole. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 13:17:36 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 14 Oct 2025 20:17:36 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.effb361d8d8e6d71cbb18293b5b90d6c@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): This seems to be very long-standing, and can be traced to the fact that, while ST_Reverse() reverses all geometry types, the ST_ForcePolygonCW and ST_ForcePolygonCCW functions only reverse polygonal types. And there's logic in the pipe that checks "is this CCW? then reverse it". So polygonal types get handled correctly, and lines get reversed every time. Which is what you're seeing. A quick in-place fix is {{{ CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) RETURNS geometry AS $$ SELECT CASE WHEN ST_GeometryType($1) IN ('ST_Polygon', 'ST_MultiPolygon') THEN ST_Reverse(ST_ForcePolygonCW($1)) ELSE $1 END $$ LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE; }}} A better fix would involve trying to centralize the "should I try and orient this" logic into a single place, as it's currently in 5 places (and more with this temporary fix). Unfortunately it seems there's no way to fix this without changing the SQL definition for ST_ForcePolygonCCW which makes a patch-level fix a "no go", so this will have to be for the 3.7 milestone. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 15:31:30 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 14 Oct 2025 22:31:30 -0000 Subject: [PostGIS] #6004: Looks like debbie's make dist job is not being triggered Message-ID: <046.c2311ab87ae44488beccf331dd84d8d7@osgeo.org> #6004: Looks like debbie's make dist job is not being triggered --------------------------+--------------------------- Reporter: robe | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: QA/buildbots | Version: 3.5.x Keywords: | --------------------------+--------------------------- Last run was 9/3/2025 https://debbie.postgis.net/view/PostGIS/job/PostGIS_Make_Dist/ -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 15:31:40 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 14 Oct 2025 22:31:40 -0000 Subject: [PostGIS] #6004: Looks like debbie's make dist job is not being triggered In-Reply-To: <046.c2311ab87ae44488beccf331dd84d8d7@osgeo.org> References: <046.c2311ab87ae44488beccf331dd84d8d7@osgeo.org> Message-ID: <061.4a36218a0a7d74651cf617bcc615e8ad@osgeo.org> #6004: Looks like debbie's make dist job is not being triggered ---------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: Website Management, Bots Component: QA/buildbots | Version: 3.5.x Resolution: | Keywords: ---------------------------+-------------------------------------- Changes (by robe): * milestone: PostGIS 3.6.1 => Website Management, Bots -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 15:44:23 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 14 Oct 2025 22:44:23 -0000 Subject: [PostGIS] #6004: Looks like debbie's make dist job is not being triggered In-Reply-To: <046.c2311ab87ae44488beccf331dd84d8d7@osgeo.org> References: <046.c2311ab87ae44488beccf331dd84d8d7@osgeo.org> Message-ID: <061.3fbad6b26c9732657dfb662047ea68d3@osgeo.org> #6004: Looks like debbie's make dist job is not being triggered ---------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: closed Priority: blocker | Milestone: Website Management, Bots Component: QA/buildbots | Version: 3.5.x Resolution: fixed | Keywords: ---------------------------+-------------------------------------- Changes (by robe): * resolution: => fixed * status: new => closed Comment: Fixed. Stopped working because of the change of url from git.osgeo.org to gitea.osgeo.org. The regex was set to match git.osgeo.org/gitea/postgis. Changed to match gitea.osgeo.org/postgis -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 18:58:56 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 01:58:56 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.be3cb7e332e724d462449dbdde80f29d@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by robe): > Unfortunately it seems there's no way to fix this without changing the SQL definition for ST_ForcePolygonCCW which makes a patch-level fix a "no go", so this will have to be for the 3.7 milestone. As long as the SQL definition doesn't change the front facing API to user. I think it's fine to change it in a patch-level. We do sql changes to functions all the time in patch releases at the very least in the name of security. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Oct 14 21:45:56 2025 From: git at osgeo.org (git at osgeo.org) Date: Tue, 14 Oct 2025 21:45:56 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-135-gc33c1a582 Message-ID: <20251015044556.74404190CD1@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via c33c1a582e5b468bd54e249b2f54d9ade37bd9e8 (commit) from 5dc95f1bc3047b048128616d4543b603b8bbdca7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c33c1a582e5b468bd54e249b2f54d9ade37bd9e8 Author: Martin Davis Date: Tue Oct 14 19:57:46 2025 -0700 Improve doc for ST_CoverageClean diff --git a/doc/reference_coverage.xml b/doc/reference_coverage.xml index a98c58427..5906b40a4 100644 --- a/doc/reference_coverage.xml +++ b/doc/reference_coverage.xml @@ -116,6 +116,95 @@ SELECT true = ALL ( + + + ST_CoverageClean + + Computes a clean (edge matched, non-overlapping, gap-cleared) polygonal coverage, given a non-clean input. + + + + + + geometry ST_CoverageClean + geometry winset + geom + float8 + gapMaximumWidth = 0 + float8 + snappingDistance = -1 + text + overlapMergeStrategy = 'MERGE_LONGEST_BORDER' + + + + + + Description + + A window function which adjusts the edges of a polygonal dataset to ensure that none of the polygons overlap, narrow gaps are removed, and shared edges are identically noded. + The result is a clean coverage that will pass validation by + and can be input to coverage processing functions. + + gapMaximumWidth controls the cleaning of gaps between polygons. Gaps with width less than this distance are merged into an adjacent polygon. + snappingDistance controls snapping of close vertices and edges. The default setting (-1) use an automatic snapping distance based on the input. Set to 0.0 to turn off snapping. + overlapMergeStrategy specifies how overlapping areas are merged into an adjacent polygon: + + + + MERGE_LONGEST_BORDER - merges into polygon with longest common border + + + MERGE_MAX_AREA - merges into polygon with maximum area + + + MERGE_MIN_AREA - merges into polygon with minimum area + + + MERGE_MIN_INDEX - merges into polygon with smallest input index (defined by order of input polygons) + + + + Availability: 3.6.0 - requires GEOS >= 3.14.0 + + + + Examples + + -- Populate demo table +CREATE TABLE example AS SELECT * FROM (VALUES + (1, 'POLYGON ((10 190, 30 160, 40 110, 100 70, 120 10, 10 10, 10 190))'::geometry), + (2, 'POLYGON ((100 190, 10 190, 30 160, 40 110, 50 80, 74 110.5, 100 130, 140 120, 140 160, 100 190))'::geometry), + (3, 'POLYGON ((140 190, 190 190, 190 80, 140 80, 140 190))'::geometry), + (4, 'POLYGON ((180 40, 120 10, 100 70, 140 80, 190 80, 180 40))'::geometry) +) AS v(id, geom); + +-- Prove it is a dirty coverage +SELECT ST_AsText(ST_CoverageInvalidEdges(geom) OVER ()) + FROM example; + +-- Clean the coverage +CREATE TABLE example_clean AS + SELECT id, ST_CoverageClean(geom) OVER () AS GEOM + FROM example; + +-- Prove it is a clean coverage +SELECT ST_AsText(ST_CoverageInvalidEdges(geom) OVER ()) + FROM example_clean; + + + + + See Also + + , + , + , + + + + + @@ -312,82 +401,4 @@ MULTIPOLYGON (((10 150, 80 190, 110 150, 140 80, 120 10, 10 10, 10 150), (50 60, - - - - - - ST_CoverageClean - - Computes a clean (edge matched, non-overlapping, gap-cleared) polygonal coverage, given a non-clean input. - - - - - - geometry ST_CoverageClean - geometry winset - geom - float8 - gapMaximumWidth = 0 - float8 - snappingDistance = -1 - text - overlapMergeStrategy = 'MERGE_LONGEST_BORDER' - - - - - - Description - - A window function which alters the edges of a polygonal coverage to ensure that none of the polygons overlap, that small gaps are snapped away, and that all shared edges are exactly identical. The result is a clean coverage that will pass validation tests like - The gapMaximumWidth controls the cleaning of gaps between polygons. Gaps smaller than this tolerance will be closed. - The snappingDistance controls the node snapping step, when nearby vertices are snapped together. The default setting (-1) applies an automatic snapping distance based on an analysis of the input. Set to 0.0 to turn off all snapping. - The overlapMergeStrategy controls the algorithm used to determine which neighboring polygons to merge overlapping areas into. - MERGE_LONGEST_BORDER chooses polygon with longest common border - MERGE_MAX_AREA chooses polygon with maximum area - MERGE_MIN_AREA chooses polygon with minimum area - MERGE_MIN_INDEX chooses polygon with smallest input index - - Availability: 3.6.0 - requires GEOS >= 3.14.0 - - - - Examples - - -- Populate demo table -CREATE TABLE example AS SELECT * FROM (VALUES - (1, 'POLYGON ((10 190, 30 160, 40 110, 100 70, 120 10, 10 10, 10 190))'::geometry), - (2, 'POLYGON ((100 190, 10 190, 30 160, 40 110, 50 80, 74 110.5, 100 130, 140 120, 140 160, 100 190))'::geometry), - (3, 'POLYGON ((140 190, 190 190, 190 80, 140 80, 140 190))'::geometry), - (4, 'POLYGON ((180 40, 120 10, 100 70, 140 80, 190 80, 180 40))'::geometry) -) AS v(id, geom); - --- Prove it is a dirty coverage -SELECT ST_AsText(ST_CoverageInvalidEdges(geom) OVER ()) - FROM example; - --- Clean the coverage -CREATE TABLE example_clean AS - SELECT id, ST_CoverageClean(geom) OVER () AS GEOM - FROM example; - --- Prove it is a clean coverage -SELECT ST_AsText(ST_CoverageInvalidEdges(geom) OVER ()) - FROM example_clean; - - - - - See Also - - , - - - - - - -
    ----------------------------------------------------------------------- Summary of changes: doc/reference_coverage.xml | 167 ++++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 78 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 14 21:56:38 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 04:56:38 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.a8270a8fee65b24f2b328e1cf7c0e6ba@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by mdavis): Replying to [comment:2 pramsey]: > Erm, once you start adding extra params onto an existing function, the "might as well have a new function" starts to kick in; bonus points if the other mode involves a completely separate code line. Why would this require extra parameters? The doc for `ST_RemoveSmallParts` says that it removes interior rings as well. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 14 21:58:31 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 04:58:31 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.f15c2048875abf563af177a183b38545@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by mdavis): Replying to [comment:3 dbaston]: > Hole removal would really need to be integrated into coverage simplification itself, since we need to know if some other polygon is occupying the hole. Yes, it needs to be integrated with coverage simplification, to ensure it produces a correct coverage result. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 04:26:10 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 11:26:10 -0000 Subject: [PostGIS] #6005: ST_ProjectionBounds(:srid) function Message-ID: <046.8f0eea109a6fd8fc7b912eade58a2b6f@osgeo.org> #6005: ST_ProjectionBounds(:srid) function -------------------------+--------------------------- Reporter: strk | Owner: pramsey Type: enhancement | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Keywords: | -------------------------+--------------------------- It's sometimes useful to pass an extent that's known to contain all the data of a given dataset to some function that takes a bounding box parameter, but constructing such bounding box is not always practical. It could be min-double, max-double I guess but such a bbox geometry might be invalid for a given projection so I thought a function that returns the largest bounding box geometry valid for a given SRS could be useful. Proj does have such functionality: https://proj.org/en/stable/development/reference/functions.html#c.proj_get_area_of_use -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 06:58:43 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 13:58:43 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.05b7af509d93ceee8579807455fe1dfe@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by strk): I believe this is another effect of the same bug: {{{ strk=# select geometrytype(tg) from public.com01012025_wgs84 limit 2; geometrytype -------------- UNEXPECTED UNEXPECTED (2 rows) }}} Those TopoGeometry objects have feature_type=3 but I'm afraid the int64 change made PostgreSQL read past the bounds of the actual data, as I anticipated in https://gitea.osgeo.org/postgis/postgis/pulls/242#issuecomment-13471 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 07:17:37 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 14:17:37 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.08b0b30535170f56c20d426677224210@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by strk): I can't think of any 100% effective way to fix the corruption introduced by the upgrade to 3.6.0. I wouldn't know how we can tell which data was created BEFORE the catalog update and which data was created AFTER it, unless we can compare the transaction identifiers between the rows in the tables and the domain catalog row ? Or we could use some fuzzy logic to check if any data value would be invalid, and bet on that being caused by the corruption. Maybe we should retire 3.6.0 and make an announcement recommending anyone who already upgraded to get back to 3.5.x from backups, if they still can ... -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 09:30:29 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 16:30:29 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.363a89019f8f91283ef544dc9b1e8a77@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Replying to [comment:12 strk]: > I can't think of any 100% effective way to fix the corruption introduced by the upgrade to 3.6.0. > > I wouldn't know how we can tell which data was created BEFORE the catalog update and which data was created AFTER it, unless we can compare the transaction identifiers between the rows in the tables and the domain catalog row ? > > Or we could use some fuzzy logic to check if any data value would be invalid, and bet on that being caused by the corruption. > > Maybe we should retire 3.6.0 and make an announcement recommending anyone who already upgraded to get back to 3.5.x from backups, if they still can ... I'm suspecting very few people are using the bigint feature, so we might be able to fix simply by updating the catalog back to what it was. Going to test that theory out. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 15 10:01:14 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 15 Oct 2025 10:01:14 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-137-g976adccb9 Message-ID: <20251015170114.BEC6C19CB36@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 976adccb9b11f9f47da2aafe0e524d3207c08914 (commit) via dba29bac7b4d2a58730953dad939e5dafd28b78b (commit) from c33c1a582e5b468bd54e249b2f54d9ade37bd9e8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 976adccb9b11f9f47da2aafe0e524d3207c08914 Merge: c33c1a582 dba29bac7 Author: Paul Ramsey Date: Wed Oct 15 10:01:06 2025 -0700 Merge branch 'master-5754' commit dba29bac7b4d2a58730953dad939e5dafd28b78b Author: Paul Ramsey Date: Wed Oct 15 09:14:37 2025 -0700 ST_ForcePolygonCCW unexpectedly reverses non-polygonal geometries too, references #5754 diff --git a/liblwgeom/cunit/cu_gserialized1.c b/liblwgeom/cunit/cu_gserialized1.c index 47fb42e02..f0c3dc1b1 100644 --- a/liblwgeom/cunit/cu_gserialized1.c +++ b/liblwgeom/cunit/cu_gserialized1.c @@ -751,8 +751,9 @@ static void test_lwgeom_force_clockwise(void) /* counterclockwise, must be reversed */ geom = lwgeom_from_wkt("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))", LW_PARSER_CHECK_NONE); - CU_ASSERT_FALSE(lwgeom_is_clockwise(geom)); + CU_ASSERT(lwgeom_has_orientation(geom,LW_COUNTERCLOCKWISE)); lwgeom_force_clockwise(geom); + CU_ASSERT(lwgeom_has_orientation(geom,LW_CLOCKWISE)); in_ewkt = "POLYGON((0 0,0 10,10 10,10 0,0 0))"; out_ewkt = lwgeom_to_ewkt(geom); if (strcmp(in_ewkt, out_ewkt)) @@ -763,8 +764,9 @@ static void test_lwgeom_force_clockwise(void) /* clockwise, fine as is */ geom = lwgeom_from_wkt("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", LW_PARSER_CHECK_NONE); - CU_ASSERT_TRUE(lwgeom_is_clockwise(geom)); + CU_ASSERT(lwgeom_has_orientation(geom,LW_CLOCKWISE)); lwgeom_force_clockwise(geom); + CU_ASSERT(lwgeom_has_orientation(geom,LW_CLOCKWISE)); in_ewkt = "POLYGON((0 0,0 10,10 10,10 0,0 0))"; out_ewkt = lwgeom_to_ewkt(geom); if (strcmp(in_ewkt, out_ewkt)) @@ -775,8 +777,8 @@ static void test_lwgeom_force_clockwise(void) /* counterclockwise shell (must be reversed), mixed-wise holes */ geom = lwgeom_from_wkt("POLYGON((0 0,10 0,10 10,0 10,0 0),(2 2,2 4,4 2,2 2),(6 2,8 2,8 4,6 2))", LW_PARSER_CHECK_NONE); - CU_ASSERT_FALSE(lwgeom_is_clockwise(geom)); lwgeom_force_clockwise(geom); + CU_ASSERT(lwgeom_has_orientation(geom,LW_CLOCKWISE)); in_ewkt = "POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 2,2 4,2 2),(6 2,8 2,8 4,6 2))"; out_ewkt = lwgeom_to_ewkt(geom); if (strcmp(in_ewkt, out_ewkt)) @@ -785,10 +787,11 @@ static void test_lwgeom_force_clockwise(void) lwfree(out_ewkt); lwgeom_free(geom); - /* clockwise shell (fine), mixed-wise holes */ + /* clockwise shell (fine), mixed-wise holes, so not oriented */ geom = lwgeom_from_wkt("POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 2,2 4,2 2),(6 2,8 4,8 2,6 2))", LW_PARSER_CHECK_NONE); - CU_ASSERT_FALSE(lwgeom_is_clockwise(geom)); + /* fix it and then it is oriented */ lwgeom_force_clockwise(geom); + CU_ASSERT(lwgeom_has_orientation(geom,LW_CLOCKWISE)); in_ewkt = "POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 2,2 4,2 2),(6 2,8 2,8 4,6 2))"; out_ewkt = lwgeom_to_ewkt(geom); if (strcmp(in_ewkt, out_ewkt)) @@ -803,10 +806,11 @@ static void test_lwgeom_force_clockwise(void) geom = lwgeom_from_hexwkb(in_ewkt, LW_PARSER_CHECK_NONE); geom2 = lwgeom_from_hexwkb(in_ewkt, LW_PARSER_CHECK_NONE); lwgeom_force_clockwise(geom2); + CU_ASSERT(lwgeom_has_orientation(geom,LW_CLOCKWISE)); /** use same check instead of strcmp to account for difference in endianness **/ - CU_ASSERT( lwgeom_same(geom, geom2) ); + CU_ASSERT(lwgeom_same(geom, geom2)); lwgeom_free(geom); lwgeom_free(geom2); } diff --git a/liblwgeom/liblwgeom.h.in b/liblwgeom/liblwgeom.h.in index 54eb1e7ed..752569540 100644 --- a/liblwgeom/liblwgeom.h.in +++ b/liblwgeom/liblwgeom.h.in @@ -1379,10 +1379,12 @@ extern int lwgeom_startpoint(const LWGEOM* lwgeom, POINT4D* pt); extern void interpolate_point4d(const POINT4D *A, const POINT4D *B, POINT4D *I, double F); /** -* Ensure the outer ring is clockwise oriented and all inner rings -* are counter-clockwise. +* Tests that geometry is oriented LW_CLOCKWISE or LW_COUNTERCLOCKWISE. +* Ensure the outer ring is oriented and all inner rings +* are anti-oriented. Returns LW_TRUE for oriented or non-orientable (empty +* or non-polygonal geometry) and LW_FALSE for misoriented. */ -extern int lwgeom_is_clockwise(LWGEOM *lwgeom); +extern int lwgeom_has_orientation(const LWGEOM *lwgeom, int orientation); /** @@ -1427,6 +1429,7 @@ extern void lwgeom_grid_in_place(LWGEOM *lwgeom, gridspec *grid); extern void lwgeom_reverse_in_place(LWGEOM *lwgeom); extern void lwgeom_force_clockwise(LWGEOM *lwgeom); +extern void lwgeom_force_counterclockwise(LWGEOM *lwgeom); extern void lwgeom_longitude_shift(LWGEOM *lwgeom); extern int lwgeom_simplify_in_place(LWGEOM *igeom, double dist, int preserve_collapsed); extern void lwgeom_affine(LWGEOM *geom, const AFFINE *affine); diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index 04a3504e2..39baf8032 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -157,6 +157,13 @@ #define LW_BOUNDARY 0 #define LW_OUTSIDE -1 +/** +* Constants for orientation checking and forcing +*/ +#define LW_CLOCKWISE 1 +#define LW_NONE 0 +#define LW_COUNTERCLOCKWISE -1 + /* * Internal prototypes */ @@ -361,12 +368,13 @@ LWCOLLECTION *lwcollection_clone_deep(const LWCOLLECTION *lwgeom); GBOX *gbox_clone(const GBOX *gbox); /* -* Clockwise +* Orientation (LW_CLOCKWISE and LW_COUNTERCLOCKWISE) */ -void lwpoly_force_clockwise(LWPOLY *poly); -void lwtriangle_force_clockwise(LWTRIANGLE *triangle); -int lwpoly_is_clockwise(LWPOLY *poly); -int lwtriangle_is_clockwise(LWTRIANGLE *triangle); +void lwpoly_force_orientation(LWPOLY *poly, int orientation); +void lwtriangle_force_orientation(LWTRIANGLE *triangle, int orientation); +int lwpoly_has_orientation(const LWPOLY *poly, int orientation); +int lwtriangle_has_orientation(const LWTRIANGLE *triangle, int orientation); +int ptarray_has_orientation(const POINTARRAY *pa, int orientation); int ptarray_isccw(const POINTARRAY *pa); /* diff --git a/liblwgeom/lwgeom.c b/liblwgeom/lwgeom.c index 6697186d8..a2d65dc0f 100644 --- a/liblwgeom/lwgeom.c +++ b/liblwgeom/lwgeom.c @@ -33,61 +33,89 @@ #define out_stack_size 32 -/** Force Right-hand-rule on LWGEOM polygons **/ -void -lwgeom_force_clockwise(LWGEOM *lwgeom) -{ - LWCOLLECTION *coll; - uint32_t i; - switch (lwgeom->type) - { - case POLYGONTYPE: - lwpoly_force_clockwise((LWPOLY *)lwgeom); - return; - - case TRIANGLETYPE: - lwtriangle_force_clockwise((LWTRIANGLE *)lwgeom); - return; - - /* Not handle POLYHEDRALSURFACE and TIN - as they are supposed to be well oriented */ - case MULTIPOLYGONTYPE: - case COLLECTIONTYPE: - coll = (LWCOLLECTION *)lwgeom; - for (i=0; ingeoms; i++) - lwgeom_force_clockwise(coll->geoms[i]); - return; - } -} - -/** Check clockwise orientation on LWGEOM polygons **/ -int -lwgeom_is_clockwise(LWGEOM *lwgeom) +/** + * Force an orientation onto geometries made up of rings, + * so the rings circle in a particular direction, clockwise + * or counter-clockwise. The orientation is one of + * LW_CLOCKWISE or LW_COUNTERCLOCKWISE. Non-polygonal + * geometries are ignored and returned untouched. + */ +static void +lwgeom_force_orientation(LWGEOM *lwgeom, int orientation) { switch (lwgeom->type) { case POLYGONTYPE: - return lwpoly_is_clockwise((LWPOLY *)lwgeom); + lwpoly_force_orientation(lwgeom_as_lwpoly(lwgeom), orientation); + return; case TRIANGLETYPE: - return lwtriangle_is_clockwise((LWTRIANGLE *)lwgeom); + lwtriangle_force_orientation(lwgeom_as_lwtriangle(lwgeom), orientation); + return; + + /* Not handle POLYHEDRALSURFACE and TIN + as they are supposed to be well oriented */ + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + { + LWCOLLECTION* coll = lwgeom_as_lwcollection(lwgeom); + for (uint32_t i = 0; coll && i < coll->ngeoms; i++) + { + lwgeom_force_orientation(coll->geoms[i], orientation); + } + return; + } + } +} + +void +lwgeom_force_clockwise(LWGEOM *lwgeom) +{ + return lwgeom_force_orientation(lwgeom, LW_CLOCKWISE); +} + +void +lwgeom_force_counterclockwise(LWGEOM *lwgeom) +{ + return lwgeom_force_orientation(lwgeom, LW_COUNTERCLOCKWISE); +} + + +/** + * Check clockwise orientation on LWGEOM polygons + * returns LW_CLOCKWISE, LW_NONE, LW_COUNTERCLOCKWISE + * Non-polygonal geometries return LW_NONE + * Geometries must have *all* rings correctly oriented + * to return a non-none orientation + */ +int +lwgeom_has_orientation(const LWGEOM *lwgeom, int orientation) +{ + switch (lwgeom->type) + { + case POLYGONTYPE: + return lwpoly_has_orientation(lwgeom_as_lwpoly(lwgeom), orientation); + + case TRIANGLETYPE: + return lwtriangle_has_orientation(lwgeom_as_lwtriangle(lwgeom), orientation); case MULTIPOLYGONTYPE: case COLLECTIONTYPE: { - uint32_t i; - LWCOLLECTION* coll = (LWCOLLECTION *)lwgeom; - - for (i=0; i < coll->ngeoms; i++) - if (!lwgeom_is_clockwise(coll->geoms[i])) + LWCOLLECTION* coll = lwgeom_as_lwcollection(lwgeom); + for (uint32_t i = 0; coll && i < coll->ngeoms; i++) + { + if(!lwgeom_has_orientation(coll->geoms[i], orientation)) return LW_FALSE; + } return LW_TRUE; } + default: return LW_TRUE; - return LW_FALSE; } + return LW_FALSE; } LWGEOM * @@ -1178,7 +1206,7 @@ lwtype_is_collection(uint8_t type) case MULTICURVETYPE: case MULTISURFACETYPE: case POLYHEDRALSURFACETYPE: - case TINTYPE: + case TINTYPE: return LW_TRUE; break; diff --git a/liblwgeom/lwpoly.c b/liblwgeom/lwpoly.c index 145e2cc75..a4949e734 100644 --- a/liblwgeom/lwpoly.c +++ b/liblwgeom/lwpoly.c @@ -265,38 +265,37 @@ lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa) } void -lwpoly_force_clockwise(LWPOLY *poly) +lwpoly_force_orientation(LWPOLY *poly, int orientation) { - uint32_t i; + /* No-op no orientation */ + if (orientation == LW_NONE) return; /* No-op empties */ - if ( lwpoly_is_empty(poly) ) - return; + if (lwpoly_is_empty(poly)) return; /* External ring */ - if ( ptarray_isccw(poly->rings[0]) ) + if (!ptarray_has_orientation(poly->rings[0], orientation)) ptarray_reverse_in_place(poly->rings[0]); - /* Internal rings */ - for (i=1; inrings; i++) - if ( ! ptarray_isccw(poly->rings[i]) ) + /* Internal rings must run opposite to external */ + for (uint32_t i = 1; i < poly->nrings; i++) + if (!ptarray_has_orientation(poly->rings[i], -1 * orientation)) ptarray_reverse_in_place(poly->rings[i]); - } int -lwpoly_is_clockwise(LWPOLY *poly) +lwpoly_has_orientation(const LWPOLY *poly, int orientation) { - uint32_t i; - - if ( lwpoly_is_empty(poly) ) + if (lwpoly_is_empty(poly)) return LW_TRUE; - if ( ptarray_isccw(poly->rings[0]) ) + /* Exterior ring matches orientation? */ + if(!ptarray_has_orientation(poly->rings[0], orientation)) return LW_FALSE; - for ( i = 1; i < poly->nrings; i++) - if ( !ptarray_isccw(poly->rings[i]) ) + /* Interior rings are opposite of orientation? */ + for (uint32_t i = 1; i < poly->nrings; i++) + if (!ptarray_has_orientation(poly->rings[i], -1 * orientation)) return LW_FALSE; return LW_TRUE; diff --git a/liblwgeom/lwtriangle.c b/liblwgeom/lwtriangle.c index adfa9c04f..b37279077 100644 --- a/liblwgeom/lwtriangle.c +++ b/liblwgeom/lwtriangle.c @@ -102,17 +102,17 @@ lwtriangle_clone(const LWTRIANGLE *g) return (LWTRIANGLE *)lwline_clone((const LWLINE *)g); } -void -lwtriangle_force_clockwise(LWTRIANGLE *triangle) +int +lwtriangle_has_orientation(const LWTRIANGLE *triangle, int orientation) { - if ( ptarray_isccw(triangle->points) ) - ptarray_reverse_in_place(triangle->points); + return ptarray_has_orientation(triangle->points, orientation); } -int -lwtriangle_is_clockwise(LWTRIANGLE *triangle) +void +lwtriangle_force_orientation(LWTRIANGLE *triangle, int orientation) { - return !ptarray_isccw(triangle->points); + if (!lwtriangle_has_orientation(triangle, orientation)) + ptarray_reverse_in_place(triangle->points); } void diff --git a/liblwgeom/ptarray.c b/liblwgeom/ptarray.c index 4bf5816e9..cce30d5b2 100644 --- a/liblwgeom/ptarray.c +++ b/liblwgeom/ptarray.c @@ -1171,12 +1171,17 @@ ptarray_signed_area(const POINTARRAY *pa) } int -ptarray_isccw(const POINTARRAY *pa) +ptarray_has_orientation(const POINTARRAY *pa, int orientation) { - double area = 0; - area = ptarray_signed_area(pa); - if ( area > 0 ) return LW_FALSE; - else return LW_TRUE; + if (ptarray_signed_area(pa) > 0) + return orientation == LW_CLOCKWISE; + else + return orientation == LW_COUNTERCLOCKWISE; +} + +int ptarray_isccw(const POINTARRAY *pa) +{ + return ptarray_has_orientation(pa, LW_COUNTERCLOCKWISE); } POINTARRAY* diff --git a/postgis/lwgeom_functions_analytic.c b/postgis/lwgeom_functions_analytic.c index abcc222c6..13e31cf01 100644 --- a/postgis/lwgeom_functions_analytic.c +++ b/postgis/lwgeom_functions_analytic.c @@ -869,21 +869,12 @@ PG_FUNCTION_INFO_V1(ST_IsPolygonCW); Datum ST_IsPolygonCW(PG_FUNCTION_ARGS) { GSERIALIZED* geom; - LWGEOM* input; - bool is_clockwise; if (PG_ARGISNULL(0)) PG_RETURN_NULL(); geom = PG_GETARG_GSERIALIZED_P(0); - input = lwgeom_from_gserialized(geom); - - is_clockwise = lwgeom_is_clockwise(input); - - lwgeom_free(input); - PG_FREE_IF_COPY(geom, 0); - - PG_RETURN_BOOL(is_clockwise); + PG_RETURN_BOOL(lwgeom_has_orientation(lwgeom_from_gserialized(geom), LW_CLOCKWISE)); } /********************************************************************** @@ -896,19 +887,12 @@ PG_FUNCTION_INFO_V1(ST_IsPolygonCCW); Datum ST_IsPolygonCCW(PG_FUNCTION_ARGS) { GSERIALIZED* geom; - LWGEOM* input; - bool is_ccw; if (PG_ARGISNULL(0)) PG_RETURN_NULL(); - geom = PG_GETARG_GSERIALIZED_P_COPY(0); - input = lwgeom_from_gserialized(geom); - lwgeom_reverse_in_place(input); - is_ccw = lwgeom_is_clockwise(input); - lwgeom_free(input); - PG_FREE_IF_COPY(geom, 0); - - PG_RETURN_BOOL(is_ccw); + geom = PG_GETARG_GSERIALIZED_P(0); + geom = PG_GETARG_GSERIALIZED_P(0); + PG_RETURN_BOOL(lwgeom_has_orientation(lwgeom_from_gserialized(geom), LW_COUNTERCLOCKWISE)); } diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c index 06ea00934..b3e1179b3 100644 --- a/postgis/lwgeom_functions_basic.c +++ b/postgis/lwgeom_functions_basic.c @@ -1934,6 +1934,31 @@ Datum LWGEOM_force_clockwise_poly(PG_FUNCTION_ARGS) PG_RETURN_POINTER(outgeom); } + +/** + * Force polygon exterior rings to circle counter-clockwise, + * and interior rings to circle clockwise. + */ +PG_FUNCTION_INFO_V1(ST_ForcePolygonCCW); +Datum ST_ForcePolygonCCW(PG_FUNCTION_ARGS) +{ + GSERIALIZED *ingeom, *outgeom; + LWGEOM *lwgeom; + + POSTGIS_DEBUG(2, "ST_ForcePolygonCCW called"); + + ingeom = PG_GETARG_GSERIALIZED_P_COPY(0); + + lwgeom = lwgeom_from_gserialized(ingeom); + lwgeom_force_counterclockwise(lwgeom); + + outgeom = geometry_serialize(lwgeom); + + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(ingeom, 0); + PG_RETURN_POINTER(outgeom); +} + /** Test deserialize/serialize operations */ PG_FUNCTION_INFO_V1(LWGEOM_noop); Datum LWGEOM_noop(PG_FUNCTION_ARGS) diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index 03a7fdde8..f508024c5 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -1592,10 +1592,11 @@ CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) _COST_LOW; -- Availability: 2.4.0 +-- Changed: 3.7.0 - C implementation CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) RETURNS geometry - AS $$ SELECT @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) $$ - LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE + AS 'MODULE_PATHNAME', 'ST_ForcePolygonCCW' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_LOW; -- Availability: 1.2.2 diff --git a/regress/core/tickets.sql b/regress/core/tickets.sql index 4b580b003..cffa4fbf8 100644 --- a/regress/core/tickets.sql +++ b/regress/core/tickets.sql @@ -1623,3 +1623,9 @@ SELECT '#5962', ST_AsText(ST_ClipByBox2D( ST_GeomFromText('MULTIPOINT((1 1),(6 4),(5 4))'), ST_MakeEnvelope(0, 0, 5, 5 )), 2); + +SELECT '#5754' AS Ticket, + ST_AsText(ST_ForcePolygonCCW('LINESTRING(0 0, 1 1, 2 0, 3 1, 4 0)'::geometry), 1) AS LsCcw, + ST_AsText(ST_ForcePolygonCW('LINESTRING(0 0, 1 1, 2 0, 3 1, 4 0)'::geometry), 1) AS LsCw, + ST_AsText(ST_ForcePolygonCCW('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'::geometry), 1) AS PlyCcw1, + ST_AsText(ST_ForcePolygonCCW('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1))'::geometry), 1) AS PlyCcw2 diff --git a/regress/core/tickets_expected b/regress/core/tickets_expected index 0f2bf2f39..98d74a836 100644 --- a/regress/core/tickets_expected +++ b/regress/core/tickets_expected @@ -492,3 +492,4 @@ public|test5978|geometry|2|4326|POINT public|test5978|shape|2|4326|POINT #5987|LINESTRING(20 20,20.1 20,20.2 19.9)|LINESTRING(20 20,20.1 20,20.2 19.9) #5962|MULTIPOINT((1 1),(3 4))|POINT(1 1) +#5754|LINESTRING(0 0,1 1,2 0,3 1,4 0)|LINESTRING(0 0,1 1,2 0,3 1,4 0)|POLYGON((0 0,1 0,1 1,0 1,0 0))|POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1)) ----------------------------------------------------------------------- Summary of changes: liblwgeom/cunit/cu_gserialized1.c | 16 ++++--- liblwgeom/liblwgeom.h.in | 9 ++-- liblwgeom/liblwgeom_internal.h | 18 +++++--- liblwgeom/lwgeom.c | 86 ++++++++++++++++++++++++------------- liblwgeom/lwpoly.c | 31 +++++++------ liblwgeom/lwtriangle.c | 14 +++--- liblwgeom/ptarray.c | 15 ++++--- postgis/lwgeom_functions_analytic.c | 24 ++--------- postgis/lwgeom_functions_basic.c | 25 +++++++++++ postgis/postgis.sql.in | 5 ++- regress/core/tickets.sql | 6 +++ regress/core/tickets_expected | 1 + 12 files changed, 157 insertions(+), 93 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 15 10:01:22 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 17:01:22 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.77df57148b26ee69c024f143e179abf1@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"dba29bac7b4d2a58730953dad939e5dafd28b78b/git" dba29ba/git]: {{{#!CommitTicketReference repository="git" revision="dba29bac7b4d2a58730953dad939e5dafd28b78b" ST_ForcePolygonCCW unexpectedly reverses non-polygonal geometries too, references #5754 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 10:02:12 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 17:02:12 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.40172f026c119f2866c034915170c07f@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): I have pushed an actual native fix into master. I am thinking that the quick in-place fix noted above would be appropriate for back patching. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 15 10:21:06 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 15 Oct 2025 10:21:06 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.0-24-g58b4e2571 Message-ID: <20251015172106.ECE8B19D278@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via 58b4e2571588b4aace175431f2ff33445c230ee4 (commit) from aca123684d92189659756a00d93a97398447f229 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 58b4e2571588b4aace175431f2ff33445c230ee4 Author: Paul Ramsey Date: Wed Oct 15 10:20:41 2025 -0700 ST_ForcePolygonCCW should not flip lines, closes #5754 diff --git a/NEWS b/NEWS index 476d10cfe..4dec87f2a 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ PostGIS 3.6.1 - #5998, [tiger_geocoder] [security] CVE-2022-2625, make sure tables requires by extension are owned by extension authored: Andrey Borodin (Yandex), reported by Sergey Bobrov (Kaspersky) + - #5754, ST_ForcePolygonCCW reverses lines (Paul Ramsey) PostGIS 3.6.0 diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index 03a7fdde8..c4177edb9 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -1584,27 +1584,6 @@ CREATE OR REPLACE FUNCTION ST_Scroll(geometry, geometry) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_LOW; --- Availability: 2.4.0 -CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) - RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - --- Availability: 2.4.0 -CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) - RETURNS geometry - AS $$ SELECT @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) $$ - LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - --- Availability: 1.2.2 -CREATE OR REPLACE FUNCTION ST_ForceRHR(geometry) - RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - -- Availability: 1.5.0 CREATE OR REPLACE FUNCTION postgis_noop(geometry) RETURNS geometry @@ -5477,6 +5456,30 @@ CREATE OR REPLACE FUNCTION ST_GeometryType(geometry) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_DEFAULT; +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + +-- Availability: 1.2.2 +CREATE OR REPLACE FUNCTION ST_ForceRHR(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) + RETURNS geometry + AS $$ SELECT + CASE WHEN @extschema at .ST_GeometryType($1) IN ('ST_Polygon', 'ST_MultiPolygon') + THEN @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) + ELSE $1 END $$ + LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + -- PostGIS equivalent function: PointN(geometry,integer) CREATE OR REPLACE FUNCTION ST_PointN(geometry,integer) RETURNS geometry ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/postgis.sql.in | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 15 10:21:09 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 17:21:09 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.a8e3ff656e9911e694c4bc5de0884ab6@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"58b4e2571588b4aace175431f2ff33445c230ee4/git" 58b4e25/git]: {{{#!CommitTicketReference repository="git" revision="58b4e2571588b4aace175431f2ff33445c230ee4" ST_ForcePolygonCCW should not flip lines, closes #5754 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 15 10:21:14 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 15 Oct 2025 10:21:14 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-70-gc2ec467e3 Message-ID: <20251015172115.0655F19DB15@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via c2ec467e307251ffd9cd1a70fe6706732fe8e33b (commit) from 64bf79d69cd9730511fae2bab10e328350cdea41 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c2ec467e307251ffd9cd1a70fe6706732fe8e33b Author: Paul Ramsey Date: Wed Oct 15 10:19:50 2025 -0700 ST_ForcePolygonCCW should not flip lines, closes #5754 diff --git a/NEWS b/NEWS index b41abc6a1..1a6472081 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,7 @@ PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) - #5989, ST_Distance error on CurvePolygon (Paul Ramsey) - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) +- #5754, ST_ForcePolygonCCW reverses lines (Paul Ramsey) PostGIS 3.5.3 diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index 4d3fc19c0..0ad1db1e3 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -1584,27 +1584,6 @@ CREATE OR REPLACE FUNCTION ST_Scroll(geometry, geometry) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_LOW; --- Availability: 2.4.0 -CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) - RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - --- Availability: 2.4.0 -CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) - RETURNS geometry - AS $$ SELECT @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) $$ - LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - --- Availability: 1.2.2 -CREATE OR REPLACE FUNCTION ST_ForceRHR(geometry) - RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - -- Availability: 1.5.0 CREATE OR REPLACE FUNCTION postgis_noop(geometry) RETURNS geometry @@ -5470,6 +5449,30 @@ CREATE OR REPLACE FUNCTION ST_GeometryType(geometry) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_DEFAULT; +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + +-- Availability: 1.2.2 +CREATE OR REPLACE FUNCTION ST_ForceRHR(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) + RETURNS geometry + AS $$ SELECT + CASE WHEN @extschema at .ST_GeometryType($1) IN ('ST_Polygon', 'ST_MultiPolygon') + THEN @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) + ELSE $1 END $$ + LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + -- PostGIS equivalent function: PointN(geometry,integer) CREATE OR REPLACE FUNCTION ST_PointN(geometry,integer) RETURNS geometry ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/postgis.sql.in | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 15 10:21:16 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 17:21:16 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.da650c50c32ad90240586988feb866e6@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"c2ec467e307251ffd9cd1a70fe6706732fe8e33b/git" c2ec467e/git]: {{{#!CommitTicketReference repository="git" revision="c2ec467e307251ffd9cd1a70fe6706732fe8e33b" ST_ForcePolygonCCW should not flip lines, closes #5754 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 15 10:21:18 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 15 Oct 2025 10:21:18 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.4-62-g51c29b960 Message-ID: <20251015172119.2C67119D855@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via 51c29b96077122fe9e2794f98585fe03a110e02e (commit) from 68f53711ce18a7a93cbed1b6b315d35fc715e481 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 51c29b96077122fe9e2794f98585fe03a110e02e Author: Paul Ramsey Date: Wed Oct 15 10:19:55 2025 -0700 ST_ForcePolygonCCW should not flip lines, closes #5754 diff --git a/NEWS b/NEWS index e1500842a..2828a8c5f 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,7 @@ Proj 6.1+ required. - #5991, CircularString distance error (Paul Ramsey) - #5989, ST_Distance error on CurvePolygon (Paul Ramsey) - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) + - #5754, ST_ForcePolygonCCW reverses lines (Paul Ramsey) PostGIS 3.4.4 diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index 2bc1a6bf7..d8be7593b 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -1611,27 +1611,6 @@ CREATE OR REPLACE FUNCTION ST_Scroll(geometry, geometry) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_LOW; --- Availability: 2.4.0 -CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) - RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - --- Availability: 2.4.0 -CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) - RETURNS geometry - AS $$ SELECT @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) $$ - LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - --- Availability: 1.2.2 -CREATE OR REPLACE FUNCTION ST_ForceRHR(geometry) - RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' - LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE - _COST_LOW; - -- Availability: 1.5.0 CREATE OR REPLACE FUNCTION postgis_noop(geometry) RETURNS geometry @@ -5496,6 +5475,30 @@ CREATE OR REPLACE FUNCTION ST_GeometryType(geometry) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_DEFAULT; +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION ST_ForcePolygonCW(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + +-- Availability: 1.2.2 +CREATE OR REPLACE FUNCTION ST_ForceRHR(geometry) + RETURNS geometry + AS 'MODULE_PATHNAME', 'LWGEOM_force_clockwise_poly' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION ST_ForcePolygonCCW(geometry) + RETURNS geometry + AS $$ SELECT + CASE WHEN @extschema at .ST_GeometryType($1) IN ('ST_Polygon', 'ST_MultiPolygon') + THEN @extschema at .ST_Reverse(@extschema at .ST_ForcePolygonCW($1)) + ELSE $1 END $$ + LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE + _COST_LOW; + -- PostGIS equivalent function: PointN(geometry,integer) CREATE OR REPLACE FUNCTION ST_PointN(geometry,integer) RETURNS geometry ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/postgis.sql.in | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 21 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 15 10:21:20 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 17:21:20 -0000 Subject: [PostGIS] #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries In-Reply-To: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> References: <045.152ad1a3cc8b31e313a9ace737ae14e0@osgeo.org> Message-ID: <060.ba4207551f41dd8b70614439b85fa6e5@osgeo.org> #5754: ST_ForcePolygonCCW unexpectedly modifies line geometries ----------------------+--------------------------- Reporter: nti | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"51c29b96077122fe9e2794f98585fe03a110e02e/git" 51c29b9/git]: {{{#!CommitTicketReference repository="git" revision="51c29b96077122fe9e2794f98585fe03a110e02e" ST_ForcePolygonCCW should not flip lines, closes #5754 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 10:45:29 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 17:45:29 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.74d810fb2edd9ca2dab2bd5e501e4730@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by strk): > I'm suspecting very few people are using the bigint feature, so we might be able to fix simply by updating the catalog back to what it was. Going to test that theory out. Yes please, tests are always good to have. I would start for a test showing EXACTLY this problem, see if you can have CI turn red by just touching `topology/test/regress/hooks/hook-before-upgrade-topology.sql` and `topology/test/regress/hooks/hook-after-upgrade-topology.sql` ... we NEED to be able to see this failure shown by `utils/check_all_upgrades.sh` -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 11:07:08 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 18:07:08 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.f537f845e57386119e609c92a328990e@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): "Remove small holes" is not the same as "remove all holes", which is the use case that drove me to the idea of filtering holes also rather than just having a single-minded `ST_NoHoles` function. That use case seems like a bad fit for `ST_RemoveSmallParts`. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 16:55:25 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 15 Oct 2025 23:55:25 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.9159281bc54e44a2623b4d2883d88892@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): this seems to rollback the change for topogeometry: {{{ UPDATE pg_catalog.pg_attribute AS n SET atttypid = 'int'::regtype, attlen = 4 FROM pg_catalog.pg_type join pg_catalog.pg_class on pg_class.oid = pg_type.typrelid join pg_catalog.pg_attribute AS pga on pga.attrelid = pg_class.oid join pg_type as pg_attr_type on pg_attr_type.oid = pga.atttypid WHERE pg_type.typname::regtype::text = 'topogeometry' AND pga.attname = 'id' AND pg_type.typnamespace::regnamespace::text = 'topology' AND n.attrelid = pga.attrelid AND n.attnum = pga.attnum AND pga.atttypid::regtype::text = 'bigint'; }}} After that my query: {{{ SELECT geometrytype(topo) FROM topo_states; }}} changes from: UNEXPECTED to: MULTIPOLYGON But I haven't checked yet what happens if I had updated records after the move. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 17:04:55 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 16 Oct 2025 00:04:55 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.db6dd3dd265c3362e48264554c0189aa@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Bah that doesn't work. If you create a topogeometry after and try to revert then the new ones become broken and the old ones are okay and vice versa. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 17:32:49 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 16 Oct 2025 00:32:49 -0000 Subject: [PostGIS] #6006: ST_MakeValid documentation does not state default value for keepcollapsed param Message-ID: <049.ad33364d065c708637013c2e61565b8c@osgeo.org> #6006: ST_MakeValid documentation does not state default value for keepcollapsed param ---------------------------+--------------------------- Reporter: atlight | Owner: robe Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: documentation | Version: 3.5.x Keywords: | ---------------------------+--------------------------- https://postgis.net/docs/ST_MakeValid.html > The "keepcollapsed" key is only valid for the "structure" algorithm, and takes a value of "true" or "false". When set to "false", geometry components that collapse to a lower dimensionality, for example a one- point linestring would be dropped. Is "true" or "false" the default value if the parameter is not specified? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 15 19:02:17 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 16 Oct 2025 02:02:17 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.e59bf90263f30ee5e3f6da615994aee1@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Okay I think this would fix the broken topogeometries but probably very slow {{{ CREATE EXTENSION postgis_topology VERSION "3.4.2"; CREATE OR REPLACE FUNCTION topology.hex_to_int(hexVal varchar) RETURNS numeric(1000) AS $$ DECLARE intVal numeric(1000) := 0; hexLength integer; i integer; hexDigit varchar; BEGIN hexLength := length(hexVal); FOR i IN 1..hexLength LOOP hexDigit := substr(hexVal, hexLength - i + 1, 1); intVal := intVal + CASE WHEN hexDigit BETWEEN '0' AND '9' THEN CAST(hexDigit AS numeric(1000)) WHEN upper(hexDigit) BETWEEN 'A' AND 'F' THEN CAST(ascii(upper(hexDigit)) - 55 AS numeric(1000)) END * CAST(16 AS numeric(1000)) ^ CAST(i - 1 AS numeric(1000)); END LOOP; RETURN intVal; END; $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION topology.fix_topogeometry(param_topo topogeometry) RETURNS topogeometry AS $$ BEGIN IF geometrytype(param_topo) != 'UNEXPECTED' THEN -- it's okay return unchanged RETURN param_topo; ELSE RETURN (param_topo.topology_id, param_topo.layer_id, topology.hex_to_int(right(lpad(to_hex(param_topo.id), 16, '0'),8))::bigint, topology.hex_to_int(left(lpad(to_hex(param_topo.id), 16, '0'),8))::bigint)::topogeometry; END IF; END $$ language plpgsql; }}} I tested with a set of mix of bad and good topogeometries upgrading from postgis_topology 3.4.2 to 3.6.0 {{{ CREATE EXTENSION postgis_topology VERSION '3.4.2'; DROP SCHEMA IF EXISTS tiger_topo CASCADE; SELECT topology.CreateTopology('tiger_topo', 4326, 0.00001); DROP TABLE IF EXISTS topo_states; CREATE TABLE topo_states (stusps char(2)); SELECT topology.AddTopoGeometryColumn('tiger_topo', 'public', 'topo_states', 'topo', 'POLYGON'); INSERT INTO topo_states(stusps, topo) SELECT stusps, ToTopoGeom(ST_SetSRID(the_geom,4326), 'tiger_topo', 1) FROM tiger_link.state WHERE stusps IN('MA','DC','RI','NH', 'NY'); }}} {{{ -- not broken SELECT stusps, geometrytype(topo) FROM topo_states; }}} {{{ stusps | geometrytype | topo --------+--------------+----------- RI | MULTIPOLYGON | (1,1,1,3) NH | MULTIPOLYGON | (1,1,2,3) NY | MULTIPOLYGON | (1,1,3,3) MA | MULTIPOLYGON | (1,1,4,3) DC | MULTIPOLYGON | (1,1,5,3) }}} {{{ ALTER EXTENSION postgis_topology UPDATE TO "3.6.0"; -- all broken SELECT stusps, geometrytype(topo), topo FROM topo_states; }}} {{{ stusps | geometrytype | topo --------+--------------+---------------------------- RI | UNEXPECTED | (1,1,12884901889,19626) NH | UNEXPECTED | (1,1,12884901890,16676265) NY | UNEXPECTED | (1,1,12884901891,16676265) MA | UNEXPECTED | (1,1,12884901892,16676265) DC | UNEXPECTED | (1,1,12884901893,16676265) (5 rows) }}} {{{ INSERT INTO topo_states(stusps, topo) SELECT stusps, ToTopoGeom(ST_SetSRID(the_geom,4326), 'tiger_topo', 1) FROM tiger_link.state WHERE stusps IN('DE'); -- new one not broken SELECT stusps, geometrytype(topo), topo FROM topo_states; }}} {{{ stusps | geometrytype | topo --------+--------------+---------------------------- RI | UNEXPECTED | (1,1,12884901889,19626) NH | UNEXPECTED | (1,1,12884901890,16676265) NY | UNEXPECTED | (1,1,12884901891,16676265) MA | UNEXPECTED | (1,1,12884901892,16676265) DC | UNEXPECTED | (1,1,12884901893,16676265) DE | MULTIPOLYGON | (1,1,6,3) (6 rows) }}} {{{ UPDATE topo_states SET topo = topology.fix_topogeometry(topo) WHERE geometrytype(topo) = 'UNEXPECTED'; -- all good SELECT stusps, geometrytype(topo), topo FROM topo_states; }}} {{{ stusps | geometrytype | topo --------+--------------+----------- DE | MULTIPOLYGON | (1,1,6,3) RI | MULTIPOLYGON | (1,1,1,3) NH | MULTIPOLYGON | (1,1,2,3) NY | MULTIPOLYGON | (1,1,3,3) MA | MULTIPOLYGON | (1,1,4,3) DC | MULTIPOLYGON | (1,1,5,3) (6 rows) }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 16 09:22:22 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 16 Oct 2025 09:22:22 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-71-g278cd40a2 Message-ID: <20251016162223.2E4451A5F32@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 278cd40a255d37d01ab5d6e8570e1d37ee51eda6 (commit) from c2ec467e307251ffd9cd1a70fe6706732fe8e33b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 278cd40a255d37d01ab5d6e8570e1d37ee51eda6 Author: Paul Ramsey Date: Thu Oct 16 09:22:10 2025 -0700 Fix typo in ticket number diff --git a/NEWS b/NEWS index 1a6472081..189723031 100644 --- a/NEWS +++ b/NEWS @@ -22,7 +22,7 @@ PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. - #5935, Require GDAL 2.4 for postgis_raster and switch to GDALGetDataTypeSizeBytes (Lauren?iu Nicola) - GT-257, fix issue with xsltproc with path has spaces (Lauren?iu Nicola) -- #5939, incorrect parameter order in ST_Relate caching (Paul Ramsey) +- #5938, incorrect parameter order in ST_Relate caching (Paul Ramsey) - #5927, ST_IsCollection throwing exception (Paul Ramsey) - #5902, ST_PointFromText cannot create geometries with M (Paul Ramsey) - #5943, Memory leak in handling GEOS GeometryFactory (Megan Ma) ----------------------------------------------------------------------- Summary of changes: NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 16 09:56:24 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 16 Oct 2025 09:56:24 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-138-g74d24bc78 Message-ID: <20251016165625.031CA1A661E@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 74d24bc78383f8e021cd6300b5aec1d7278b5487 (commit) from 976adccb9b11f9f47da2aafe0e524d3207c08914 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 74d24bc78383f8e021cd6300b5aec1d7278b5487 Author: Paul Ramsey Date: Thu Oct 16 09:55:50 2025 -0700 Fix up test for #5938, ST_Relate(geom,geom,pattern) failure in certain caching situations with RelateNG prepared geometry diff --git a/regress/core/tickets.sql b/regress/core/tickets.sql index cffa4fbf8..0b34a3028 100644 --- a/regress/core/tickets.sql +++ b/regress/core/tickets.sql @@ -1628,4 +1628,14 @@ SELECT '#5754' AS Ticket, ST_AsText(ST_ForcePolygonCCW('LINESTRING(0 0, 1 1, 2 0, 3 1, 4 0)'::geometry), 1) AS LsCcw, ST_AsText(ST_ForcePolygonCW('LINESTRING(0 0, 1 1, 2 0, 3 1, 4 0)'::geometry), 1) AS LsCw, ST_AsText(ST_ForcePolygonCCW('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'::geometry), 1) AS PlyCcw1, - ST_AsText(ST_ForcePolygonCCW('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1))'::geometry), 1) AS PlyCcw2 + ST_AsText(ST_ForcePolygonCCW('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1))'::geometry), 1) AS PlyCcw2; + +-- ------------------------------------------------------------------------------------- +-- #5938 +SELECT + '#5938', + ST_Relate(a.geom, b.geom), + ST_Relate(a.geom, b.geom, '1FF00F212') +FROM +(VALUES ('LINESTRING (170 290, 205 272)'),('LINESTRING (120 215, 176 197)'),('LINESTRING (170 290, 205 272)')) AS a(geom), +(VALUES ('POLYGON ((100 200, 140 230, 180 310, 280 310, 390 270, 400 210, 320 140, 215 141, 150 170, 100 200))')) AS b(geom); diff --git a/regress/core/tickets_expected b/regress/core/tickets_expected index 98d74a836..fbf04a8c1 100644 --- a/regress/core/tickets_expected +++ b/regress/core/tickets_expected @@ -493,3 +493,6 @@ public|test5978|shape|2|4326|POINT #5987|LINESTRING(20 20,20.1 20,20.2 19.9)|LINESTRING(20 20,20.1 20,20.2 19.9) #5962|MULTIPOINT((1 1),(3 4))|POINT(1 1) #5754|LINESTRING(0 0,1 1,2 0,3 1,4 0)|LINESTRING(0 0,1 1,2 0,3 1,4 0)|POLYGON((0 0,1 0,1 1,0 1,0 0))|POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1)) +#5938|1FF00F212|t +#5938|1FF00F212|t +#5938|1FF00F212|t ----------------------------------------------------------------------- Summary of changes: regress/core/tickets.sql | 12 +++++++++++- regress/core/tickets_expected | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 16 09:57:10 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 16 Oct 2025 16:57:10 -0000 Subject: [PostGIS] #5938: ST_Relate(geom, geom, pattern) inconsistent In-Reply-To: <049.23d2b75be5cb6bb67daf80d14df54779@osgeo.org> References: <049.23d2b75be5cb6bb67daf80d14df54779@osgeo.org> Message-ID: <064.a68a199e6e95c7f2ba016ee269c872df@osgeo.org> #5938: ST_Relate(geom, geom, pattern) inconsistent ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.4 Component: postgis | Version: 3.5.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by pramsey): Test added to master in 74d24bc78 to close the door on this. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 16 12:38:17 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 16 Oct 2025 19:38:17 -0000 Subject: [PostGIS] Batch modify: #5854, #5903, #5160, #5317, #5408, #5487, ... In-Reply-To: <194.04a53f51c60d40e0b285d0e780dba8eb@osgeo.org> References: <194.04a53f51c60d40e0b285d0e780dba8eb@osgeo.org> Message-ID: <187.2816bddd607af2874ef5ea7426732270@osgeo.org> Batch modification to #5854, #5903, #5160, #5317, #5408, #5487, #5655, #5702, #5771, #5786, #5797, #5840, #5859, #5860, #5864, #5886, #5904, #5914, #5916, #5918, #5930, #5931, #5932, #5933, #5950, #5953, #5958, #5959, #5772, #5842, #5973 by pramsey: milestone to PostGIS 3.5.5 Comment: Ticket retargeted after milestone closed -- Tickets URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 16 12:47:41 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 16 Oct 2025 12:47:41 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.3-73-g2fc837ec4 Message-ID: <20251016194741.D78121A8B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 2fc837ec43f5acb631613b12117115f5c2654bd2 (commit) via e0a547ecb746093f1fc3f2bb003477a81e36869b (commit) from 278cd40a255d37d01ab5d6e8570e1d37ee51eda6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2fc837ec43f5acb631613b12117115f5c2654bd2 Author: Paul Ramsey Date: Thu Oct 16 12:47:30 2025 -0700 Bump for 3.5.4 release diff --git a/README.postgis b/README.postgis index 660a9ff94..a474b20f8 100644 --- a/README.postgis +++ b/README.postgis @@ -1,8 +1,8 @@ PostGIS - Geographic Information Systems Extensions to PostgreSQL ================================================================= -:Version: 3.5.3 -:Date: 2025-05-17 +:Version: 3.5.4 +:Date: 2025-10-16 :Website: https://postgis.net This distribution contains a module which implements GIS simple features, ties diff --git a/Version.config b/Version.config index 36a05d320..68af1b6f8 100644 --- a/Version.config +++ b/Version.config @@ -5,7 +5,7 @@ POSTGIS_MAJOR_VERSION=3 POSTGIS_MINOR_VERSION=5 -POSTGIS_MICRO_VERSION=4dev +POSTGIS_MICRO_VERSION=4 # Liblwgeom interface versioning, reset to 0:0:0 (cur:age:rev) # when changing POSTGIS_MINOR_VERSION diff --git a/doc/release_notes.xml b/doc/release_notes.xml index 4ee780ec0..f9db79bc1 100644 --- a/doc/release_notes.xml +++ b/doc/release_notes.xml @@ -2,6 +2,44 @@ Appendix Release Notes + +
    + PostGIS 3.5.4 + 2025/10/16 + This version requires PostgreSQL 12-18beta1, GEOS 3.8 or higher, and Proj 6.1+. To take advantage of all features, GEOS 3.12+ is needed. To take advantage of all SFCGAL features, SFCGAL 1.5.0+ is needed. + + Bug Fixes + 5977, Fix downgrade protection with standard conforming strings off (Sandro Santilli) + 5951, Fix crash in ST_GetFaceEdges with corrupted topology (Sandro Santilli) + 5947, [topology] Fix crash in ST_ModEdgeHeal (Sandro Santilli) + 5925, 5946, [topology] Have GetFaceContainingPoint survive EMPTY edges (Sandro Santilli) + 5936, [topology] Do script-based upgrade in a single transaction (Sandro Santilli) + 5908, [topology] Fix crash in GetFaceContainingPoint (Sandro Santilli) + 5907, [topology] Fix crash in TopoGeo_AddPolygon with EMPTY input (Sandro Santilli) + 5922, [topology] Fix crash in TopoGeo_AddLinestring with EMPTY input (Sandro Santilli) + 5921, Crash freeing uninitialized pointer (Arsenii Mukhin) + 5912, Crash on GML with xlink and no prefix (Paul Ramsey) + 5905, Crash on deeply nested geometries (Paul Ramsey) + 5909, ST_ValueCount crashes on empty table (Paul Ramsey) + 5917, ST_Relate becomes unresponsive (Paul Ramsey) + 5923, CG_ExtrudeStraightSkeleton crashes on empty polygon (Lo?c Bartoletti) + 5935, Require GDAL 2.4 for postgis_raster and switch to GDALGetDataTypeSizeBytes (Lauren?iu Nicola) + GT-257, fix issue with xsltproc with path has spaces (Lauren?iu Nicola) + 5938, incorrect parameter order in ST_Relate caching (Paul Ramsey) + 5927, ST_IsCollection throwing exception (Paul Ramsey) + 5902, ST_PointFromText cannot create geometries with M (Paul Ramsey) + 5943, Memory leak in handling GEOS GeometryFactory (Megan Ma) + 5407, Use memset in place of bzero (Paul Ramsey) + 5082, LRS proportions clamped to [0,1] (Pawel Ostrowski) + 5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) + 5991, CircularString distance error (Paul Ramsey) + 5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) + 5989, ST_Distance error on CurvePolygon (Paul Ramsey) + 5962, Consistent clipping of MULTI/POINT (Paul Ramsey) + 5754, ST_ForcePolygonCCW reverses lines (Paul Ramsey) + +
    +
    PostGIS 3.5.3 2025/05/17 diff --git a/extensions/upgradeable_versions.mk b/extensions/upgradeable_versions.mk index ef22e5cbe..ce55984bd 100644 --- a/extensions/upgradeable_versions.mk +++ b/extensions/upgradeable_versions.mk @@ -112,4 +112,5 @@ UPGRADEABLE_VERSIONS = \ 3.5.0 \ 3.5.1 \ 3.5.2 \ - 3.5.3 + 3.5.3 \ + 3.5.4dev commit e0a547ecb746093f1fc3f2bb003477a81e36869b Author: Paul Ramsey Date: Thu Oct 16 12:47:21 2025 -0700 Reformat NEWS file a little diff --git a/NEWS b/NEWS index 189723031..4b14ae069 100644 --- a/NEWS +++ b/NEWS @@ -1,40 +1,40 @@ -PostGIS 3.5.4dev -xxxx/xx/xx +PostGIS 3.5.4 +2025/10/16 + To take advantage of all postgis_sfcgal extension features SFCGAL 1.5+ is needed. PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. * Bug fixes * -- #5977, Fix downgrade protection with standard conforming strings off (Sandro Santilli) -- #5951, Fix crash in ST_GetFaceEdges with corrupted topology (Sandro Santilli) -- #5947, [topology] Fix crash in ST_ModEdgeHeal (Sandro Santilli) -- #5925, #5946, [topology] Have GetFaceContainingPoint survive EMPTY edges (Sandro Santilli) -- #5936, [topology] Do script-based upgrade in a single transaction (Sandro Santilli) -- #5908, [topology] Fix crash in GetFaceContainingPoint (Sandro Santilli) -- #5907, [topology] Fix crash in TopoGeo_AddPolygon with EMPTY input (Sandro Santilli) -- #5922, [topology] Fix crash in TopoGeo_AddLinestring with EMPTY input (Sandro Santilli) -- #5921, Crash freeing uninitialized pointer (Arsenii Mukhin) -- #5912, Crash on GML with xlink and no prefix (Paul Ramsey) -- #5905, Crash on deeply nested geometries (Paul Ramsey) -- #5909, ST_ValueCount crashes on empty table (Paul Ramsey) -- #5917, ST_Relate becomes unresponsive (Paul Ramsey) -- #5923, CG_ExtrudeStraightSkeleton crashes on empty polygon (Lo?c Bartoletti) -- #5935, Require GDAL 2.4 for postgis_raster - and switch to GDALGetDataTypeSizeBytes (Lauren?iu Nicola) -- GT-257, fix issue with xsltproc with path has spaces (Lauren?iu Nicola) -- #5938, incorrect parameter order in ST_Relate caching (Paul Ramsey) -- #5927, ST_IsCollection throwing exception (Paul Ramsey) -- #5902, ST_PointFromText cannot create geometries with M (Paul Ramsey) -- #5943, Memory leak in handling GEOS GeometryFactory (Megan Ma) -- #5407, Use memset in place of bzero (Paul Ramsey) -- #5082, LRS proportions clamped to [0,1] (Pawel Ostrowski) -- #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) -- #5991, CircularString distance error (Paul Ramsey) -- #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) -- #5989, ST_Distance error on CurvePolygon (Paul Ramsey) -- #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) -- #5754, ST_ForcePolygonCCW reverses lines (Paul Ramsey) - + - #5977, Fix downgrade protection with standard conforming strings off (Sandro Santilli) + - #5951, Fix crash in ST_GetFaceEdges with corrupted topology (Sandro Santilli) + - #5947, [topology] Fix crash in ST_ModEdgeHeal (Sandro Santilli) + - #5925, #5946, [topology] Have GetFaceContainingPoint survive EMPTY edges (Sandro Santilli) + - #5936, [topology] Do script-based upgrade in a single transaction (Sandro Santilli) + - #5908, [topology] Fix crash in GetFaceContainingPoint (Sandro Santilli) + - #5907, [topology] Fix crash in TopoGeo_AddPolygon with EMPTY input (Sandro Santilli) + - #5922, [topology] Fix crash in TopoGeo_AddLinestring with EMPTY input (Sandro Santilli) + - #5921, Crash freeing uninitialized pointer (Arsenii Mukhin) + - #5912, Crash on GML with xlink and no prefix (Paul Ramsey) + - #5905, Crash on deeply nested geometries (Paul Ramsey) + - #5909, ST_ValueCount crashes on empty table (Paul Ramsey) + - #5917, ST_Relate becomes unresponsive (Paul Ramsey) + - #5923, CG_ExtrudeStraightSkeleton crashes on empty polygon (Lo?c Bartoletti) + - #5935, Require GDAL 2.4 for postgis_raster + and switch to GDALGetDataTypeSizeBytes (Lauren?iu Nicola) + - GT-257, fix issue with xsltproc with path has spaces (Lauren?iu Nicola) + - #5938, incorrect parameter order in ST_Relate caching (Paul Ramsey) + - #5927, ST_IsCollection throwing exception (Paul Ramsey) + - #5902, ST_PointFromText cannot create geometries with M (Paul Ramsey) + - #5943, Memory leak in handling GEOS GeometryFactory (Megan Ma) + - #5407, Use memset in place of bzero (Paul Ramsey) + - #5082, LRS proportions clamped to [0,1] (Pawel Ostrowski) + - #5985, Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) + - #5991, CircularString distance error (Paul Ramsey) + - #5994, Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) + - #5989, ST_Distance error on CurvePolygon (Paul Ramsey) + - #5962, Consistent clipping of MULTI/POINT (Paul Ramsey) + - #5754, ST_ForcePolygonCCW reverses lines (Paul Ramsey) PostGIS 3.5.3 2025/05/17 @@ -44,21 +44,21 @@ PostgreSQL 12-18beta1 required. GEOS 3.8+ required. Proj 6.1+ required. * Bug fixes * -- Do not complain about illegal option when calling shp2pgsql -? - (Sandro Santilli, Giovanni Zezza) -- #5862, [topology] Prevent another topology corruption with - TopoGeo_addPoint near almost collinear edges (Sandro Santilli) -- #5841, Change approach to interrupt handling to conform to PgSQL - recommended practice (Paul Ramsey) -- #5855, Fix index binding in ST_DFullyWithin (Paul Ramsey) -- #5819, Support longer names in estimated extent (Paul Ramsey) -- Fix misassignment of result in _lwt_HealEdges (Maxim Korotkov) -- #5876, ST_AddPoint with empty argument adds garbage (Paul Ramsey) -- #5874, Line substring returns wrong answer (Paul Ramsey) -- #5829, geometry_columns with non-standard constraints (Paul Ramsey) -- #5818, [sfcgal] GT-244 Fix CG_IsSolid function (Lo?c Bartoletti) -- #5885, Fix documentation about grid-based overlay operations (Sandro Santilli) -- For [sfcgal] SFCGAL 2.1.0+ prevent using deprecated functions (Regina Obe) + - Do not complain about illegal option when calling shp2pgsql -? + (Sandro Santilli, Giovanni Zezza) + - #5862, [topology] Prevent another topology corruption with + TopoGeo_addPoint near almost collinear edges (Sandro Santilli) + - #5841, Change approach to interrupt handling to conform to PgSQL + recommended practice (Paul Ramsey) + - #5855, Fix index binding in ST_DFullyWithin (Paul Ramsey) + - #5819, Support longer names in estimated extent (Paul Ramsey) + - Fix misassignment of result in _lwt_HealEdges (Maxim Korotkov) + - #5876, ST_AddPoint with empty argument adds garbage (Paul Ramsey) + - #5874, Line substring returns wrong answer (Paul Ramsey) + - #5829, geometry_columns with non-standard constraints (Paul Ramsey) + - #5818, [sfcgal] GT-244 Fix CG_IsSolid function (Lo?c Bartoletti) + - #5885, Fix documentation about grid-based overlay operations (Sandro Santilli) + - For [sfcgal] SFCGAL 2.1.0+ prevent using deprecated functions (Regina Obe) PostGIS 3.5.2 2025/01/18 @@ -68,11 +68,10 @@ PostgreSQL 12-17 required. GEOS 3.8+ required. Proj 6.1+ required. * Bug fixes * -- #5677, Retain SRID during unary union (Paul Ramsey) -- #5833, pg_upgrade fix for postgis_sfcgal (Regina Obe) -- #5564, BRIN crash fix and support for parallel in PG17+ - (Paul Ramsey, Regina Obe) - + - #5677, Retain SRID during unary union (Paul Ramsey) + - #5833, pg_upgrade fix for postgis_sfcgal (Regina Obe) + - #5564, BRIN crash fix and support for parallel in PG17+ + (Paul Ramsey, Regina Obe) PostGIS 3.5.1 2024/12/22 @@ -82,37 +81,34 @@ PostgreSQL 12-17 required. GEOS 3.8+ required. Proj 6.1+ required. * Bug fixes * -- #5792, [topology] Prevent topology corruption with TopoGeo_addPoint near almost - collinear edges (Sandro Santilli) -- #5795, [topology] Fix ST_NewEdgesSplit can cause invalid topology - (Bj?rn Harrtell) -- #5794, Fix crash in TopoGeo_addPoint (Sandro Santilli) -- #5785, [raster] ST_MapAlgebra segfaults when expression references - a supernumerary rast argument (Dian M Fay) -- #5787, [topology] Check that ST_ChangeEdgeGeom doesn't change winding of rings - (Sandro Santilli) -- #5791, Add legacy stubs for old transaction functions - to allow pg_upgrade (Regina Obe) -- #5800, PROJ compiled version reading the wrong minor and micro - (Regina Obe) -- #5790, Non-schema qualified calls causing issue with - materialized views (Regina Obe) -- #5812, Performance regression in ST_Within (Paul Ramsey) -- #5815, Remove hash/merge promise from <> operator (Paul Ramsey) -- #5823, Build support for Pg18 (Paul Ramsey) + - #5792, [topology] Prevent topology corruption with TopoGeo_addPoint near almost + collinear edges (Sandro Santilli) + - #5795, [topology] Fix ST_NewEdgesSplit can cause invalid topology + (Bj?rn Harrtell) + - #5794, Fix crash in TopoGeo_addPoint (Sandro Santilli) + - #5785, [raster] ST_MapAlgebra segfaults when expression references + a supernumerary rast argument (Dian M Fay) + - #5787, [topology] Check that ST_ChangeEdgeGeom doesn't change winding of rings + (Sandro Santilli) + - #5791, Add legacy stubs for old transaction functions + to allow pg_upgrade (Regina Obe) + - #5800, PROJ compiled version reading the wrong minor and micro + (Regina Obe) + - #5790, Non-schema qualified calls causing issue with + materialized views (Regina Obe) + - #5812, Performance regression in ST_Within (Paul Ramsey) + - #5815, Remove hash/merge promise from <> operator (Paul Ramsey) + - #5823, Build support for Pg18 (Paul Ramsey) * Enhancements * - #5782, Improve robustness of min distance calculation (Sandro Santilli) - - [topology] Speedup topology building when closing large rings with many - holes (Bj?rn Harrtell) + - [topology] Speedup topology building when closing large rings with many holes (Bj?rn Harrtell) - #5810, [tiger_geocoder] Update tiger geocoder to handle TIGER 2024 data (Regina Obe) * Breaking Changes * - - #5799, make ST_TileEnvelope clip envelopes to tile plane - extent (Paul Ramsey) - + - #5799, make ST_TileEnvelope clip envelopes to tile plane extent (Paul Ramsey) PostGIS 3.5.0 2024/09/25 @@ -122,9 +118,9 @@ PostgreSQL 12-17 required. GEOS 3.8+ required. Proj 6.1+ required. Many thanks to our translation teams, in particular: -Dapeng Wang, Zuo Chenwei from HighGo (Chinese Team) -Teramoto Ikuhiro (Japanese Team) -Andreas Schild (German Team) + - Dapeng Wang, Zuo Chenwei from HighGo (Chinese Team) + - Teramoto Ikuhiro (Japanese Team) + - Andreas Schild (German Team) * Breaking Changes * @@ -149,17 +145,15 @@ Andreas Schild (German Team) will need rebuilding to upgrade to new signature (Jan Tojnar) - #5496, ST_Clip all variants replaced, will require - rebuilding of materialized views that use them - (funding from The National Institute for Agricultural - and Food Research and Technology (INIA-CSIC)), - Regina Obe) + rebuilding of materialized views that use them + (funding from The National Institute for Agricultural + and Food Research and Technology (INIA-CSIC)), + Regina Obe) - #5659, ST_DFullyWithin behaviour has changed to be ST_Contains(ST_Buffer(A, R), B) (Paul Ramsey) - Remove the WFS_locks extra package. (Paul Ramsey) - #5747, GH-776, ST_Length: Return 0 for CurvePolygon (Dan Baston) - - #5770, support for GEOS 3.13 and RelateNG. Most functionality - remains the same, but new GEOS predicate implementation - has a few small changes. + - #5770, support for GEOS 3.13 and RelateNG. Most functionality remains the same, but new GEOS predicate implementation has a few small changes. - Boundary Node Rule relate matrices might be different when using the "multi-valent end point" rule. - Relate matrices for situations with invalid MultiPolygons @@ -222,7 +216,6 @@ Andreas Schild (German Team) (was ST_StraightSkeleton) to use m as a distance in result (Hannes Janetzek, Lo?c Bartoletti) - PostGIS 3.4.0 2023/08/15 @@ -242,6 +235,7 @@ There are 2 new ./configure switches: raster2pgsql and shp2pgsql even if PostgreSQL is not installed * New Features * + - #5055, complete manual internationalization (Sandro Santilli) - #5052, target version support in postgis_extensions_upgrade (Sandro Santilli) @@ -262,45 +256,43 @@ There are 2 new ./configure switches: - #5267, ST_LineExtend for extending linestrings (Paul Ramsey) - New coverage functions ST_CoverageInvalidEdges, ST_CoverageSimplify, ST_CoverageUnion (Paul Ramsey) - * Enhancements * - #5194, do not update system catalogs from postgis_extensions_upgrade (Sandro Santilli) - - #5092, reduce number of upgrade paths installed on system, - by providing an ANY intermediary path that all upgrades will - go thru (Sandro Santilli) + - #5092, reduce number of upgrade paths installed on system, by providing an ANY intermediary path that all upgrades will go thru (Sandro Santilli) - #635, honour --bindir (and --prefix) configure switch for executables (Sandro Santilli) - Honour --mandir (and --prefix) configure switch for man pages install path (Sandro Santilli) - - Honour --htmldir (and --docdir and --prefix) configure switch for - html pages install path (Sandro Santilli) + - Honour --htmldir (and --docdir and --prefix) configure switch for html pages install path (Sandro Santilli) - [postgis_topology] Speed up check of topology faces without edges (Sandro Santilli) - [postgis_topology] Speed up coincident nodes check in topology validation (Sandro Santilli) - GH718, ST_QuantizeCoordinates(): speed-up implementation (Even Rouault) - Repair spatial planner stats to use computed selectivity for contains/within queries (Paul Ramsey) - - GH734, Additional metadata on Proj installation in postgis_proj_version (Paul Ramsey) + - GH734, Additional metadata on Proj installation in postgis_proj_version + (Paul Ramsey) - #5177, Allow building tools without PostgreSQL server headers (Sandro Santilli) - #5447, Manual pages added for postgis and postgis_restore utilities (Sandro Santilli) - ST_Project signature for geometry, and two-point signature (Paul Ramsey) - - #4913, ST_AsSVG support for curve types CircularString, CompoundCurve, MultiCurve, - and MultiSurface (Regina Obe) + - #4913, ST_AsSVG support for curve types CircularString, CompoundCurve, + MultiCurve, and MultiSurface (Regina Obe) - #5266, #5460 ST_ClosestPoint, ST_ShortestLine support for geography type (MobilityDB Esteban Zimanyi, Maxime Schoemans, Paul Ramsey) * Breaking Changes * + - #5229, Drop support for Proj < 6.1 and PG 11 (Regina Obe) - #5306, GH734, postgis_full_version() and postgis_proj_version() now output more information about proj network configuration and data paths. GEOS compile-time version also shown if different from run-time (Paul Ramsey, Sandro Santilli) - - #5447, postgis_restore.pl renamed to postgis_restore - (Sandro Santilli) - - Utilities now installed in OS bin or - user specified --bindir and --prefix - instead of postgresql bin - and extension stripped except on windows - (postgis, postgis_restore, shp2pgsql, raster2pgsql, pgsql2shp, - pgtopo_import, pgtopo_export) + - #5447, postgis_restore.pl renamed to postgis_restore + (Sandro Santilli) + - Utilities now installed in OS bin or + user specified --bindir and --prefix + instead of postgresql bin + and extension stripped except on windows + (postgis, postgis_restore, shp2pgsql, raster2pgsql, pgsql2shp, + pgtopo_import, pgtopo_export) PostGIS 3.3.0 2022/08/26 ----------------------------------------------------------------------- Summary of changes: NEWS | 198 ++++++++++++++++++------------------- README.postgis | 4 +- Version.config | 2 +- doc/release_notes.xml | 38 +++++++ extensions/upgradeable_versions.mk | 3 +- 5 files changed, 138 insertions(+), 107 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 16 15:55:53 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 16 Oct 2025 15:55:53 -0700 (PDT) Subject: [SCM] postgis.net branch website updated. clarity-final-158-g8f9eb96 Message-ID: <20251016225556.A41CF5D2C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "postgis.net". The branch, website has been updated via 8f9eb9691253c978c2fe7960737514d0d64ea8c5 (commit) from 582c9058567f96623dbbef8eef56342bd22e0f67 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f9eb9691253c978c2fe7960737514d0d64ea8c5 Author: Paul Ramsey Date: Thu Oct 16 15:55:47 2025 -0700 News entry for 3.5.4 diff --git a/config.toml b/config.toml index 7c714ac..cb5643c 100644 --- a/config.toml +++ b/config.toml @@ -174,8 +174,8 @@ enableRobotsTXT = true tag = "3.6.0" [params.postgis.releases.35] minor = "3.5" - dev = "3.5.4dev" - tag = "3.5.3" + dev = "3.5.5dev" + tag = "3.5.4" [params.postgis.releases.34] minor = "3.4" dev = "3.4.5dev" diff --git a/content/news/2025/10-16_postgis-3.5.4.md b/content/news/2025/10-16_postgis-3.5.4.md new file mode 100644 index 0000000..efb6285 --- /dev/null +++ b/content/news/2025/10-16_postgis-3.5.4.md @@ -0,0 +1,75 @@ +--- +title: PostGIS 3.5.4 +layout: post +category: news +tags: [release, 3.5] +author: Paul Ramsey +thumbnail: +date: "2025-10-16" +--- + +The PostGIS Team is pleased to release PostGIS 3.5.4. + +This version requires PostgreSQL 12 - 18beta1, GEOS 3.8 or higher, and Proj 6.1+. +To take advantage of all features, GEOS 3.12+ is needed. +SFCGAL 1.4+ is needed to enable postgis_sfcgal support. +To take advantage of all SFCGAL features, SFCGAL 1.5+ is needed. + +### 3.5.4 + +* [source download]({{< loc "postgis.release_source">}}/postgis-3.5.4.tar.gz) [md5]({{< loc "postgis.dev_download">}}/postgis-3.5.4.tar.gz.md5) +* [NEWS](https://git.osgeo.org/gitea/postgis/postgis/raw/tag/3.5.4/NEWS) +* PDF docs: [en]({{< loc "postgis.release_docs">}}/postgis-3.5.4-en.pdf) + +This release is a bug fix release that includes bug fixes since PostGIS 3.5.3. + + + +### Bug fixes + +- [#5977](https://trac.osgeo.org/postgis/ticket/5977), Fix downgrade protection with standard conforming strings off (Sandro Santilli) +- [#5951](https://trac.osgeo.org/postgis/ticket/5951), Fix crash in ST_GetFaceEdges with corrupted topology (Sandro Santilli) +- [#5947](https://trac.osgeo.org/postgis/ticket/5947), [topology] Fix crash in ST_ModEdgeHeal (Sandro Santilli) +- [#5925](https://trac.osgeo.org/postgis/ticket/5925), [#5946](https://trac.osgeo.org/postgis/ticket/5946), [topology] Have GetFaceContainingPoint survive EMPTY edges (Sandro Santilli) +- [#5936](https://trac.osgeo.org/postgis/ticket/5936), [topology] Do script-based upgrade in a single transaction (Sandro Santilli) +- [#5908](https://trac.osgeo.org/postgis/ticket/5908), [topology] Fix crash in GetFaceContainingPoint (Sandro Santilli) +- [#5907](https://trac.osgeo.org/postgis/ticket/5907), [topology] Fix crash in TopoGeo_AddPolygon with EMPTY input (Sandro Santilli) +- [#5922](https://trac.osgeo.org/postgis/ticket/5922), [topology] Fix crash in TopoGeo_AddLinestring with EMPTY input (Sandro Santilli) +- [#5921](https://trac.osgeo.org/postgis/ticket/5921), Crash freeing uninitialized pointer (Arsenii Mukhin) +- [#5912](https://trac.osgeo.org/postgis/ticket/5912), Crash on GML with xlink and no prefix (Paul Ramsey) +- [#5905](https://trac.osgeo.org/postgis/ticket/5905), Crash on deeply nested geometries (Paul Ramsey) +- [#5909](https://trac.osgeo.org/postgis/ticket/5909), ST_ValueCount crashes on empty table (Paul Ramsey) +- [#5917](https://trac.osgeo.org/postgis/ticket/5917), ST_Relate becomes unresponsive (Paul Ramsey) +- [#5923](https://trac.osgeo.org/postgis/ticket/5923), CG_ExtrudeStraightSkeleton crashes on empty polygon (Lo?c Bartoletti) +- [#5935](https://trac.osgeo.org/postgis/ticket/5935), Require GDAL 2.4 for postgis_raster and switch to GDALGetDataTypeSizeBytes (Lauren?iu Nicola) +- GT-257, fix issue with xsltproc with path has spaces (Lauren?iu Nicola) +- [#5938](https://trac.osgeo.org/postgis/ticket/5938), incorrect parameter order in ST_Relate caching (Paul Ramsey) +- [#5927](https://trac.osgeo.org/postgis/ticket/5927), ST_IsCollection throwing exception (Paul Ramsey) +- [#5902](https://trac.osgeo.org/postgis/ticket/5902), ST_PointFromText cannot create geometries with M (Paul Ramsey) +- [#5943](https://trac.osgeo.org/postgis/ticket/5943), Memory leak in handling GEOS GeometryFactory (Megan Ma) +- [#5407](https://trac.osgeo.org/postgis/ticket/5407), Use memset in place of bzero (Paul Ramsey) +- [#5082](https://trac.osgeo.org/postgis/ticket/5082), LRS proportions clamped to [0,1] (Pawel Ostrowski) +- [#5985](https://trac.osgeo.org/postgis/ticket/5985), Fix configure issue with Debian 12 and 13 (Regina Obe, Sandro Santilli) +- [#5991](https://trac.osgeo.org/postgis/ticket/5991), CircularString distance error (Paul Ramsey) +- [#5994](https://trac.osgeo.org/postgis/ticket/5994), Null pointer in ST_AsGeoJsonRow (Alexander Kukushkin) +- [#5989](https://trac.osgeo.org/postgis/ticket/5989), ST_Distance error on CurvePolygon (Paul Ramsey) +- [#5962](https://trac.osgeo.org/postgis/ticket/5962), Consistent clipping of MULTI/POINT (Paul Ramsey) +- [#5754](https://trac.osgeo.org/postgis/ticket/5754), ST_ForcePolygonCCW reverses lines (Paul Ramsey) + + +### Upgrading + +After installing the binaries or after running pg_upgrade: + +For PostGIS 3.5, 3.4, 3.3, 3.2, 3.1, 3.0 do below which will upgrade all your postgis extensions. + +```sql +SELECT postgis_extensions_upgrade(); +``` + +If you come across any issues, feel free to report via our [ticket tracker](https://trac.osgeo.org/postgis) +or [mailing list](https://lists.osgeo.org/listinfo/postgis-users) with details + +View all [tickets for 3.5.4 milestone][1]. + +[1]: https://trac.osgeo.org/postgis/query?status=assigned&status=closed&milestone=PostGIS+3.5.4 ----------------------------------------------------------------------- Summary of changes: config.toml | 4 +- content/news/2025/10-16_postgis-3.5.4.md | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 content/news/2025/10-16_postgis-3.5.4.md hooks/post-receive -- postgis.net From git at osgeo.org Thu Oct 16 16:14:28 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 16 Oct 2025 16:14:28 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.4-1-ge1c281533 Message-ID: <20251016231429.234D34D8B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via e1c2815332b04b32b62b7eb29e3324549c5b54c1 (commit) from 2fc837ec43f5acb631613b12117115f5c2654bd2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e1c2815332b04b32b62b7eb29e3324549c5b54c1 Author: Paul Ramsey Date: Thu Oct 16 16:14:23 2025 -0700 Bump versions for 3.5.5dev cycle diff --git a/NEWS b/NEWS index 4b14ae069..72aaf5e0d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +PostGIS 3.5.5 +xxxx/xx/xx + +To take advantage of all postgis_sfcgal extension features SFCGAL 1.5+ is needed. +PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. + +* Bug fixes * + + + + PostGIS 3.5.4 2025/10/16 diff --git a/Version.config b/Version.config index 68af1b6f8..84305269c 100644 --- a/Version.config +++ b/Version.config @@ -5,7 +5,7 @@ POSTGIS_MAJOR_VERSION=3 POSTGIS_MINOR_VERSION=5 -POSTGIS_MICRO_VERSION=4 +POSTGIS_MICRO_VERSION=5dev # Liblwgeom interface versioning, reset to 0:0:0 (cur:age:rev) # when changing POSTGIS_MINOR_VERSION diff --git a/extensions/upgradeable_versions.mk b/extensions/upgradeable_versions.mk index ce55984bd..0a5f85aa9 100644 --- a/extensions/upgradeable_versions.mk +++ b/extensions/upgradeable_versions.mk @@ -113,4 +113,4 @@ UPGRADEABLE_VERSIONS = \ 3.5.1 \ 3.5.2 \ 3.5.3 \ - 3.5.4dev + 3.5.4 ----------------------------------------------------------------------- Summary of changes: NEWS | 11 +++++++++++ Version.config | 2 +- extensions/upgradeable_versions.mk | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 08:53:28 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 15:53:28 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.8904fd3fbbc025eff2e538145812a0e9@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by francoisb): Replying to [comment:12 strk]: > I wouldn't know how we can tell which data was created BEFORE the catalog update and which data was created AFTER it, unless we can compare the transaction identifiers between the rows in the tables and the domain catalog row ? > The upgrade path from 3.6.0 is indeed challenging, because one needs to distinguish: - Topogeometry columns that need fixing, because created before the 3.6.0 upgrade, not somehow manually fixed already, and still have bad values. - Topogeometry columns that do NOT need fixing, because created after the 3.6.0 upgrade (and have correct values to begin with), or the user somehow managed to fix the bad values already. > Or we could use some fuzzy logic to check if any data value would be invalid, and bet on that being caused by the corruption. Exactly. A possible heuristic to answer this: All topogeometry columns have a built-in `CHECK` constraint to enforce a correct `type` subfield (from 1 to 4, depending on layer geometry type). Bad topogeometry values have garbage for this `type` (depending on memory contents, usually 0 at the beginning of a session), which is therefore violating the constraint. An actual value other than the one of the 4 valid ones defined in the `CHECK` constraint, and this in any row of a table, could be a criteria to trigger data recovery path for the entire table. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 17 09:02:59 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 16:02:59 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.69b8e4329b3c4f4ea0400c5e3a863164@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by francoisb): FWIW, in my database (PostgreSQL 16.10, macOS), I was able to recover the topogeometry columns with these two steps: 1) Upgrade the topology to use the bigint feature: {{{ SELECT UpgradeTopology('topo_1'); }}} Note I'm not 100% sure this step is actually needed, but I add it here because I did it. We could test without, and perhaps remove it. 2) Recover `id` and `type` values from the bytes of corrupted `id`, with a query like: {{{ UPDATE table_1 SET topogeom = ( (topogeom).topology_id, (topogeom).layer_id, (topogeom).id & 0xFFFFFFFF, -- 32 least significant bits from corrupted "id" (topogeom).id >> 32 -- 32 most significant bits from corrupted "id" )::topogeometry WHERE topogeom IS NOT NULL RETURNING topogeom; }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 17 09:57:22 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 09:57:22 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-139-g8a5acc9a1 Message-ID: <20251017165723.1A2FF16E564@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 8a5acc9a1b5945db2d50f7126479e74eb2b6eb71 (commit) from 74d24bc78383f8e021cd6300b5aec1d7278b5487 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8a5acc9a1b5945db2d50f7126479e74eb2b6eb71 Author: Paul Ramsey Date: Fri Oct 17 09:57:10 2025 -0700 Break up examples in ST_LineMerge, closes #5842 diff --git a/doc/reference_processing.xml b/doc/reference_processing.xml index 80c16af3f..8f5fd34b9 100644 --- a/doc/reference_processing.xml +++ b/doc/reference_processing.xml @@ -1468,6 +1468,8 @@ FROM test; Examples + + Cardinality 2 @@ -1476,7 +1478,7 @@ FROM test; - Merging lines with different orientation. + Nodes with cardinality 2 are merged away. @@ -1488,7 +1490,9 @@ FROM test; -------------------------------------------- LINESTRING(10 160,60 120,120 140,180 120) - + + +Cardinality 3 or More @@ -1509,7 +1513,10 @@ FROM test; -------------------------------------------- MULTILINESTRING((10 160,60 120,120 140),(100 180,120 140),(120 140,180 120)) + + + Non-Touching Lines If merging is not possible due to non-touching lines, the original MultiLineString is returned. @@ -1519,7 +1526,10 @@ SELECT ST_AsText(ST_LineMerge( ---------------- MULTILINESTRING((-45.2 -33.2,-46 -32),(-29 -27,-30 -29.7,-36 -31,-45 -33)) + + + Directed Parameter @@ -1539,15 +1549,18 @@ TRUE)); ------------------------------------------------------- MULTILINESTRING((120 50,60 30,10 70),(120 50,180 30)) + -Example showing Z-dimension handling. + +Z-dimension Handling SELECT ST_AsText(ST_LineMerge( 'MULTILINESTRING((-29 -27 11,-30 -29.7 10,-36 -31 5,-45 -33 6), (-29 -27 12,-30 -29.7 5), (-45 -33 1,-46 -32 11))' )); --------------------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------- LINESTRING Z (-30 -29.7 5,-29 -27 11,-30 -29.7 10,-36 -31 5,-45 -33 1,-46 -32 11) + See Also ----------------------------------------------------------------------- Summary of changes: doc/reference_processing.xml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 09:57:32 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 16:57:32 -0000 Subject: [PostGIS] #5842: Images belong to the example below or above? In-Reply-To: <049.ff878a7663ab766a398b588c698536ff@osgeo.org> References: <049.ff878a7663ab766a398b588c698536ff@osgeo.org> Message-ID: <064.873c0d3ab284b50a7cdb5f8643e8b976@osgeo.org> #5842: Images belong to the example below or above? ----------------------------+--------------------------- Reporter: jidanni | Owner: robe Type: enhancement | Status: closed Priority: low | Milestone: PostGIS 3.5.5 Component: documentation | Version: 3.4.x Resolution: fixed | Keywords: ----------------------------+--------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"8a5acc9a1b5945db2d50f7126479e74eb2b6eb71/git" 8a5acc9/git]: {{{#!CommitTicketReference repository="git" revision="8a5acc9a1b5945db2d50f7126479e74eb2b6eb71" Break up examples in ST_LineMerge, closes #5842 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 17 10:07:51 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 10:07:51 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-140-g60c6bb4fe Message-ID: <20251017170752.26A1516F463@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 60c6bb4fe2a6a3256ba5daaa6ded1a4c5ebe0e5f (commit) from 8a5acc9a1b5945db2d50f7126479e74eb2b6eb71 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 60c6bb4fe2a6a3256ba5daaa6ded1a4c5ebe0e5f Author: Paul Ramsey Date: Fri Oct 17 10:07:44 2025 -0700 Note the default values for keepcollapsed in ST_MakeValid, closes #6006 diff --git a/doc/reference_validation.xml b/doc/reference_validation.xml index ed94bb362..d824a504b 100644 --- a/doc/reference_validation.xml +++ b/doc/reference_validation.xml @@ -351,22 +351,35 @@ SELECT ST_IsValidReason('LINESTRING(220227 150406,2220227 150407,222020 150410)' - "linework" is the original algorithm, and builds valid geometries + "linework" is the default algorithm, and builds valid geometries by first extracting all lines, noding that linework together, then building - a value output from the linework. + a value output from the linework. The requirement that no vertices are + lost can generate complex collections as outputs. "structure" is an algorithm that distinguishes between interior and exterior rings, building new geometry by unioning - exterior rings, and then differencing all interior rings. + exterior rings, and then differencing all interior rings. The results + tend to be more intuitive, where collapsed lines are discarded in + the output. The "keepcollapsed" key is only valid for the "structure" algorithm, - and takes a value of "true" or "false". When set to "false", - geometry components that collapse to a lower dimensionality, - for example a one-point linestring would be dropped. - + and takes a value of "true" or "false". + + + + Keep collapsed of "false" is the default, and means that + geometry components that collapse to a lower dimensionality, + for example a one-point linestring will be dropped. + + + Keep collapsed of "true" means + geometry components that collapse to a lower dimensionality + will be retained. + + Performed by the GEOS module. ----------------------------------------------------------------------- Summary of changes: doc/reference_validation.xml | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 10:07:59 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 17:07:59 -0000 Subject: [PostGIS] #6006: ST_MakeValid documentation does not state default value for keepcollapsed param In-Reply-To: <049.ad33364d065c708637013c2e61565b8c@osgeo.org> References: <049.ad33364d065c708637013c2e61565b8c@osgeo.org> Message-ID: <064.c7347af5942b23f311bd9c36c3841f06@osgeo.org> #6006: ST_MakeValid documentation does not state default value for keepcollapsed param ----------------------------+--------------------------- Reporter: atlight | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: documentation | Version: 3.5.x Resolution: fixed | Keywords: ----------------------------+--------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"60c6bb4fe2a6a3256ba5daaa6ded1a4c5ebe0e5f/git" 60c6bb4/git]: {{{#!CommitTicketReference repository="git" revision="60c6bb4fe2a6a3256ba5daaa6ded1a4c5ebe0e5f" Note the default values for keepcollapsed in ST_MakeValid, closes #6006 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 17 10:18:05 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 10:18:05 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.4-2-g66694dc2c Message-ID: <20251017171806.21984190709@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 66694dc2c2bad48c80f8230e091e616ce74ff07f (commit) from e1c2815332b04b32b62b7eb29e3324549c5b54c1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 66694dc2c2bad48c80f8230e091e616ce74ff07f Author: Pavel Seleznev Date: Wed Sep 10 16:51:35 2025 +0300 Remove uninitialized variable warning diff --git a/postgis/gserialized_estimate.c b/postgis/gserialized_estimate.c index 453989585..24984e9d7 100644 --- a/postgis/gserialized_estimate.c +++ b/postgis/gserialized_estimate.c @@ -2601,7 +2601,7 @@ Datum gserialized_estimated_extent(PG_FUNCTION_ARGS) int16 attnum, idx_attnum; Oid atttypid = InvalidOid; char nsp_tbl[2*NAMEDATALEN+6]; - char *tbl; + char *tbl = NULL; Oid tbl_oid, idx_oid = 0; ND_STATS *nd_stats; GBOX *gbox = NULL; ----------------------------------------------------------------------- Summary of changes: postgis/gserialized_estimate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 10:19:38 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 17:19:38 -0000 Subject: [PostGIS] #5986: Remove compilation warning on uninitialized variable In-Reply-To: <047.479abb5721ee42c63620d32fe2ca6151@osgeo.org> References: <047.479abb5721ee42c63620d32fe2ca6151@osgeo.org> Message-ID: <062.2b4fc0d8a1a249243950c9840bdcdddb@osgeo.org> #5986: Remove compilation warning on uninitialized variable ---------------------+--------------------------- Reporter: sepal | Owner: strk Type: patch | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: build | Version: 3.5.x Resolution: fixed | Keywords: ---------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed Comment: Cherry picked. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 17 11:29:49 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 18:29:49 -0000 Subject: [PostGIS] #3130: ST_MMin(geometry), ST_MMax(geometry) In-Reply-To: <046.4589eedfbc5bbb0e9a63df79f25fda08@osgeo.org> References: <046.4589eedfbc5bbb0e9a63df79f25fda08@osgeo.org> Message-ID: <061.78b9d92e3fd08643beee719036338b73@osgeo.org> #3130: ST_MMin(geometry), ST_MMax(geometry) --------------------------+----------------------------- Reporter: strk | Owner: strk Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: duplicate | Keywords: --------------------------+----------------------------- Changes (by komzpa): * resolution: => duplicate * status: new => closed Comment: duplicates #2858 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 17 13:16:56 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 13:16:56 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-142-gd7c5ead4d Message-ID: <20251017201656.8D150193019@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via d7c5ead4d9998d34b6a7753bf757981ffdefb326 (commit) from 5cd33ae8d1a9dc8f878ac7792d03566667d1cffc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d7c5ead4d9998d34b6a7753bf757981ffdefb326 Author: Darafei Praliaskouski Date: Sat Oct 18 00:15:20 2025 +0400 Add development environment setup notes Compatible with Codex References #5638 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..683dd6a0b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,245 @@ +# PostGIS development environment + +This document aims to get your development environment up as fast as possible so +you can jump ahead into improving the PostGIS codebase. +It assumes Ubuntu 24.04 as it is current on Codex space as the time of writing. + +This repository does not ship ready-to-run binaries. Contributors are expected to +build PostGIS and its extensions locally and to run the regression suites before +submitting patches. The notes below summarise what the CI images +(https://github.com/postgis/postgis-build-env) provide and adapt them to a plain +Ubuntu host where Docker is unavailable. + +## 1. Base system preparation + +* Work as a user that is allowed to run `sudo`. +* Keep the system lean: always prefer `apt-get` with `--no-install-recommends`. +* Make sure the packaged PostgreSQL client binaries precede any other build you + may already have in `PATH` (see Section 2). + +```bash +sudo apt-get update +sudo apt-get install -y --no-install-recommends \ + autoconf automake autotools-dev \ + bison flex \ + build-essential clang clang-tools clang-format llvm \ + ca-certificates curl wget gnupg \ + ccache cmake ninja-build pkg-config \ + cppcheck \ + gdb valgrind lcov \ + git gettext \ + libcunit1 libcunit1-dev \ + libexpat1-dev libfreexl-dev \ + libgdal-dev gdal-bin \ + libgeos-dev \ + libgmp-dev libmpfr-dev \ + libgsl-dev \ + libjson-c-dev \ + libopenjp2-7-dev libpng-dev libtiff-dev libwebp-dev \ + libpcre3-dev \ + libpq-dev \ + libproj-dev proj-bin \ + libprotobuf-c-dev protobuf-c-compiler \ + libprotobuf-dev protobuf-compiler \ + libsfcgal-dev \ + libsqlite3-dev sqlite3 \ + libspatialite-dev \ + libxml2-dev libxslt1-dev libxml2-utils \ + libyaml-dev \ + postgresql postgresql-client postgresql-server-dev-all \ + python3 python3-distutils python3-pip python3-venv python3-psycopg2 \ + xsltproc docbook-xsl docbook-xsl-ns docbook-xml \ + zlib1g-dev +``` + +This installs software so local workflow can exercise sanitizers, formatters, and coverage reports. + +## 2. Configure PostgreSQL for local testing + +The CI images keep PostgreSQL entirely under `/usr/local/pgsql`. On Ubuntu we +use the packaged server binaries instead. When running as a privileged user (the +typical situation in this environment) reuse the default cluster owned by the +`postgres` system account: + +```bash +export PG_MAJOR=$(pg_config --version | awk '{print $2}' | cut -d. -f1) +export PGHOME=/usr/lib/postgresql/${PG_MAJOR} +export PATH="${PGHOME}/bin:${PATH}" + +# Start the packaged "main" cluster if it is not already online. +sudo -u postgres pg_ctlcluster "${PG_MAJOR}" main start + +# Allow automated tools to connect without prompting for a password by editing the existing local entries. +sudo perl -0pi -e 's/^(host\s+all\s+all\s+127\.0\.0\.1\/32\s+)scram-sha-256/\1trust/m; s/^(host\s+all\s+all\s+::1\/128\s+)scram-sha-256/\1trust/m' \ + /etc/postgresql/${PG_MAJOR}/main/pg_hba.conf +sudo -u postgres pg_ctlcluster "${PG_MAJOR}" main reload + +# Make the current UNIX account a PostgreSQL superuser. +sudo -u postgres createuser -s $(whoami) + +# Alternative: keep SCRAM authentication and set a password for automated tooling. +sudo -u postgres psql -c "ALTER ROLE $(whoami) WITH PASSWORD 'postgres';" +export PGPASSWORD=postgres +``` + +Revert the authentication edits once you finish testing so other users of the system are not left with trust rules in place. + +If you prefer a completely isolated cluster, create an unprivileged build user +and run `initdb` as in the upstream documentation. The remainder of this guide +assumes the packaged cluster is used and listens on the default port 5432. + +## 3. Enable core dumps and logbt (optional but recommended) + +The `ci/github/logbt` helper captures backtraces from crashes. On Ubuntu you +need elevated privileges once to reconfigure the kernel core pattern. + +```bash +sudo ./ci/github/logbt --setup +sudo sysctl kernel.core_pattern +# Keep the directory writable: +sudo mkdir -p /tmp/logbt-coredumps +sudo chmod 1777 /tmp/logbt-coredumps +ulimit -c unlimited +``` + +When running under constrained CI where you cannot change `kernel.core_pattern`, +skip the `logbt` steps; the test suite still runs but you will not get automatic +core backtraces. + +## 4. Build prerequisites + +The following projects are detected automatically via `pkg-config` or helper +scripts during `./configure`. After installing the Ubuntu packages you should +have: + +* GEOS (`geos-config`) +* PROJ (`proj` >= 7) +* GDAL (`gdal-config`) +* JSON-C (`json-c` >= 0.13) +* PROTOBUF-C (for `ST_AsMVT`) +* SFCGAL (for 3D/advanced geometry tests) +* Libxml2, libxslt and docbook stylesheets (for documentation targets) +* Valgrind (for CUnit leak checks) + +Verify their presence if `./configure` fails. + +## 5. Building PostGIS + +```bash +./autogen.sh +./configure \ + --with-jsondir=/usr \ + --with-projdir=/usr \ + --with-raster \ + --with-topology \ + --with-sfcgal +make -j"$(nproc)" +``` + +When iterating repeatedly, `make clean` or `make distclean` may be necessary if +you switch compilers or change major dependencies. + +## 6. Running the regression tests + +Tests expect the PostgreSQL cluster started in section 2 to be running and the +current user to be able to create databases. Export the connection parameters so +every helper uses the same cluster: + +```bash +export PGHOST=127.0.0.1 +export PGPORT=5432 # adjust if your cluster uses another port +export PGUSER=$(whoami) +export PGDATABASE=postgres +``` + +Before running the tests, install the freshly built artifacts into PostgreSQL so +that the regression harness can locate the control files and shared libraries: + +```bash +sudo make install +``` + +Execute the same test targets used in CI: + +```bash +# Standard compile + regression suite +make check RUNTESTFLAGS="--verbose --extension --raster --topology --sfcgal --tiger" + +# Undefined behaviour sanitiser runs +CC=clang ./configure CFLAGS="-g3 -O0 -fno-omit-frame-pointer -fsanitize=undefined" LDFLAGS="-fsanitize=undefined" +make -j"$(nproc)" +make check RUNTESTFLAGS="--verbose --extension --raster --topology --sfcgal" + +# Coverage build (requires lcov and a clean tree) +make distclean +CFLAGS="-g -O0 --coverage" LDFLAGS="--coverage" ./configure --enable-debug \ + --with-jsondir=/usr --with-projdir=/usr --with-raster --with-topology --with-sfcgal +make -j"$(nproc)" +make check RUNTESTFLAGS="--verbose --extension --raster --topology --sfcgal" +``` + +Additional targets of interest: + +* `make garden` ? runs documentation and extra QA checks. +* `make check RUNTESTFLAGS="--upgrade --extension --verbose"` ? exercises + extension upgrade paths; make sure `sudo make install` has been executed into + the same PostgreSQL instance before invoking this. +* `make installcheck` ? runs tests against an installed copy (after `make install`). + +## 7. Inspecting coverage results + +Coverage builds rely on the `lcov` utilities. After executing the coverage `make check` run: + +```bash +# Capture data from the build tree +lcov --capture --directory . --output-file coverage.info + +# Optionally filter out system libraries and generated files +lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage.filtered.info + +# Produce an HTML report for browsing +genhtml coverage.filtered.info --output-directory coverage-html + +# Quickly spot uncovered lines in the terminal +lcov --list coverage.filtered.info | less +``` + +Open `coverage-html/index.html` in a browser or upload the report to your CI +artifacts to explore missing lines interactively. + +If you rely on the `ci/github/run_*.sh` wrappers, export `PGHOME` and `PGDATA` as +shown above and replace `/usr/local/pgsql/bin/pg_ctl` in those scripts with the +packaged location or create a symlink at `/usr/local/pgsql/bin` pointing to +`${PGHOME}/bin`. + +## 8. Cleaning up + +To reclaim disk space: + +```bash +sudo -u postgres pg_ctlcluster "${PG_MAJOR}" main stop +sudo rm -rf /tmp/logbt-coredumps +``` + +If you created a private cluster instead of using the packaged one, stop it with +`pg_ctl -D "$PGDATA" stop` and remove the data directory manually. + +## 9. Maintaining formatting + +Before submitting patches that modify C or C++ files, run clang-format only on +the relevant hunks to avoid unrelated churn: + +```bash +git clang-format +``` + +The command formats staged changes by default. Use `git clang-format ` to +reflow a specific range, or pass `--extensions c,cpp,h` when touching files with +non-standard suffixes. Validate that the resulting diff stays focused on the +code you touched. + +Review STYLE file in root of the repository for other stylistic preferences. + +The Codecov upload commands in `ci/github/run_coverage.sh` and +`ci/github/run_garden.sh` require outbound network access; they are harmless to +ignore locally. ----------------------------------------------------------------------- Summary of changes: AGENTS.md | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 AGENTS.md hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 13:16:58 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 20:16:58 -0000 Subject: [PostGIS] #5638: Need some more developer documentation In-Reply-To: <046.6065d6cbf765554938200b84f3bea454@osgeo.org> References: <046.6065d6cbf765554938200b84f3bea454@osgeo.org> Message-ID: <061.98c9c40433a6c00f830464d8de0198bc@osgeo.org> #5638: Need some more developer documentation ----------------------------+--------------------------- Reporter: robe | Owner: robe Type: task | Status: new Priority: critical | Milestone: PostGIS 3.7.0 Component: documentation | Version: 3.4.x Resolution: | Keywords: ----------------------------+--------------------------- Comment (by Darafei Praliaskouski ): In [changeset:"d7c5ead4d9998d34b6a7753bf757981ffdefb326/git" d7c5ead/git]: {{{#!CommitTicketReference repository="git" revision="d7c5ead4d9998d34b6a7753bf757981ffdefb326" Add development environment setup notes Compatible with Codex References #5638 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 17 13:47:48 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 13:47:48 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-143-gfd358eeaf Message-ID: <20251017204749.0C966193D22@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via fd358eeafb64d35535d6650aeb308cf8852665c9 (commit) from d7c5ead4d9998d34b6a7753bf757981ffdefb326 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fd358eeafb64d35535d6650aeb308cf8852665c9 Author: Darafei Date: Fri Oct 17 19:19:11 2025 +0000 Translated PostGIS Manual using Weblate (Belarusian) Currently translated at 0.3% (20 of 5857 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/be/ diff --git a/doc/po/be/postgis-manual.po b/doc/po/be/postgis-manual.po index 5ef301da5..3b1e49857 100644 --- a/doc/po/be/postgis-manual.po +++ b/doc/po/be/postgis-manual.po @@ -5,28 +5,32 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-08-21 03:28+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2025-10-17 20:47+0000\n" +"Last-Translator: Darafei \n" +"Language-Team: Belarusian \n" "Language: be\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 5.4.3\n" #. Tag: chapter #, no-c-format msgid "&database_tuning;" -msgstr "" +msgstr "&database_tuning;" #. Tag: title #, no-c-format msgid "PostGIS Administration" -msgstr "" +msgstr "??????????????? PostGIS" #. Tag: title #, no-c-format msgid "Configuring raster support" -msgstr "" +msgstr "??????????? ????????? ???????" #. Tag: para #, no-c-format @@ -34,6 +38,7 @@ msgid "" "If you enabled raster support you may want to read below how to properly " "configure it." msgstr "" +"???? ?? ???????? ????????? ???????, ????? ???????, ?? ?? ????????? ?????????." #. Tag: para #, no-c-format @@ -45,16 +50,24 @@ msgid "" "For PostGIS 2.2, you can use the more cross-platform approach of setting the " "corresponding ." msgstr "" +"????????? ? PostGIS 2.1.3, ??????????? ?????? ? ??? ???????? ??????? ?? " +"????????? ?????????. ??? ?? ????????, ??????? ? ????????? ??????? ?????????? " +"POSTGIS_GDAL_ENABLED_DRIVERS ? " +"POSTGIS_ENABLE_OUTDB_RASTERS. ? PostGIS 2.2 ????? " +"??????????? ????? ????????????????? ????????? ? ????????? ?????????? ." #. Tag: para #, no-c-format msgid "If you want to enable offline raster:" -msgstr "" +msgstr "???? ?? ?????? ???????? ??????????? ??????:" #. Tag: para #, no-c-format msgid "Any other setting or no setting at all will disable out of db rasters." msgstr "" +"???? ???? ???????? ??? ??? ?????????? ???????? ?? ?????????? ??????????? " +"???????." #. Tag: para #, no-c-format @@ -62,6 +75,8 @@ msgid "" "In order to enable all GDAL drivers available in your GDAL install, set this " "environment variable as follows" msgstr "" +"??? ???????? ??? ???????? GDAL, ????????? ? ????? ????????? GDAL, ??????? " +"?????????? ????????? ????????? ?????" #. Tag: para #, no-c-format @@ -69,11 +84,12 @@ msgid "" "If you want to only enable specific drivers, set your environment variable " "as follows:" msgstr "" +"???? ????? ???????? ?????? ?????? ????????, ??????? ?????????? ????????? ???:" #. Tag: para #, no-c-format msgid "If you are on windows, do not quote the driver list" -msgstr "" +msgstr "? Windows ?? ?????? ???? ????????? ? ????????." #. Tag: para #, no-c-format @@ -84,6 +100,11 @@ msgid "" "main/environment where 10 refers to " "version of PostgreSQL and main refers to the cluster." msgstr "" +"?????? ?????????? ????????? ???????? ?? ??. ??? PostgreSQL, ???????????? ? " +"Ubuntu ??? Debian ???? apt-postgresql, ????????? ?????????? /etc/" +"postgresql/" +"10/main/environment, ??? 10 ? ?????? PostgreSQL, ? main ? ????? ????????." #. Tag: para #, no-c-format @@ -95,6 +116,11 @@ msgid "" "clicking Advanced System Settings ->Advanced->Environment " "Variables and adding new system variables." msgstr "" +"? Windows, ???? PostgreSQL ?????? ?? ??????, ??????? ????????? ??????????: " +"??? ?? Computer -> Properties -> Advanced System Settings, ??? ???? " +"Control Panel\\All Control Panel Items\\System. ????? " +"Advanced System Settings -> Advanced -> Environment " +"Variables ? ??????? ????? ????????? ??????????." #. Tag: para #, no-c-format @@ -102,16 +128,18 @@ msgid "" "After you set the environment variables, you'll need to restart your " "PostgreSQL service for the changes to take effect." msgstr "" +"????? ?????? ? ?????????? ????????? ????????????? ?????? PostgreSQL, ??? ??? " +"???????? ? ????." #. Tag: title #, no-c-format msgid "Creating spatial databases" -msgstr "" +msgstr "????????? ??????????? ??? ????????" #. Tag: title #, no-c-format msgid "Spatially enable database using EXTENSION" -msgstr "" +msgstr "??????????? ????????? ???? ???? EXTENSION" #. Tag: para #, no-c-format @@ -120,6 +148,9 @@ msgid "" "extensions/postgis modules, you can turn a database into a spatial one using " "the EXTENSION mechanism." msgstr "" +"???? ?? ??????????????? PostgreSQL 9.1+ ? ??????? ?? ?????????? ?????? " +"extensions/postgis, ?? ?????? ??????? ???? ??????????? ???? ???????? " +"EXTENSION." #. Tag: para #, no-c-format @@ -128,17 +159,19 @@ msgid "" "the functions and comments. Raster and topology are packaged as a separate " "extension." msgstr "" +"??????? ????????? postgis ??????? geometry, geography, spatial_ref_sys ? ??? " +"??????? ? ???????????. Raster ? topology ???????????? ?? ??????? ?????????." #. Tag: para #, no-c-format msgid "" "Run the following SQL snippet in the database you want to enable spatially:" -msgstr "" +msgstr "????????? ???????? ???????? SQL ? ????, ???? ????? ?????????? ????????:" #. Tag: title #, no-c-format msgid "Spatially enable database without using EXTENSION (discouraged)" -msgstr "" +msgstr "??????????? ????????? ???? ??? EXTENSION (?? ?????????????)" #. Tag: para #, no-c-format @@ -147,148 +180,181 @@ msgid "" "installed in the PostgreSQL extension directory (for example during testing, " "development or in a restricted environment)." msgstr "" +"???? ???????? ?????? ???? ?? ?? ?????? ??? ?? ?????? ??????????? PostGIS ? " +"?????????? ?????????? PostgreSQL (????????? ??? ??????????, ??????????? ??? " +"? ??????????? ?????????)." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Adding PostGIS objects and function definitions into your database is done " "by loading the various sql files located in [prefix]/share/" "contrib as specified during the build phase." msgstr "" +"????????? ??'????? ? ??????? PostGIS ? ???? ??????? ????????? sql-?????? ? " +"[prefix]/share/contrib, ?? ???? ????????? ?????? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "The core PostGIS objects (geometry and geography types, and their support " "functions) are in the postgis.sql script. Raster " "objects are in the rtpostgis.sql script. Topology " "objects are in the topology.sql script." msgstr "" +"???????? ??'???? PostGIS (???? geometry ? geography ? ?? ???????) ? " +"postgis.sql. ?????? ? ? rtpostgis.sql. ????????? ? ? topology.sql." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "For a complete set of EPSG coordinate system definition identifiers, you can " "also load the spatial_ref_sys.sql definitions file and " "populate the spatial_ref_sys table. This will permit you " "to perform ST_Transform() operations on geometries." msgstr "" +"??? ??????? ?????? ??????????????? EPSG ????? ????????? " +"spatial_ref_sys.sql ? ????????? ??????? " +"spatial_ref_sys. ???? ????????? ?????????? ST_Transform()." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you wish to add comments to the PostGIS functions, you can find them in " "the postgis_comments.sql script. Comments can be viewed " "by simply typing \\dd [function_name] from a " "psql terminal window." msgstr "" +"????????? ?? ??????? PostGIS ??????????? ? postgis_comments.sql. ??????????? ?? ????? ???? \\dd [function_name] " +"? psql." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Run the following Shell commands in your terminal:" -msgstr "" +msgstr "????????? ? ????????? ????????? ??????? Shell:" #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Upgrading spatial databases" -msgstr "" +msgstr "?????????? ??????????? ??? ????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Upgrading existing spatial databases can be tricky as it requires " "replacement or introduction of new PostGIS object definitions." msgstr "" +"?????????? ???????? ??????????? ??? ???? ???? ?????????, ?? ???????? ?????? " +"??? ??????? ????? ??????????? ??'????? PostGIS." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Unfortunately not all definitions can be easily replaced in a live database, " "so sometimes your best bet is a dump/reload process." msgstr "" +"?? ??? ?????????? ????? ?????? ???????? ? ????? ????, ???? ????? ???? ?? ??? " +"??????? ???? ? ??????????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "PostGIS provides a SOFT UPGRADE procedure for minor or bugfix releases, and " "a HARD UPGRADE procedure for major releases." msgstr "" +"PostGIS ???????? ????????? ??????? ?????????? ??? ???????? ? ???????????? " +"??????? ? ??????? ?????????? ??? ????????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Before attempting to upgrade PostGIS, it is always worth to backup your " "data. If you use the -Fc flag to pg_dump you will always be able to restore " "the dump with a HARD UPGRADE." msgstr "" +"????? ??????????? ??????? ?????????? ??????????? ?????. ???? ?????????????? " +"???? -Fc ? pg_dump, ?? ??????? ??????? ???????? ???? ??? ??????? ??????????." #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Soft upgrade" -msgstr "" +msgstr "?????? ??????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you installed your database using extensions, you'll need to upgrade " "using the extension model as well. If you installed using the old sql script " "way, you are advised to switch your install to extensions because the script " "way is no longer supported." msgstr "" +"???? ???? ??????????? ???? extensions, ????????? ????? ??????? ???? ??. ???? " +"????????? ??????? ??????? sql-?????????, ???? ???????? ?? extensions, ?? " +"?????? ?? ????????? ????? ?? ???????????????." #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Soft Upgrade 9.1+ using extensions" -msgstr "" +msgstr "?????? ?????????? 9.1+ ???? extensions" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you originally installed PostGIS with extensions, then you need to " "upgrade using extensions as well. Doing a minor upgrade with extensions, is " "fairly painless." msgstr "" +"???? PostGIS ??? ?????????? ???? extensions, ?????????? ??????? ??????? ???? " +"??. ???????? ?????????? ???? extensions ???????? ??????????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you are running PostGIS 3 or above, then you should use the function to upgrade to the latest " "version you have installed." msgstr "" +"? PostGIS 3 ? ????? ???????????? ???????? , ??? ???????? ?? ??????? ??????????? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "If you are running PostGIS 2.5 or lower, then do the following:" -msgstr "" +msgstr "???? ? ??? PostGIS 2.5 ??? ?????, ??????? ?????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you have multiple versions of PostGIS installed, and you don't want to " "upgrade to the latest, you can explicitly specify the version as follows:" msgstr "" +"???? ?????????? ???????? ?????? PostGIS ? ?? ?? ?????? ?????????? ?? ????? " +"?????, ????? ??????? ????????? ????????? ?????? ???:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "If you get an error notice something like:" -msgstr "" +msgstr "???? ?? ???????? ???????????? ??? ???????, ????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Then you'll need to backup your database, create a fresh one as described in " " and then restore your backup on " "top of this new database." msgstr "" +"????? ??????? ????? ????, ???????? ?????, ?? ??????? ? , ? ???????? ????? ? ??." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "If you get a notice message like:" -msgstr "" +msgstr "???? ?? ??????? ???????????? ????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Then everything is already up to date and you can safely ignore it. " "UNLESS you're attempting to upgrade from " @@ -296,97 +362,125 @@ msgid "" "in that case you can append \"next\" to the version string, and next time " "you'll need to drop the \"next\" suffix again:" msgstr "" +"???????, ??? ??? ??????????, ? ???? ????? ??????????. ?????? ???????? ? development-?????? ?? ????????? ??? ?????? " +"??????. ???? ????? ?????? ?????? \"next\" ?? ????? ??????, ? ? ???????? ??? " +"??? ????? ????? ????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you installed PostGIS originally without a version specified, you can " "often skip the reinstallation of postgis extension before restoring since " "the backup just has CREATE EXTENSION postgis and thus picks up " "the newest latest version during restore." msgstr "" +"???? PostGIS ?????????????? ???????????? ??? ?????????? ??????, ????? ????? " +"?? ??????????????? ????????? ????? ???????????: ? ?????? ????? CREATE " +"EXTENSION postgis, ? ??? ?????????? ??????????? ????????? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you are upgrading PostGIS extension from a version prior to 3.0.0, you " "will have a new extension postgis_raster which you can " "safely drop, if you don't need raster support. You can drop as follows:" msgstr "" +"???? ???????????? ? ?????? ????????? ?? 3.0.0, ?'?????? ????? ????????? " +"postgis_raster. ???? ?????? ?? ?????????, ??? ????? " +"???????? ???????? ???:" #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Soft Upgrade Pre 9.1+ or without extensions" -msgstr "" +msgstr "?????? ?????????? ??? Pre 9.1+ ??? ??? extensions" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "This section applies only to those who installed PostGIS not using " "extensions. If you have extensions and try to upgrade with this approach " "you'll get messages like:" msgstr "" +"???? ??????? ?????? ??? ????????? ??? extensions. ???? ??? ? ??? ???? ? ?? " +"??????????? ???? ???????, ????????? ???????????? ???????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "NOTE: if you are moving from PostGIS 1.* to PostGIS 2.* or from PostGIS 2.* " "prior to r7409, you cannot use this procedure but would rather need to do a " "HARD UPGRADE." msgstr "" +"???????: ??? ????????? ? PostGIS 1.* ?? 2.* ??? ? PostGIS 2.* ?? r7409 " +"?????????? ????? ?????????? ?????? ? ???????? ??????? ??????????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "After compiling and installing (make install) you should find a set of " "*_upgrade.sql files in the installation folders. You " "can list them all with:" msgstr "" +"????? ?????? ? ????????? (make install) ?? ????????? ????? ?????? " +"*_upgrade.sql ? ????????????? ??????. ?????????? ?? " +"???? ????? ???:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Load them all in turn, starting from postgis_upgrade.sql." msgstr "" +"????????? ?? ??? ?? ???????, ????????? ? postgis_upgrade." +"sql." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "The same procedure applies to raster, topology and sfcgal extensions, with " "upgrade files named rtpostgis_upgrade.sql, " "topology_upgrade.sql and sfcgal_upgrade.sql respectively. If you need them:" msgstr "" +"?????????? ??? raster, topology ? sfcgal: ????? rtpostgis_upgrade." +"sql, topology_upgrade.sql ? " +"sfcgal_upgrade.sql ?????????. ???? ??? ?????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "You are advised to switch to an extension based install by running" -msgstr "" +msgstr "??????????? ???????? ?? ????????? ???? extensions, ?????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If you can't find the postgis_upgrade.sql specific for " "upgrading your version you are using a version too early for a soft upgrade " "and need to do a HARD UPGRADE." msgstr "" +"???? ?? ?????????? ????????? ????? ?????? postgis_upgrade.sql, ???? ?????? ??????? ?????? ??? ??????? ?????????? ? ???????? " +"??????? ??????????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "The function should inform you " "about the need to run this kind of upgrade using a \"procs need upgrade\" " "message." msgstr "" +"??????? ?????????? ??? ??????? ? " +"????? ?????????? ?????? \"procs need upgrade\"." #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Hard upgrade" -msgstr "" +msgstr "??????? ??????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "By HARD UPGRADE we mean full dump/reload of postgis-enabled databases. You " "need a HARD UPGRADE when PostGIS objects' internal storage changes or when " @@ -394,9 +488,13 @@ msgid "" "Notes appendix reports for each version whether you need a dump/" "reload (HARD UPGRADE) to upgrade." msgstr "" +"??????? ?????????? ? ???? ????? ???? ? ?????????? ??? ? PostGIS. ??? " +"???????? ??? ????? ?????????? ??????? ??'????? PostGIS ??? ???? ?????? " +"?????????? ?????????. ? Release Notes " +"???????????, ?? ???????? ???? ? ?????????? ??? ?????? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "The dump/reload process is assisted by the postgis_restore script which " "takes care of skipping from the dump all definitions which belong to PostGIS " @@ -404,40 +502,52 @@ msgid "" "database with PostGIS installed without getting duplicate symbol errors or " "bringing forward deprecated objects." msgstr "" +"?????? postgis_restore ????????? ?????????? ? ????? ??? ??????????, ???? " +"????????? ?? PostGIS (? ??? ???? ??????), ??? ???????? ???????? ????? ? " +"????? ? ???? ? ??? ??????????? PostGIS ??? ?????? ? ??? ???????? ?????????? " +"??'?????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Supplementary instructions for windows users are available at Windows Hard " "upgrade." msgstr "" +"?????????? ?????????? ??? Windows: Windows Hard upgrade." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "The Procedure is as follows:" -msgstr "" +msgstr "????????? ?????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Create a \"custom-format\" dump of the database you want to upgrade (let's " "call it olddb) include binary blobs (-b) and verbose (-v) " "output. The user can be the owner of the db, need not be postgres super " "account." msgstr "" +"???????? ???? ? ??????? \"custom\" ??? ???? olddb, " +"????????? ???????? ??'???? (-b) ? ?????????? ????? (-v). ???????????? ???? " +"???? ???????????? ????, ?? ?????????? superuser." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Do a fresh install of PostGIS in a new database -- we'll refer to this " "database as newdb. Please refer to and " "for instructions on how to do this." msgstr "" +"??????? ?????? ????????? PostGIS ? ????? ???? ? ??????? ?? newdb. ????????????? ? ? ." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "The spatial_ref_sys entries found in your dump will be restored, but they " "will not override existing ones in spatial_ref_sys. This is to ensure that " @@ -445,9 +555,13 @@ msgid "" "If for any reason you really want your own overrides of standard entries " "just don't load the spatial_ref_sys.sql file when creating the new db." msgstr "" +"?????? spatial_ref_sys ? ????? ?????? ?????????, ??? ?? ?????????? ????????. " +"???? ????????, ??? ??????????? ? ?????????? ?????? ??????? ? ?????????? " +"????. ???? ??? ???????? ???? ?????????? ??????????? ???????, ?????? ?? " +"?????????? spatial_ref_sys.sql ??? ????????? ????? ????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "If your database is really old or you know you've been using long deprecated " "functions in your views and functions, you might need to load " @@ -457,22 +571,29 @@ msgid "" "functions can be later removed by loading uninstall_legacy.sql." msgstr "" +"???? ???? ?????? ?????? ??? ?? ??????????? ????? ??????????? ????????? ? " +"view ? function, ???? ??????????? ????????? legacy.sql, " +"??? ??? ?????????. ?????? ???? ?????? ???? ???????? ?????. ????, ???? " +"???????, ???????? view ? function ????? ??????. ?????????? ????? ????? " +"???????? ???? uninstall_legacy.sql." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Restore your backup into your fresh newdb database using " "postgis_restore. Unexpected errors, if any, will be printed to the standard " "error stream by psql. Keep a log of those." msgstr "" +"???????? ????? ? ????? ???? newdb ???? postgis_restore. " +"????????? ??????? psql ??????? ? stderr. ?????????? ???." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Errors may arise in the following cases:" -msgstr "" +msgstr "??????? ???????? ? ????????? ????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Some of your views or functions make use of deprecated PostGIS objects. In " "order to fix this you may try loading legacy.sql script " @@ -482,9 +603,14 @@ msgid "" "to fix your code to stop using deprecated functions and drop them loading " "uninstall_legacy.sql." msgstr "" +"????????? ???? view ??? function ??????????????? ?????????? ??'???? PostGIS. " +"??????????? ????????? legacy.sql ????? ??????????? ??? " +"???????????? ? ?????? PostGIS, ??? ??? ???? ????, ? ????? ???????? ???. ???? " +"???? ? legacy.sql ???????, ?? ??????????? ???????? ??? " +"? ???????? ?????????? ???? uninstall_legacy.sql." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Some custom records of spatial_ref_sys in dump file have an invalid SRID " "value. Valid SRID values are bigger than 0 and smaller than 999000. Values " @@ -495,15 +621,26 @@ msgid "" "invariant to hold and possibly also its primary key ( when multiple invalid " "SRIDS get converted to the same reserved SRID value )." msgstr "" +"????????? ???? ??????? ?????? spatial_ref_sys ? ????? ????? ?????????? SRID. " +"????????? SRID ? ????? ?? 0 ? ???? ?? 999000. ???????? 999000..999999 " +"????????????? ??? ?????????? ????????????, ? ???????? > 999999 " +"??????????????. ??? ???? ????? ?????? ?????? ?????????, ??? ????? ???????? " +"> 999999 ?????? ?????????? ? ????????????? ????????, ??? ? ??????? " +"spatial_ref_sys ?????? ???????? ?, ???????, ???????? ???? (???? ???????? " +"??????????? SRID ?????????????? ? ????? ????????????? SRID)." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "In order to fix this you should copy your custom SRS to a SRID with a valid " "value (maybe in the 910000..910999 range), convert all your tables to the " "new srid (see ), delete the invalid " "entry from spatial_ref_sys and re-construct the check(s) with:" msgstr "" +"??? ?????????, ?????????? ??? SRS ?? ???????? SRID (????????? 910000..910999)" +", ??????????????? ??? ??????? ?? ???? SRID (??. ), ???????? ?????????? ????? ? spatial_ref_sys ? " +"???????? ????????:" #. Tag: para #, no-c-format @@ -538,90 +675,106 @@ msgid "" msgstr "" #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Performance Tuning" -msgstr "" +msgstr "??????? ??????????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Tuning for PostGIS performance is much like tuning for any PostgreSQL " "workload. The only additional consideration is that geometries and rasters " "are usually large, so memory-related optimizations generally have more of an " "impact on PostGIS than other types of PostgreSQL queries." msgstr "" +"??????? ?????????????? PostGIS ???????? ?? ??????? ?????? ???????????? " +"???????? PostgreSQL. ??????????? ? ???, ??? ????????? ? ?????? ????? " +"???????, ???? ???????????, ???????? ? ???????, ????? ???? ??????? ????????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "For general details about optimizing PostgreSQL, refer to Tuning your PostgreSQL Server." msgstr "" +"??????????? ??? ???????? ??????????? PostgreSQL: Tuning your " +"PostgreSQL Server." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "For PostgreSQL 9.4+ configuration can be set at the server level without " "touching postgresql.conf or postgresql.auto.conf " "by using the ALTER SYSTEM command." msgstr "" +"? PostgreSQL 9.4+ ????? ???????? ???????????? ?? ??????? ??????? ???????? " +"ALTER SYSTEM ??? ???????? postgresql.conf ??? " +"postgresql.auto.conf." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "In addition to the Postgres settings, PostGIS has some custom settings which " "are listed in ." msgstr "" +"?????? ????? Postgres, ? PostGIS ???? ???? ?????? ? ???????? ." #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Startup" -msgstr "" +msgstr "??????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "These settings are configured in postgresql.conf:" -msgstr "" +msgstr "????? ????????? ???????????? ? postgresql.conf:" #. Tag: link -#, no-c-format +#, fuzzy, no-c-format msgid "constraint_exclusion" -msgstr "" +msgstr "constraint_exclusion" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Default: partition" -msgstr "" +msgstr "?? ?????????: partition" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "This is generally used for table partitioning. The default for this is set " "to \"partition\" which is ideal for PostgreSQL 8.4 and above since it will " "force the planner to only analyze tables for constraint consideration if " "they are in an inherited hierarchy and not pay the planner penalty otherwise." msgstr "" +"???????????????? ??? ??????????????? ??????. ???????? \"partition\" " +"??????????? ????????? ? PostgreSQL 8.4: ???????????? ??????? ??????????? " +"?????? ??? ?????? ? ???????? ??????????? ? ?? ?????? ??????? ???????." #. Tag: link -#, no-c-format +#, fuzzy, no-c-format msgid "shared_buffers" -msgstr "" +msgstr "shared_buffers" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Default: ~128MB in PostgreSQL 9.6" -msgstr "" +msgstr "?? ?????????: ???? 128 ?? ? PostgreSQL 9.6" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Set to about 25% to 40% of available RAM. On windows you may not be able to " "set as high." msgstr "" +"?????? ???? 25%?40% ????????? RAM. ? Windows ???? ?? ???????????? ????????? " +"??? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "max_worker_processes " @@ -629,84 +782,100 @@ msgid "" "setting has additional importance in that it controls the max number of " "processes you can have for parallel queries." msgstr "" +"max_worker_processes " +"???????? ? PostgreSQL 9.4+. ? 9.6+ ??????? ?????????? ???????? ???????? ??? " +"??????????? ???????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Default: 8" -msgstr "" +msgstr "?? ?????????: 8" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Sets the maximum number of background processes that the system can support. " "This parameter can only be set at server start." msgstr "" +"???????? ???????????? ????????? ??????? ????????. ????? ?????? ?????? ??? " +"?????? ???????." #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "Runtime" -msgstr "" +msgstr "??? ?????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "work_mem - sets the size of " "memory used for sort operations and complex queries" msgstr "" +"work_mem ? ????? ?????? ??? " +"?????????? ? ????????? ????????" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Default: 1-4MB" -msgstr "" +msgstr "?? ?????????: 1?4 ??" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Adjust up for large dbs, complex queries, lots of RAM" -msgstr "" +msgstr "???????????? ??? ??????? ???, ????????? ??????? ? ???? ???? RAM" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Adjust down for many concurrent users or low RAM." -msgstr "" +msgstr "????????? ??? ??????? ?????????????? ??? ???????? RAM." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "If you have lots of RAM and few developers:" -msgstr "" +msgstr "???? ???? RAM ? ???? ??????????? ??????????????:" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "maintenance_work_mem " "- the memory size used for VACUUM, CREATE INDEX, etc." msgstr "" +"maintenance_work_mem ?" +" ?????? ??? VACUUM, CREATE INDEX ? ???." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Default: 16-64MB" -msgstr "" +msgstr "?? ?????????: 16?64 ??" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Generally too low - ties up I/O, locks objects while swapping memory" msgstr "" +"???????? ??????? ???? ? ????????? I/O ? ?????? ??'????, ???? ?????????? " +"??????? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Recommend 32MB to 1GB on production servers w/lots of RAM, but depends on " "the # of concurrent users. If you have lots of RAM and few developers:" msgstr "" +"??????????? 32 ?? ? 1 ?? ?? ????????-???????? ? ??????? RAM, ??? ???????? ?? " +"??????????????. ???? RAM ???? ? ?????????????? ????:" #. Tag: link -#, no-c-format +#, fuzzy, no-c-format msgid "max_parallel_workers_per_gather" -msgstr "" +msgstr "max_parallel_workers_per_gather" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "This setting is only available for PostgreSQL 9.6+ and will only affect " "PostGIS 2.3+, since only PostGIS 2.3+ supports parallel queries. If set to " @@ -717,14 +886,19 @@ msgid "" "make sure to bump up max_worker_processes to at least as high " "as this number." msgstr "" +"???????? ? PostgreSQL 9.6+ ? ??????? ?? PostGIS 2.3+, ?? ?????? ?? " +"???????????? ??????????? ??????. ???? > 0, ????????? ?????? (????????? ? " +"ST_Intersects) ??????? ????????? ? ????????? ???????? ? " +"??????????? ? ????. ???? ?????????? ???? ? ???????? ?????????? ???????? ? " +"????????? max_worker_processes ?? ??????? ?? ?????? ? ???????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "Default: 0" -msgstr "" +msgstr "?? ?????????: 0" #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Sets the maximum number of workers that can be started by a single " "Gather node. Parallel workers are taken from the pool of " @@ -734,11 +908,15 @@ msgid "" "may be inefficient. Setting this value to 0, which is the default, disables " "parallel query execution." msgstr "" +"???????? ???????? ??? ?????? ????? Gather. ??????? " +"??????? ? ???? max_worker_processes. ???????? ????????? " +"????????? ???? ???? ??????, ? ???? ?????? ? ?????? ????????? ????????. " +"???????? 0 ???????? ?????????????." #. Tag: title -#, no-c-format +#, fuzzy, no-c-format msgid "PostGIS Extras" -msgstr "" +msgstr "??????? PostGIS" #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/be/postgis-manual.po | 414 +++++++++++++++++++++++++++++++------------- 1 file changed, 296 insertions(+), 118 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Oct 17 15:15:26 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 15:15:26 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-144-g863681495 Message-ID: <20251017221526.B2DAA194EE2@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 8636814957602317b35130153770a06bfcb1784b (commit) from fd358eeafb64d35535d6650aeb308cf8852665c9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8636814957602317b35130153770a06bfcb1784b Author: Darafei Praliaskouski Date: Sat Oct 18 02:14:27 2025 +0400 Add notes on how to run single test References #5638 diff --git a/AGENTS.md b/AGENTS.md index 683dd6a0b..61b9fe6f8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -186,6 +186,33 @@ Additional targets of interest: the same PostgreSQL instance before invoking this. * `make installcheck` ? runs tests against an installed copy (after `make install`). +### Running a single C unit test + +After building the tree (Section 5), you can exercise one CUnit suite in +isolation. From the repository root run: + +```bash +cd liblwgeom/cunit +make cu_tester +./cu_tester geodetic # replace "geodetic" with another suite or test name as needed +``` + +The `cu_tester` binary also accepts individual test names if you need to drill +down further. + +### Running a single SQL regression test + +With PostgreSQL running as configured above and the extension installed via +`sudo make install`, target one SQL file by passing it to the regression driver: + +```bash +export PGPASSWORD=postgres # or reuse another password if you kept SCRAM auth +make -C regress check RUNTESTFLAGS="--extension" TESTS="$(pwd)/regress/core/affine" +``` + +Swap `regress/core/affine` for the test you need. + + ## 7. Inspecting coverage results Coverage builds rely on the `lcov` utilities. After executing the coverage `make check` run: @@ -238,7 +265,10 @@ reflow a specific range, or pass `--extensions c,cpp,h` when touching files with non-standard suffixes. Validate that the resulting diff stays focused on the code you touched. -Review STYLE file in root of the repository for other stylistic preferences. +Review `STYLE` file in root of the repository for other stylistic preferences. +For release policies, upgrade implications, and naming +conventions for new features, skim `doc/developer.md` (PostGIS Developer +How-To) for a concise overview of those workflows. The Codecov upload commands in `ci/github/run_coverage.sh` and `ci/github/run_garden.sh` require outbound network access; they are harmless to ----------------------------------------------------------------------- Summary of changes: AGENTS.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 15:15:29 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 17 Oct 2025 22:15:29 -0000 Subject: [PostGIS] #5638: Need some more developer documentation In-Reply-To: <046.6065d6cbf765554938200b84f3bea454@osgeo.org> References: <046.6065d6cbf765554938200b84f3bea454@osgeo.org> Message-ID: <061.e0936a7dbeb7a09279e79c0a8132265c@osgeo.org> #5638: Need some more developer documentation ----------------------------+--------------------------- Reporter: robe | Owner: robe Type: task | Status: new Priority: critical | Milestone: PostGIS 3.7.0 Component: documentation | Version: 3.4.x Resolution: | Keywords: ----------------------------+--------------------------- Comment (by Darafei Praliaskouski ): In [changeset:"8636814957602317b35130153770a06bfcb1784b/git" 8636814/git]: {{{#!CommitTicketReference repository="git" revision="8636814957602317b35130153770a06bfcb1784b" Add notes on how to run single test References #5638 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 17 23:10:06 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 23:10:06 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-145-g362287e12 Message-ID: <20251018061006.870E7196F38@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 362287e12869aa13a34cc15d240ebe690f0cc9c9 (commit) from 8636814957602317b35130153770a06bfcb1784b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 362287e12869aa13a34cc15d240ebe690f0cc9c9 Author: Darafei Praliaskouski Date: Sat Oct 18 10:09:27 2025 +0400 doc: fix CI build (refsect1 -> refsection) diff --git a/doc/reference_processing.xml b/doc/reference_processing.xml index 8f5fd34b9..f4d7100ba 100644 --- a/doc/reference_processing.xml +++ b/doc/reference_processing.xml @@ -1468,7 +1468,7 @@ FROM test; Examples - + Cardinality 2 @@ -1490,8 +1490,8 @@ FROM test; -------------------------------------------- LINESTRING(10 160,60 120,120 140,180 120) - - + + Cardinality 3 or More @@ -1513,9 +1513,9 @@ FROM test; -------------------------------------------- MULTILINESTRING((10 160,60 120,120 140),(100 180,120 140),(120 140,180 120)) - + - + Non-Touching Lines If merging is not possible due to non-touching lines, the original MultiLineString is returned. @@ -1526,9 +1526,9 @@ SELECT ST_AsText(ST_LineMerge( ---------------- MULTILINESTRING((-45.2 -33.2,-46 -32),(-29 -27,-30 -29.7,-36 -31,-45 -33)) - + - + Directed Parameter @@ -1549,9 +1549,9 @@ TRUE)); ------------------------------------------------------- MULTILINESTRING((120 50,60 30,10 70),(120 50,180 30)) - + - + Z-dimension Handling SELECT ST_AsText(ST_LineMerge( @@ -1560,7 +1560,7 @@ SELECT ST_AsText(ST_LineMerge( --------------------------------------------------------------------------------- LINESTRING Z (-30 -29.7 5,-29 -27 11,-30 -29.7 10,-36 -31 5,-45 -33 1,-46 -32 11) - + See Also ----------------------------------------------------------------------- Summary of changes: doc/reference_processing.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Oct 17 23:41:05 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 17 Oct 2025 23:41:05 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-146-g9eeb5628b Message-ID: <20251018064105.9CDEA1975B3@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 9eeb5628b067f09e8182961c461a896f35c352f2 (commit) from 362287e12869aa13a34cc15d240ebe690f0cc9c9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9eeb5628b067f09e8182961c461a896f35c352f2 Author: Darafei Praliaskouski Date: Sat Oct 18 10:40:33 2025 +0400 [ci] Add Belarusian translations to list of languages diff --git a/doc/Makefile.in b/doc/Makefile.in index d47824537..8ff8a7296 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -21,7 +21,7 @@ # that we could produce a large number of files (think chunked HTML) # -translations = it_IT pt_BR fr es pl ka ko_KR da de ja ru zh_Hans ro sv uk +translations = it_IT pt_BR fr es pl ka ko_KR da de ja ru zh_Hans ro sv uk be PACKAGE_TARNAME = @PACKAGE_TARNAME@ ----------------------------------------------------------------------- Summary of changes: doc/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 17 23:41:59 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 18 Oct 2025 06:41:59 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.a10436a837c02dab3a8e84301b448c6d@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Nice job. Ah that's much cleaner than my solution. I would leave out the RETURNING topogeom in final solution as of course that could be a huge return :) -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sat Oct 18 00:01:17 2025 From: git at osgeo.org (git at osgeo.org) Date: Sat, 18 Oct 2025 00:01:17 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-147-g3f2e2d575 Message-ID: <20251018070117.5BC88198ACC@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 3f2e2d575a6fe34b4cc82a97f316c3ed1b877a12 (commit) from 9eeb5628b067f09e8182961c461a896f35c352f2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3f2e2d575a6fe34b4cc82a97f316c3ed1b877a12 Author: Darafei Praliaskouski Date: Sat Oct 18 11:00:46 2025 +0400 [ci] add Makefile.in for be translations diff --git a/doc/po/be/Makefile.in b/doc/po/be/Makefile.in new file mode 100644 index 000000000..703bb0f96 --- /dev/null +++ b/doc/po/be/Makefile.in @@ -0,0 +1,3 @@ +include @srcdir@/../Makefile.local +DOCSUFFIX=-be +srcdir=@srcdir@ ----------------------------------------------------------------------- Summary of changes: doc/po/{da => be}/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) copy doc/po/{da => be}/Makefile.in (78%) hooks/post-receive -- PostGIS From git at osgeo.org Sat Oct 18 01:31:17 2025 From: git at osgeo.org (git at osgeo.org) Date: Sat, 18 Oct 2025 01:31:17 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-148-gb472a69c6 Message-ID: <20251018083117.6C2CB199DB4@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via b472a69c6d6b3975aae4fe724f506b54f5bffaa8 (commit) from 3f2e2d575a6fe34b4cc82a97f316c3ed1b877a12 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b472a69c6d6b3975aae4fe724f506b54f5bffaa8 Author: Darafei Praliaskouski Date: Sat Oct 18 12:31:01 2025 +0400 [ci] add lang be to woodpecker config diff --git a/.woodpecker/docs.yml b/.woodpecker/docs.yml index 9ec7caa0c..aefe46c4d 100644 --- a/.woodpecker/docs.yml +++ b/.woodpecker/docs.yml @@ -251,6 +251,17 @@ steps: include: - "doc/po/uk/*.po" + check-xml-be: + image: *test_image + pull: true + commands: + - make -C build-docs/doc/po/be local-check-xml + depends_on: prepare + when: + - path: + include: + - "doc/po/be/*.po" + ### TARGET html html-it_IT: image: *test_image @@ -417,6 +428,17 @@ steps: include: - "doc/po/uk/*.po" + html-be: + image: *test_image + pull: true + commands: + - make -C build-docs/doc/po/be local-html + depends_on: check-xml-be + when: + - path: + include: + - "doc/po/be/*.po" + ### TARGET cheatsheets cheatsheets-it_IT: image: *test_image @@ -583,6 +605,17 @@ steps: include: - "doc/po/uk/*.po" + cheatsheets-be: + image: *test_image + pull: true + commands: + - make -C build-docs/doc/po/be local-cheatsheets + depends_on: check-xml-be + when: + - path: + include: + - "doc/po/be/*.po" + ### TARGET check-cheatsheets check-cheatsheets-it_IT: image: *test_image @@ -749,3 +782,14 @@ steps: include: - "doc/po/uk/*.po" + check-cheatsheets-be: + image: *test_image + pull: true + commands: + - make -C build-docs/doc/po/be local-check-cheatsheets + depends_on: [ cheatsheets-be, build-cheatsheets ] + when: + - path: + include: + - "doc/po/be/*.po" + ----------------------------------------------------------------------- Summary of changes: .woodpecker/docs.yml | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) hooks/post-receive -- PostGIS From trac at osgeo.org Sat Oct 18 01:35:12 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 18 Oct 2025 08:35:12 -0000 Subject: [PostGIS] #4158: ST_Subdivide unable to subdivide isochrone In-Reply-To: <048.3d48643696d0f20f9650a8ff10fac12c@osgeo.org> References: <048.3d48643696d0f20f9650a8ff10fac12c@osgeo.org> Message-ID: <063.2beb67587a6ffef84926e614fe09e99d@osgeo.org> #4158: ST_Subdivide unable to subdivide isochrone -------------------------+-------------------------- Reporter: komzpa | Owner: komzpa Type: defect | Status: closed Priority: medium | Milestone: PostGIS GEOS Component: postgis | Version: 2.4.x Resolution: worksforme | Keywords: -------------------------+-------------------------- Changes (by komzpa): * resolution: => worksforme * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sat Oct 18 10:51:37 2025 From: git at osgeo.org (git at osgeo.org) Date: Sat, 18 Oct 2025 10:51:37 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-149-g0f533d759 Message-ID: <20251018175138.2C68919FA90@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 0f533d759b306f058e867e603314542471579faf (commit) from b472a69c6d6b3975aae4fe724f506b54f5bffaa8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0f533d759b306f058e867e603314542471579faf Author: Sandro Santilli Date: Sat Oct 18 19:51:14 2025 +0200 Fix typos, thanks codespell diff --git a/NEWS b/NEWS index 5a240adb4..0610745f2 100644 --- a/NEWS +++ b/NEWS @@ -185,7 +185,7 @@ PostGIS 3.4.0 This version requires PostgreSQL 12-16, GEOS 3.6 or higher, and Proj 6.1+. To take advantage of all features, GEOS 3.12+ is needed. -To take advantage of all SFCGAL featurs, SFCGAL 1.4.1+ is needed. +To take advantage of all SFCGAL features, SFCGAL 1.4.1+ is needed. Many thanks to our translation teams, in particular: @@ -371,7 +371,7 @@ with the new fast index build that requires PG14, we have decided to disable the feature by default until we get more user testing as to the true impact of real-world queries. -If you are running PG14+, you can reenable it by doing +If you are running PG14+, you can re-enable it by doing ALTER OPERATOR FAMILY gist_geometry_ops_2d USING gist ADD FUNCTION 11 (geometry) @@ -516,7 +516,7 @@ Additional features are enabled if you are running GEOS 3.9. - #4710, ST_ClusterKMeans now works with 3D geometries (Darafei Praliaskouski) - #4801, ST_ClusterKMeans supports weights in POINT[Z]M geometries (Darafei Praliaskouski) - - #4805, _ST_SortableHash exposed to work around parallel soring performance issue + - #4805, _ST_SortableHash exposed to work around parallel sorting performance issue in Postgres. If your table is huge, use ORDER BY _ST_SortableHash(geom) instead of ORDER BY geom to make parallel sort faster (Darafei Praliaskouski) - #4625, Correlation statistics now calculated. @@ -528,7 +528,7 @@ Additional features are enabled if you are running GEOS 3.9. - #4789, Sped up TopoJSON output for areal TopoGeometry with many holes (Sandro Santilli) - #4758, Improved topology noding robustness (Sandro Santilli) - - Make ST_Subdivide interruptable (Sandro Santilli) + - Make ST_Subdivide interruptible (Sandro Santilli) - #4660, Changes in double / coordinate printing (Ra?l Mar?n) - Use the shortest representation (enough to guarantee roundtrip). - Uses scientific notation for absolute numbers smaller than 1e-8. @@ -591,7 +591,7 @@ and GEOS 3.8.0 and postgis.backend switch (Darafei Praliaskouski) - #4267, Enable Proj 6 deprecated APIs (Darafei Praliaskouski, Ra?l Mar?n) - #4268, Bump minimum SFCGAL version to 1.3.1 (Darafei Praliaskouski) - - #4331, ST_3DMakeBox now returns error instead of a miniscule box (Regina Obe) + - #4331, ST_3DMakeBox now returns error instead of a minuscule box (Regina Obe) - #4342, Removed "versioned" variants of ST_AsGeoJSON and ST_AsKML (Paul Ramsey) - #4356, ST_Accum removed. Use array_agg instead. (Darafei Praliaskouski) - #4414, Include version number in address_standardizer lib (Ra?l Mar?n) @@ -1481,7 +1481,7 @@ PostGIS 2.1.0 - #2026, ST_Union(raster) now unions all bands of all rasters - #2089, liblwgeom: lwgeom_set_handlers replaces lwgeom_init_allocators. - #2150, regular_blocking is no longer a constraint. column of same name - in raster_columns now checks for existance of spatially_unique + in raster_columns now checks for existence of spatially_unique and coverage_tile constraints - ST_Intersects(raster, geometry) behaves in the same manner as ST_Intersects(geometry, raster). @@ -1910,7 +1910,7 @@ PostGIS 2.0.0 (eg CREATE TABLE t (g GEOMETRY(Polgyon, 4326))) - ST_AsBinary and ST_AsText now return 3D/4D results in ISO SQL/MM format when called on 3D/4D features. - - The "unknonwn SRID" is now 0, not -1. + - The "unknown SRID" is now 0, not -1. (eg ST_SRID(ST_GeomFromText('POINT(0 0)')) returns 0) - ST_NumGeometries returns 1 for singletons. ST_GeometryN returns the the geometry for singletons. @@ -2452,7 +2452,7 @@ PostGIS 1.1.3 PostGIS 1.1.2 2006/03/30 - - Regress tests can now be run *before* postgis intallation + - Regress tests can now be run *before* postgis installation - BUGFIX in SnapToGrid() computation of output bounding box - More portable ./configure script - Changed ./run_test script to have more sane default behaviour @@ -2502,7 +2502,7 @@ PostGIS 1.1.0 - Bug fixes: - Fixed memory leak in polygonize() - - Fixed bug in lwgeom_as_anytype cast funcions + - Fixed bug in lwgeom_as_anytype cast functions - Fixed USE_GEOS, USE_PROJ and USE_STATS elements of postgis_version() output to always reflect library state. @@ -2512,7 +2512,7 @@ PostGIS 1.1.0 - Changed Z() function to return NULL if requested dimension is not available - - Peformance improvements: + - Performance improvements: - Much faster transform() function, caching proj4 objects - Removed automatic call to fix_geometry_columns() in AddGeometryColumns() and update_geometry_stats() @@ -2632,7 +2632,7 @@ PostGIS 1.0.0 - NEW -p flag for shp2pgsql - BUGFIX in transform() releasing random memory address - BUGFIX in force_3dm() allocating less memory then required - - NEW chapter about OGC compliancy enforcement + - NEW chapter about OGC compliance enforcement - BUGFIX in shp2pgsql escape of values starting with "'" or "\t" - NEW autoconf support for JTS lib - BUGFIX in estimator testers (support for LWGEOM and schema parsing) @@ -2661,7 +2661,7 @@ PostGIS 1.0.0RC4 - jdbc2: code cleanups, Makefile improvements - FLEX & YACC variables set *after* pgsql Makefile.global is included and only if the pgsql *stripped* version - evaulates to the empty string + evaluates to the empty string - added already generated parser in release - build scripts refinements - MultiLine handling BUG fix in loader and dumper @@ -2731,10 +2731,10 @@ PostGIS 1.0.0RC1 - Objects are all now "lightweight" with a smaller disk and index representation. Large databases should see a moderate to large performance increase. - - Objects now have a hexidecimal canonical representation. + - Objects now have a hexadecimal canonical representation. To see a "user friendly" version of the objects use the AsText() function. - - The loader and dumper use the hexidecimal canonical representation, + - The loader and dumper use the hexadecimal canonical representation, so coordinate drift due to floating point string parsing is now eliminated. - New functions: UpdateGeometrySRID(), AsGML(), SnapToGrid(), @@ -2890,7 +2890,7 @@ PostGIS 0.7.0 - xmin(),ymin(),zmin(),xmax(),ymax(),zmax() functions - Bug Fixes - transform() more graceful when grid shifts are missing - - setsrid() made cachable + - setsrid() made cacheable - patches to loader/dumper diff --git a/doc/developer.md b/doc/developer.md index 3c51f4cab..95da8837f 100644 --- a/doc/developer.md +++ b/doc/developer.md @@ -203,7 +203,7 @@ On many occasions, we'll introduce functionality that can only be used if PostGI with a dependency library higher than X? Where X is some version of a dependency library. Dependency guards need to be put in both the C library files and our test files. -On some occassions where we need to do something different based on version of PostgreSQL, +On some occasions where we need to do something different based on version of PostgreSQL, you'll see guards in the SQL files as well. We have guards in place in the code to handle these for dependency libraries ----------------------------------------------------------------------- Summary of changes: NEWS | 30 +++++++++++++++--------------- doc/developer.md | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Sun Oct 19 10:21:12 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 19 Oct 2025 10:21:12 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-150-gd1f4deb9b Message-ID: <20251019172113.4223274D3@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via d1f4deb9be180aec802c09f795dc7d2135d6436f (commit) from 0f533d759b306f058e867e603314542471579faf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d1f4deb9be180aec802c09f795dc7d2135d6436f Author: Martin Davis Date: Sun Oct 19 10:21:09 2025 -0700 Improve doc for ST_CoverageClean diff --git a/doc/html/images/Makefile.in b/doc/html/images/Makefile.in index a0cb8de14..233b1fa6d 100644 --- a/doc/html/images/Makefile.in +++ b/doc/html/images/Makefile.in @@ -103,6 +103,9 @@ GENERATED_IMAGES= \ st_concavehull03.png \ st_concavehull04.png \ st_convexhull01.png \ + st_coverageclean01.png \ + st_coverageclean02.png \ + st_coverageclean03.png \ st_coverageinvalidedges01.png \ st_coveragesimplify01.png \ st_coveragesimplify02.png \ diff --git a/doc/html/images/wkt/st_coverageclean01.wkt b/doc/html/images/wkt/st_coverageclean01.wkt new file mode 100644 index 000000000..65b98e825 --- /dev/null +++ b/doc/html/images/wkt/st_coverageclean01.wkt @@ -0,0 +1,2 @@ +ArgA;GEOMETRYCOLLECTION (POLYGON ((10 190, 30 160, 27 134.5, 40 110, 122 47, 120 10, 10 10, 10 190)), POLYGON ((150 190, 10 190, 30 160, 50 140, 40 110, 50 80, 130 70, 135 111, 140 130, 140 160, 150 190)), POLYGON ((140 190, 190 190, 190 80, 140 80, 140 190)), POLYGON ((190 10, 120 10, 97 77, 160 90, 170 70, 190 80, 190 10))) + diff --git a/doc/html/images/wkt/st_coverageclean02.wkt b/doc/html/images/wkt/st_coverageclean02.wkt new file mode 100644 index 000000000..fddb46e75 --- /dev/null +++ b/doc/html/images/wkt/st_coverageclean02.wkt @@ -0,0 +1,3 @@ +ArgA;GEOMETRYCOLLECTION (POLYGON ((10 190, 30 160, 27 134.5, 40 110, 122 47, 120 10, 10 10, 10 190)), POLYGON ((150 190, 10 190, 30 160, 50 140, 40 110, 50 80, 130 70, 135 111, 140 130, 140 160, 150 190)), POLYGON ((140 190, 190 190, 190 80, 140 80, 140 190)), POLYGON ((190 10, 120 10, 97 77, 160 90, 170 70, 190 80, 190 10))) +Result-endpoints;GEOMETRYCOLLECTION (LINESTRING (40 110, 122 47, 120 10), LINESTRING (40 110, 50 80, 130 70, 135 111, 140 130, 140 160, 150 190, 10 190), LINESTRING (190 80, 140 80, 140 190, 190 190), LINESTRING (120 10, 97 77, 160 90, 170 70)) + diff --git a/doc/html/images/wkt/st_coverageclean03.wkt b/doc/html/images/wkt/st_coverageclean03.wkt new file mode 100644 index 000000000..d8ba84b46 --- /dev/null +++ b/doc/html/images/wkt/st_coverageclean03.wkt @@ -0,0 +1,2 @@ +ArgB;GEOMETRYCOLLECTION (POLYGON ((10 10, 10 190, 30 160, 27 134.5, 40 110, 84.69194312796209 75.66350710900474, 98.03118908382066 73.99610136452242, 102.03213844252163 62.341161928306555, 120 10, 10 10)), POLYGON ((140 130, 140 85.87301587301587, 131.7275615567911 84.16600476568705, 97 77, 98.03118908382066 73.99610136452242, 84.69194312796209 75.66350710900474, 40 110, 50 140, 30 160, 10 190, 140 190, 140 160, 140 130)), POLYGON ((140 160, 140 190, 150 190, 190 190, 190 80, 165 80, 140 80, 140 85.87301587301587, 140 130, 140 160)), POLYGON ((140 85.87301587301587, 140 80, 165 80, 190 80, 190 10, 120 10, 102.03213844252163 62.341161928306555, 98.03118908382066 73.99610136452242, 97 77, 131.7275615567911 84.16600476568705, 140 85.87301587301587))) + diff --git a/doc/reference_coverage.xml b/doc/reference_coverage.xml index 5906b40a4..d00788df2 100644 --- a/doc/reference_coverage.xml +++ b/doc/reference_coverage.xml @@ -142,14 +142,23 @@ SELECT true = ALL ( Description - A window function which adjusts the edges of a polygonal dataset to ensure that none of the polygons overlap, narrow gaps are removed, and shared edges are identically noded. - The result is a clean coverage that will pass validation by - and can be input to coverage processing functions. + A window function which adjusts the edges of a set of valid polygonal geometries to produce a clean coverage. + Cleaning involves: - gapMaximumWidth controls the cleaning of gaps between polygons. Gaps with width less than this distance are merged into an adjacent polygon. - snappingDistance controls snapping of close vertices and edges. The default setting (-1) use an automatic snapping distance based on the input. Set to 0.0 to turn off snapping. - overlapMergeStrategy specifies how overlapping areas are merged into an adjacent polygon: - + + + snapping vertices and edges to remove small discrepancies and ensure common edges are identically noded + + + merging overlaps into a parent polygon + + + merging narrow gaps into adjacent polygons + + + gapMaximumWidth controls which gaps between polygons are merged. Gaps with width <= this distance are merged into an adjacent polygon. + snappingDistance controls snapping of vertices and edges. The default (-1) automatically determines a snapping distance based on the input extent. Set to 0.0 to turn off snapping. + overlapMergeStrategy specifies how overlaps are merged into a parent polygon: MERGE_LONGEST_BORDER - merges into polygon with longest common border @@ -164,6 +173,18 @@ SELECT true = ALL ( MERGE_MIN_INDEX - merges into polygon with smallest input index (defined by order of input polygons) + The result is a clean polygonal coverage that will pass validation by + and can be input to coverage processing functions. + + + To aid in determining a maximum gap width, + gaps can be computed by cleaning with gapMaximumWidth => 0 + and using to union the result coverage. + Holes in the union correspond to gaps in the original dataset. + Gap widths can be measured by extracting the holes as polygons + and running + on them; the gap width is twice the computed radius. + Availability: 3.6.0 - requires GEOS >= 3.14.0 @@ -171,27 +192,53 @@ SELECT true = ALL ( Examples - -- Populate demo table + -- Populate input table CREATE TABLE example AS SELECT * FROM (VALUES - (1, 'POLYGON ((10 190, 30 160, 40 110, 100 70, 120 10, 10 10, 10 190))'::geometry), - (2, 'POLYGON ((100 190, 10 190, 30 160, 40 110, 50 80, 74 110.5, 100 130, 140 120, 140 160, 100 190))'::geometry), + (1, 'POLYGON ((10 190, 30 160, 27 134.5, 40 110, 122 47, 120 10, 10 10, 10 190))'::geometry), + (2, 'POLYGON ((150 190, 10 190, 30 160, 50 140, 40 110, 50 80, 130 70, 135 111, 140 130, 140 160, 150 190))'::geometry), (3, 'POLYGON ((140 190, 190 190, 190 80, 140 80, 140 190))'::geometry), - (4, 'POLYGON ((180 40, 120 10, 100 70, 140 80, 190 80, 180 40))'::geometry) + (4, 'POLYGON ((190 10, 120 10, 97 77, 160 90, 170 70, 190 80, 190 10))'::geometry) ) AS v(id, geom); + --- Prove it is a dirty coverage + + + + + + Polygons with overlaps and gaps + + + +-- Show it is an invalid coverage SELECT ST_AsText(ST_CoverageInvalidEdges(geom) OVER ()) FROM example; + --- Clean the coverage + + + + + + Invalid coverage edges + + + +-- Clean the coverage, merging gaps with width <= 1 CREATE TABLE example_clean AS - SELECT id, ST_CoverageClean(geom) OVER () AS GEOM + SELECT id, ST_CoverageClean(geom, 1) OVER () AS GEOM FROM example; + + + + + + + + Clean polygonal coverage, with overlaps and narrow gaps removed + + --- Prove it is a clean coverage -SELECT ST_AsText(ST_CoverageInvalidEdges(geom) OVER ()) - FROM example_clean; - ----------------------------------------------------------------------- Summary of changes: doc/html/images/Makefile.in | 3 ++ doc/html/images/wkt/st_coverageclean01.wkt | 2 + doc/html/images/wkt/st_coverageclean02.wkt | 3 ++ doc/html/images/wkt/st_coverageclean03.wkt | 2 + doc/reference_coverage.xml | 87 +++++++++++++++++++++++------- 5 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 doc/html/images/wkt/st_coverageclean01.wkt create mode 100644 doc/html/images/wkt/st_coverageclean02.wkt create mode 100644 doc/html/images/wkt/st_coverageclean03.wkt hooks/post-receive -- PostGIS From git at osgeo.org Sun Oct 19 18:43:27 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 19 Oct 2025 18:43:27 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-151-g01c391901 Message-ID: <20251020014327.6BFE0190DD9@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 01c39190148c91ec62889fadbabc25afb7f707fd (commit) from d1f4deb9be180aec802c09f795dc7d2135d6436f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 01c39190148c91ec62889fadbabc25afb7f707fd Author: Martin Davis Date: Sun Oct 19 18:43:24 2025 -0700 Improve doc for ST_DumpRings diff --git a/doc/reference_accessor.xml b/doc/reference_accessor.xml index 25668392f..016122e20 100644 --- a/doc/reference_accessor.xml +++ b/doc/reference_accessor.xml @@ -906,7 +906,11 @@ FROM ( The exterior ring (shell) has index 0. The interior rings (holes) have indices of 1 and higher. - This only works for POLYGON geometries. It does not work for MULTIPOLYGONS + This only works for POLYGON geometries, not MULTIPOLYGONs. + Use to extract polygon elements from polygonal geometries: + ST_DumpRings( (ST_Dump(geom)).geom ) + + Availability: PostGIS 1.1.3. Requires PostgreSQL 7.3 or higher. &Z_support; ----------------------------------------------------------------------- Summary of changes: doc/reference_accessor.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 20 06:03:49 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 20 Oct 2025 13:03:49 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.85126e8b084dfa57dcbcf25b69e323fa@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by alexobs): > Oh, does this do the same thing with ST_Intersects? Yes, I'm seeing the same behavior with ST_Intersects. > Doing a bisection on a system that displays the problem would be good. I could try that, but I don't have much experience with manually compiling software, let alone postgres plugins. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Oct 20 09:12:55 2025 From: git at osgeo.org (git at osgeo.org) Date: Mon, 20 Oct 2025 09:12:55 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-152-g19e25a659 Message-ID: <20251020161255.ED155198F43@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 19e25a659e825484fcd8a013b5364a2621ae46b5 (commit) from 01c39190148c91ec62889fadbabc25afb7f707fd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 19e25a659e825484fcd8a013b5364a2621ae46b5 Author: Martin Davis Date: Mon Oct 20 09:12:46 2025 -0700 Improve doc example for ST_DumpRings diff --git a/doc/reference_accessor.xml b/doc/reference_accessor.xml index 016122e20..ac5864537 100644 --- a/doc/reference_accessor.xml +++ b/doc/reference_accessor.xml @@ -918,28 +918,21 @@ FROM ( Examples - General form of query. + Extracting all rings as polygons. SELECT polyTable.field1, polyTable.field1, (ST_DumpRings(polyTable.geom)).geom As geom FROM polyTable; - A polygon with a single hole. -SELECT path, ST_AsEWKT(geom) As geom + Extracting shell and holes from a polygon. +SELECT path, ST_AsText(geom) As geom FROM ST_DumpRings( - ST_GeomFromEWKT('POLYGON((-8149064 5133092 1,-8149064 5132986 1,-8148996 5132839 1,-8148972 5132767 1,-8148958 5132508 1,-8148941 5132466 1,-8148924 5132394 1, - -8148903 5132210 1,-8148930 5131967 1,-8148992 5131978 1,-8149237 5132093 1,-8149404 5132211 1,-8149647 5132310 1,-8149757 5132394 1, - -8150305 5132788 1,-8149064 5133092 1), - (-8149362 5132394 1,-8149446 5132501 1,-8149548 5132597 1,-8149695 5132675 1,-8149362 5132394 1))') - ) as foo; - path | geom ----------------------------------------------------------------------------------------------------------------- - {0} | POLYGON((-8149064 5133092 1,-8149064 5132986 1,-8148996 5132839 1,-8148972 5132767 1,-8148958 5132508 1, - | -8148941 5132466 1,-8148924 5132394 1, - | -8148903 5132210 1,-8148930 5131967 1, - | -8148992 5131978 1,-8149237 5132093 1, - | -8149404 5132211 1,-8149647 5132310 1,-8149757 5132394 1,-8150305 5132788 1,-8149064 5133092 1)) - {1} | POLYGON((-8149362 5132394 1,-8149446 5132501 1, - | -8149548 5132597 1,-8149695 5132675 1,-8149362 5132394 1)) + 'POLYGON ((1 9, 9 9, 9 1, 1 1, 1 9), (2 2, 2 3, 3 3, 3 2, 2 2), (4 2, 4 4, 6 4, 6 2, 4 2))'); + + path | geom +------+-------------------------------- + {0} | POLYGON((1 9,9 9,9 1,1 1,1 9)) + {1} | POLYGON((2 2,2 3,3 3,3 2,2 2)) + {2} | POLYGON((4 2,4 4,6 4,6 2,4 2)) ----------------------------------------------------------------------- Summary of changes: doc/reference_accessor.xml | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Oct 20 12:30:25 2025 From: trac at osgeo.org (PostGIS) Date: Mon, 20 Oct 2025 19:30:25 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.b7a051e254c560bf6143b56df801c27d@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by alexobs): I tried bisecting it this afternoon, by marking tag '3.5.0' as bad and tag '3.4.3' as good, and according to git the offending commit is 8efa9b214e72d52188518a9f46859cfb98b4c612. The parent commit, 4bac13b03d659fb59db1432b23c56b9e0fa604f3, indeed does not have the problem for me. I hope that's useful. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 05:20:13 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 12:20:13 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. Message-ID: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> #6007: Diffferrent results with two version of postgis master. -------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Keywords: | -------------------------------+--------------------------- Postgis below gives one result https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/pipelines/2111443784 {{{ POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY }}} while this gives another result -num surfaces total|219 +num surfaces total|217 https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/jobs/11789714169 {{{ POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 05:22:36 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 12:22:36 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.3efd9b4d4528d16cf7aa68b438362b01@osgeo.org> #6007: Diffferrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Description changed by Lars Aksel Opsahl: Old description: > Postgis below gives one result > > https://gitlab.com/nibioopensource/resolve-overlap-and- > gap/-/pipelines/2111443784 > > {{{ > POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" > GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF > URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj > DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ > 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 > (Internal)" TOPOLOGY > > }}} > > while this gives another result > > -num surfaces total|219 > +num surfaces total|217 > > https://gitlab.com/nibioopensource/resolve-overlap-and- > gap/-/jobs/11789714169 > > {{{ > POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" > GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF > URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj > DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ > 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 > (Internal)" TOPOLOGY > > > }}} New description: Postgis below gives one result https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/pipelines/2111443784 {{{ POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY }}} while this gives another result -num surfaces total|219 +num surfaces total|217 https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/jobs/11789714169 {{{ POSTGIS="3.7.0dev 3.6.0rc2-133-gd1c28c62c" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY }}} -- -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 05:49:19 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 12:49:19 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.40b608fe964f1c93ac40eac2ee034149@osgeo.org> #6007: Diffferrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Description changed by strk: Old description: > Postgis below gives one result > > https://gitlab.com/nibioopensource/resolve-overlap-and- > gap/-/pipelines/2111443784 > > {{{ > POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" > GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF > URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj > DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ > 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 > (Internal)" TOPOLOGY > > }}} > > while this gives another result > > -num surfaces total|219 > +num surfaces total|217 > > https://gitlab.com/nibioopensource/resolve-overlap-and- > gap/-/jobs/11789714169 > > {{{ > POSTGIS="3.7.0dev 3.6.0rc2-133-gd1c28c62c" [EXTENSION] PGSQL="160" > GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF > URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj > DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ > 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 > (Internal)" TOPOLOGY > }}} New description: Postgis below gives one result https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/pipelines/2111443784 {{{ POSTGIS="3.7.0dev 3.6.0rc2-55-gfda22140e" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY }}} while this gives another result: https://gitlab.com/nibioopensource/resolve-overlap-and- gap/-/jobs/11789714169 {{{ POSTGIS="3.7.0dev 3.6.0rc2-133-gd1c28c62c" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.8.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.8.0) LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY }}} The difference: {{{ -num surfaces total|219 +num surfaces total|217 }}} -- -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 05:50:43 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 12:50:43 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.8d5d43762e337439ab64b1ec6f2a1059@osgeo.org> #6007: Diffferrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Comment (by strk): is the testcase making any effort to control the order in which objects are added in the topology, or could a differently built index result in a differently ordered set entering the topology ? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 05:55:47 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 12:55:47 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.c6e5b44dc2fc84e476903cb4dd68aca2@osgeo.org> #6007: Diffferrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Comment (by Lars Aksel Opsahl): The order of adding data to the topology are controlled in detail. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 08:48:30 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 15:48:30 -0000 Subject: [PostGIS] #6008: Add a Variant of ST_Polygon(raster) with Guaranteed Valid Geometry Output Message-ID: <053.d544190b08d7ee8136ffc3619dd338b7@osgeo.org> #6008: Add a Variant of ST_Polygon(raster) with Guaranteed Valid Geometry Output -------------------------------------------------+------------------------- Reporter: GISuser5432 | Owner: robe Type: task | Status: new Priority: high | Milestone: PostGIS | 3.6.1 Component: raster | Version: 3.6.x Keywords: PostGIS_Raster; ST_Polygon(rast); | Valid Geometry; | -------------------------------------------------+------------------------- I am upgrading an old project that uses ST_Polygon(raster) [https://postgis.net/docs/RT_ST_Polygon.html] in a production environment. While preparing to upgrade PostGIS to the latest version, I noticed that starting from version **3.3.0**, the function no longer **checks the validity** of the output geometry to improve performance. Although this optimization makes sense for speed, there are use cases where **100% valid output is critical**. Handling invalid geometries case by case in production can be error-prone. **Proposal:** Add an optional argument to ST_Polygon(raster) that allows users to choose between: * Fast mode (current behavior, no validity check) * Robust mode (guarantees valid geometry output) I am not certain whether passing the result through ST_MakeValid(geom) is always sufficient, or if invalid geometries can still occur. A variant or option that guarantees validity would be extremely valuable for production environments. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 08:57:08 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 15:57:08 -0000 Subject: [PostGIS] #6008: Add a Variant of ST_Polygon(raster) with Guaranteed Valid Geometry Output In-Reply-To: <053.d544190b08d7ee8136ffc3619dd338b7@osgeo.org> References: <053.d544190b08d7ee8136ffc3619dd338b7@osgeo.org> Message-ID: <068.0d16c8b4398abf4bbfde4bfd5130b366@osgeo.org> #6008: Add a Variant of ST_Polygon(raster) with Guaranteed Valid Geometry Output -------------------------+------------------------------------------------- Reporter: | Owner: robe GISuser5432 | Type: task | Status: new Priority: high | Milestone: PostGIS 3.6.1 Component: raster | Version: 3.6.x Resolution: | Keywords: PostGIS_Raster; ST_Polygon(rast); | Valid Geometry; -------------------------+------------------------------------------------- Comment (by pramsey): Passing the output through `ST_MakeValid(geom, 'method=structure')` or `ST_MakeValid(geom, 'method=linework')` is something you can do now. If the actual `ST_Polygon` function is failing, that's a different problem entirely, and looking at [https://github.com/postgis/postgis/pull/674/files GH674] not a problem that was introduced when the validity checks were removed. I'd rather you just wrap your function in ST_MakeValid than add a flag that just does the exact same thing. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 09:04:58 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 16:04:58 -0000 Subject: [PostGIS] #6009: Error of ST_Polygon(raster) function in PostGIS 3.4.3 and 3.5.4 Message-ID: <053.5b0683b43da79bf5e5b9011a9047b449@osgeo.org> #6009: Error of ST_Polygon(raster) function in PostGIS 3.4.3 and 3.5.4 -------------------------------------------------+------------------------- Reporter: GISuser5432 | Owner: robe Type: defect | Status: new Priority: high | Milestone: PostGIS | 3.5.5 Component: raster | Version: 3.5.x Keywords: PostGIS_Raster; Raster; | ST_Polygon(Raster) | -------------------------------------------------+------------------------- I tried to run ST_Polygon(Raster) on a raster table and for 3 rows, it produced an error. This is the simple query: {{{#!div style="font-size: 80%" Code highlighting: {{{#!sql SELECT ST_Polygon(raster) FROM error_sounding_2m }}} }}} This is the error message: {{{ ERROR: rt_raster_surface: Could not union the pixel polygons using GEOSUnaryUnion() SQL state: XX000 }}} This is the version of the PostGIS: {{{ POSTGIS="3.4.3 e365945" [EXTENSION] PGSQL="170" GEOS="3.9.0-CAPI-1.16.2" PROJ="7.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/var/lib/postgresql/.local/share/proj DATABASE_PATH=/usr/share/proj/proj.db" GDAL="GDAL 3.2.2, released 2021/03/05" LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" RASTER }}} I also checked it for 3.5 and I had the same error. Only in 3.6 the error was fixed! The DB dump is attached for 3 raw of raster in a DB called enav. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 09:05:52 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 16:05:52 -0000 Subject: [PostGIS] #6009: Error of ST_Polygon(raster) function in PostGIS 3.4.3 and 3.5.4 In-Reply-To: <053.5b0683b43da79bf5e5b9011a9047b449@osgeo.org> References: <053.5b0683b43da79bf5e5b9011a9047b449@osgeo.org> Message-ID: <068.380695d47c818f1f08aef3aa2be2e037@osgeo.org> #6009: Error of ST_Polygon(raster) function in PostGIS 3.4.3 and 3.5.4 -------------------------+------------------------------------------------- Reporter: | Owner: robe GISuser5432 | Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.5 Component: raster | Version: 3.5.x Resolution: | Keywords: PostGIS_Raster; Raster; | ST_Polygon(Raster) -------------------------+------------------------------------------------- Changes (by GISuser5432): * Attachment "error_sounding_2m.sql" added. Restore this into a db called enav. There are 3 rows of raster that ST_Polygon(raster) cannot process them! -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 10:10:42 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 17:10:42 -0000 Subject: [PostGIS] #6008: Add a Variant of ST_Polygon(raster) with Guaranteed Valid Geometry Output In-Reply-To: <053.d544190b08d7ee8136ffc3619dd338b7@osgeo.org> References: <053.d544190b08d7ee8136ffc3619dd338b7@osgeo.org> Message-ID: <068.672907cda1b29ef1ac845342ca0f3218@osgeo.org> #6008: Add a Variant of ST_Polygon(raster) with Guaranteed Valid Geometry Output -------------------------+------------------------------------------------- Reporter: | Owner: robe GISuser5432 | Type: task | Status: new Priority: high | Milestone: PostGIS 3.6.1 Component: raster | Version: 3.6.x Resolution: | Keywords: PostGIS_Raster; ST_Polygon(rast); | Valid Geometry; -------------------------+------------------------------------------------- Comment (by GISuser5432): Thanks Paul. If ST_MakeValid() is enough. Then, no need to modify the function. Yes, the actual ST_Polygon() also fails. I added it in another ticket: https://trac.osgeo.org/postgis/ticket/6009 Only with 3.6 did not fail. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 10:45:06 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 21 Oct 2025 17:45:06 -0000 Subject: [PostGIS] #6009: Error of ST_Polygon(raster) function in PostGIS 3.4.3 and 3.5.4 In-Reply-To: <053.5b0683b43da79bf5e5b9011a9047b449@osgeo.org> References: <053.5b0683b43da79bf5e5b9011a9047b449@osgeo.org> Message-ID: <068.806c881422a4551d295a01ef274480ee@osgeo.org> #6009: Error of ST_Polygon(raster) function in PostGIS 3.4.3 and 3.5.4 -------------------------+------------------------------------------------- Reporter: | Owner: robe GISuser5432 | Type: defect | Status: new Priority: high | Milestone: PostGIS 3.5.5 Component: raster | Version: 3.5.x Resolution: | Keywords: PostGIS_Raster; Raster; | ST_Polygon(Raster) -------------------------+------------------------------------------------- Description changed by GISuser5432: Old description: > I tried to run ST_Polygon(Raster) on a raster table and for 3 rows, it > produced an error. > > This is the simple query: > > {{{#!div style="font-size: 80%" > Code highlighting: > {{{#!sql > SELECT ST_Polygon(raster) > FROM error_sounding_2m > }}} > }}} > > > This is the error message: > > {{{ > ERROR: rt_raster_surface: Could not union the pixel polygons using > GEOSUnaryUnion() > > SQL state: XX000 > }}} > > This is the version of the PostGIS: > > {{{ > POSTGIS="3.4.3 e365945" [EXTENSION] PGSQL="170" GEOS="3.9.0-CAPI-1.16.2" > PROJ="7.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org > USER_WRITABLE_DIRECTORY=/var/lib/postgresql/.local/share/proj > DATABASE_PATH=/usr/share/proj/proj.db" GDAL="GDAL 3.2.2, released > 2021/03/05" LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" > WAGYU="0.5.0 (Internal)" RASTER > > }}} > > > I also checked it for 3.5 and I had the same error. Only in 3.6 the error > was fixed! > > The DB dump is attached for 3 raw of raster in a DB called enav. New description: I tried to run ST_Polygon(Raster) on a raster table and for 3 rows, it produced an error. This is the simple query: {{{#!div style="font-size: 80%" Code highlighting: {{{#!sql SELECT ST_Polygon(raster) FROM error_sounding_2m }}} }}} This is the error message: {{{ ERROR: rt_raster_surface: Could not union the pixel polygons using GEOSUnaryUnion() SQL state: XX000 }}} This is the version of the PostGIS: {{{ POSTGIS="3.4.3 e365945" [EXTENSION] PGSQL="170" GEOS="3.9.0-CAPI-1.16.2" PROJ="7.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/var/lib/postgresql/.local/share/proj DATABASE_PATH=/usr/share/proj/proj.db" GDAL="GDAL 3.2.2, released 2021/03/05" LIBXML="2.9.10" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" RASTER }}} I also checked it for 3.5 and I had the same error. Only in 3.6 the error was fixed! I must also say that all tests were done in Docker containers of PostGIS. The DB dump is attached for 3 raw of raster in a DB called enav. -- -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 21 20:17:27 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 03:17:27 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.765098f4697cc2ab1fd0ceacae1d8936@osgeo.org> #6007: Diffferrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Comment (by Lars Aksel Opsahl): I checked code for ordering now. {{{ order by ST_isClosed(geom) desc, ST_NPoints(geom) desc, cover_num desc }}} So I add the closed lines which have most points and then I sort based on which order the layer have priority. So if two lines from the same input layer have the same number of points I have a random issue in ordering. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 22 13:13:20 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 20:13:20 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.092820a9f4e209fbcf8944d89608fe48@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by pramsey): Thanks for the bisect, that's kind of huge. This commit does include changes in the estimate file, I am not sure why they would induce the effect you are seeing, but given that most changes don't touch that file, I'm inclined to think you've isolated the main change. If you're feeling particularly spunky you could back out the [https://github.com/postgis/postgis/commit/8efa9b214e72d52188518a9f46859cfb98b4c612 change] to `gserialized_estimate.c` and see if the problem goes away for you. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 22 13:38:33 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 22 Oct 2025 13:38:33 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-153-gc33f545a1 Message-ID: <20251022203833.CD789169EE7@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via c33f545a1feffd88ab6f8fdc34536e1b8ede9ed1 (commit) from 19e25a659e825484fcd8a013b5364a2621ae46b5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c33f545a1feffd88ab6f8fdc34536e1b8ede9ed1 Author: Paul Ramsey Date: Wed Oct 22 13:38:18 2025 -0700 Add ST_MMin and ST_MMax functions to match up to the other XYZ variants. Closes #2858. diff --git a/doc/reference_accessor.xml b/doc/reference_accessor.xml index ac5864537..b75f26317 100644 --- a/doc/reference_accessor.xml +++ b/doc/reference_accessor.xml @@ -906,10 +906,10 @@ FROM ( The exterior ring (shell) has index 0. The interior rings (holes) have indices of 1 and higher. - This only works for POLYGON geometries, not MULTIPOLYGONs. + This only works for POLYGON geometries, not MULTIPOLYGONs. Use to extract polygon elements from polygonal geometries: ST_DumpRings( (ST_Dump(geom)).geom ) - + Availability: PostGIS 1.1.3. Requires PostgreSQL 7.3 or higher. &Z_support; @@ -921,7 +921,7 @@ FROM ( Extracting all rings as polygons. SELECT polyTable.field1, polyTable.field1, (ST_DumpRings(polyTable.geom)).geom As geom -FROM polyTable; +FROM polyTable Extracting shell and holes from a polygon. SELECT path, ST_AsText(geom) As geom diff --git a/doc/reference_bbox.xml b/doc/reference_bbox.xml index 46bfcc698..797c36f3d 100644 --- a/doc/reference_bbox.xml +++ b/doc/reference_bbox.xml @@ -1,45 +1,45 @@
    - Bounding Box Functions - - These functions produce or operate on bounding boxes. - They can also provide and accept geometry values, by using automatic or explicit casts. - - See also . - + Bounding Box Functions + + These functions produce or operate on bounding boxes. + They can also provide and accept geometry values, by using automatic or explicit casts. + + See also . + - - - Box2D + + + Box2D - Returns a BOX2D representing the 2D extent of a geometry. - + Returns a BOX2D representing the 2D extent of a geometry. + - - - - box2d Box2D - geometry geom - - - + + + + box2d Box2D + geometry geom + + + - - Description + + Description - Returns a representing the 2D extent of the geometry. + Returns a representing the 2D extent of the geometry. - Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. - &curve_support; - &P_support; - &T_support; - + Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. + &curve_support; + &P_support; + &T_support; + - - Examples + + Examples SELECT Box2D(ST_GeomFromText('LINESTRING(1 2, 3 4, 5 6)')); @@ -54,46 +54,46 @@ box2d -------- BOX(220186.984375 150406,220288.25 150506.140625) - + - - - See Also + + + See Also - , - - + , + + - - - Box3D + + + Box3D - Returns a BOX3D representing the 3D extent of a geometry. - + Returns a BOX3D representing the 3D extent of a geometry. + - - - - box3d Box3D - geometry geom - - - + + + + box3d Box3D + geometry geom + + + - - Description + + Description - Returns a representing the 3D extent of the geometry. - Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. - &curve_support; - &P_support; - &T_support; - &Z_support; - + Returns a representing the 3D extent of the geometry. + Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. + &curve_support; + &P_support; + &T_support; + &Z_support; + - - Examples + + Examples SELECT Box3D(ST_GeomFromEWKT('LINESTRING(1 2 3, 3 4 5, 5 6 5)')); @@ -108,75 +108,75 @@ Box3d -------- BOX3D(220227 150406 1,220268 150415 1) - + - - - See Also + + + See Also - , - - + , + + - - - ST_EstimatedExtent + + + ST_EstimatedExtent - Returns the estimated extent of a spatial table. - + Returns the estimated extent of a spatial table. + - - - - box2d ST_EstimatedExtent - text schema_name - text table_name - text geocolumn_name - boolean parent_only - + + + + box2d ST_EstimatedExtent + text schema_name + text table_name + text geocolumn_name + boolean parent_only + - - box2d ST_EstimatedExtent - text schema_name - text table_name - text geocolumn_name - + + box2d ST_EstimatedExtent + text schema_name + text table_name + text geocolumn_name + - - box2d ST_EstimatedExtent - text table_name - text geocolumn_name - - - + + box2d ST_EstimatedExtent + text table_name + text geocolumn_name + + + - - Description + + Description - Returns the estimated extent of a spatial table as a . - The current schema is used if not specified. - The estimated extent is taken from the geometry column's statistics. + Returns the estimated extent of a spatial table as a . + The current schema is used if not specified. + The estimated extent is taken from the geometry column's statistics. This is usually much faster than computing the exact extent of the table using or . The default behavior is to also use statistics collected from child tables (tables - with INHERITS) if available. If parent_only is set to TRUE, only - statistics for the given table are used and child tables are ignored. - + with INHERITS) if available. If parent_only is set to TRUE, only + statistics for the given table are used and child tables are ignored. + - For PostgreSQL >= 8.0.0 statistics are gathered by VACUUM - ANALYZE and the result extent will be about 95% of the actual one. + For PostgreSQL >= 8.0.0 statistics are gathered by VACUUM + ANALYZE and the result extent will be about 95% of the actual one. For PostgreSQL < 8.0.0 statistics are gathered by running - update_geometry_stats() and the result extent is exact. + update_geometry_stats() and the result extent is exact. In the absence of statistics (empty table or no ANALYZE called) this function returns NULL. Prior to version 1.5.4 an exception was thrown instead. - + @@ -188,201 +188,201 @@ BOX3D(220227 150406 1,220268 150415 1) Availability: 1.0.0 Changed: 2.1.0. Up to 2.0.x this was called ST_Estimated_Extent. - &curve_support; - + &curve_support; + - - Examples + + Examples - SELECT ST_EstimatedExtent('ny', 'edges', 'geom'); + SELECT ST_EstimatedExtent('ny', 'edges', 'geom'); --result-- BOX(-8877653 4912316,-8010225.5 5589284) SELECT ST_EstimatedExtent('feature_poly', 'geom'); --result-- BOX(-124.659652709961 24.6830825805664,-67.7798080444336 49.0012092590332) - - + + - - - See Also + + + See Also - , - - + , + + - - - ST_Expand - Returns a bounding box expanded from another bounding box or a geometry. - + + + ST_Expand + Returns a bounding box expanded from another bounding box or a geometry. + - - - - geometry ST_Expand - geometry geom - float units_to_expand - + + + + geometry ST_Expand + geometry geom + float units_to_expand + - - geometry ST_Expand - geometry geom - float dx - float dy - float dz=0 - float dm=0 - + + geometry ST_Expand + geometry geom + float dx + float dy + float dz=0 + float dm=0 + - - box2d ST_Expand - box2d box - float units_to_expand - + + box2d ST_Expand + box2d box + float units_to_expand + - - box2d ST_Expand - box2d box - float dx - float dy - + + box2d ST_Expand + box2d box + float dx + float dy + - - box3d ST_Expand - box3d box - float units_to_expand - + + box3d ST_Expand + box3d box + float units_to_expand + - - box3d ST_Expand - box3d box - float dx - float dy - float dz=0 - - - + + box3d ST_Expand + box3d box + float dx + float dy + float dz=0 + + + - - Description + + Description - Returns a bounding box expanded from the bounding box of the input, - either by specifying a single distance with which the box should be expanded on both - axes, or by specifying an expansion distance for each axis. + Returns a bounding box expanded from the bounding box of the input, + either by specifying a single distance with which the box should be expanded on both + axes, or by specifying an expansion distance for each axis. - Uses double-precision. Can be used for distance queries, or to add a bounding box - filter to a query to take advantage of a spatial index. + Uses double-precision. Can be used for distance queries, or to add a bounding box + filter to a query to take advantage of a spatial index. - In addition to the version of ST_Expand accepting and returning a geometry, variants - are provided that accept and return + In addition to the version of ST_Expand accepting and returning a geometry, variants + are provided that accept and return and data types. - + - Distances are in the units of the spatial reference system of the input. + Distances are in the units of the spatial reference system of the input. - ST_Expand is similar to , - except while buffering expands a geometry in all directions, - ST_Expand expands the bounding box along each axis. + ST_Expand is similar to , + except while buffering expands a geometry in all directions, + ST_Expand expands the bounding box along each axis. - - Pre version 1.3, ST_Expand was used in conjunction with to do indexable distance queries. For example, - geom && ST_Expand('POINT(10 20)', 10) AND ST_Distance(geom, 'POINT(10 20)') < 10. - This has been replaced by the simpler and more efficient function. - + + Pre version 1.3, ST_Expand was used in conjunction with to do indexable distance queries. For example, + geom && ST_Expand('POINT(10 20)', 10) AND ST_Distance(geom, 'POINT(10 20)') < 10. + This has been replaced by the simpler and more efficient function. + Availability: 1.5.0 behavior changed to output double precision instead of float4 coordinates. Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. Enhanced: 2.3.0 support was added to expand a box by different amounts in different dimensions. - &P_support; - &T_support; + &P_support; + &T_support; - + - - Examples - Examples below use US National Atlas Equal Area (SRID=2163) which is a meter projection - - + + Examples + Examples below use US National Atlas Equal Area (SRID=2163) which is a meter projection + + --10 meter expanded box around bbox of a linestring SELECT CAST(ST_Expand(ST_GeomFromText('LINESTRING(2312980 110676,2312923 110701,2312892 110714)', 2163),10) As box2d); - st_expand + st_expand ------------------------------------ BOX(2312882 110666,2312990 110724) --10 meter expanded 3D box of a 3D box SELECT ST_Expand(CAST('BOX3D(778783 2951741 1,794875 2970042.61545891 10)' As box3d),10) - st_expand + st_expand ----------------------------------------------------- BOX3D(778773 2951731 -9,794885 2970052.61545891 20) --10 meter geometry astext rep of a expand box around a point geometry SELECT ST_AsEWKT(ST_Expand(ST_GeomFromEWKT('SRID=2163;POINT(2312980 110676)'),10)); - st_asewkt + st_asewkt ------------------------------------------------------------------------------------------------- SRID=2163;POLYGON((2312970 110666,2312970 110686,2312990 110686,2312990 110666,2312970 110666)) - - + + - - See Also - , , - - + + See Also + , , + + - - - ST_Extent - Aggregate function that returns the bounding box of geometries. - + + + ST_Extent + Aggregate function that returns the bounding box of geometries. + - - - - box2d ST_Extent - geometry set geomfield - - - + + + + box2d ST_Extent + geometry set geomfield + + + - - Description + + Description - An aggregate function that returns a bounding box + An aggregate function that returns a bounding box that bounds a set of geometries. - The bounding box coordinates are in the spatial reference system of the input geometries. + The bounding box coordinates are in the spatial reference system of the input geometries. - ST_Extent is similar in concept to Oracle Spatial/Locator's SDO_AGGR_MBR. + ST_Extent is similar in concept to Oracle Spatial/Locator's SDO_AGGR_MBR. - - ST_Extent returns boxes with only X and Y ordinates even with 3D geometries. + + ST_Extent returns boxes with only X and Y ordinates even with 3D geometries. To return XYZ ordinates use . - + - - The returned box3d value does not include a SRID. + + The returned box3d value does not include a SRID. Use to convert it into a geometry with SRID metadata. The SRID is the same as the input geometries. - + - Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. - &P_support; - &T_support; + Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. + &P_support; + &T_support; - + - - Examples - Examples below use Massachusetts State Plane ft (SRID=2249) - + + Examples + Examples below use Massachusetts State Plane ft (SRID=2249) + SELECT ST_Extent(geom) as bextent FROM sometable; - st_bextent + st_bextent ------------------------------------ BOX(739651.875 2908247.25,794875.8125 2970042.75) @@ -392,7 +392,7 @@ SELECT ST_Extent(geom) as bextent FROM sometable GROUP BY category ORDER BY category; - bextent | name + bextent | name ----------------------------------------------------+---------------- BOX(778783.5625 2951741.25,794875.8125 2970042.75) | A BOX(751315.8125 2919164.75,765202.6875 2935417.25) | B @@ -402,226 +402,226 @@ GROUP BY category ORDER BY category; -- and render the extended text representation of that geometry SELECT ST_SetSRID(ST_Extent(geom),2249) as bextent FROM sometable; - bextent + bextent -------------------------------------------------------------------------------- SRID=2249;POLYGON((739651.875 2908247.25,739651.875 2970042.75,794875.8125 2970042.75, 794875.8125 2908247.25,739651.875 2908247.25)) - - + + - - See Also - + + See Also + , , - - - + + + - - - ST_3DExtent - Aggregate function that returns the 3D bounding box of geometries. - + + + ST_3DExtent + Aggregate function that returns the 3D bounding box of geometries. + - - - - box3d ST_3DExtent - geometry set geomfield - - - + + + + box3d ST_3DExtent + geometry set geomfield + + + - - Description + + Description - An aggregate function that returns a (includes Z ordinate) bounding box + An aggregate function that returns a (includes Z ordinate) bounding box that bounds a set of geometries. - The bounding box coordinates are in the spatial reference system of the input geometries. + The bounding box coordinates are in the spatial reference system of the input geometries. - - The returned box3d value does not include a SRID. + + The returned box3d value does not include a SRID. Use to convert it into a geometry with SRID metadata. The SRID is the same as the input geometries. - + - Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. - Changed: 2.0.0 In prior versions this used to be called ST_Extent3D - &Z_support; - &curve_support; - &P_support; - &T_support; - + Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. + Changed: 2.0.0 In prior versions this used to be called ST_Extent3D + &Z_support; + &curve_support; + &P_support; + &T_support; + - - Examples - + + Examples + SELECT ST_3DExtent(foo.geom) As b3extent FROM (SELECT ST_MakePoint(x,y,z) As geom - FROM generate_series(1,3) As x - CROSS JOIN generate_series(1,2) As y - CROSS JOIN generate_series(0,2) As Z) As foo; - b3extent + FROM generate_series(1,3) As x + CROSS JOIN generate_series(1,2) As y + CROSS JOIN generate_series(0,2) As Z) As foo; + b3extent -------------------- BOX3D(1 1 0,3 2 2) --Get the extent of various elevated circular strings SELECT ST_3DExtent(foo.geom) As b3extent FROM (SELECT ST_Translate(ST_Force_3DZ(ST_LineToCurve(ST_Buffer(ST_Point(x,y),1))),0,0,z) As geom - FROM generate_series(1,3) As x - CROSS JOIN generate_series(1,2) As y - CROSS JOIN generate_series(0,2) As Z) As foo; + FROM generate_series(1,3) As x + CROSS JOIN generate_series(1,2) As y + CROSS JOIN generate_series(0,2) As Z) As foo; - b3extent + b3extent -------------------- BOX3D(1 0 0,4 2 2) - - + + - - See Also - , , - - + + See Also + , , + + - - - ST_MakeBox2D + + + ST_MakeBox2D - Creates a BOX2D defined by two 2D point geometries. - + Creates a BOX2D defined by two 2D point geometries. + - - - - box2d ST_MakeBox2D - geometry pointLowLeft - geometry pointUpRight - - - + + + + box2d ST_MakeBox2D + geometry pointLowLeft + geometry pointUpRight + + + - - Description + + Description - Creates a defined by two Point - geometries. This is useful for doing range queries. - + Creates a defined by two Point + geometries. This is useful for doing range queries. + - - Examples + + Examples - - + - - - See Also + + + See Also - , , - - + , , + + - - - ST_3DMakeBox + + + ST_3DMakeBox - Creates a BOX3D defined by two 3D point geometries. - - - - - box3d ST_3DMakeBox - geometry point3DLowLeftBottom - geometry point3DUpRightTop - - - + Creates a BOX3D defined by two 3D point geometries. + + + + + box3d ST_3DMakeBox + geometry point3DLowLeftBottom + geometry point3DUpRightTop + + + - - Description + + Description - Creates a defined by two 3D Point - geometries. + Creates a defined by two 3D Point + geometries. - - - - - - This function supports 3D and will not drop the z-index. - Changed: 2.0.0 In prior versions this used to be called ST_MakeBox3D - + + + + + + This function supports 3D and will not drop the z-index. + Changed: 2.0.0 In prior versions this used to be called ST_MakeBox3D + - - Examples + + Examples - + SELECT ST_3DMakeBox(ST_MakePoint(-989502.1875, 528439.5625, 10), - ST_MakePoint(-987121.375 ,529933.1875, 10)) As abb3d + ST_MakePoint(-987121.375 ,529933.1875, 10)) As abb3d --bb3d-- -------- BOX3D(-989502.1875 528439.5625 10,-987121.375 529933.1875 10) - - + + - - - See Also + + + See Also - , , - - + , , + + - - - ST_XMax + + + ST_XMax - Returns the X maxima of a 2D or 3D bounding box or a geometry. - + Returns the X maxima of a 2D or 3D bounding box or a geometry. + - - - - float ST_XMax - box3d aGeomorBox2DorBox3D - - - + + + + float ST_XMax + box3d aGeomorBox2DorBox3D + + + - - Description + + Description - Returns the X maxima of a 2D or 3D bounding box or a geometry. + Returns the X maxima of a 2D or 3D bounding box or a geometry. - - Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. - However, it will not accept a geometry or box2d text representation, since those do not auto-cast. - + + Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. + However, it will not accept a geometry or box2d text representation, since those do not auto-cast. + - &Z_support; - &curve_support; - + &Z_support; + &curve_support; + - - Examples + + Examples - SELECT ST_XMax('BOX3D(1 2 3, 4 5 6)'); + SELECT ST_XMax('BOX3D(1 2 3, 4 5 6)'); st_xmax ------- 4 @@ -644,52 +644,52 @@ SELECT ST_XMax(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,2 st_xmax -------- 220288.248780547 - - + + - - - See Also + + + See Also - , , , , - - + , , , , , , + + - - - ST_XMin + + + ST_XMin - Returns the X minima of a 2D or 3D bounding box or a geometry. - + Returns the X minima of a 2D or 3D bounding box or a geometry. + - - - - float ST_XMin - box3d aGeomorBox2DorBox3D - - - + + + + float ST_XMin + box3d aGeomorBox2DorBox3D + + + - - Description + + Description - Returns the X minima of a 2D or 3D bounding box or a geometry. + Returns the X minima of a 2D or 3D bounding box or a geometry. - - Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. - However it will not accept a geometry or box2d text representation, since those do not auto-cast. - + + Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. + However it will not accept a geometry or box2d text representation, since those do not auto-cast. + - &Z_support; - &curve_support; - + &Z_support; + &curve_support; + - - Examples + + Examples - SELECT ST_XMin('BOX3D(1 2 3, 4 5 6)'); + SELECT ST_XMin('BOX3D(1 2 3, 4 5 6)'); st_xmin ------- 1 @@ -712,52 +712,52 @@ SELECT ST_XMin(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,2 st_xmin -------- 220186.995121892 - - + + - - - See Also + + + See Also - , , , , - - + , , , , , , + + - - - ST_YMax + + + ST_YMax - Returns the Y maxima of a 2D or 3D bounding box or a geometry. - + Returns the Y maxima of a 2D or 3D bounding box or a geometry. + - - - - float ST_YMax - box3d aGeomorBox2DorBox3D - - - + + + + float ST_YMax + box3d aGeomorBox2DorBox3D + + + - - Description + + Description - Returns the Y maxima of a 2D or 3D bounding box or a geometry. + Returns the Y maxima of a 2D or 3D bounding box or a geometry. - - Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. - However it will not accept a geometry or box2d text representation, since those do not auto-cast. - + + Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. + However it will not accept a geometry or box2d text representation, since those do not auto-cast. + - &Z_support; - &curve_support; - + &Z_support; + &curve_support; + - - Examples + + Examples - SELECT ST_YMax('BOX3D(1 2 3, 4 5 6)'); + SELECT ST_YMax('BOX3D(1 2 3, 4 5 6)'); st_ymax ------- 5 @@ -780,52 +780,52 @@ SELECT ST_YMax(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,2 st_ymax -------- 150506.126829327 - - + + - - - See Also + + + See Also - , , , , - - + , , , , , , + + - - - ST_YMin + + + ST_YMin - Returns the Y minima of a 2D or 3D bounding box or a geometry. - + Returns the Y minima of a 2D or 3D bounding box or a geometry. + - - - - float ST_YMin - box3d aGeomorBox2DorBox3D - - - + + + + float ST_YMin + box3d aGeomorBox2DorBox3D + + + - - Description + + Description - Returns the Y minima of a 2D or 3D bounding box or a geometry. + Returns the Y minima of a 2D or 3D bounding box or a geometry. - - Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. - However it will not accept a geometry or box2d text representation, since those do not auto-cast. - + + Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. + However it will not accept a geometry or box2d text representation, since those do not auto-cast. + - &Z_support; - &curve_support; - + &Z_support; + &curve_support; + - - Examples + + Examples - SELECT ST_YMin('BOX3D(1 2 3, 4 5 6)'); + SELECT ST_YMin('BOX3D(1 2 3, 4 5 6)'); st_ymin ------- 2 @@ -848,52 +848,52 @@ SELECT ST_YMin(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,2 st_ymin -------- 150406 - - + + - - - See Also + + + See Also - , , , , , - - + , , , , , , , + + - - - ST_ZMax + + + ST_ZMax - Returns the Z maxima of a 2D or 3D bounding box or a geometry. - + Returns the Z maxima of a 2D or 3D bounding box or a geometry. + - - - - float ST_ZMax - box3d aGeomorBox2DorBox3D - - - + + + + float ST_ZMax + box3d aGeomorBox2DorBox3D + + + - - Description + + Description - Returns the Z maxima of a 2D or 3D bounding box or a geometry. + Returns the Z maxima of a 2D or 3D bounding box or a geometry. - - Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. - However it will not accept a geometry or box2d text representation, since those do not auto-cast. - + + Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. + However it will not accept a geometry or box2d text representation, since those do not auto-cast. + - &Z_support; - &curve_support; - + &Z_support; + &curve_support; + - - Examples + + Examples - SELECT ST_ZMax('BOX3D(1 2 3, 4 5 6)'); + SELECT ST_ZMax('BOX3D(1 2 3, 4 5 6)'); st_zmax ------- 6 @@ -916,52 +916,52 @@ SELECT ST_ZMax(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,2 st_zmax -------- 3 - - + + - - - See Also + + + See Also - , , , , , - - + , , , , , , , + + - - - ST_ZMin + + + ST_ZMin - Returns the Z minima of a 2D or 3D bounding box or a geometry. - + Returns the Z minima of a 2D or 3D bounding box or a geometry. + - - - - float ST_ZMin - box3d aGeomorBox2DorBox3D - - - + + + + float ST_ZMin + box3d aGeomorBox2DorBox3D + + + - - Description + + Description - Returns the Z minima of a 2D or 3D bounding box or a geometry. + Returns the Z minima of a 2D or 3D bounding box or a geometry. - - Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. - However it will not accept a geometry or box2d text representation, since those do not auto-cast. - + + Although this function is only defined for box3d, it also works for box2d and geometry values due to automatic casting. + However it will not accept a geometry or box2d text representation, since those do not auto-cast. + - &Z_support; - &curve_support; - + &Z_support; + &curve_support; + - - Examples + + Examples - SELECT ST_ZMin('BOX3D(1 2 3, 4 5 6)'); + SELECT ST_ZMin('BOX3D(1 2 3, 4 5 6)'); st_zmin ------- 3 @@ -984,15 +984,94 @@ SELECT ST_ZMin(ST_GeomFromEWKT('CIRCULARSTRING(220268 150415 1,220227 150505 2,2 st_zmin -------- 1 - - + + - - - See Also + + + See Also - , , , , , , - - + , , , , , , , , + + + + + + ST_MMin + + Returns the M minima of a geometry. + + + + + + float ST_MMingeometry geom + + + + + + Description + + Returns the M minima of a geometry, or null of the geometry lacks M values. + + &Z_support; + &curve_support; + + + + Examples + + SELECT ST_MMin('POINT M (1 2 3)'); +st_mmin +------- +3 + + + + + See Also + + , , , , , , + + + + + + + ST_MMax + + Returns the M minima of a geometry. + + + + + + float ST_MMaxgeometry geom + + + + + + Description + Returns the M minima of a geometry, or null of the geometry lacks M values. + + &Z_support; + &curve_support; + + + + Examples + SELECT ST_MMax('POINT M (1 2 3)'); +st_mmax +------- +3 + + + + See Also + , , , , , , + +
    diff --git a/doc/reference_coverage.xml b/doc/reference_coverage.xml index d00788df2..ccd8b868a 100644 --- a/doc/reference_coverage.xml +++ b/doc/reference_coverage.xml @@ -177,14 +177,14 @@ SELECT true = ALL ( and can be input to coverage processing functions. - To aid in determining a maximum gap width, + To aid in determining a maximum gap width, gaps can be computed by cleaning with gapMaximumWidth => 0 and using to union the result coverage. Holes in the union correspond to gaps in the original dataset. Gap widths can be measured by extracting the holes as polygons and running on them; the gap width is twice the computed radius. - + Availability: 3.6.0 - requires GEOS >= 3.14.0
    diff --git a/postgis/lwgeom_box3d.c b/postgis/lwgeom_box3d.c index 96288e624..11ba71483 100644 --- a/postgis/lwgeom_box3d.c +++ b/postgis/lwgeom_box3d.c @@ -455,6 +455,41 @@ Datum BOX3D_zmax(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(Max(box->zmin, box->zmax)); } + +Datum ST_MMin(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_MMin); +Datum ST_MMin(PG_FUNCTION_ARGS) +{ + GBOX gbox; + GSERIALIZED *gser = PG_GETARG_GSERIALIZED_P(0); + + if (gserialized_get_gbox_p(gser, &gbox) != LW_TRUE) + PG_RETURN_NULL(); + + if (!FLAGS_GET_M(gbox.flags)) + PG_RETURN_NULL(); + + PG_RETURN_FLOAT8(Min(gbox.mmin, gbox.mmax)); +} + + +Datum ST_MMax(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ST_MMax); +Datum ST_MMax(PG_FUNCTION_ARGS) +{ + GBOX gbox; + GSERIALIZED *gser = PG_GETARG_GSERIALIZED_P(0); + + if (gserialized_get_gbox_p(gser, &gbox) != LW_TRUE) + PG_RETURN_NULL(); + + if (!FLAGS_GET_M(gbox.flags)) + PG_RETURN_NULL(); + + PG_RETURN_FLOAT8(Max(gbox.mmin, gbox.mmax)); +} + + /** * Used in the ST_Extent and ST_Extent3D aggregates, does not read the * serialized cached bounding box (since that is floating point) diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index f508024c5..c1a57bc0d 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -1098,6 +1098,20 @@ CREATE OR REPLACE FUNCTION ST_ZMax(box3d) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE _COST_DEFAULT; +-- Availability: 3.7.0 +CREATE OR REPLACE FUNCTION ST_MMin(geometry) + RETURNS FLOAT8 + AS 'MODULE_PATHNAME','ST_MMin' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_DEFAULT; + +-- Availability: 3.7.0 +CREATE OR REPLACE FUNCTION ST_MMax(geometry) + RETURNS FLOAT8 + AS 'MODULE_PATHNAME','ST_MMax' + LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE + _COST_DEFAULT; + ----------------------------------------------------------------------------- -- BOX2D FUNCTIONS ----------------------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: doc/reference_accessor.xml | 6 +- doc/reference_bbox.xml | 1291 +++++++++++++++++++++++--------------------- doc/reference_coverage.xml | 4 +- postgis/lwgeom_box3d.c | 35 ++ postgis/postgis.sql.in | 14 + 5 files changed, 739 insertions(+), 611 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 22 13:38:36 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 20:38:36 -0000 Subject: [PostGIS] #2858: ST_MMin and ST_MMax functions for geometry In-Reply-To: <049.f0819de351c23e16becf82a744093435@osgeo.org> References: <049.f0819de351c23e16becf82a744093435@osgeo.org> Message-ID: <064.4d964ce11db904f5369a6762c14ddac7@osgeo.org> #2858: ST_MMin and ST_MMax functions for geometry --------------------------+----------------------------- Reporter: mwtoews | Owner: pramsey Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: fixed | Keywords: --------------------------+----------------------------- Changes (by Paul Ramsey ): * resolution: => fixed * status: new => closed Comment: In [changeset:"c33f545a1feffd88ab6f8fdc34536e1b8ede9ed1/git" c33f545/git]: {{{#!CommitTicketReference repository="git" revision="c33f545a1feffd88ab6f8fdc34536e1b8ede9ed1" Add ST_MMin and ST_MMax functions to match up to the other XYZ variants. Closes #2858. }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 22 16:09:46 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 23:09:46 -0000 Subject: [PostGIS] #6007: Diffferrent results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.d7e84f0e4f0447377c945030b2e7e54e@osgeo.org> #6007: Diffferrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: strk Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: topology | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Changes (by robe): * component: postgis => topology * owner: pramsey => strk Comment: I'm assuming this is a topology issue so switching the component -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 22 16:10:35 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 23:10:35 -0000 Subject: [PostGIS] #2858: ST_MMin and ST_MMax functions for geometry In-Reply-To: <049.f0819de351c23e16becf82a744093435@osgeo.org> References: <049.f0819de351c23e16becf82a744093435@osgeo.org> Message-ID: <064.9110a5260651456045d5d077926add09@osgeo.org> #2858: ST_MMin and ST_MMax functions for geometry --------------------------+--------------------------- Reporter: mwtoews | Owner: pramsey Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: fixed | Keywords: --------------------------+--------------------------- Changes (by robe): * milestone: PostGIS Fund Me => PostGIS 3.7.0 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 22 16:24:37 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 23:24:37 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.c8083f8c388597c6b9d9dc81a98cb3e1@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by robe): This sounds an awful lot like this ticket #5984 I recall whenever I saw the misbehavior - the SELECT _postgis_stats('nodes', 'geom','2') ; would spit out junk. I'm curious what yours shows @alexobs for your bad case. I think we determined in that ticket too that 3.4 was good and 3.5 and above exhibited the bad behavior. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 22 16:34:36 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 22 Oct 2025 23:34:36 -0000 Subject: [PostGIS] #5996: ST_FilterHolesByArea In-Reply-To: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> References: <049.f052c80b962359385eca1ee5a8b06d8d@osgeo.org> Message-ID: <064.8a5b9e024ea003c130594a0afc97843a@osgeo.org> #5996: ST_FilterHolesByArea ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by robe): Yah I think a ST_FilterHolesByArea, you can always make the Area value optional and if no area value is passed in, it would assume all holes should be filtered. Yah ST_RemoveSmallParts is not quite the same thing as it would remove small polygons that don't even have holes and I'd hate to add another argument to that function (saying true/false holes only), at that point creating a whole new function makes more sense to me and is clearer in intent. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 03:55:43 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 10:55:43 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.cf527b89e94e8c01692e1e9787467e5c@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by alexobs): Reverting the changes in `gserialized_estimate.c` from that commit indeed fixes the problem! I did some more testing and found that specifically removing `(double)` from line 1666 fixes it: {{{ diff --git a/postgis/gserialized_estimate.c b/postgis/gserialized_estimate.c index 76907c858..c090d8754 100644 --- a/postgis/gserialized_estimate.c +++ b/postgis/gserialized_estimate.c @@ -1663,7 +1663,7 @@ compute_gserialized_stats_mode(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfu * then take the appropriate root to get the estimated number of cells * on this axis (eg, pow(0.5) for 2d, pow(0.333) for 3d, pow(0.25) for 4d) */ - histo_size[d] = (int)pow((double)histo_cells_target * histo_ndims * edge_ratio, 1/(double)histo_ndims); + histo_size[d] = (int)pow(histo_cells_target * histo_ndims * edge_ratio, 1/(double)histo_ndims); /* If something goes awry, just give this dim one slot */ if ( ! histo_size[d] ) histo_size[d] = 1; }}} @robe This is the output I get from that query before and after the fix. Before: {{{ {"ndims":2,"size":[-2147483648,-2147483648],"extent":{"min":[2.85124,50.7356],"max":[7.24006,53.9675]},"table_features":141994640,"sample_features":150000,"not_null_features":150000,"histogram_features":149992,"histogram_cells":0,"cells_covered":0} }}} After {{{ {"ndims":2,"size":[1,1],"extent":{"min":[2.88071,50.7375],"max":[7.23847,53.8955]},"table_features":141941376,"sample_features":150000,"not_null_features":150000,"histogram_features":149990,"histogram_cells":1,"cells_covered":149990} }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 06:34:13 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 13:34:13 -0000 Subject: [PostGIS] #2157: Redo ST_ConcaveHull utilizing Delaunay Triangulation In-Reply-To: <046.0b03bb2aeaffcf29f48b6360f4cccb40@osgeo.org> References: <046.0b03bb2aeaffcf29f48b6360f4cccb40@osgeo.org> Message-ID: <061.80412f9dba30d4f1c9f51f5126d324c7@osgeo.org> #2157: Redo ST_ConcaveHull utilizing Delaunay Triangulation --------------------------+----------------------------- Reporter: robe | Owner: robe Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: fixed | Keywords: --------------------------+----------------------------- Changes (by komzpa): * resolution: => fixed * status: new => closed Comment: GEOS native since 3.3 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 06:51:07 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 13:51:07 -0000 Subject: [PostGIS] #5208: ST_ReducePrecision on a MultiPolygon always returns Polygon In-Reply-To: <054.522f06ac3b74a811017236c39ae72855@osgeo.org> References: <054.522f06ac3b74a811017236c39ae72855@osgeo.org> Message-ID: <069.318f6e314e77d69b727853167d9e4b66@osgeo.org> #5208: ST_ReducePrecision on a MultiPolygon always returns Polygon ---------------------------+-------------------------- Reporter: tudorbarascu | Owner: pramsey Type: defect | Status: closed Priority: low | Milestone: PostGIS GEOS Component: postgis | Version: 3.2.x Resolution: fixed | Keywords: ---------------------------+-------------------------- Changes (by komzpa): * resolution: => fixed * status: new => closed Comment: Fixed in GEOS https://github.com/libgeos/geos/commit/cd49218e4e270aca8f58060c012a446691d15965 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 08:31:49 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 15:31:49 -0000 Subject: [PostGIS] #4776: st_geometrytype causes 100% CPU loop in postgres13 on specific linestring In-Reply-To: <052.deaa67adfbebb313070ad604a8c7599d@osgeo.org> References: <052.deaa67adfbebb313070ad604a8c7599d@osgeo.org> Message-ID: <067.b4eb681e6087c265eda7108269a38078@osgeo.org> #4776: st_geometrytype causes 100% CPU loop in postgres13 on specific linestring -------------------------+-------------------------------- Reporter: tvijlbrief | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS PostgreSQL Component: postgis | Version: 3.0.x Resolution: fixed | Keywords: -------------------------+-------------------------------- Changes (by komzpa): * resolution: => fixed * status: new => closed Comment: Fixed Postgres version was released. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 23 09:00:47 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 23 Oct 2025 09:00:47 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-154-g6ca5741c2 Message-ID: <20251023160047.D089A19166C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 6ca5741c2cc58ee2ad1fdf6232c7179ea6b140db (commit) from c33f545a1feffd88ab6f8fdc34536e1b8ede9ed1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6ca5741c2cc58ee2ad1fdf6232c7179ea6b140db Author: Paul Ramsey Date: Thu Oct 23 09:00:25 2025 -0700 Add news entry for #2858 diff --git a/NEWS b/NEWS index 0610745f2..30b34a70b 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ xxxx/xx/xx - #5993, [topology] Add max_edges parameter to TopoGeo_AddLinestring (Sandro Santilli) - #6001, support MultiLineString in ST_MakeLine (Paul Ramsey) + - #2858, ST_MMin and STMMax (Paul Ramsey) PostGIS 3.6.0 ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 23 09:16:06 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:16:06 -0000 Subject: [PostGIS] #1625: ST_Within and ST_DWithin disagree In-Reply-To: <046.b610ade23d0c42e5c98a3c2a66c8034d@osgeo.org> References: <046.b610ade23d0c42e5c98a3c2a66c8034d@osgeo.org> Message-ID: <061.67502a182c8b1b4762ea7a8ca17cd596@osgeo.org> #1625: ST_Within and ST_DWithin disagree ----------------------+----------------------------- Reporter: strk | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: fixed | Keywords: ----------------------+----------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed Comment: Seems to have been fixed. At least, the example is. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 09:17:35 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:17:35 -0000 Subject: [PostGIS] #2179: ST_MakeValid support for NaN values. In-Reply-To: <046.10b9b27da4c9a52bd2b4891d996e362a@osgeo.org> References: <046.10b9b27da4c9a52bd2b4891d996e362a@osgeo.org> Message-ID: <061.d4acf79f1f1c36e5b5610ad4f98690df@osgeo.org> #2179: ST_MakeValid support for NaN values. ----------------------+----------------------------- Reporter: strk | Owner: strk Type: defect | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: 2.0.x Resolution: fixed | Keywords: ----------------------+----------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed Comment: I feel like, over the past years, our handling of NaN has gotten sufficiently better that we can close this general ticket. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 09:21:35 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:21:35 -0000 Subject: [PostGIS] #4222: ST_DumpAsPolygons not interruptible In-Reply-To: <048.6083b4d7f69db9112d1c01b5cfb6aed4@osgeo.org> References: <048.6083b4d7f69db9112d1c01b5cfb6aed4@osgeo.org> Message-ID: <063.9eb2e222c1cff41706123292b45279a9@osgeo.org> #4222: ST_DumpAsPolygons not interruptible ----------------------+--------------------------- Reporter: komzpa | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 2.4.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by pramsey): * milestone: PostGIS Fund Me => PostGIS 3.7.0 * owner: komzpa => pramsey Comment: I think with `rt_util_gdal_progress_func` this might be a one liner now. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 09:23:42 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:23:42 -0000 Subject: [PostGIS] #4222: ST_DumpAsPolygons not interruptible In-Reply-To: <048.6083b4d7f69db9112d1c01b5cfb6aed4@osgeo.org> References: <048.6083b4d7f69db9112d1c01b5cfb6aed4@osgeo.org> Message-ID: <063.4055806187c3d87226c5d6014689c7df@osgeo.org> #4222: ST_DumpAsPolygons not interruptible ----------------------+--------------------------- Reporter: komzpa | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 2.4.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by pramsey): * milestone: PostGIS 3.7.0 => PostGIS 3.6.1 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 09:28:30 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:28:30 -0000 Subject: [PostGIS] #4560: ST_3DInterpolatePoint In-Reply-To: <046.0c5f530ced274a58e267beab933ae3f5@osgeo.org> References: <046.0c5f530ced274a58e267beab933ae3f5@osgeo.org> Message-ID: <061.4780634d373861a017475c6b10fa035a@osgeo.org> #4560: ST_3DInterpolatePoint ----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: | Keywords: ----------------------+--------------------------- Changes (by pramsey): * milestone: PostGIS Fund Me => PostGIS 3.7.0 Comment: So project the point in 3D and read off the M? {{{ SELECT ST_InterpolatePoint('LINESTRING ZM (0 0 0 0, 10 0 10 20)', 'POINT Z (5 5 5)'); }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 09:59:07 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:59:07 -0000 Subject: [PostGIS] #6007: Differrent results with two version of postgis master. (was: Diffferrent results with two version of postgis master.) In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.54a22e3da771b0131334bbc6da63f6cd@osgeo.org> #6007: Differrent results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Changes (by strk): * component: topology => postgis * owner: strk => pramsey * summary: Diffferrent results with two version of postgis master. => Differrent results with two version of postgis master. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 09:59:35 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 16:59:35 -0000 Subject: [PostGIS] #6007: Different results with two version of postgis master. (was: Differrent results with two version of postgis master.) In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.b1a23a20fa633d1b1f8cf87c23818504@osgeo.org> #6007: Different results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Changes (by strk): * summary: Differrent results with two version of postgis master. => Different results with two version of postgis master. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 10:02:03 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 17:02:03 -0000 Subject: [PostGIS] #1024: Change 3D relationship functions to use &&& in addition to && In-Reply-To: <046.513acbbae5af033f236f531442d74b8b@osgeo.org> References: <046.513acbbae5af033f236f531442d74b8b@osgeo.org> Message-ID: <061.608c1c9c65d0a2627fba198172ccf07e@osgeo.org> #1024: Change 3D relationship functions to use &&& in addition to && --------------------------+----------------------------- Reporter: robe | Owner: pramsey Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: invalid | Keywords: --------------------------+----------------------------- Changes (by pramsey): * resolution: => invalid * status: new => closed Comment: This happened incidentally when we changed from inlined operators to supportfns. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 10:02:36 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 17:02:36 -0000 Subject: [PostGIS] #2167: ST_LineInterpolatePoint(geography) In-Reply-To: <046.20d39648ac370b4f5926331d87261f78@osgeo.org> References: <046.20d39648ac370b4f5926331d87261f78@osgeo.org> Message-ID: <061.3d922f2273773f4021134a81656a8e2f@osgeo.org> #2167: ST_LineInterpolatePoint(geography) --------------------------+----------------------------- Reporter: strk | Owner: pramsey Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: fixed | Keywords: --------------------------+----------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 10:08:59 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 17:08:59 -0000 Subject: [PostGIS] #2919: Include GDAL error message in raster failure messages In-Reply-To: <046.57cb7b5b0d24e5891867b5defa9cedb7@osgeo.org> References: <046.57cb7b5b0d24e5891867b5defa9cedb7@osgeo.org> Message-ID: <061.5fe95a0c3f538e12202a61b49aa1a22b@osgeo.org> #2919: Include GDAL error message in raster failure messages --------------------------+--------------------------- Reporter: strk | Owner: pramsey Type: enhancement | Status: new Priority: medium | Milestone: PostGIS 3.7.0 Component: raster | Version: master Resolution: | Keywords: --------------------------+--------------------------- Changes (by pramsey): * milestone: PostGIS Fund Me => PostGIS 3.7.0 * owner: dustymugs => pramsey -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 11:00:48 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 18:00:48 -0000 Subject: [PostGIS] #5992: DEBUG: picksplit method for column 1 of index "edge_gist" failed In-Reply-To: <046.424d702d2aadc17564a39641098ed329@osgeo.org> References: <046.424d702d2aadc17564a39641098ed329@osgeo.org> Message-ID: <061.c8aaf977fdbf2060e6a38a1dafcd1d1f@osgeo.org> #5992: DEBUG: picksplit method for column 1 of index "edge_gist" failed ----------------------+--------------------------- Reporter: strk | Owner: komzpa Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: ----------------------+--------------------------- Changes (by komzpa): * owner: pramsey => komzpa -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 13:23:46 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 20:23:46 -0000 Subject: [PostGIS] #6007: Different results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.74557a7636b6ab9e5853b3419b0ba408@osgeo.org> #6007: Different results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Comment (by strk): The difference between those two revision is the 0-tolerance: {{{ git diff fda22140e..d1c28c62c liblwgeom/topo/ diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c index c0d6d5356..3e7cfdc1e 100644 --- a/liblwgeom/topo/lwgeom_topo.c +++ b/liblwgeom/topo/lwgeom_topo.c @@ -6764,7 +6764,7 @@ _lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int LWT_ELEMID id = 0; /* Get tolerance, if 0 was given */ - if (!tol) + if ( tol == -1 ) tol = _LWT_MINTOLERANCE(topo, pt); LWDEBUGG(1, pt, "Adding point"); @@ -7168,7 +7168,7 @@ _lwt_AddLine(LWT_TOPOLOGY* topo, LWLINE* line, double tol, int* nedges, *nedges = -1; /* error condition, by default */ /* Get tolerance, if 0 was given */ - if ( ! tol ) tol = _LWT_MINTOLERANCE( topo, (LWGEOM*)line ); + if ( tol == -1 ) tol = _LWT_MINTOLERANCE( topo, (LWGEOM*)line ); LWDEBUGF(1, "Working tolerance:%.15g", tol); LWDEBUGF(1, "Input line has srid=%d", line->srid); @@ -7605,7 +7605,7 @@ lwt_AddPolygon(LWT_TOPOLOGY* topo, LWPOLY* poly, double tol, int* nfaces) } /* Get tolerance, if 0 was given */ - if ( ! tol ) tol = _LWT_MINTOLERANCE( topo, (LWGEOM*)poly ); + if ( tol == -1 ) tol = _LWT_MINTOLERANCE( topo, (LWGEOM*)poly ); LWDEBUGF(1, "Working tolerance:%.15g", tol); lwt_LoadPolygon(topo, poly, tol); }}} See if you get the expected behaviour by passing -1 instead of 0 to your TopoGeo_LoadGeometry or TopoGeo_Add* calls. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 13:26:48 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 20:26:48 -0000 Subject: [PostGIS] #6007: Different results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.f065b067b574f334ba98a087fcba99ce@osgeo.org> #6007: Different results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Comment (by strk): For the 0-tolerance work refer to #5688 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 23 16:48:08 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 23 Oct 2025 16:48:08 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-155-g0c57be8a1 Message-ID: <20251023234809.20D5C196DA9@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 0c57be8a1a45f2e23448a2eba0b8dc3530f822aa (commit) from 6ca5741c2cc58ee2ad1fdf6232c7179ea6b140db (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0c57be8a1a45f2e23448a2eba0b8dc3530f822aa Author: Darafei Praliaskouski Date: Fri Oct 24 03:47:48 2025 +0400 Optimize GiST index for repeated edge subdivision in topology If the first box is covering all the tuples on the index page picksplit was failing to produce two partitions as penalty with first one was 0 for all elements. Closes #5992 diff --git a/NEWS b/NEWS index 30b34a70b..b1faae2f8 100644 --- a/NEWS +++ b/NEWS @@ -13,7 +13,8 @@ xxxx/xx/xx - #5993, [topology] Add max_edges parameter to TopoGeo_AddLinestring (Sandro Santilli) - #6001, support MultiLineString in ST_MakeLine (Paul Ramsey) - - #2858, ST_MMin and STMMax (Paul Ramsey) + - #2858, ST_MMin and ST_MMax (Paul Ramsey) + - #5992, Optimize GiST index for repeated edge subdivision in topology (Darafei Praliaskouski) PostGIS 3.6.0 diff --git a/postgis/gserialized_gist_2d.c b/postgis/gserialized_gist_2d.c index 6e2c28e5e..3ac5a3567 100644 --- a/postgis/gserialized_gist_2d.c +++ b/postgis/gserialized_gist_2d.c @@ -19,7 +19,7 @@ ********************************************************************** * * Copyright 2009 Paul Ramsey - * Copyright 2017-2022 Darafei Praliaskouski + * Copyright 2017-2025 Darafei Praliaskouski * **********************************************************************/ @@ -1260,6 +1260,27 @@ box2df_penalty(const BOX2DF *b1, const BOX2DF *b2) return 0; } +static inline float +box2df_penalty_single(const BOX2DF *box) +{ + float boxxmin = box->xmin, boxxmax = box->xmax; + float boxymin = box->ymin, boxymax = box->ymax; + + float dx = boxxmax - boxxmin, dy = boxymax - boxymin; + + float area = dx * dy; + float edge = dx + dy; + + /* REALM 1: Area is nonzero, return it */ + if (area > FLT_EPSILON) + return pack_float(area, 1); + /* REALM 0: Area is zero, return edge */ + else if (edge > FLT_EPSILON) + return pack_float(edge, 0); + + return 0; +} + /* ** GiST support function. Calculate the "penalty" cost of adding this entry into an existing entry. ** Calculate the change in volume of the old entry once the new entry is added. @@ -1764,9 +1785,7 @@ Datum gserialized_gist_picksplit_2d(PG_FUNCTION_ARGS) OffsetNumber i, maxoff; ConsiderSplitContext context; - BOX2DF *box, - *leftBox, - *rightBox; + BOX2DF *leftBox, *rightBox; int dim, commonEntriesCount; SplitInterval *intervalsLower, @@ -1790,7 +1809,7 @@ Datum gserialized_gist_picksplit_2d(PG_FUNCTION_ARGS) */ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - box = (BOX2DF *) DatumGetPointer(entryvec->vector[i].key); + BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[i].key); if (i == FirstOffsetNumber) context.boundingBox = *box; else @@ -1814,7 +1833,7 @@ Datum gserialized_gist_picksplit_2d(PG_FUNCTION_ARGS) /* Project each entry as an interval on the selected axis. */ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - box = (BOX2DF *) DatumGetPointer(entryvec->vector[i].key); + BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[i].key); if (dim == 0) { intervalsLower[i - FirstOffsetNumber].lower = box->xmin; @@ -2010,7 +2029,7 @@ Datum gserialized_gist_picksplit_2d(PG_FUNCTION_ARGS) /* * Get upper and lower bounds along selected axis. */ - box = (BOX2DF *) DatumGetPointer(entryvec->vector[i].key); + BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[i].key); if (context.dim == 0) { lower = box->xmin; @@ -2065,42 +2084,43 @@ Datum gserialized_gist_picksplit_2d(PG_FUNCTION_ARGS) if (nentries > INDEX_TUPLES_PER_PAGE && nentries <= 2 * INDEX_TUPLES_PER_PAGE) m = Max(m, nentries - INDEX_TUPLES_PER_PAGE); - /* - * Calculate delta between penalties of join "common entries" to - * different groups. - */ + Assert(m >= 1); + for (i = 0; i < (OffsetNumber)commonEntriesCount; i++) { - box = (BOX2DF *) DatumGetPointer(entryvec->vector[ - commonEntries[i].index].key); - /** PG!6 Abs was removed in favor of standard c lib **/ - commonEntries[i].delta = fabs(box2df_penalty(leftBox, box) - box2df_penalty(rightBox, box)); + BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[commonEntries[i].index].key); + + if (v->spl_nright > 0 && v->spl_nleft > 0) + { + /* Calculate delta between penalties of join "common entries" to different groups. */ + commonEntries[i].delta = + fabsf(box2df_penalty(leftBox, box) - box2df_penalty(rightBox, box)); + } + else + { + /* One group became degenerate during split - distribute boxes by their size */ + commonEntries[i].delta = -box2df_penalty_single(box); + } } - /* - * Sort "common entries" by calculated deltas in order to distribute - * the most ambiguous entries first. - */ + /* Sort "common entries" to distribute the most ambiguous entries first. */ qsort(commonEntries, commonEntriesCount, sizeof(CommonEntry), common_entry_cmp); - /* - * Distribute "common entries" between groups. - */ + /* Distribute "common entries" between groups. */ for (i = 0; i < (OffsetNumber)commonEntriesCount; i++) { - float right_penalty, left_penalty; bool place_right = true; - box = (BOX2DF *)DatumGetPointer(entryvec->vector[commonEntries[i].index].key); + BOX2DF *box = (BOX2DF *)DatumGetPointer(entryvec->vector[commonEntries[i].index].key); /* Recheck penalties. After we put undecided tuples to some side they're changed */ - left_penalty = box2df_penalty(leftBox, box); - right_penalty = box2df_penalty(rightBox, box); + float left_penalty = box2df_penalty(leftBox, box); + float right_penalty = box2df_penalty(rightBox, box); - /* Check if penalty is absolutely telling a tuple should go to some side */ - if (right_penalty > 0 && left_penalty == 0) - place_right = false; - else if (right_penalty == 0 && left_penalty > 0) + /* Guarantee at least one tuple on each side to make Postgres happy */ + if (v->spl_nright == 0 && v->spl_nleft > 0) place_right = true; + else if (v->spl_nleft == 0 && v->spl_nright > 0) + place_right = false; /* Check if we have to place this entry in either group to achieve LIMIT_RATIO */ else if (v->spl_nleft + (commonEntriesCount - i) <= m) place_right = false; ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +- postgis/gserialized_gist_2d.c | 80 +++++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 31 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 23 16:48:41 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 23 Oct 2025 23:48:41 -0000 Subject: [PostGIS] #5992: DEBUG: picksplit method for column 1 of index "edge_gist" failed In-Reply-To: <046.424d702d2aadc17564a39641098ed329@osgeo.org> References: <046.424d702d2aadc17564a39641098ed329@osgeo.org> Message-ID: <061.7b5bb5c03d50e40df4b2c2cf6e11f6d1@osgeo.org> #5992: DEBUG: picksplit method for column 1 of index "edge_gist" failed ----------------------+--------------------------- Reporter: strk | Owner: komzpa Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"0c57be8a1a45f2e23448a2eba0b8dc3530f822aa/git" 0c57be8/git]: {{{#!CommitTicketReference repository="git" revision="0c57be8a1a45f2e23448a2eba0b8dc3530f822aa" Optimize GiST index for repeated edge subdivision in topology If the first box is covering all the tuples on the index page picksplit was failing to produce two partitions as penalty with first one was 0 for all elements. Closes #5992 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 23 17:01:13 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 23 Oct 2025 17:01:13 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-156-g1b88d3722 Message-ID: <20251024000113.950EF1985EF@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 1b88d3722487b689b97942c713e62ffce714289c (commit) from 0c57be8a1a45f2e23448a2eba0b8dc3530f822aa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1b88d3722487b689b97942c713e62ffce714289c Author: Darafei Praliaskouski Date: Fri Oct 24 04:01:00 2025 +0400 Allow the compiler to detect the parallelism for LTO (-flto=auto) Closes #5702 diff --git a/configure.ac b/configure.ac index 61ab6bbf2..d89e82c55 100644 --- a/configure.ac +++ b/configure.ac @@ -1335,8 +1335,19 @@ if test $ENABLE_DEBUG -eq 1; then else CFLAGS="$CFLAGS -O2" if test $ENABLE_LTO -eq 1; then - _LT_COMPILER_OPTION([if $compiler supports -flto],[_cv_flto],[-flto],[],[CFLAGS="$CFLAGS -flto"],[]) - _LT_LINKER_OPTION([if $compiler supports -flto],[_cv_flto],[[-flto]],[LDFLAGS="$LDFLAGS -flto"]) + if test "$GCC" = yes; then + _LT_COMPILER_OPTION([if $compiler supports -flto=auto],[_cv_flto_auto],[-flto=auto],[],[CFLAGS="$CFLAGS -flto=auto"],[]) + if test "$_cv_flto_auto" != yes; then + _LT_COMPILER_OPTION([if $compiler supports -flto],[_cv_flto],[-flto],[],[CFLAGS="$CFLAGS -flto"],[]) + fi + _LT_LINKER_OPTION([if the linker supports -flto=auto],[_cv_ld_flto_auto],[[-flto=auto]],[LDFLAGS="$LDFLAGS -flto=auto"]) + if test "$_cv_ld_flto_auto" != yes; then + _LT_LINKER_OPTION([if the linker supports -flto],[_cv_ld_flto],[[-flto]],[LDFLAGS="$LDFLAGS -flto"]) + fi + else + _LT_COMPILER_OPTION([if $compiler supports -flto],[_cv_flto],[-flto],[],[CFLAGS="$CFLAGS -flto"],[]) + _LT_LINKER_OPTION([if $compiler supports -flto],[_cv_flto],[[-flto]],[LDFLAGS="$LDFLAGS -flto"]) + fi fi fi ----------------------------------------------------------------------- Summary of changes: configure.ac | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 23 17:01:21 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 24 Oct 2025 00:01:21 -0000 Subject: [PostGIS] #5702: lto-wrapper: warning: using serial compilation of # LTRANS jobs In-Reply-To: <046.cc6d8f55e3a89624cb45b3024cfb2659@osgeo.org> References: <046.cc6d8f55e3a89624cb45b3024cfb2659@osgeo.org> Message-ID: <061.d9e011ff7d900c7251ba39a9134d98ff@osgeo.org> #5702: lto-wrapper: warning: using serial compilation of # LTRANS jobs ---------------------+--------------------------- Reporter: strk | Owner: strk Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.5 Component: build | Version: master Resolution: fixed | Keywords: ---------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"1b88d3722487b689b97942c713e62ffce714289c/git" 1b88d372/git]: {{{#!CommitTicketReference repository="git" revision="1b88d3722487b689b97942c713e62ffce714289c" Allow the compiler to detect the parallelism for LTO (-flto=auto) Closes #5702 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 23 17:03:34 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 23 Oct 2025 17:03:34 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-157-g385a9ff4e Message-ID: <20251024000334.A0652199350@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 385a9ff4e608bb5486b6146d43f51fdd534d884e (commit) from 1b88d3722487b689b97942c713e62ffce714289c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 385a9ff4e608bb5486b6146d43f51fdd534d884e Author: Darafei Praliaskouski Date: Fri Oct 24 04:03:18 2025 +0400 NEWS entry for #5702 LTO fix diff --git a/NEWS b/NEWS index b1faae2f8..376a414cb 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ xxxx/xx/xx - #6001, support MultiLineString in ST_MakeLine (Paul Ramsey) - #2858, ST_MMin and ST_MMax (Paul Ramsey) - #5992, Optimize GiST index for repeated edge subdivision in topology (Darafei Praliaskouski) + - #5702, Allow the compiler to detect the parallelism -flto=auto (Darafei Praliaskouski) PostGIS 3.6.0 ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 23 18:22:47 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 23 Oct 2025 18:22:47 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-158-g0848c6ab1 Message-ID: <20251024012247.C4BC61990D6@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 0848c6ab155041008cdd432042669448878f05cc (commit) from 385a9ff4e608bb5486b6146d43f51fdd534d884e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0848c6ab155041008cdd432042669448878f05cc Author: Darafei Praliaskouski Date: Fri Oct 24 05:22:33 2025 +0400 ST_AsGeoJSON warns about duplicate property keys Closes #4798 diff --git a/NEWS b/NEWS index 376a414cb..6fc642459 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ xxxx/xx/xx - #2858, ST_MMin and ST_MMax (Paul Ramsey) - #5992, Optimize GiST index for repeated edge subdivision in topology (Darafei Praliaskouski) - #5702, Allow the compiler to detect the parallelism -flto=auto (Darafei Praliaskouski) + - #4798, ST_AsGeoJSON warns about duplicate property keys (Darafei Praliaskouski) PostGIS 3.6.0 diff --git a/doc/reference_output.xml b/doc/reference_output.xml index a5f2e95da..7d08befec 100644 --- a/doc/reference_output.xml +++ b/doc/reference_output.xml @@ -1,4 +1,3 @@ -
    Geometry Output @@ -706,6 +705,8 @@ Conversely, passing the parameter will save column type lookups. The id_column parameter is used to set the "id" member of the returned GeoJSON features. As per GeoJSON RFC, this SHOULD be used whenever a feature has a commonly used identifier, such as a primary key. When not specified, the produced features will not get an "id" member and any columns other than the geometry, including any potential keys, will just end up inside the feature?s "properties" member. + When the input record includes duplicate column names, the resulting "properties" object will contain repeated keys. ST_AsGeoJSON raises a warning in that case because PostgreSQL jsonb keeps only the last value for duplicate keys. + The GeoJSON specification states that polygons are oriented using the Right-Hand Rule, and some clients require this orientation. This can be ensured by using . @@ -730,7 +731,8 @@ Conversely, passing the parameter will save column type lookups. Changed: 2.0.0 support default args and named args. Changed: 3.0.0 support records as input Changed: 3.0.0 output SRID if not EPSG:4326. - Changed: 3.5.0 allow specifying the column containing the feature id + Changed: 3.5.0 allow specifying the column containing the feature id + Changed: 3.7.0 added warning about duplicate keys &Z_support; diff --git a/postgis/lwgeom_out_geojson.c b/postgis/lwgeom_out_geojson.c index 0338cdf18..1454343e8 100644 --- a/postgis/lwgeom_out_geojson.c +++ b/postgis/lwgeom_out_geojson.c @@ -19,6 +19,7 @@ #include "utils/datetime.h" #include "utils/lsyscache.h" #include "utils/json.h" +#include "utils/hsearch.h" #if POSTGIS_PGSQL_VERSION < 130 #include "utils/jsonapi.h" #else @@ -47,10 +48,20 @@ typedef enum /* type categories for datum_to_json */ JSONTYPE_OTHER /* all else */ } JsonTypeCategory; -static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, - Datum *vals, bool *nulls, int *valcount, - JsonTypeCategory tcategory, Oid outfuncoid, - bool use_line_feeds); +typedef struct GeoJsonPropKey { + char key[NAMEDATALEN]; +} GeoJsonPropKey; + +static void array_dim_to_json(StringInfo result, + int dim, + int ndims, + int *dims, + Datum *vals, + bool *nulls, + int *valcount, + JsonTypeCategory tcategory, + Oid outfuncoid, + bool use_line_feeds); static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds); static void composite_to_geojson(FunctionCallInfo fcinfo, @@ -127,18 +138,24 @@ composite_to_geojson(FunctionCallInfo fcinfo, Oid geog_oid) { HeapTupleHeader td; - Oid tupType; - int32 tupTypmod; - TupleDesc tupdesc; - HeapTupleData tmptup, - *tuple; - int i; - bool needsep = false; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tmptup, *tuple; + int i; + bool needsep = false; const char *sep; - StringInfo props = makeStringInfo(); - StringInfo id = makeStringInfo(); - bool geom_column_found = false; - bool id_column_found = false; + StringInfo props = makeStringInfo(); + StringInfo id = makeStringInfo(); + bool geom_column_found = false; + bool id_column_found = false; + HTAB *prop_keys = NULL; + HASHCTL ctl; + + MemSet(&ctl, 0, sizeof(ctl)); + ctl.keysize = NAMEDATALEN; + ctl.entrysize = sizeof(GeoJsonPropKey); + ctl.hcxt = CurrentMemoryContext; sep = use_line_feeds ? ",\n " : ", "; @@ -149,6 +166,15 @@ composite_to_geojson(FunctionCallInfo fcinfo, tupTypmod = HeapTupleHeaderGetTypMod(td); tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + /* + * Keep track of property names for this feature so that we can warn + * when SQL supplies duplicate aliases. GeoJSON accepts repeated keys, + * yet downstream PostgreSQL jsonb casts retain only the last value, so + * surfacing the issue here prevents silent information loss. + */ + prop_keys = + hash_create("GeoJSON property keys", Max(tupdesc->natts, 8), &ctl, HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); + /* Build a temporary HeapTuple control structure */ tmptup.t_len = HeapTupleHeaderGetDatumLength(td); tmptup.t_data = td; @@ -158,14 +184,14 @@ composite_to_geojson(FunctionCallInfo fcinfo, for (i = 0; i < tupdesc->natts; i++) { - Datum val; - bool isnull; - char *attname; + Datum val; + bool isnull; + char *attname; JsonTypeCategory tcategory; - Oid outfuncoid; + Oid outfuncoid; Form_pg_attribute att = TupleDescAttr(tupdesc, i); - bool is_geom_column = false; - bool is_id_column = false; + bool is_geom_column = false; + bool is_id_column = false; if (att->attisdropped) continue; @@ -220,10 +246,22 @@ composite_to_geojson(FunctionCallInfo fcinfo, } else { + bool found; + if (needsep) appendStringInfoString(props, sep); needsep = true; + (void)hash_search(prop_keys, attname, HASH_ENTER, &found); + if (found) + { + ereport( + WARNING, + (errmsg("duplicate key \"%s\" encountered while building GeoJSON properties", + attname), + errhint("Only the last value for each key is preserved when casting to JSONB."))); + } + escape_json(props, attname); appendStringInfoString(props, ": "); @@ -242,16 +280,14 @@ composite_to_geojson(FunctionCallInfo fcinfo, } if (!geom_column_found) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("geometry column is missing"))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("geometry column is missing"))); if (id_column_name) { if (!id_column_found) ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("Specified id column \"%s\" is missing", id_column_name))); + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("Specified id column \"%s\" is missing", id_column_name))); appendStringInfoString(result, ", \"id\": "); appendStringInfo(result, "%s", id->data); @@ -261,6 +297,7 @@ composite_to_geojson(FunctionCallInfo fcinfo, appendStringInfo(result, "%s", props->data); appendStringInfoString(result, "}}"); + hash_destroy(prop_keys); ReleaseTupleDesc(tupdesc); } diff --git a/regress/core/tickets.sql b/regress/core/tickets.sql index 0b34a3028..6fd77a19d 100644 --- a/regress/core/tickets.sql +++ b/regress/core/tickets.sql @@ -1442,6 +1442,18 @@ FROM ST_SetSRID(ST_MakePoint(7, 51), 4326) geom ) data; +-- https://trac.osgeo.org/postgis/ticket/4798 +SET client_min_messages TO WARNING; +SELECT + '#4798', ST_AsGeoJSON(data.*) +FROM + (SELECT + 1 AS column, + 2 AS column, + ST_SetSRID(ST_MakePoint(7, 51), 4326) AS geom + ) AS data; +RESET client_min_messages; + -- https://trac.osgeo.org/postgis/ticket/5008 SELECT diff --git a/regress/core/tickets_expected b/regress/core/tickets_expected index fbf04a8c1..c39981696 100644 --- a/regress/core/tickets_expected +++ b/regress/core/tickets_expected @@ -460,6 +460,8 @@ ERROR: LWGEOM_addpoint: Invalid offset #4770.c|POINT(0 0)|300 #4770.c|MULTIPOINT((0 0),(1 1))|602 #4799|{"type": "Feature", "geometry": {"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:25832"}},"coordinates":[359667,5651729]}, "properties": {"id": 1, "geom1": {"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:3035"}},"coordinates":[4110471,3103061]}}} +WARNING: duplicate key "column" encountered while building GeoJSON properties +#4798|{"type": "Feature", "geometry": {"type":"Point","coordinates":[7,51]}, "properties": {"column": 1, "column": 2}} #5008|f|f ERROR: Line has no points #5350|M 0 0 l 1 -1 ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/reference_output.xml | 6 ++- postgis/lwgeom_out_geojson.c | 89 ++++++++++++++++++++++++++++++------------- regress/core/tickets.sql | 12 ++++++ regress/core/tickets_expected | 2 + 5 files changed, 82 insertions(+), 28 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 23 18:22:49 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 24 Oct 2025 01:22:49 -0000 Subject: [PostGIS] #4798: ST_AsGeoJSON should warn about duplicate keys In-Reply-To: <048.9e70b822005c858f142b8907d42c527a@osgeo.org> References: <048.9e70b822005c858f142b8907d42c527a@osgeo.org> Message-ID: <063.2d75f1f9b1729950aa72ce9be291ee61@osgeo.org> #4798: ST_AsGeoJSON should warn about duplicate keys --------------------------+---------------------------------- Reporter: tobwen | Owner: pramsey Type: enhancement | Status: closed Priority: low | Milestone: PostGIS Fund Me Component: postgis | Version: master Resolution: fixed | Keywords: geojson, json, jsonb --------------------------+---------------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"0848c6ab155041008cdd432042669448878f05cc/git" 0848c6a/git]: {{{#!CommitTicketReference repository="git" revision="0848c6ab155041008cdd432042669448878f05cc" ST_AsGeoJSON warns about duplicate property keys Closes #4798 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 23:21:27 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 24 Oct 2025 06:21:27 -0000 Subject: [PostGIS] #6007: Different results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.e2358a3d3fe01b44e0934fb33a90c1cd@osgeo.org> #6007: Different results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: | Keywords: --------------------------------+--------------------------- Comment (by Lars Aksel Opsahl): Yes this diff seems not to indicate bug, but more solve an issue related to snapping in a error case I am working on now. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 23 23:23:53 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 24 Oct 2025 06:23:53 -0000 Subject: [PostGIS] #6007: Different results with two version of postgis master. In-Reply-To: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> References: <050.7f7ef4cd03e42a9e70e5113b2176649b@osgeo.org> Message-ID: <065.3f18b3637dc8c13725ac1ae7b7709cc7@osgeo.org> #6007: Different results with two version of postgis master. --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: master Resolution: invalid | Keywords: --------------------------------+--------------------------- Changes (by Lars Aksel Opsahl): * resolution: => invalid * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 24 03:38:01 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 24 Oct 2025 10:38:01 -0000 Subject: [PostGIS] #5601: A ST_Intersect row is missed when using JOIN. In-Reply-To: <049.d42856e54c86bb8d9a5d73b9f28553cd@osgeo.org> References: <049.d42856e54c86bb8d9a5d73b9f28553cd@osgeo.org> Message-ID: <064.562addb397517b67b1746db239880ffd@osgeo.org> #5601: A ST_Intersect row is missed when using JOIN. -----------------------+-------------------------- Reporter: Wenjing | Owner: pramsey Type: defect | Status: closed Priority: critical | Milestone: PostGIS GEOS Component: postgis | Version: 3.4.x Resolution: fixed | Keywords: -----------------------+-------------------------- Changes (by komzpa): * resolution: => fixed * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 24 05:51:36 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 24 Oct 2025 12:51:36 -0000 Subject: [PostGIS] #2574: Have ST_3DDWithin to recognize Triangle as a type In-Reply-To: <055.22a624e1405320b227671530e800b927@osgeo.org> References: <055.22a624e1405320b227671530e800b927@osgeo.org> Message-ID: <070.d8861fde746e41d9c5fd77bfbe38e657@osgeo.org> #2574: Have ST_3DDWithin to recognize Triangle as a type ----------------------------+----------------------------- Reporter: smathermather | Owner: colivier Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: postgis | Version: 2.1.x Resolution: fixed | Keywords: ----------------------------+----------------------------- Changes (by komzpa): * resolution: => fixed * status: new => closed Comment: Works {{{ POSTGIS="3.7.0dev 3.6.0rc2-157-g385a9ff4e" [EXTENSION] PGSQL="180" GEOS="3.14.0-CAPI-1.20.4" PROJ="9.7.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 9.7.0) GDAL="GDAL 3.12.0beta1 "Chicoutimi", released 2025/10/20" LIBXML="2.15.1" LIBJSON="0.18" LIBPROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)" RASTER 16:50:48 [kom] > -- Helpers: two triangles and a few other geoms -- tri_a: near origin, XY plane at z=0 WITH tri_a AS ( SELECT 'TRIANGLE Z ((0 0 0, 1 0 0, 0 1 0, 0 0 0))'::geometry AS g ), -- tri_b_xy: translated along +X by 10, same plane z=0 -- shortest 3D distance to tri_a is exactly 9 (from x=1 to x=10) tri_b_xy AS ( SELECT 'TRIANGLE Z ((10 0 0, 11 0 0, 10 1 0, 10 0 0))'::geometry AS g ), -- tri_b_xyz: same footprint as tri_b_xy but raised to z=8 -- true 3D shortest distance to tri_a is sqrt(9^2 + 8^2) = sqrt(145) ? 12.0415945788 tri_b_xyz AS ( SELECT 'TRIANGLE Z ((10 0 8, 11 0 8, 10 1 8, 10 0 8))'::geometry AS g ), pt_inside_tri_a AS ( SELECT ST_MakePoint(0.25, 0.25, 0.0)::geometry AS g ), poly_near_tri_a AS ( -- simple square polygon hovering 0.5 units above tri_a in Z SELECT 'POLYGON Z ((0.2 0.2 0.5, 0.8 0.2 0.5, 0.8 0.8 0.5, 0.2 0.8 0.5, 0.2 0.2 0.5))'::geometry AS g ) -- 1) REPRO of current pre-fix failure (expected to ERROR today; should PASS after fix): -- If your build still errors with "Unsupported geometry type: Triangle", -- these SELECTs will fail right here. After the fix, they return booleans. SELECT 'tri vs tri (XY, d=8) expect false' AS test, ST_3DDWithin((SELECT g FROM tri_a), (SELECT g FROM tri_b_xy), 8.0) AS ok UNION ALL SELECT 'tri vs tri (XY, d=9) expect true', ST_3DDWithin((SELECT g FROM tri_a), (SELECT g FROM tri_b_xy), 9.0) UNION ALL SELECT 'tri vs tri (XYZ, d=12) expect false', ST_3DDWithin((SELECT g FROM tri_a), (SELECT g FROM tri_b_xyz), 12.0) UNION ALL SELECT 'tri vs tri (XYZ, d=12.05) expect true', ST_3DDWithin((SELECT g FROM tri_a), (SELECT g FROM tri_b_xyz), 12.05) UNION ALL SELECT 'tri vs point (inside, d=0) expect true', ST_3DDWithin((SELECT g FROM tri_a), (SELECT g FROM pt_inside_tri_a), 0.0) UNION ALL SELECT 'tri vs polygon (hovering at z=0.5, d=0.5) expect true', ST_3DDWithin((SELECT g FROM tri_a), (SELECT g FROM poly_near_tri_a), 0.5); ?????????????????????????????????????????????????????????????? ? test ? ok ? ?????????????????????????????????????????????????????????????? ? tri vs tri (XY, d=8) expect false ? f ? ? tri vs tri (XY, d=9) expect true ? t ? ? tri vs tri (XYZ, d=12) expect false ? f ? ? tri vs tri (XYZ, d=12.05) expect true ? t ? ? tri vs point (inside, d=0) expect true ? t ? ? tri vs polygon (hovering at z=0.5, d=0.5) expect true ? t ? ?????????????????????????????????????????????????????????????? (6 rows) Time: 0,629 ms }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 24 10:47:50 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 24 Oct 2025 10:47:50 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-159-gfec314965 Message-ID: <20251024174750.65B61213F@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via fec3149657a8433d67df12708c5d3fc3bc584424 (commit) from 0848c6ab155041008cdd432042669448878f05cc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fec3149657a8433d67df12708c5d3fc3bc584424 Author: juan sebastian jimenez aldana Date: Fri Oct 24 15:55:44 2025 +0000 Translated PostGIS Manual using Weblate (Spanish) Currently translated at 21.9% (1284 of 5857 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/es/ diff --git a/doc/po/es/postgis-manual.po b/doc/po/es/postgis-manual.po index 5b5a24178..f19dd9cd1 100644 --- a/doc/po/es/postgis-manual.po +++ b/doc/po/es/postgis-manual.po @@ -3,13 +3,15 @@ # # DeepL , 2025. # Paulo Cesar Coronado , 2025. +# juan sebastian jimenez aldana , 2025. msgid "" msgstr "" "Project-Id-Version: postgis 3.5\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-08-21 03:28+0000\n" -"PO-Revision-Date: 2025-09-04 23:47+0000\n" -"Last-Translator: DeepL \n" +"PO-Revision-Date: 2025-10-24 17:47+0000\n" +"Last-Translator: juan sebastian jimenez aldana \n" "Language-Team: Spanish \n" "Language: es\n" @@ -113,7 +115,7 @@ msgstr "" "al cluster." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "On windows, if you are running as a service, you can set via System " "variables which for Windows 7 you can get to by right-clicking on Computer-" @@ -122,6 +124,14 @@ msgid "" "clicking Advanced System Settings ->Advanced->Environment " "Variables and adding new system variables." msgstr "" +"En Windows, si se ejecuta como un servicio, se puede configurar a trav?s de " +"las variables del sistema, a las que se puede acceder en Windows 7 haciendo " +"clic con el bot?n derecho del rat?n en Equipo-> Propiedades Configuraci?n " +"avanzada del sistema o en el explorador navegando hasta Panel de " +"control\\Todos los elementos del panel de control\\Sistema. A " +"continuaci?n, haga clic en Configuraci?n avanzada del sistema -> " +"> Avanzadas ->> Variables de entorno y a?ada nuevas variables " +"del sistema." #. Tag: para #, no-c-format @@ -129,11 +139,13 @@ msgid "" "After you set the environment variables, you'll need to restart your " "PostgreSQL service for the changes to take effect." msgstr "" +"Despu?s de configurar las variables de entorno, deber? reiniciar el servicio " +"PostgreSQL para que los cambios surtan efecto." #. Tag: title #, no-c-format msgid "Creating spatial databases" -msgstr "" +msgstr "Creaci?n de bases de datos espaciales" #. Tag: title #, no-c-format @@ -195,6 +207,9 @@ msgid "" "by loading the various sql files located in [prefix]/share/" "contrib as specified during the build phase." msgstr "" +"Para agregar objetos PostGIS y definiciones de funciones a su base de datos, " +"cargue los distintos archivos sql ubicados en [prefix]/share/" +"contrib, tal y como se especifica durante la fase de compilaci?n." #. Tag: para #, no-c-format @@ -204,6 +219,11 @@ msgid "" "objects are in the rtpostgis.sql script. Topology " "objects are in the topology.sql script." msgstr "" +"Los objetos principales de PostGIS (tipos geom?tricos y geogr?ficos, y sus " +"funciones de soporte) se encuentran en el script postgis.sql. Los objetos r?ster se encuentran en el script rtpostgis." +"sql. Los objetos topol?gicos se encuentran en el script " +"topology.sql." #. Tag: para #, no-c-format @@ -213,6 +233,11 @@ msgid "" "populate the spatial_ref_sys table. This will permit you " "to perform ST_Transform() operations on geometries." msgstr "" +"Para obtener un conjunto completo de identificadores de definici?n del " +"sistema de coordenadas EPSG, tambi?n puede cargar el archivo de definiciones " +"spatial_ref_sys.sql y rellenar la tabla " +"spatial_ref_sys. Esto le permitir? realizar operaciones " +"ST_Transform() en geometr?as." #. Tag: para #, no-c-format @@ -222,16 +247,20 @@ msgid "" "by simply typing \\dd [function_name] from a " "psql terminal window." msgstr "" +"Si desea a?adir comentarios a las funciones de PostGIS, los encontrar? en el " +"script postgis_comments.sql. Los comentarios se pueden " +"ver simplemente escribiendo \\dd [nombre_funci?n] desde " +"una ventana de terminal psql." #. Tag: para #, no-c-format msgid "Run the following Shell commands in your terminal:" -msgstr "" +msgstr "Ejecute los siguientes comandos Shell en su terminal:" #. Tag: title #, no-c-format msgid "Upgrading spatial databases" -msgstr "" +msgstr "Actualizaci?n de bases de datos espaciales" #. Tag: para #, no-c-format @@ -239,6 +268,9 @@ msgid "" "Upgrading existing spatial databases can be tricky as it requires " "replacement or introduction of new PostGIS object definitions." msgstr "" +"Actualizar las bases de datos espaciales existentes puede resultar " +"complicado, ya que requiere sustituir o introducir nuevas definiciones de " +"objetos PostGIS." #. Tag: para #, no-c-format @@ -246,6 +278,9 @@ msgid "" "Unfortunately not all definitions can be easily replaced in a live database, " "so sometimes your best bet is a dump/reload process." msgstr "" +"Desafortunadamente, no todas las definiciones se pueden reemplazar " +"f?cilmente en una base de datos activa, por lo que a veces la mejor opci?n " +"es un proceso de volcado/recarga." #. Tag: para #, no-c-format @@ -253,6 +288,9 @@ msgid "" "PostGIS provides a SOFT UPGRADE procedure for minor or bugfix releases, and " "a HARD UPGRADE procedure for major releases." msgstr "" +"PostGIS proporciona un procedimiento de ACTUALIZACI?N SUAVE para versiones " +"menores o correcciones de errores, y un procedimiento de ACTUALIZACI?N " +"COMPLETA para versiones principales." #. Tag: para #, no-c-format @@ -261,11 +299,14 @@ msgid "" "data. If you use the -Fc flag to pg_dump you will always be able to restore " "the dump with a HARD UPGRADE." msgstr "" +"Antes de intentar actualizar PostGIS, siempre es recomendable hacer una " +"copia de seguridad de sus datos. Si utiliza el indicador -Fc con pg_dump, " +"siempre podr? restaurar el volcado con una ACTUALIZACI?N DURO." #. Tag: title #, no-c-format msgid "Soft upgrade" -msgstr "" +msgstr "Actualizaci?n suave" #. Tag: para #, no-c-format @@ -275,11 +316,15 @@ msgid "" "way, you are advised to switch your install to extensions because the script " "way is no longer supported." msgstr "" +"Si instal? su base de datos utilizando extensiones, tambi?n deber? " +"actualizarla utilizando el modelo de extensiones. Si la instal? utilizando " +"el antiguo m?todo de script sql, le recomendamos que cambie su instalaci?n a " +"extensiones, ya que el m?todo de script ya no es compatible." #. Tag: title #, no-c-format msgid "Soft Upgrade 9.1+ using extensions" -msgstr "" +msgstr "Actualizaci?n suave 9.1+ utilizando extensiones" #. Tag: para #, no-c-format @@ -288,6 +333,9 @@ msgid "" "upgrade using extensions as well. Doing a minor upgrade with extensions, is " "fairly painless." msgstr "" +"Si instal? PostGIS originalmente con extensiones, entonces tambi?n deber? " +"actualizarlo utilizando extensiones. Realizar una actualizaci?n menor con " +"extensiones es bastante sencillo." #. Tag: para #, no-c-format @@ -296,11 +344,14 @@ msgid "" "linkend=\"PostGIS_Extensions_Upgrade\"/> function to upgrade to the latest " "version you have installed." msgstr "" +"Si utiliza PostGIS 3 o superior, debe utilizar la funci?n para actualizar a la ?ltima versi?n que " +"tenga instalada." #. Tag: para #, no-c-format msgid "If you are running PostGIS 2.5 or lower, then do the following:" -msgstr "" +msgstr "Si utiliza PostGIS 2.5 o una versi?n anterior, haga lo siguiente:" #. Tag: para #, no-c-format @@ -308,11 +359,13 @@ msgid "" "If you have multiple versions of PostGIS installed, and you don't want to " "upgrade to the latest, you can explicitly specify the version as follows:" msgstr "" +"Si tiene varias versiones de PostGIS instaladas y no desea actualizar a la " +"?ltima, puede especificar expl?citamente la versi?n de la siguiente manera:" #. Tag: para #, no-c-format msgid "If you get an error notice something like:" -msgstr "" +msgstr "Si recibe un aviso de error similar al siguiente:" #. Tag: para #, no-c-format @@ -321,11 +374,15 @@ msgid "" " and then restore your backup on " "top of this new database." msgstr "" +"A continuaci?n, deber? realizar una copia de seguridad de su base de datos, " +"crear una nueva tal y como se describe en y, a continuaci?n, restaurar su copia de " +"seguridad sobre esta nueva base de datos." #. Tag: para #, no-c-format msgid "If you get a notice message like:" -msgstr "" +msgstr "Si recibe un mensaje de aviso como:" #. Tag: para #, no-c-format @@ -336,6 +393,11 @@ msgid "" "in that case you can append \"next\" to the version string, and next time " "you'll need to drop the \"next\" suffix again:" msgstr "" +"Entonces todo estar? ya actualizado y podr? ignorarlo sin problema. " +"UNLESS que est? intentando actualizar de " +"una versi?n de desarrollo a la siguiente (que no tiene un nuevo n?mero de " +"versi?n); en ese caso, puede a?adir ?next? a la cadena de la versi?n, y la " +"pr?xima vez tendr? que eliminar el sufijo ?next? de nuevo:" #. Tag: para #, no-c-format @@ -345,6 +407,10 @@ msgid "" "the backup just has CREATE EXTENSION postgis and thus picks up " "the newest latest version during restore." msgstr "" +"Si instal? PostGIS originalmente sin especificar una versi?n, a menudo puede " +"omitir la reinstalaci?n de la extensi?n postgis antes de restaurar, ya que " +"la copia de seguridad solo tiene CREATE EXTENSION postgis y, " +"por lo tanto, toma la ?ltima versi?n m?s reciente durante la restauraci?n." #. Tag: para #, no-c-format @@ -353,11 +419,15 @@ msgid "" "will have a new extension postgis_raster which you can " "safely drop, if you don't need raster support. You can drop as follows:" msgstr "" +"Si est? actualizando la extensi?n PostGIS desde una versi?n anterior a la " +"3.0.0, tendr? una nueva extensi?n postgis_raster que " +"puede eliminar de forma segura si no necesita compatibilidad con r?ster. " +"Puede eliminarla de la siguiente manera:" #. Tag: title #, no-c-format msgid "Soft Upgrade Pre 9.1+ or without extensions" -msgstr "" +msgstr "Actualizaci?n suave Pre 9.1+ o sin extensiones" #. Tag: para #, no-c-format @@ -366,6 +436,9 @@ msgid "" "extensions. If you have extensions and try to upgrade with this approach " "you'll get messages like:" msgstr "" +"Esta secci?n solo se aplica a aquellos que hayan instalado PostGIS sin " +"utilizar extensiones. Si tiene extensiones e intenta actualizar con este " +"m?todo, aparecer?n mensajes como:" #. Tag: para #, no-c-format @@ -374,6 +447,9 @@ msgid "" "prior to r7409, you cannot use this procedure but would rather need to do a " "HARD UPGRADE." msgstr "" +"NOTA: si est? migrando de PostGIS 1.* a PostGIS 2.* o de PostGIS 2.* " +"anterior a r7409, no puede utilizar este procedimiento, sino que deber? " +"realizar una HARD UPGRADE." #. Tag: para #, no-c-format @@ -382,6 +458,9 @@ msgid "" "*_upgrade.sql files in the installation folders. You " "can list them all with:" msgstr "" +"Despu?s de compilar e instalar (make install), deber?a encontrar un conjunto " +"de archivos *_upgrade.sql en las carpetas de " +"instalaci?n. Puede enumerarlos todos con:" #. Tag: para #, no-c-format @@ -389,6 +468,8 @@ msgid "" "Load them all in turn, starting from postgis_upgrade.sql." msgstr "" +"C?rguelos todos por orden, empezando por postgis_upgrade." +"sql." #. Tag: para #, no-c-format @@ -398,11 +479,16 @@ msgid "" "topology_upgrade.sql and sfcgal_upgrade.sql respectively. If you need them:" msgstr "" +"El mismo procedimiento se aplica a las extensiones raster, topology y " +"sfcgal, con archivos de actualizaci?n denominados rtpostgis_upgrade" +".sql, topology_upgrade.sql y " +"sfcgal_upgrade.sql, respectivamente. Si los necesita:" #. Tag: para #, no-c-format msgid "You are advised to switch to an extension based install by running" msgstr "" +"Se recomienda cambiar a una instalaci?n basada en extensiones ejecutando" #. Tag: para #, no-c-format @@ -411,6 +497,10 @@ msgid "" "upgrading your version you are using a version too early for a soft upgrade " "and need to do a HARD UPGRADE." msgstr "" +"Si no encuentra el archivo postgis_upgrade.sql " +"espec?fico para actualizar su versi?n, significa que est? utilizando una " +"versi?n demasiado antigua para realizar una actualizaci?n suave y debe " +"realizar una HARD UPGRADE." #. Tag: para #, no-c-format @@ -419,11 +509,14 @@ msgid "" "about the need to run this kind of upgrade using a \"procs need upgrade\" " "message." msgstr "" +"La funci?n deber?a informarle sobre " +"la necesidad de ejecutar este tipo de actualizaci?n mediante un mensaje ?" +"procs need upgrade? (los procedimientos necesitan actualizaci?n)." #. Tag: title #, no-c-format msgid "Hard upgrade" -msgstr "" +msgstr "Actualizaci?n dif?cil" #. Tag: para #, no-c-format @@ -434,6 +527,13 @@ msgid "" "Notes appendix reports for each version whether you need a dump/" "reload (HARD UPGRADE) to upgrade." msgstr "" +"Por ACTUALIZACI?N COMPLETA nos referimos al volcado/recarga completa de " +"bases de datos habilitadas para PostGIS. Necesita una ACTUALIZACI?N COMPLETA " +"cuando cambia el almacenamiento interno de los objetos PostGIS o cuando no " +"es posible realizar una ACTUALIZACI?N PARCIAL. El ap?ndice Notas de la versi?n indica para cada versi?n si es " +"necesario realizar un volcado/recarga (ACTUALIZACI?N COMPLETA) para " +"actualizar." #. Tag: para #, no-c-format @@ -444,6 +544,11 @@ msgid "" "database with PostGIS installed without getting duplicate symbol errors or " "bringing forward deprecated objects." msgstr "" +"El proceso de volcado/recarga cuenta con la ayuda del script " +"postgis_restore, que se encarga de omitir del volcado todas las definiciones " +"que pertenecen a PostGIS (incluidas las antiguas), lo que le permite " +"restaurar sus esquemas y datos en una base de datos con PostGIS instalado " +"sin obtener errores de s?mbolos duplicados ni transferir objetos obsoletos." #. Tag: para #, no-c-format @@ -452,11 +557,14 @@ msgid "" "href=\"http://trac.osgeo.org/postgis/wiki/UsersWikiWinUpgrade\">Windows Hard " "upgrade." msgstr "" +"Las instrucciones complementarias para usuarios de Windows est?n disponibles " +"en Windows Hard upgrade." #. Tag: para #, no-c-format msgid "The Procedure is as follows:" -msgstr "" +msgstr "El procedimiento es el siguiente:" #. Tag: para #, no-c-format @@ -466,6 +574,10 @@ msgid "" "output. The user can be the owner of the db, need not be postgres super " "account." msgstr "" +"Cree un volcado con ?formato personalizado? de la base de datos que desea " +"actualizar (llam?mosla olddb) e incluya blobs binarios " +"(-b) y salida detallada (-v). El usuario puede ser el propietario de la base " +"de datos, no es necesario que sea la cuenta superusuario de Postgres." #. Tag: para #, no-c-format @@ -475,6 +587,10 @@ msgid "" "linkend=\"create_new_db\"/> and " "for instructions on how to do this." msgstr "" +"Realice una nueva instalaci?n de PostGIS en una nueva base de datos; nos " +"referiremos a esta base de datos como newdb. Consulte " +" y para obtener instrucciones sobre c?mo hacerlo." #. Tag: para #, no-c-format @@ -485,6 +601,12 @@ msgid "" "If for any reason you really want your own overrides of standard entries " "just don't load the spatial_ref_sys.sql file when creating the new db." msgstr "" +"Las entradas spatial_ref_sys que se encuentren en su volcado se restaurar?n, " +"pero no sustituir?n a las existentes en spatial_ref_sys. Esto es para " +"garantizar que las correcciones del conjunto oficial se propaguen " +"correctamente a las bases de datos restauradas. Si por cualquier motivo " +"desea realmente sustituir las entradas est?ndar, simplemente no cargue el " +"archivo spatial_ref_sys.sql al crear la nueva base de datos." #. Tag: para #, no-c-format @@ -497,6 +619,13 @@ msgid "" "functions can be later removed by loading uninstall_legacy.sql." msgstr "" +"Si su base de datos es muy antigua o sabe que ha estado utilizando funciones " +"obsoletas en sus vistas y funciones, es posible que tenga que cargar " +"legacy.sql para que todas sus funciones y vistas, etc., " +"vuelvan a funcionar correctamente. Haga esto solo si es realmente necesario. " +"Si es posible, considere actualizar sus vistas y funciones antes de realizar " +"el volcado. Las funciones obsoletas se pueden eliminar posteriormente " +"cargando uninstall_legacy.sql." #. Tag: para #, no-c-format @@ -505,11 +634,15 @@ msgid "" "postgis_restore. Unexpected errors, if any, will be printed to the standard " "error stream by psql. Keep a log of those." msgstr "" +"Restaure su copia de seguridad en su nueva base de datos newdb utilizando postgis_restore. Si se produce alg?n error inesperado, " +"psql lo imprimir? en el flujo de errores est?ndar. Mantenga un registro de " +"dichos errores." #. Tag: para #, no-c-format msgid "Errors may arise in the following cases:" -msgstr "" +msgstr "Pueden surgir errores en los siguientes casos:" #. Tag: para #, no-c-format @@ -522,6 +655,13 @@ msgid "" "to fix your code to stop using deprecated functions and drop them loading " "uninstall_legacy.sql." msgstr "" +"Algunas de sus vistas o funciones utilizan objetos PostGIS obsoletos. Para " +"solucionar esto, puede intentar cargar el script legacy.sql antes de restaurar o tendr? que restaurar a una versi?n de PostGIS " +"que a?n contenga esos objetos e intentar la migraci?n de nuevo despu?s de " +"portar su c?digo. Si la forma legacy.sql le funciona, " +"no olvide corregir su c?digo para dejar de utilizar funciones obsoletas y " +"eliminarlas cargando uninstall_legacy.sql." #. Tag: para #, no-c-format @@ -535,6 +675,16 @@ msgid "" "invariant to hold and possibly also its primary key ( when multiple invalid " "SRIDS get converted to the same reserved SRID value )." msgstr "" +"Algunos registros personalizados de spatial_ref_sys en el archivo de volcado " +"tienen un valor SRID no v?lido. Los valores SRID v?lidos son mayores que 0 y " +"menores que 999000. Los valores en el rango 999000.999999 est?n reservados " +"para uso interno, mientras que los valores >999999 no se pueden utilizar " +"en absoluto. Todos los registros personalizados con SRID no v?lidos se " +"conservar?n, y los valores > 999999 se mover?n al rango reservado, pero " +"la tabla spatial_ref_sys perder?a una restricci?n de verificaci?n que " +"garantiza que se mantenga esa invariante y, posiblemente, tambi?n su clave " +"principal (cuando varios SRID no v?lidos se convierten al mismo valor SRID " +"reservado)." #. Tag: para #, no-c-format @@ -544,6 +694,11 @@ msgid "" "new srid (see ), delete the invalid " "entry from spatial_ref_sys and re-construct the check(s) with:" msgstr "" +"Para solucionar esto, debe copiar su SRS personalizado a un SRID con un " +"valor v?lido (tal vez en el rango 910000..910999), convertir todas sus " +"tablas al nuevo srid (consulte ), " +"eliminar la entrada no v?lida de spatial_ref_sys y reconstruir las " +"verificaciones con:" #. Tag: para #, no-c-format @@ -553,6 +708,10 @@ msgid "" "IGN cartography, you will have probably SRIDs out of range and you " "will see, when importing your database, issues like this :" msgstr "" +"Si est? actualizando una base de datos antigua que contiene cartograf?a " +"francesa IGN , es probable que los SRID est?n fuera " +"de rango y que, al importar la base de datos, aparezcan problemas como este:" #. Tag: para #, no-c-format @@ -561,11 +720,14 @@ msgid "" "IGN from the sql which is resulting from postgis_restore. So, after having " "run :" msgstr "" +"En este caso, puede intentar seguir los siguientes pasos: primero, elimine " +"completamente el IGN del sql que resulta de postgis_restore. Por lo tanto, " +"despu?s de ejecutar:" #. Tag: para #, no-c-format msgid "run this command :" -msgstr "" +msgstr "corre este comando:" #. Tag: para #, no-c-format @@ -576,11 +738,16 @@ msgid "" "Put_IGN_SRS_into_Postgis.sql\"> this script After these operations, " "import your data :" msgstr "" +"Cree su nueva base de datos, active las extensiones Postgis necesarias e " +"inserte correctamente el sistema franc?s IGN con: este script Despu?s de estas " +"operaciones, importe sus datos:" #. Tag: title #, no-c-format msgid "Performance Tuning" -msgstr "" +msgstr "Optimizaci?n del rendimiento" #. Tag: para #, no-c-format @@ -590,6 +757,11 @@ msgid "" "are usually large, so memory-related optimizations generally have more of an " "impact on PostGIS than other types of PostgreSQL queries." msgstr "" +"El ajuste del rendimiento de PostGIS es muy similar al ajuste de cualquier " +"carga de trabajo de PostgreSQL. La ?nica consideraci?n adicional es que las " +"geometr?as y las r?ster suelen ser grandes, por lo que las optimizaciones " +"relacionadas con la memoria suelen tener un mayor impacto en PostGIS que en " +"otros tipos de consultas de PostgreSQL." #. Tag: para #, no-c-format @@ -598,6 +770,9 @@ msgid "" "href=\"https://wiki.postgresql.org/wiki/" "Tuning_Your_PostgreSQL_Server\">Tuning your PostgreSQL Server." msgstr "" +"Para obtener informaci?n general sobre c?mo optimizar PostgreSQL, consulte " +"Ajustar su servidor PostgreSQL." #. Tag: para #, no-c-format @@ -606,6 +781,9 @@ msgid "" "touching postgresql.conf or postgresql.auto.conf " "by using the ALTER SYSTEM command." msgstr "" +"Para PostgreSQL 9.4+, la configuraci?n se puede establecer a nivel del " +"servidor sin tocar postgresql.conf o postgresql.auto." +"conf utilizando el comando ALTER SYSTEM." #. Tag: para #, no-c-format @@ -613,16 +791,19 @@ msgid "" "In addition to the Postgres settings, PostGIS has some custom settings which " "are listed in ." msgstr "" +"Adem?s de la configuraci?n de Postgres, PostGIS tiene algunas " +"configuraciones personalizadas que se enumeran en ." #. Tag: title #, no-c-format msgid "Startup" -msgstr "" +msgstr "Inicio" #. Tag: para #, no-c-format msgid "These settings are configured in postgresql.conf:" -msgstr "" +msgstr "Estos ajustes se configuran en postgresql.conf:" #. Tag: link #, fuzzy, no-c-format @@ -632,7 +813,7 @@ msgstr "constraint_exclusion" #. Tag: para #, no-c-format msgid "Default: partition" -msgstr "" +msgstr "Predeterminado: partici?n" #. Tag: para #, no-c-format @@ -642,16 +823,21 @@ msgid "" "force the planner to only analyze tables for constraint consideration if " "they are in an inherited hierarchy and not pay the planner penalty otherwise." msgstr "" +"Esto se utiliza generalmente para la partici?n de tablas. El valor " +"predeterminado es ?partici?n?, lo cual es ideal para PostgreSQL 8.4 y " +"versiones posteriores, ya que obliga al planificador a analizar las tablas " +"solo para considerar las restricciones si se encuentran en una jerarqu?a " +"heredada y, en caso contrario, no paga la penalizaci?n del planificador." #. Tag: link #, no-c-format msgid "shared_buffers" -msgstr "" +msgstr "buffers_compartidos" #. Tag: para #, no-c-format msgid "Default: ~128MB in PostgreSQL 9.6" -msgstr "" +msgstr "Predeterminado: ~128 MB en PostgreSQL 9.6" #. Tag: para #, no-c-format @@ -659,6 +845,8 @@ msgid "" "Set to about 25% to 40% of available RAM. On windows you may not be able to " "set as high." msgstr "" +"Config?re entre el 25 % y el 40 % de la RAM disponible. En Windows es " +"posible que no pueda configurar un valor tan alto." #. Tag: para #, no-c-format @@ -669,6 +857,12 @@ msgid "" "setting has additional importance in that it controls the max number of " "processes you can have for parallel queries." msgstr "" +"max_worker_processes " +"Esta configuraci?n solo est? disponible para PostgreSQL 9.4+. Para " +"PostgreSQL 9.6+, esta configuraci?n tiene una importancia adicional, ya que " +"controla el n?mero m?ximo de procesos que se pueden tener para consultas " +"paralelas." #. Tag: para #, no-c-format @@ -681,6 +875,8 @@ msgid "" "Sets the maximum number of background processes that the system can support. " "This parameter can only be set at server start." msgstr "" +"Establece el n?mero m?ximo de procesos en segundo plano que el sistema puede " +"admitir. Este par?metro solo se puede configurar al iniciar el servidor." #. Tag: title #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/es/postgis-manual.po | 240 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 218 insertions(+), 22 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Sun Oct 26 08:21:28 2025 From: git at osgeo.org (git at osgeo.org) Date: Sun, 26 Oct 2025 08:21:28 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-160-g2de4990a6 Message-ID: <20251026152129.3B8A3190427@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 2de4990a6879b6a935c7617bd57a1d98c4ec4110 (commit) from fec3149657a8433d67df12708c5d3fc3bc584424 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2de4990a6879b6a935c7617bd57a1d98c4ec4110 Author: Darafei Praliaskouski Date: Sun Oct 26 19:21:02 2025 +0400 Wrap hash in ifdef for PG<=13 diff --git a/postgis/lwgeom_out_geojson.c b/postgis/lwgeom_out_geojson.c index 1454343e8..288b0c89c 100644 --- a/postgis/lwgeom_out_geojson.c +++ b/postgis/lwgeom_out_geojson.c @@ -173,7 +173,11 @@ composite_to_geojson(FunctionCallInfo fcinfo, * surfacing the issue here prevents silent information loss. */ prop_keys = +#if POSTGIS_PGSQL_VERSION <= 130 + hash_create("GeoJSON property keys", Max(tupdesc->natts, 8), &ctl, HASH_ELEM | HASH_CONTEXT); +#else hash_create("GeoJSON property keys", Max(tupdesc->natts, 8), &ctl, HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); +#endif /* Build a temporary HeapTuple control structure */ tmptup.t_len = HeapTupleHeaderGetDatumLength(td); ----------------------------------------------------------------------- Summary of changes: postgis/lwgeom_out_geojson.c | 4 ++++ 1 file changed, 4 insertions(+) hooks/post-receive -- PostGIS From trac at osgeo.org Tue Oct 28 14:29:27 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 28 Oct 2025 21:29:27 -0000 Subject: [PostGIS] #6010: ST_Polygon(rast) returns the box of the tile instead of multipolygons of only valued pixels. Message-ID: <053.e75a882ed0a76b9cbe60661a303659f4@osgeo.org> #6010: ST_Polygon(rast) returns the box of the tile instead of multipolygons of only valued pixels. -------------------------------------------------+------------------------- Reporter: GISuser5432 | Owner: robe Type: defect | Status: new Priority: medium | Milestone: PostGIS | 3.6.1 Component: raster | Version: 3.6.x Keywords: ST_Polygon (raster) ; Raster; | PostGIS_Raster; | -------------------------------------------------+------------------------- I have tested PostGIS 3.5.2 and 3.6 and in both of them ST_Polygon(rast) returns the box of the tile (something like ST_Envelope). It is supposed to ignore NoData pixels but they are well included in the resulting rectangular polygon! If we use this query and open the result in QGIS we will see the tile extent (NoData pixels exist in this box!): This is the simple query: {{{#!div style="font-size: 80%" Code highlighting: {{{#!sql SELECT ST_Polygon( ST_SetBandNoDataValue(rast, 1.7976931348623157e+308) ) FROM stpolygon_error }}} }}} I added explicit NoData value declaration to make sure that the error is not because of this. I used a docker image of postgis with these details: {{{ POSTGIS="3.6.0 4c1967d" [EXTENSION] PGSQL="180" GEOS="3.13.1-CAPI-1.19.2" PROJ="9.6.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/var/lib/postgresql/.local/share/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 9.6.0) GDAL="GDAL 3.10.3, released 2025/04/01" LIBXML="2.9.14" LIBJSON="0.18" LIBPROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)" RASTER }}} The red polygon is the result of ST_Polygon(rast) and 70% of the image at right side is filled with NoData values. [[Image(polygonError.JPG)]] A Table called stpolygon_error with a single row of raster is dumped and attached for test. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 28 14:30:09 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 28 Oct 2025 21:30:09 -0000 Subject: [PostGIS] #6010: ST_Polygon(rast) returns the box of the tile instead of multipolygons of only valued pixels. In-Reply-To: <053.e75a882ed0a76b9cbe60661a303659f4@osgeo.org> References: <053.e75a882ed0a76b9cbe60661a303659f4@osgeo.org> Message-ID: <068.96ccb6a840c72d70ad2c782a53af19f4@osgeo.org> #6010: ST_Polygon(rast) returns the box of the tile instead of multipolygons of only valued pixels. -------------------------+------------------------------------------------- Reporter: | Owner: robe GISuser5432 | Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: raster | Version: 3.6.x Resolution: | Keywords: ST_Polygon (raster) ; Raster; | PostGIS_Raster; -------------------------+------------------------------------------------- Changes (by GISuser5432): * Attachment "ST_Polygon_Error.sql" added. The dump of the table with a single row to test. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Tue Oct 28 14:30:47 2025 From: trac at osgeo.org (PostGIS) Date: Tue, 28 Oct 2025 21:30:47 -0000 Subject: [PostGIS] #6010: ST_Polygon(rast) returns the box of the tile instead of multipolygons of only valued pixels. In-Reply-To: <053.e75a882ed0a76b9cbe60661a303659f4@osgeo.org> References: <053.e75a882ed0a76b9cbe60661a303659f4@osgeo.org> Message-ID: <068.e6d021951b93bebd1d8d5e4c24d62efb@osgeo.org> #6010: ST_Polygon(rast) returns the box of the tile instead of multipolygons of only valued pixels. -------------------------+------------------------------------------------- Reporter: | Owner: robe GISuser5432 | Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: raster | Version: 3.6.x Resolution: | Keywords: ST_Polygon (raster) ; Raster; | PostGIS_Raster; -------------------------+------------------------------------------------- Changes (by GISuser5432): * Attachment "polygonError.JPG" added. image of the result of the ST_Polygon(rast) -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 29 07:20:40 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 29 Oct 2025 07:20:40 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-161-ga14926dae Message-ID: <20251029142040.879DA162FD6@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via a14926dae52db384d86dd3ff84ee9317f05837f9 (commit) from 2de4990a6879b6a935c7617bd57a1d98c4ec4110 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a14926dae52db384d86dd3ff84ee9317f05837f9 Author: Sandro Santilli Date: Wed Oct 29 15:20:22 2025 +0100 Fix typos, ignore intentional ones diff --git a/.codespell.ignore b/.codespell.ignore index de287e7b3..e75d0d639 100644 --- a/.codespell.ignore +++ b/.codespell.ignore @@ -35,3 +35,5 @@ techer unknwn nin msdos +Koordinates +Pease diff --git a/NEWS b/NEWS index 6fc642459..4cde8f448 100644 --- a/NEWS +++ b/NEWS @@ -1571,8 +1571,8 @@ PostGIS 2.1.0 - #2302, ST_Roughness for raster (Nathaniel Clay) - #2290, ST_ColorMap(raster) to generate RGBA bands - #2254, Add SFCGAL backend support. - (Backend selection throught postgis.backend var) - Functions available both throught GEOS or SFCGAL: + (Backend selection through postgis.backend var) + Functions available both through GEOS or SFCGAL: ST_Intersects, ST_3DIntersects, ST_Intersection, ST_Area, ST_Distance, ST_3DDistance New functions available only with SFCGAL backend: @@ -2347,7 +2347,7 @@ PostGIS 1.3.1 PostGIS 1.3.0 2007/08/09 - - Began migration of functions to the SQL-MM-centric naming convension + - Began migration of functions to the SQL-MM-centric naming convention using the spatial type (SP) prefix - Performance enhancements: - Created cached and indexed point-in-polygon short-circuits ----------------------------------------------------------------------- Summary of changes: .codespell.ignore | 2 ++ NEWS | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 29 08:10:38 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 15:10:38 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.7693b176ec8bce8030d072d18ee41959@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by strk): Replying to [comment:18 francoisb]: > > The upgrade path from 3.6.0 is indeed challenging, because one needs to distinguish: > - Topogeometry columns that need fixing, because created before the 3.6.0 upgrade, not somehow manually fixed already, and still have bad values. > - Topogeometry columns that do NOT need fixing, because created after the 3.6.0 upgrade (and have correct values to begin with), or the user somehow managed to fix the bad values already. I think it's even worse as the SAME TABLE could contain records that need fixing and records that do not... Although I suspect it would be very unlikely that someone added more records to a corrupted topology table. > > Or we could use some fuzzy logic to check if any data value would be invalid, and bet on that being caused by the corruption. > > Exactly. A possible heuristic to answer this: All topogeometry columns have a built-in `CHECK` constraint to enforce a correct `type` subfield (from 1 to 4, depending on layer geometry type). Bad topogeometry values have garbage for this `type` (depending on memory contents, usually 0 at the beginning of a session), which is therefore violating the constraint. An actual value other than the one of the 4 valid ones defined in the `CHECK` constraint, and this in any row of a table, could be a criteria to trigger data recovery path for the entire table. There is also a built-in "xmin" field in each record that tells you the identifier of the transaction which introduced that record. That value could be compared with the "xmin" value of the record identifying the PostGIS version (for example the "postgis_version" record in pg_proc). Using too much fuzzy heuristics could be very dangerous so we should maybe provide the fix as a separate script to optionally run ? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 08:17:36 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 15:17:36 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.4441f327e80f6aca3895536476bb0b26@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by strk): Replying to [comment:19 francoisb]: > FWIW, in my database (PostgreSQL 16.10, macOS), I was able to recover the topogeometry columns with these two steps: > > 1) Upgrade the topology to use the bigint feature: > > {{{ > SELECT UpgradeTopology('topo_1'); > }}} Wow, I did't even notice the existance of this function, I don't like the name of it :( For those like me who missed it, its documentation is here: https://postgis.net/docs//en/UpgradeTopology.html I dunno why we call it an "upgrade" to get a bigger size :/ > Note I'm not 100% sure this step is actually needed, but I add it here because I did it. We could test without, and perhaps remove it. > > 2) Recover `id` and `type` values from the bytes of corrupted `id`, with a query like: > > {{{ > UPDATE table_1 > SET > topogeom = ( > (topogeom).topology_id, > (topogeom).layer_id, > (topogeom).id & 0xFFFFFFFF, -- 32 least significant bits from corrupted "id" > (topogeom).id >> 32 -- 32 most significant bits from corrupted "id" > )::topogeometry > WHERE topogeom IS NOT NULL > RETURNING topogeom; > }}} Nice one, it might be time to start a PR with this code made available as a repair function so to provide improvements as we see them (like maybe check the xmin against the postgis xmin...). Would you be up for such task ? Then I'll be happy to test it against my existing corrupted tables as right now I cannot even `pg_upgrade` a cluster due to this bug, apparently. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 08:54:13 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 15:54:13 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) Message-ID: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) ----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Keywords: | ----------------------------+--------------------------- As reported in https://github.com/MobilityDB/MobilityDB/issues/721#issuecomment-3420138807 , the following query crashes PostGIS: {{{ select st_intersects(geometry 'POINT(61.39676026068628 39.18938813731074)', geometry 'MULTIPOINT(EMPTY,(38.18379705771804 1.379111967980862),(48.032580409199 96.20595159940422),(94.26673082634807 32.44167249649763),(7.300334237515926 61.43170236609876),(13.169536320492625 14.411543076857924),(9.375487919896841 58.5021048784256),(23.129081027582288 16.69569476507604),(94.89733050577343 60.82506775856018),(28.634277591481805 44.86722475849092),(50.71957716718316 94.28150206804276))'); Server beendete die Verbindung unerwartet }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 08:59:32 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 15:59:32 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.21e16498fdece0f57fe146c0f54e252c@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------------+--------------------------- Comment (by strk): Did you check if the segfault comes from GEOS itself ? You could use "geosop" to try it: {{{ geosop \ -a 'POINT(61.39676026068628 39.18938813731074)' \ -b 'MULTIPOINT(EMPTY,(38.18379705771804 1.379111967980862),(48.032580409199 96.20595159940422),(94.26673082634807 32.44167249649763),(7.300334237515926 61.43170236609876),(13.169536320492625 14.411543076857924),(9.375487919896841 58.5021048784256),(23.129081027582288 16.69569476507604),(94.89733050577343 60.82506775856018),(28.634277591481805 44.86722475849092),(50.71957716718316 94.28150206804276))' \ intersects }}} The geosop command gives me false as of version 3.14.1dev (geos-config --version, revision is not available unfortunately) -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 09:08:44 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 16:08:44 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.5680e88a803ff30e99c5a5802fce9aba@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------------+--------------------------- Comment (by Christoph Berg): Yes, that crashes as well: {{{ geosop -a 'POINT(61.39676026068628 39.18938813731074)' -b 'MULTIPOINT(EMPTY,(38.18379705771804 1.379111967980862),(48.032580409199 96.20595159940422),(94.26673082634807 32.44167249649763),(7.300334237515926 61.43170236609876),(13.169536320492625 14.411543076857924),(9.375487919896841 58.5021048784256),(23.129081027582288 16.69569476507604),(94.89733050577343 60.82506775856018),(28.634277591481805 44.86722475849092),(50.71957716718316 94.28150206804276))' intersects Segmentation fault (core dumped) }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 09:12:00 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 16:12:00 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.9bb176623ac7d44b0d527b7b4a5e4f02@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------------+--------------------------- Comment (by pramsey): What is your `postgis_full_version()`? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 09:18:08 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 16:18:08 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.dc1c3892cb72a95f1ad73b2f133756dc@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------------+--------------------------- Comment (by Christoph Berg): {{{POSTGIS="3.6.0 4c1967d" [EXTENSION] PGSQL="180" GEOS="3.10.2-CAPI-1.16.0" PROJ="8.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 8.2.1) LIBXML="2.9.13" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)"}}} No crash on Debian unstable here either. It's only affecting the mobilitydb tests on jammy, not on the newer dists. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 09:38:44 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 16:38:44 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.3a948955cd8e469b25c7867fa84527b1@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------------+--------------------------- Comment (by pramsey): Hey presto, on 3.10.2 I can crash that geosop example on MacOS. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 09:53:35 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 16:53:35 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.7ab88da46506d8e31a8e0eb53e2709a6@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: -----------------------------+--------------------------- Changes (by pramsey): * resolution: => invalid * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 10:01:31 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 17:01:31 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.80c84b62c71ed61dbb6fd8a431961b10@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: -----------------------------+--------------------------- Comment (by Christoph Berg): Sorry, apt.postgresql.org has so far not been in the business of shipping the whole GIS stack. We are using the system-provided libraries and just build postgis. We'll probably just stop building mobility (where this crash is happening in the testsuite) on Ubuntu jammy then. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 10:28:54 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 17:28:54 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.2959dae6bf8652d62e600b85cec518db@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: -----------------------------+--------------------------- Comment (by pramsey): I can understand not bumping major/minor versions, but is there any reason they don't build out the patch releases? GEOS 3.10.7 is out, and it has this fix too. Keeping up with patches on packages you have already shipped seems lowest common denominator. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 29 15:56:28 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 29 Oct 2025 15:56:28 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-162-gbe84ae80b Message-ID: <20251029225628.F37F516A57D@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via be84ae80b1539e6b05a28911d765d83058ba03fe (commit) from a14926dae52db384d86dd3ff84ee9317f05837f9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be84ae80b1539e6b05a28911d765d83058ba03fe Author: Darafei Praliaskouski Date: Thu Oct 30 02:55:59 2025 +0400 Prevent histogram target overflow when analysing massive tables Add CUnit tests for overflow scenarios Closes #5959 diff --git a/NEWS b/NEWS index 4cde8f448..29083c77d 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,10 @@ xxxx/xx/xx - #5702, Allow the compiler to detect the parallelism -flto=auto (Darafei Praliaskouski) - #4798, ST_AsGeoJSON warns about duplicate property keys (Darafei Praliaskouski) +* Bug Fixes * + + - #5959, Prevent histogram target overflow when analysing massive tables (Darafei Praliaskouski) + PostGIS 3.6.0 2025/09/01 diff --git a/configure.ac b/configure.ac index d89e82c55..efd360053 100644 --- a/configure.ac +++ b/configure.ac @@ -1938,6 +1938,7 @@ AC_CONFIG_FILES([GNUmakefile libpgcommon/Makefile libpgcommon/cunit/Makefile postgis/Makefile + postgis/cunit/Makefile postgis/sqldefines.h sfcgal/Makefile $SFCGAL_MAKEFILE_LIST diff --git a/postgis/cunit/Makefile.in b/postgis/cunit/Makefile.in new file mode 100644 index 000000000..483e4ca10 --- /dev/null +++ b/postgis/cunit/Makefile.in @@ -0,0 +1,43 @@ +# ********************************************************************** +# * +# * PostGIS - Spatial Types for PostgreSQL +# * http://postgis.net +# * +# * Copyright 2025 Darafei Praliaskouski +# * +# * This is free software; you can redistribute and/or modify it under +# * the terms of the GNU General Public Licence. See the COPYING file. +# * +# ********************************************************************** + +srcdir = @srcdir@ +top_builddir = @top_builddir@ + +CC=@CC@ +LIBTOOL=@LIBTOOL@ +CFLAGS = @CFLAGS@ @CPPFLAGS@ @PGSQL_BE_CPPFLAGS@ @CUNIT_CPPFLAGS@ -I.. -I$(top_builddir) -I at top_srcdir@/liblwgeom -I at top_builddir@/liblwgeom -I at top_srcdir@/libpgcommon -I at top_builddir@/libpgcommon +LDFLAGS = @CUNIT_LDFLAGS@ -lm + +VPATH = $(srcdir) + +OBJS = cu_tester.o + +# Build the standalone histogram helper tester. +all: cu_tester + +# Execute the suite directly; no installation step is required. +check: all + $(LIBTOOL) --mode=execute ./cu_tester + +# Link the tester with libtool; all helper code is header-only. +cu_tester: $(OBJS) + $(LIBTOOL) --mode=link $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(OBJS) cu_tester + +clobber distclean: clean + rm -f Makefile diff --git a/postgis/cunit/cu_tester.c b/postgis/cunit/cu_tester.c new file mode 100644 index 000000000..b4dd46aa7 --- /dev/null +++ b/postgis/cunit/cu_tester.c @@ -0,0 +1,154 @@ +/********************************************************************** + * + * PostGIS - Spatial Types for PostgreSQL + * http://postgis.net + * + * This file is part of PostGIS + * + * PostGIS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * PostGIS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PostGIS. If not, see . + * + ********************************************************************** + * + * Copyright 2025 (C) Darafei Praliaskouski + * + **********************************************************************/ + +#include "postgres.h" + +#include +#include +#include + +#include "../gserialized_estimate_support.h" + +static ND_BOX +make_box(float minx, float miny, float minz, float minm, float maxx, float maxy, float maxz, float maxm) +{ + ND_BOX box; + + memset(&box, 0, sizeof(box)); + box.min[0] = minx; + box.min[1] = miny; + box.min[2] = minz; + box.min[3] = minm; + box.max[0] = maxx; + box.max[1] = maxy; + box.max[2] = maxz; + box.max[3] = maxm; + return box; +} + +static void +histogram_budget_clamps(void) +{ + /* Zero or negative row counts disable histogram construction. */ + CU_ASSERT_EQUAL(histogram_cell_budget(0.0, 2, 100), 0); + CU_ASSERT_EQUAL(histogram_cell_budget(-1.0, 4, 100), 0); + + /* Degenerate dimensionality cannot allocate histogram space. */ + CU_ASSERT_EQUAL(histogram_cell_budget(1000.0, 0, 100), 0); + + /* Matches the classic pow(attstattarget, ndims) path. */ + CU_ASSERT_EQUAL(histogram_cell_budget(1e6, 2, 100), 10000); + CU_ASSERT_EQUAL(histogram_cell_budget(1e6, 3, 50), 125000); + + /* attstattarget^ndims exceeds ndims * 100000 and must be clamped. */ + CU_ASSERT_EQUAL(histogram_cell_budget(1e6, 4, 50), 400000); + + /* attstattarget<=0 is normalised to the smallest viable target. */ + CU_ASSERT_EQUAL(histogram_cell_budget(1e6, 2, 0), 1); + + /* Row clamp shrinks the grid for small relations. */ + CU_ASSERT_EQUAL(histogram_cell_budget(1.0, 2, 100), 20); + + /* Large tables now preserve the dimensional cap instead of overflowing. */ + CU_ASSERT_EQUAL(histogram_cell_budget(1.5e8, 2, 100), 10000); + + /* Regression for #5984: huge attstat targets stabilise instead of wrapping. */ + CU_ASSERT_EQUAL(histogram_cell_budget(5e6, 2, 10000), 200000); + + /* Trigger the INT_MAX guard once both other caps exceed it. */ + CU_ASSERT_EQUAL(histogram_cell_budget((double)INT_MAX, 50000, INT_MAX), INT_MAX); +} + +static void +nd_stats_indexing_behaviour(void) +{ + ND_STATS stats; + const int good_index[ND_DIMS] = {1, 2, 0, 0}; + const int bad_index[ND_DIMS] = {1, 5, 0, 0}; + + memset(&stats, 0, sizeof(stats)); + stats.ndims = 3; + stats.size[0] = 4.0f; + stats.size[1] = 5.0f; + stats.size[2] = 3.0f; + + /* Three-dimensional index (x=1, y=2, z=0) collapses into 1 + 2 * 4. */ + CU_ASSERT_EQUAL(nd_stats_value_index(&stats, good_index), 1 + 2 * 4); + /* Any request outside the histogram bounds triggers a guard. */ + CU_ASSERT_EQUAL(nd_stats_value_index(&stats, bad_index), -1); + + /* Regression for #5959: ndims higher than populated sizes still honours guards. */ + stats.ndims = 4; + CU_ASSERT_EQUAL(nd_stats_value_index(&stats, good_index), -1); +} + +static void +nd_box_ratio_cases(void) +{ + ND_BOX covering = make_box(0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 2.0f, 2.0f, 0.0f); + ND_BOX interior = make_box(0.5f, 0.5f, 0.5f, 0.0f, 1.5f, 1.5f, 1.5f, 0.0f); + ND_BOX partial = make_box(0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f); + ND_BOX target = make_box(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f); + ND_BOX flat = make_box(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f); + ND_BOX touch = make_box(2.0f, 0.0f, 0.0f, 0.0f, 3.0f, 1.0f, 1.0f, 0.0f); + + /* Full coverage should evaluate to one regardless of the extra extent. */ + CU_ASSERT_DOUBLE_EQUAL(nd_box_ratio(&covering, &interior, 3), 1.0, 1e-12); + /* A shared octant carries one eighth of the reference volume. */ + CU_ASSERT_DOUBLE_EQUAL(nd_box_ratio(&partial, &target, 3), 0.125, 1e-12); + /* Degenerate slabs have zero volume in three dimensions. */ + CU_ASSERT_DOUBLE_EQUAL(nd_box_ratio(&covering, &flat, 3), 0.0, 1e-12); + /* Boxes that only touch along a face should not count as overlap. */ + CU_ASSERT_DOUBLE_EQUAL(nd_box_ratio(&covering, &touch, 3), 0.0, 1e-12); +} + +int +main(void) +{ + CU_pSuite suite; + unsigned int failures = 0; + if (CU_initialize_registry() != CUE_SUCCESS) + return CU_get_error(); + + suite = CU_add_suite("gserialized_histogram_helpers", NULL, NULL); + if (!suite) + goto cleanup; + + if (!CU_add_test(suite, "histogram budget clamps", histogram_budget_clamps) || + !CU_add_test(suite, "nd_stats value index guards", nd_stats_indexing_behaviour) || + !CU_add_test(suite, "nd_box ratio edge cases", nd_box_ratio_cases)) + { + goto cleanup; + } + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + +cleanup: + failures = CU_get_number_of_tests_failed(); + CU_cleanup_registry(); + return failures == 0 ? CUE_SUCCESS : 1; +} diff --git a/postgis/gserialized_estimate.c b/postgis/gserialized_estimate.c index bcbbcf676..5c4b4387b 100644 --- a/postgis/gserialized_estimate.c +++ b/postgis/gserialized_estimate.c @@ -19,11 +19,10 @@ ********************************************************************** * * Copyright 2012 (C) Paul Ramsey + * Copyright 2025 (C) Darafei Praliaskouski * **********************************************************************/ - - /********************************************************************** THEORY OF OPERATION @@ -112,10 +111,12 @@ dimensionality cases. (2D geometry) &&& (3D column), etc. #include "stringbuffer.h" #include "liblwgeom.h" #include "lwgeodetic.h" -#include "lwgeom_pg.h" /* For debugging macros. */ +#include "lwgeom_pg.h" /* For debugging macros. */ #include "gserialized_gist.h" /* For index common functions */ +#include "gserialized_estimate_support.h" #include +#include #if HAVE_IEEEFP_H #include #endif @@ -144,8 +145,7 @@ Datum _postgis_gserialized_stats(PG_FUNCTION_ARGS); /* Local prototypes */ static Oid table_get_spatial_index(Oid tbl_oid, int16 attnum, int *key_type, int16 *idx_attnum); -static GBOX * spatial_index_read_extent(Oid idx_oid, int idx_att_num, int key_type); - +static GBOX *spatial_index_read_extent(Oid idx_oid, int idx_att_num, int key_type); /* Other prototypes */ float8 gserialized_joinsel_internal(PlannerInfo *root, List *args, JoinType jointype, int mode); @@ -186,13 +186,6 @@ Datum geometry_estimated_extent(PG_FUNCTION_ARGS); */ #define SDFACTOR 3.25 -/** -* The maximum number of dimensions our code can handle. -* We'll use this to statically allocate a bunch of -* arrays below. -*/ -#define ND_DIMS 4 - /** * Minimum width of a dimension that we'll bother trying to * compute statistics on. Bearing in mind we have no control @@ -219,68 +212,6 @@ Datum geometry_estimated_extent(PG_FUNCTION_ARGS); #define FALLBACK_ND_SEL 0.2 #define FALLBACK_ND_JOINSEL 0.3 -/** -* N-dimensional box type for calculations, to avoid doing -* explicit axis conversions from GBOX in all calculations -* at every step. -*/ -typedef struct ND_BOX_T -{ - float4 min[ND_DIMS]; - float4 max[ND_DIMS]; -} ND_BOX; - -/** -* N-dimensional box index type -*/ -typedef struct ND_IBOX_T -{ - int min[ND_DIMS]; - int max[ND_DIMS]; -} ND_IBOX; - - -/** -* N-dimensional statistics structure. Well, actually -* four-dimensional, but set up to handle arbitrary dimensions -* if necessary (really, we just want to get the 2,3,4-d cases -* into one shared piece of code). -*/ -typedef struct ND_STATS_T -{ - /* Dimensionality of the histogram. */ - float4 ndims; - - /* Size of n-d histogram in each dimension. */ - float4 size[ND_DIMS]; - - /* Lower-left (min) and upper-right (max) spatial bounds of histogram. */ - ND_BOX extent; - - /* How many rows in the table itself? */ - float4 table_features; - - /* How many rows were in the sample that built this histogram? */ - float4 sample_features; - - /* How many not-Null/Empty features were in the sample? */ - float4 not_null_features; - - /* How many features actually got sampled in the histogram? */ - float4 histogram_features; - - /* How many cells in histogram? (sizex*sizey*sizez*sizem) */ - float4 histogram_cells; - - /* How many cells did those histogram features cover? */ - /* Since we are pro-rating coverage, this number should */ - /* now always equal histogram_features */ - float4 cells_covered; - - /* Variable length # of floats for histogram */ - float4 value[1]; -} ND_STATS; - typedef struct { /* Saved state from std_typanalyze() */ AnalyzeAttrComputeStatsFunc std_compute_stats; @@ -318,13 +249,12 @@ text_p_get_mode(const text *txt) char *modestr; if (VARSIZE_ANY_EXHDR(txt) <= 0) return mode; - modestr = (char*)VARDATA(txt); - if ( modestr[0] == 'N' ) + modestr = (char *)VARDATA(txt); + if (modestr[0] == 'N') mode = 0; return mode; } - /** * Integer comparison function for qsort */ @@ -372,7 +302,7 @@ total_double(const double *vals, int nvals) int i; float total = 0; /* Calculate total */ - for ( i = 0; i < nvals; i++ ) + for (i = 0; i < nvals; i++) total += vals[i]; return total; @@ -425,33 +355,6 @@ stddev(const int *vals, int nvals) } #endif /* POSTGIS_DEBUG_LEVEL >= 3 */ -/** -* Given a position in the n-d histogram (i,j,k) return the -* position in the 1-d values array. -*/ -static int -nd_stats_value_index(const ND_STATS *stats, int *indexes) -{ - int d; - int accum = 1, vdx = 0; - - /* Calculate the index into the 1-d values array that the (i,j,k,l) */ - /* n-d histogram coordinate implies. */ - /* index = x + y * sizex + z * sizex * sizey + m * sizex * sizey * sizez */ - for ( d = 0; d < (int)(stats->ndims); d++ ) - { - int size = (int)(stats->size[d]); - if ( indexes[d] < 0 || indexes[d] >= size ) - { - POSTGIS_DEBUGF(3, " bad index at (%d, %d)", indexes[0], indexes[1]); - return -1; - } - vdx += indexes[d] * accum; - accum *= size; - } - return vdx; -} - /** * Convert an #ND_BOX to a JSON string for printing */ @@ -722,50 +625,6 @@ nd_box_overlap(const ND_STATS *nd_stats, const ND_BOX *nd_box, ND_IBOX *nd_ibox) return true; } -/** -* Returns the proportion of b2 that is covered by b1. -*/ -static inline double -nd_box_ratio(const ND_BOX *b1, const ND_BOX *b2, int ndims) -{ - int d; - bool covered = true; - double ivol = 1.0; - double vol2 = 1.0; - - for ( d = 0 ; d < ndims; d++ ) - { - if ( b1->max[d] <= b2->min[d] || b1->min[d] >= b2->max[d] ) - return 0.0; /* Disjoint */ - - if ( b1->min[d] > b2->min[d] || b1->max[d] < b2->max[d] ) - covered = false; - } - - if ( covered ) - return 1.0; - - for ( d = 0; d < ndims; d++ ) - { - double width2 = b2->max[d] - b2->min[d]; - double imin, imax, iwidth; - - vol2 *= width2; - - imin = Max(b1->min[d], b2->min[d]); - imax = Min(b1->max[d], b2->max[d]); - iwidth = imax - imin; - iwidth = Max(0.0, iwidth); - - ivol *= iwidth; - } - - if ( vol2 == 0.0 ) - return vol2; - - return ivol / vol2; -} - /* How many bins shall we use in figuring out the distribution? */ #define MAX_NUM_BINS 50 #define BIN_MIN_SIZE 10 @@ -894,9 +753,9 @@ nd_increment(ND_IBOX *ibox, int ndims, int *counter) { int d = 0; - while ( d < ndims ) + while (d < ndims) { - if ( counter[d] < ibox->max[d] ) + if (counter[d] < ibox->max[d]) { counter[d] += 1; break; @@ -905,7 +764,7 @@ nd_increment(ND_IBOX *ibox, int ndims, int *counter) d++; } /* That's it, cannot increment any more! */ - if ( d == ndims ) + if (d == ndims) return false; /* Increment complete! */ @@ -1321,9 +1180,9 @@ gserialized_joinsel_internal(PlannerInfo *root, List *args, JoinType jointype, i PG_FUNCTION_INFO_V1(gserialized_gist_joinsel); Datum gserialized_gist_joinsel(PG_FUNCTION_ARGS) { - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); + PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); /* Oid operator = PG_GETARG_OID(1); */ - List *args = (List *) PG_GETARG_POINTER(2); + List *args = (List *)PG_GETARG_POINTER(2); JoinType jointype = (JoinType) PG_GETARG_INT16(3); int mode = PG_GETARG_INT32(4); @@ -1512,22 +1371,13 @@ compute_gserialized_stats_mode(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfu #endif } - /* - * We'll build a histogram having stats->attr->attstattarget - * (default 100) cells on each side, within reason... - * we'll use ndims*100000 as the maximum number of cells. - * Also, if we're sampling a relatively small table, we'll try to ensure that - * we have a smaller grid. - */ #if POSTGIS_PGSQL_VERSION >= 170 - histo_cells_target = (int)pow((double)(stats->attstattarget), (double)ndims); POSTGIS_DEBUGF(3, " stats->attstattarget: %d", stats->attstattarget); + histo_cells_target = histogram_cell_budget(total_rows, ndims, stats->attstattarget); #else - histo_cells_target = (int)pow((double)(stats->attr->attstattarget), (double)ndims); POSTGIS_DEBUGF(3, " stats->attr->attstattarget: %d", stats->attr->attstattarget); + histo_cells_target = histogram_cell_budget(total_rows, ndims, stats->attr->attstattarget); #endif - histo_cells_target = Min(histo_cells_target, ndims * 100000); - histo_cells_target = Min(histo_cells_target, (int)(10 * ndims * total_rows)); POSTGIS_DEBUGF(3, " target # of histogram cells: %d", histo_cells_target); /* If there's no useful features, we can't work out stats */ @@ -1836,8 +1686,6 @@ compute_gserialized_stats_mode(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfu return; } - - /** * In order to do useful selectivity calculations in both 2-D and N-D * modes, we actually have to generate two stats objects, one for 2-D @@ -1875,7 +1723,6 @@ compute_gserialized_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, } } - /** * This function will be called when the ANALYZE command is run * on a column of the "geometry" or "geography" type. diff --git a/postgis/gserialized_estimate_support.h b/postgis/gserialized_estimate_support.h new file mode 100644 index 000000000..0d3a23d75 --- /dev/null +++ b/postgis/gserialized_estimate_support.h @@ -0,0 +1,197 @@ +/********************************************************************** + * + * PostGIS - Spatial Types for PostgreSQL + * http://postgis.net + * + * This file is part of PostGIS + * + * PostGIS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * PostGIS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PostGIS. If not, see . + * + ********************************************************************** + * + * Internal helpers shared between the gserialized selectivity + * implementation and the unit tests. + * + * Keeping the routines header-only ensures the planner code and the + * harness evaluate the exact same floating-point flows without the + * cross-object plumbing that previously complicated maintenance. + * Nothing here is installed; the header is meant for + * gserialized_estimate.c and for the dedicated CUnit suite only. + * + ********************************************************************** + * + * Copyright 2012 (C) Paul Ramsey + * Copyright 2025 (C) Darafei Praliaskouski + * + **********************************************************************/ + +#ifndef POSTGIS_GSERIALIZED_ESTIMATE_SUPPORT_H +#define POSTGIS_GSERIALIZED_ESTIMATE_SUPPORT_H + +#include "postgres.h" + +#include +#include + +/* The maximum number of dimensions our statistics code supports. */ +#define ND_DIMS 4 + +/* Lightweight n-dimensional box representation for selectivity math. */ +typedef struct ND_BOX_T { + float4 min[ND_DIMS]; + float4 max[ND_DIMS]; +} ND_BOX; + +/* Integer counterpart used for histogram cell iteration. */ +typedef struct ND_IBOX_T { + int min[ND_DIMS]; + int max[ND_DIMS]; +} ND_IBOX; + +/* On-disk representation of the histogram emitted by ANALYZE. */ +typedef struct ND_STATS_T { + float4 ndims; + float4 size[ND_DIMS]; + ND_BOX extent; + float4 table_features; + float4 sample_features; + float4 not_null_features; + float4 histogram_features; + float4 histogram_cells; + float4 cells_covered; + float4 value[1]; +} ND_STATS; + +/* + * Return the flattened index for the histogram coordinate expressed by + * 'indexes'. A negative result signals that one of the axes fell outside + * the histogram definition. + */ +static inline int +nd_stats_value_index(const ND_STATS *stats, const int *indexes) +{ + int d; + int accum = 1; + int vdx = 0; + + for (d = 0; d < (int)(stats->ndims); d++) + { + int size = (int)(stats->size[d]); + if (indexes[d] < 0 || indexes[d] >= size) + return -1; + vdx += indexes[d] * accum; + accum *= size; + } + return vdx; +} + +/* + * Derive the histogram grid budget requested by PostgreSQL's ANALYZE machinery. + * The planner caps the cell count via three heuristics that take the requested + * attstattarget, the histogram dimensionality, and the underlying row count + * into account. Double precision arithmetic keeps the intermediate products in + * range so the cap behaves consistently across build architectures. + */ +static inline int +histogram_cell_budget(double total_rows, int ndims, int attstattarget) +{ + double budget; + double dims_cap; + double rows_cap; + double attstat; + double dims; + + if (ndims <= 0) + return 0; + + if (attstattarget <= 0) + attstattarget = 1; + + /* Requested resolution coming from PostgreSQL's ANALYZE knob. */ + attstat = (double)attstattarget; + dims = (double)ndims; + budget = pow(attstat, dims); + + /* Hard ceiling that keeps the statistics collector responsive. */ + dims_cap = (double)ndims * 100000.0; + if (budget > dims_cap) + budget = dims_cap; + + /* Small relations do not need a histogram that dwarfs the sample. */ + if (total_rows <= 0.0) + return 0; + + rows_cap = 10.0 * (double)ndims * total_rows; + if (rows_cap < 0.0) + rows_cap = 0.0; + + /* Keep intermediate computations in double precision before clamping. */ + if (rows_cap > (double)INT_MAX) + rows_cap = (double)INT_MAX; + + if (budget > rows_cap) + budget = rows_cap; + + if (budget >= (double)INT_MAX) + return INT_MAX; + if (budget <= 0.0) + return 0; + + return (int)budget; +} + +/* + * Compute the portion of 'target' covered by 'cover'. The caller supplies the + * dimensionality because ND_BOX always carries four slots. Degenerate volumes + * fold to zero, allowing the callers to detect slabs that ANALYZE sometimes + * emits for skewed datasets. + */ +static inline double +nd_box_ratio(const ND_BOX *cover, const ND_BOX *target, int ndims) +{ + int d; + bool fully_covered = true; + double ivol = 1.0; + double refvol = 1.0; + + for (d = 0; d < ndims; d++) + { + if (cover->max[d] <= target->min[d] || cover->min[d] >= target->max[d]) + return 0.0; /* Disjoint */ + + if (cover->min[d] > target->min[d] || cover->max[d] < target->max[d]) + fully_covered = false; + } + + if (fully_covered) + return 1.0; + + for (d = 0; d < ndims; d++) + { + double width = target->max[d] - target->min[d]; + double imin = Max(cover->min[d], target->min[d]); + double imax = Min(cover->max[d], target->max[d]); + double iwidth = Max(0.0, imax - imin); + + refvol *= width; + ivol *= iwidth; + } + + if (refvol == 0.0) + return refvol; + + return ivol / refvol; +} + +#endif /* POSTGIS_GSERIALIZED_ESTIMATE_SUPPORT_H */ ----------------------------------------------------------------------- Summary of changes: NEWS | 4 + configure.ac | 1 + postgis/cunit/Makefile.in | 43 +++++++ postgis/cunit/cu_tester.c | 154 ++++++++++++++++++++++++++ postgis/gserialized_estimate.c | 183 +++--------------------------- postgis/gserialized_estimate_support.h | 197 +++++++++++++++++++++++++++++++++ 6 files changed, 414 insertions(+), 168 deletions(-) create mode 100644 postgis/cunit/Makefile.in create mode 100644 postgis/cunit/cu_tester.c create mode 100644 postgis/gserialized_estimate_support.h hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 29 15:56:37 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 22:56:37 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.db8de63efc08df201e5e6156c4fb825f@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"be84ae80b1539e6b05a28911d765d83058ba03fe/git" be84ae80/git]: {{{#!CommitTicketReference repository="git" revision="be84ae80b1539e6b05a28911d765d83058ba03fe" Prevent histogram target overflow when analysing massive tables Add CUnit tests for overflow scenarios Closes #5959 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 29 16:16:50 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 29 Oct 2025 16:16:50 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-163-g5faa572a7 Message-ID: <20251029231650.6BB2E16BA06@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 5faa572a734cce40195709a14db60301c1bf5a0c (commit) from be84ae80b1539e6b05a28911d765d83058ba03fe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5faa572a734cce40195709a14db60301c1bf5a0c Author: Darafei Praliaskouski Date: Thu Oct 30 03:16:32 2025 +0400 [doc] Document POSTGIS_REGRESS_DB_OWNER for sandboxed regression roles Closes #5950 diff --git a/NEWS b/NEWS index 29083c77d..5ba9497a8 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ xxxx/xx/xx - #5992, Optimize GiST index for repeated edge subdivision in topology (Darafei Praliaskouski) - #5702, Allow the compiler to detect the parallelism -flto=auto (Darafei Praliaskouski) - #4798, ST_AsGeoJSON warns about duplicate property keys (Darafei Praliaskouski) + - #5950, Document POSTGIS_REGRESS_DB_OWNER for sandboxed regression roles (Darafei Praliaskouski) * Bug Fixes * diff --git a/doc/developer.md b/doc/developer.md index 95da8837f..550f90490 100644 --- a/doc/developer.md +++ b/doc/developer.md @@ -275,6 +275,27 @@ with lib xxx or higher. Also the function has to be available in the C lib, as s on the C lib side and very rarely on the sql files. +Regression harness privileges +============================= + +Continuous integration workers are frequently configured with sandboxed PostgreSQL roles +that cannot create databases or install extensions. The regression harness accepts two +environment variables to test the complete installation flow without granting superuser +rights to the calling account: + +* `POSTGIS_REGRESS_DB_OWNER` ? instructs `regress/run_test.pl` to hand ownership of the + temporary regression database to a privileged role while the less privileged caller + maintains the session. This mirrors production setups where database creation is + delegated to controlled roles. +* `POSTGIS_REGRESS_ROLE_EXT_CREATOR` ? optional override when the extension creation role + is distinct from the database owner. + +When both roles are configured in PostgreSQL to create the PostGIS extensions, the test +suite exercises the same upgrade and `CREATE EXTENSION` pathways as a superuser-driven +run. This avoids the traps described in +while keeping the CI account unprivileged. + + diff --git a/doc/installation.xml b/doc/installation.xml index e7ff09792..de6ec932c 100644 --- a/doc/installation.xml +++ b/doc/installation.xml @@ -758,23 +758,41 @@ CREATE EXTENSION postgis_tiger_geocoder FROM unpackaged; - - - Currently, the make check relies on the - PATH and PGPORT environment variables when - performing the checks - it does not use the - PostgreSQL version that may have been specified using the - configuration parameter --with-pgconfig. So make - sure to modify your PATH to match the detected PostgreSQL installation - during configuration or be prepared to deal with the impending - headaches. - - + + + Currently, the make check relies on the + PATH and PGPORT environment variables when + performing the checks - it does not use the + PostgreSQL version that may have been specified using the + configuration parameter --with-pgconfig. So make + sure to modify your PATH to match the detected PostgreSQL installation + during configuration or be prepared to deal with the impending + headaches. + + - - If successful, make check will produce the output of almost 500 tests. The results will look similar to the - following (numerous lines omitted below): - + + + Sandboxed build accounts that are not PostgreSQL superusers can + delegate database ownership during the regression cycle by exporting + POSTGIS_REGRESS_DB_OWNER. The harness will create + the temporary regression database owned by the nominated role while + continuing to connect using the less privileged account. Combine this + with POSTGIS_REGRESS_ROLE_EXT_CREATOR when the + extension creation role must differ from the database owner. + + + These variables allow automated environments to exercise the full + upgrade and extension install paths without promoting the calling + account to superuser, provided the target PostgreSQL instance permits + extension installation by those delegate roles. + + + + + If successful, make check will produce the output of almost 500 tests. The results will look similar to the + following (numerous lines omitted below): + diff --git a/regress/README b/regress/README index 7e29fd909..afff17c6d 100644 --- a/regress/README +++ b/regress/README @@ -39,5 +39,12 @@ Notes about running individual regression tests The script run_test.pl can be called directly to run individual regression tests. Run it without parameters for info about its usage. +When the account invoking the harness lacks database ownership or extension +creation privileges, export `POSTGIS_REGRESS_DB_OWNER` to nominate a role that +will own the temporary regression database. If extension installation must be +delegated further, set `POSTGIS_REGRESS_ROLE_EXT_CREATOR`. These variables allow +tests to succeed from sandboxed environments without elevating the calling +account. + Note that tests run in a staged install which is created by running make staged-install. This step is a part of the complete make check. ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/developer.md | 21 +++++++++++++++++++++ doc/installation.xml | 52 +++++++++++++++++++++++++++++++++++----------------- regress/README | 7 +++++++ 4 files changed, 64 insertions(+), 17 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 29 16:16:51 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 23:16:51 -0000 Subject: [PostGIS] #5950: Document the use of POSTGIS_REGRESS_DB_OWNER In-Reply-To: <046.4a601a37c67a6ad58a02f3f0bf2170ec@osgeo.org> References: <046.4a601a37c67a6ad58a02f3f0bf2170ec@osgeo.org> Message-ID: <061.89139f97c4828ec3f99c5b517818dbab@osgeo.org> #5950: Document the use of POSTGIS_REGRESS_DB_OWNER ----------------------------+--------------------------- Reporter: robe | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.5 Component: documentation | Version: 3.5.x Resolution: fixed | Keywords: ----------------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"5faa572a734cce40195709a14db60301c1bf5a0c/git" 5faa572/git]: {{{#!CommitTicketReference repository="git" revision="5faa572a734cce40195709a14db60301c1bf5a0c" [doc] Document POSTGIS_REGRESS_DB_OWNER for sandboxed regression roles Closes #5950 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Wed Oct 29 16:46:43 2025 From: git at osgeo.org (git at osgeo.org) Date: Wed, 29 Oct 2025 16:46:43 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-164-g59d2f3dc7 Message-ID: <20251029234643.D481D16CF59@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3 (commit) from 5faa572a734cce40195709a14db60301c1bf5a0c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3 Author: Darafei Praliaskouski Date: Thu Oct 30 03:46:26 2025 +0400 Guard against histogram axis dimension underflow References #5959 References #5984 diff --git a/postgis/cunit/cu_tester.c b/postgis/cunit/cu_tester.c index b4dd46aa7..eb6ba5b0d 100644 --- a/postgis/cunit/cu_tester.c +++ b/postgis/cunit/cu_tester.c @@ -28,6 +28,7 @@ #include #include +#include #include #include "../gserialized_estimate_support.h" @@ -82,6 +83,23 @@ histogram_budget_clamps(void) CU_ASSERT_EQUAL(histogram_cell_budget((double)INT_MAX, 50000, INT_MAX), INT_MAX); } +static void +histogram_axis_allocation_guards(void) +{ + /* Baseline: evenly split a 10k target over two varying dimensions. */ + CU_ASSERT_EQUAL(histogram_axis_cells(10000, 2, 0.5), 100); + + /* Skewed axis ratios that collapse to tiny powers still return one cell. */ + CU_ASSERT_EQUAL(histogram_axis_cells(10000, 2, 1e-9), 1); + + /* Denormals, NaNs and negative ratios should not leak to the histogram. */ + CU_ASSERT_EQUAL(histogram_axis_cells(10000, 2, NAN), 1); + CU_ASSERT_EQUAL(histogram_axis_cells(10000, 2, -0.5), 1); + + /* Extremely aggressive ratios remain bounded by the square root of the budget. */ + CU_ASSERT_EQUAL(histogram_axis_cells(INT_MAX, 2, 1.0), (int)sqrt((double)INT_MAX * 2.0)); +} + static void nd_stats_indexing_behaviour(void) { @@ -138,6 +156,7 @@ main(void) goto cleanup; if (!CU_add_test(suite, "histogram budget clamps", histogram_budget_clamps) || + !CU_add_test(suite, "histogram axis guards", histogram_axis_allocation_guards) || !CU_add_test(suite, "nd_stats value index guards", nd_stats_indexing_behaviour) || !CU_add_test(suite, "nd_box ratio edge cases", nd_box_ratio_cases)) { diff --git a/postgis/gserialized_estimate.c b/postgis/gserialized_estimate.c index 5c4b4387b..d616cbeba 100644 --- a/postgis/gserialized_estimate.c +++ b/postgis/gserialized_estimate.c @@ -1516,11 +1516,10 @@ compute_gserialized_stats_mode(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfu * Scale the target cells number by the # of dims and ratio, * then take the appropriate root to get the estimated number of cells * on this axis (eg, pow(0.5) for 2d, pow(0.333) for 3d, pow(0.25) for 4d) - */ - histo_size[d] = (int)pow((double)histo_cells_target * histo_ndims * edge_ratio, 1/(double)histo_ndims); - /* If something goes awry, just give this dim one slot */ - if ( ! histo_size[d] ) - histo_size[d] = 1; + * The dedicated helper clamps pathological floating point inputs so we + * do not resurrect the NaN propagation reported in #5959 on amd64. + */ + histo_size[d] = histogram_axis_cells(histo_cells_target, histo_ndims, edge_ratio); } histo_cells_new *= histo_size[d]; } diff --git a/postgis/gserialized_estimate_support.h b/postgis/gserialized_estimate_support.h index 0d3a23d75..6b372a43e 100644 --- a/postgis/gserialized_estimate_support.h +++ b/postgis/gserialized_estimate_support.h @@ -151,6 +151,46 @@ histogram_cell_budget(double total_rows, int ndims, int attstattarget) return (int)budget; } +/* + * Allocate histogram buckets along a single axis in proportion to the observed + * density variation. The caller passes in the global histogram target along + * with the number of axes that exhibited variation in the sampled data and the + * relative contribution of the current axis (edge_ratio). Earlier versions + * evaluated the pow() call directly in the caller, which exposed the planner to + * NaN propagation on some amd64 builds when the ratio was denormal or negative + * (see #5959). Keeping the calculation in one place allows us to clamp the + * inputs and provide a predictable fallback for problematic floating point + * combinations. + */ +static inline int +histogram_axis_cells(int histo_cells_target, int histo_ndims, double edge_ratio) +{ + double scaled; + double axis_cells; + + if (histo_cells_target <= 0 || histo_ndims <= 0) + return 1; + + if (!(edge_ratio > 0.0) || !isfinite(edge_ratio)) + return 1; + + scaled = (double)histo_cells_target * (double)histo_ndims * edge_ratio; + if (!(scaled > 0.0) || !isfinite(scaled)) + return 1; + + axis_cells = pow(scaled, 1.0 / (double)histo_ndims); + if (!(axis_cells > 0.0) || !isfinite(axis_cells)) + return 1; + + if (axis_cells >= (double)INT_MAX) + return INT_MAX; + + if (axis_cells <= 1.0) + return 1; + + return (int)axis_cells; +} + /* * Compute the portion of 'target' covered by 'cover'. The caller supplies the * dimensionality because ND_BOX always carries four slots. Degenerate volumes ----------------------------------------------------------------------- Summary of changes: postgis/cunit/cu_tester.c | 19 ++++++++++++++++ postgis/gserialized_estimate.c | 9 ++++---- postgis/gserialized_estimate_support.h | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Oct 29 16:46:45 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 23:46:45 -0000 Subject: [PostGIS] #5959: Query planner vastly underestimates number of rows matched by GIST index In-Reply-To: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> References: <049.94b8cd0de5de54d9df9629186637db25@osgeo.org> Message-ID: <064.9850004988e565ba04ba465e66bdf421@osgeo.org> #5959: Query planner vastly underestimates number of rows matched by GIST index ----------------------+--------------------------- Reporter: alexobs | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.5.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Darafei Praliaskouski ): In [changeset:"59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3/git" 59d2f3d/git]: {{{#!CommitTicketReference repository="git" revision="59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3" Guard against histogram axis dimension underflow References #5959 References #5984 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 16:46:45 2025 From: trac at osgeo.org (PostGIS) Date: Wed, 29 Oct 2025 23:46:45 -0000 Subject: [PostGIS] #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate In-Reply-To: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> References: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> Message-ID: <061.b057f0bdedd7ad8133d22fd8d8f43c87@osgeo.org> #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate -----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: critical | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by Darafei Praliaskouski ): In [changeset:"59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3/git" 59d2f3d/git]: {{{#!CommitTicketReference repository="git" revision="59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3" Guard against histogram axis dimension underflow References #5959 References #5984 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 17:40:26 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 00:40:26 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.38599bfdd7c55e32e9e9099c41982144@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Replying to [comment:22 strk]: > Replying to [comment:19 francoisb]: > > FWIW, in my database (PostgreSQL 16.10, macOS), I was able to recover the topogeometry columns with these two steps: > > > > 1) Upgrade the topology to use the bigint feature: > > > > {{{ > > SELECT UpgradeTopology('topo_1'); > > }}} > > Wow, I did't even notice the existance of this function, I don't like the name of it :( > For those like me who missed it, its documentation is here: https://postgis.net/docs//en/UpgradeTopology.html > > I dunno why we call it an "upgrade" to get a bigger size :/ > > > Note I'm not 100% sure this step is actually needed, but I add it here because I did it. We could test without, and perhaps remove it. > > > > 2) Recover `id` and `type` values from the bytes of corrupted `id`, with a query like: > > > > {{{ > > UPDATE table_1 > > SET > > topogeom = ( > > (topogeom).topology_id, > > (topogeom).layer_id, > > (topogeom).id & 0xFFFFFFFF, -- 32 least significant bits from corrupted "id" > > (topogeom).id >> 32 -- 32 most significant bits from corrupted "id" > > )::topogeometry > > WHERE topogeom IS NOT NULL > > RETURNING topogeom; > > }}} > > Nice one, it might be time to start a PR with this code made available as a repair function so to provide improvements as we see them (like maybe check the xmin against the postgis xmin...). Would you be up for such task ? Then I'll be happy to test it against my existing corrupted tables as right now I cannot even `pg_upgrade` a cluster due to this bug, apparently. Wouldn't you end up overupdating with that. I was thinking more like {{{ UPDATE table_1 SET topogeom = ( (topogeom).topology_id, (topogeom).layer_id, (topogeom).id & 0xFFFFFFFF, -- 32 least significant bits from corrupted "id" (topogeom).id >> 32 -- 32 most significant bits from corrupted "id" )::topogeometry WHERE ( (topogeom).id & 0xFFFFFFFF ) <> (topogeom).id; }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 19:21:08 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 02:21:08 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.b5b022fdb35c4d61dfe0232dcca351cd@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): I still need to test this some more but this is a WIP of a function. I'm going to focus on creating upgrade tests for damaged topogeoms and then try to fix with this function and will write a companion function to check damaged topogeometries. {{{ CREATE OR REPLACE FUNCTION topology.fix_topogeometry_column(topo_schema name, topo_table name, topo_column name) RETURNS text AS $$ DECLARE var_sql text; var_row_count bigint; result text; BEGIN -- if topogeometry is bigint, then fix damaged integer, need to upgrade to bigint IF EXISTS ( SELECT 1 FROM pg_catalog.pg_type join pg_class on pg_class.oid = pg_type.typrelid join pg_catalog.pg_attribute AS pga on pga.attrelid = pg_class.oid join pg_type as pg_attr_type on pg_attr_type.oid = pga.atttypid WHERE pg_type.typname::regtype::text = 'topogeometry' AND pga.attname = 'id' AND pg_type.typnamespace::regnamespace::text = 'topology' AND pga.atttypid::regtype::text = 'bigint' ) THEN var_sql = format('UPDATE %1$I.%2$I SET %3$I = ( (%3$I).topology_id, (%3$I).layer_id, (%3$I).id & 0xFFFFFFFF, (%3$I).id >> 32 )::topogeometry WHERE ( (%3$I).id & 0xFFFFFFFF ) <> (%3$I).id OR ( (%3$I).id >> 32 ) = (%3$I).type ', topo_schema, topo_table, topo_column); EXECUTE var_sql; GET DIAGNOSTICS var_row_count = ROW_COUNT; result = format('%s rows updated for %s.%s.%s column to bigint id type', var_row_count, topo_schema, topo_table, topo_column); ELSE --we are coming from bigint and going back to integer var_sql = format('UPDATE %1$I.%2$I SET %3$I = ( (%3$I).topology_id, (%3$I).layer_id, (%3$I).id, l.feature_type )::topogeometry FROM topology.layer AS l WHERE l.topology_id = (%3$I).topology_id AND l.layer_id = (%3$I).layer_id AND (%3$I).type <> l.feature_type ', topo_schema, topo_table, topo_column); EXECUTE var_sql; GET DIAGNOSTICS var_row_count = ROW_COUNT; result = format('%s rows updated for %s.%s.%s column back to integer id type', var_row_count, topo_schema, topo_table, topo_column); END IF; RETURN result; END $$ language plpgsql; }}} Use case, we would run across all layers in the database and it will fix broken rows {{{ SELECT topology.fix_topogeometry_column(schema_name, table_name, feature_column) FROM topology.layer; }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Oct 29 22:33:55 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 05:33:55 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.4423c1e4284479e6f6f9bf3672d66105@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by strk): Replying to [comment:23 robe]: > Wouldn't you end up overupdating with that. I was thinking more like > > WHERE ( (topogeom).id & 0xFFFFFFFF ) <> (topogeom).id; I was thinking more like: {{{ WHERE ( xmin < ( select xmin from pg_proc where oid = 'topology.st_createtopogeo'::regproc ) }}} Example state I've produced by sourcing the topology/test/load_topology.sql and topology/test/load_features.sql while in 3.5.5dev, upgrading to 3.7.0dev and then sourcing topology/test/more_features.sql: {{{ strk at strk=# select xmin,feature_name,geometrytype(feature) from features.city_streets; xmin | feature_name | geometrytype -------+--------------+----------------- 37032 | R1 | UNEXPECTED 37032 | R2 | UNEXPECTED 37032 | R3 | UNEXPECTED 37032 | R4 | UNEXPECTED 37176 | E7E8 | MULTILINESTRING 37177 | E20E19 | MULTILINESTRING 37178 | E25 | MULTILINESTRING 37179 | R1a | MULTILINESTRING (8 rows) strk at strk=# select xmin from pg_proc where oid = 'topology.st_createtopogeo'::regproc; xmin ------- 37035 (1 row) }}} For the function we'd better include a version name in the function, maybe call it 'fix_topogeometry_column_currupted_by_3.6.0_upgrade` ? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 02:14:52 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 09:14:52 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.c82186d3c7cb766610461d8383df8329@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: -----------------------------+--------------------------- Comment (by Christoph Berg): Right, but that would be up for Ubuntu to fix. I know the process of fixing it in Debian, but Ubuntu is something else. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 06:00:15 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 06:00:15 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.4-3-g949a623cd Message-ID: <20251030130015.D893A16FE55@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 949a623cd0afc9802ebb228d8dc7b477272b9b18 (commit) from 66694dc2c2bad48c80f8230e091e616ce74ff07f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 949a623cd0afc9802ebb228d8dc7b477272b9b18 Author: Regina Obe Date: Thu Oct 30 09:00:02 2025 -0400 Fix up winnie scripts to handle conditional install of postgis raster and postgis topology extensions during regress diff --git a/ci/winnie/build_postgis.sh b/ci/winnie/build_postgis.sh index f410e720e..20db15c43 100644 --- a/ci/winnie/build_postgis.sh +++ b/ci/winnie/build_postgis.sh @@ -48,10 +48,6 @@ git describe --long --all --tags # Report where we are at sh autogen.sh -if [ -n "$PCRE_VER" ]; then - export PATH="${PROJECTS}/pcre/rel-${PCRE_VER}w${OS_BUILD}${GCC_TYPE}/include:${PROJECTS}/pcre/rel-${PCRE_VER}w${OS_BUILD}${GCC_TYPE}/lib:${PATH}" -fi - export LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${LZ4_PATH}/bin -L${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/lib -L${PROJECTS}/zlib/rel-zlib-${ZLIB_VER}w${OS_BUILD}${GCC_TYPE}/lib" if [$INCLUDE_MINOR_LIB == "1"]; then diff --git a/ci/winnie/package_postgis.sh b/ci/winnie/package_postgis.sh index 13af0b6f2..bcaa2435e 100644 --- a/ci/winnie/package_postgis.sh +++ b/ci/winnie/package_postgis.sh @@ -12,7 +12,7 @@ DWN=${WEB}/download #export PG_VER=9.2beta2 if [ -n "$SOURCE_FOLDER" ]; then - export POSTGIS_SRC=${PROJECTS}/postgis/$SOURCE_FOLDER + export POSTGIS_SRC=${PROJECTS}/postgis/$SOURCE_FOLDER cd $POSTGIS_SRC fi @@ -47,46 +47,54 @@ mkdir -p $outdir/share/contrib/postgis-${POSTGIS_MINOR_VER}/proj mkdir -p $outdir/share/extension mkdir $outdir/bin mkdir $outdir/lib -mkdir $outdir/bin/postgisgui -mkdir $outdir/bin/postgisgui/share -mkdir $outdir/bin/postgisgui/lib + mkdir $outdir/utils -cp ${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui - -cp ${PGPATH}/bin/libpq.dll $outdir/bin/postgisgui -#cp ${PGPATHEDB}/bin/libiconv2.dll $outdir/bin/postgisgui -cp ${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/bin/libicon*.dll $outdir/bin/postgisgui -cp ${PGPATHEDB}/bin/libintl*.dll $outdir/bin/postgisgui - -#cp ${PGPATHEDB}/bin/ssleay32.dll $outdir/bin/postgisgui -#cp ${PGPATHEDB}/bin/libeay32.dll $outdir/bin/postgisgui -#cp ${PGPATHEDB}/bin/libcrypto-1_1-x64.dll $outdir/bin/postgisgui -#cp ${PGPATHEDB}/bin/libssl-1_1-x64.dll $outdir/bin/postgisgui - -#pg 15 is shipping with newer ssl -cp ${PGPATHEDB}/bin/libcrypto-3-x64.dll $outdir/bin/postgisgui -cp ${PGPATHEDB}/bin/libssl-3-x64.dll $outdir/bin/postgisgui cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libstdc++-6.dll $outdir/bin cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libgcc*.dll $outdir/bin -cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui -cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libstdc++-6.dll $outdir/bin/postgisgui -cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libgcc*.dll $outdir/bin/postgisgui -cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/etc $outdir/bin/postgisgui -cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/share/themes $outdir/bin/postgisgui/share -cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/gtk-2.0 $outdir/bin/postgisgui/lib -cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/*.dll $outdir/bin/postgisgui/lib -cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/gdk-pixbuf-2.0 $outdir/bin/postgisgui/lib + +# don't package postgisgui if we don't have gtk2 +if [ -d "${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}" ]; then + mkdir $outdir/bin/postgisgui + mkdir $outdir/bin/postgisgui/share + mkdir $outdir/bin/postgisgui/lib + #pg 15 is shipping with newer ssl + cp ${PGPATHEDB}/bin/libcrypto-3-x64.dll $outdir/bin/postgisgui + cp ${PGPATHEDB}/bin/libssl-3-x64.dll $outdir/bin/postgisgui + cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui + cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libstdc++-6.dll $outdir/bin/postgisgui + cp /c/ming${OS_BUILD}${GCC_TYPE}/mingw${OS_BUILD}/bin/libgcc*.dll $outdir/bin/postgisgui + cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/etc $outdir/bin/postgisgui + cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/share/themes $outdir/bin/postgisgui/share + cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/gtk-2.0 $outdir/bin/postgisgui/lib + cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/*.dll $outdir/bin/postgisgui/lib + cp -r ${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/gdk-pixbuf-2.0 $outdir/bin/postgisgui/lib + cp ${PGPATHEDB}/bin/libintl*.dll $outdir/bin/postgisgui + cp ${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui + + cp ${PGPATH}/bin/libpq.dll $outdir/bin/postgisgui + #cp ${PGPATHEDB}/bin/libiconv2.dll $outdir/bin/postgisgui + cp ${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/bin/libicon*.dll $outdir/bin/postgisgui + #proj + cp ${PROJ_PATH}/bin/*.dll $outdir/bin/postgisgui + #geos + cp -p ${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui + + cp loader/shp2pgsql-gui.exe ${RELDIR}/${RELVERDIR}/bin/postgisgui + cp loader/.libs/shp2pgsql-gui.exe ${RELDIR}/${RELVERDIR}/bin/postgisgui + + #shp2pgsql-gui now has dependency on geos (though in theory it shouldn't) + cp -p ${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll ${RELDIR}/${RELVERDIR}/bin/postgisgui +fi; # proj cp ${PROJ_LIB}/* $outdir/share/contrib/postgis-${POSTGIS_MINOR_VER}/proj cp ${PROJ_PATH}/bin/*.dll $outdir/bin -cp ${PROJ_PATH}/bin/*.dll $outdir/bin/postgisgui + # geos cp -p ${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin -cp -p ${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui #for protobuf cp ${PROJECTS}/protobuf/rel-${PROTOBUF_VER}w${OS_BUILD}${GCC_TYPE}/bin/libprotobuf-c-*.dll $outdir/bin @@ -99,7 +107,7 @@ if [ "$POSTGIS_MAJOR_VERSION" > "1" ] ; then cp -rp ${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYPE}/share/gdal $outdir/gdal-data # needed for address standardizer - cp -p ${PROJECTS}/pcre/rel-${PCRE_VER}w${OS_BUILD}${GCC_TYPE}/bin/libpcre-1*.dll $outdir/bin + cp -p ${PCRE_PATH}/bin/*.dll $outdir/bin fi; @@ -116,8 +124,6 @@ if [ -n "$SFCGAL_VER" ]; then #cp -p ${PROJECTS}/CGAL/rel-cgal-${CGAL_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin cp -p ${PROJECTS}/CGAL/rel-sfcgal-${SFCGAL_VER}w${OS_BUILD}${GCC_TYPE}/lib/*.dll $outdir/bin - # cp -p ${PROJECTS}/CGAL/rel-cgal-${CGAL_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll $outdir/bin/postgisgui - # cp -p ${PROJECTS}/CGAL/rel-sfcgal-${SFCGAL_VER}w${OS_BUILD}${GCC_TYPE}/lib/*.dll $outdir/bin/postgisgui fi; echo "PROTOBUF VERSION: ${PROTOBUF_VER} https://github.com/google/protobuf" >> $verfile @@ -147,14 +153,10 @@ cp loader/shp2pgsql.exe ${RELDIR}/${RELVERDIR}/bin cp loader/.libs/shp2pgsql.exe ${RELDIR}/${RELVERDIR}/bin cp loader/pgsql2shp.exe ${RELDIR}/${RELVERDIR}/bin cp loader/.libs/pgsql2shp.exe ${RELDIR}/${RELVERDIR}/bin -cp loader/shp2pgsql-gui.exe ${RELDIR}/${RELVERDIR}/bin/postgisgui -cp loader/.libs/shp2pgsql-gui.exe ${RELDIR}/${RELVERDIR}/bin/postgisgui cp topology/loader/* ${RELDIR}/${RELVERDIR}/bin #cp liblwgeom/.libs/*.dll ${RELDIR}/${RELVERDIR}/bin/postgisgui -#shp2pgsql-gui now has dependency on geos (though in theory it shouldn't) -cp -p ${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin/*.dll ${RELDIR}/${RELVERDIR}/bin/postgisgui cp spatial_ref_sys.sql ${RELDIR}/${RELVERDIR}/share/contrib/postgis-${POSTGIS_MINOR_VER} cp topology/topology.sql ${RELDIR}/${RELVERDIR}/share/contrib/postgis-${POSTGIS_MINOR_VER} #cp topology/topology_upgrade_*.sql ${RELDIR}/${RELVERDIR}/share/contrib/postgis-${POSTGIS_MINOR_VER} diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh index 19d49335e..5a86e8db9 100644 --- a/ci/winnie/regress_postgis.sh +++ b/ci/winnie/regress_postgis.sh @@ -39,10 +39,10 @@ echo PATH AFTER: $PATH echo WORKSPACE IS $WORKSPACE #mkdir ${PROJECTS}/postgis/tmp -export PGIS_REG_TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_MICRO_VER}_pg${PG_VER}_geos${GEOS_VER}_gdal${GDAL_VER}w${OS_BUILD} -rm -rf ${PGIS_REG_TMPDIR} -mkdir ${PGIS_REG_TMPDIR} -export TMPDIR=${PGIS_REG_TMPDIR} +#export PGIS_REG_TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_MICRO_VER}_pg${PG_VER}_geos${GEOS_VER}_gdal${GDAL_VER}w${OS_BUILD} +#rm -rf ${PGIS_REG_TMPDIR} +#mkdir ${PGIS_REG_TMPDIR} +#export TMPDIR=${PGIS_REG_TMPDIR} #rm -rf ${PGIS_REG_TMPDIR} #TMPDIR=${PROJECTS}/postgis/tmp/${POSTGIS_VER}_${PG_VER}_${GEOS_VERSION}_${PROJ_VER} @@ -68,6 +68,14 @@ if [ $INCLUDE_MINOR_LIB == "1" ]; then EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --with-library-minor-version" fi +if [ $REGRESS_WITHOUT_TOPOLOGY == "1" ]; then + EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-topology" +fi + +if [ $REGRESS_WITHOUT_RASTER == "1" ]; then + EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-raster" +fi + #CPPFLAGS="-I${PGPATH}/include -I${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/include" \ #CFLAGS="-Wall -fno-omit-frame-pointer" @@ -91,22 +99,34 @@ LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${LZ4_PATH}/lib -L${PROJECTS #patch liblwgeom generated make to get rid of dynamic linking #sed -i 's/LDFLAGS += -no-undefined//g' liblwgeom/Makefile -make -j 4 +make -j 2 make install -make check RUNTESTFLAGS=-v + +# don't run tests twice. Only run regular if extension test is not asked for +if [ "$MAKE_EXTENSION" == "0" ]; then + make check RUNTESTFLAGS=-v +fi + if [ "$MAKE_EXTENSION" == "1" ]; then export PGUSER=postgres #need to copy install files to EDB install (since not done by make install cd ${POSTGIS_SRC} echo "Postgis src dir is ${POSTGIS_SRC}" - strip postgis/postgis-*.dll - strip raster/rt_pg/postgis_raster-*.dll - strip sfcgal/*.dll - cp topology/*.dll ${PGPATHEDB}/lib + #strip postgis/postgis-*.dll + #strip raster/rt_pg/postgis_raster-*.dll + #strip sfcgal/*.dll + + if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then + cp -r topology/*.dll ${PGPATHEDB}/lib + fi cp postgis/postgis*.dll ${PGPATHEDB}/lib cp sfcgal/*.dll ${PGPATHEDB}/lib - cp raster/rt_pg/postgis_raster-*.dll ${PGPATHEDB}/lib + + if [ $REGRESS_WITHOUT_RASTER == "0" ]; then + cp raster/rt_pg/postgis_raster-*.dll ${PGPATHEDB}/lib + fi + export POSTGIS_MINOR_VER=${POSTGIS_MAJOR_VERSION}.${POSTGIS_MINOR_VERSION} export POSTGIS_MINOR_MAX_VER="ANY" @@ -119,8 +139,20 @@ value=${value//UPGRADEABLE_VERSIONS = /} #echo $value export UPGRADEABLE_VERSIONS=$value export WIN_RELEASED_VERSIONS="2.0.0 2.0.1 2.0.3 2.0.4 2.0.6 2.1.4 2.1.7 2.1.8 2.2.0 2.2.3 2.3.0 2.3.7 2.4.0 2.4.4" +export extensions_to_install="postgis postgis_sfcgal postgis_tiger_geocoder address_standardizer" + +if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then + extensions_to_install="${extensions_to_install} postgis_topology" +fi + +if [ $REGRESS_WITHOUT_RASTER == "0" ]; then + extensions_to_install="${extensions_to_install} postgis_raster" +fi + + #echo "Versions are: $UPGRADEABLE_VERSIONS" -for EXTNAME in postgis postgis_raster postgis_sfcgal postgis_tiger_geocoder address_standardizer postgis_topology; do +for EXTNAME in $extensions_to_install; do + cp extensions/$EXTNAME/sql/* ${PGPATHEDB}/share/extension cp extensions/$EXTNAME/sql/$EXTNAME--TEMPLATED--TO--ANY.sql ${PGPATHEDB}/share/extension/$EXTNAME--$POSTGIS_MICRO_VER--${POSTGIS_MINOR_MAX_VER}.sql; @@ -142,10 +174,10 @@ done #cp -r ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}.sql ${PGPATHEDB}/share/extension #cp -r ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}next.sql ${PGPATHEDB}/share/extension #cp -r ${PGPATH}/share/extension/address_standardizer*${POSTGIS_MICRO_VER}.sql ${PGPATHEDB}/share/extension - cp -r extensions/*/*.control ${PGPATHEDB}/share/extension - cp -r extensions/*/*.dll ${PGPATHEDB}/lib +cp -r extensions/*/*.control ${PGPATHEDB}/share/extension +cp -r extensions/*/*.dll ${PGPATHEDB}/lib - make check RUNTESTFLAGS="--extension -v" +make check RUNTESTFLAGS="--extension -v" if [ "$UPGRADE_TEST" == "1" ]; then export CURRENTVERSION=${POSTGIS_MAJOR_VERSION}.${POSTGIS_MINOR_VERSION}.${POSTGIS_MICRO_VERSION} @@ -157,13 +189,14 @@ fi cd extensions/address_standardizer make installcheck - #test tiger geocoder - cd ${POSTGIS_SRC} - cd extensions/postgis_tiger_geocoder - make installcheck - if [ "$?" != "0" ]; then - exit $? - fi +#test tiger geocoder +# cd ${POSTGIS_SRC} +# cd extensions/postgis_tiger_geocoder +# make installcheck +# if [ "$?" != "0" ]; then +# exit $? +# fi +#end extension fi if [ "$DUMP_RESTORE" == "1" ]; then diff --git a/ci/winnie/winnie_common.sh b/ci/winnie/winnie_common.sh index 8b5925fee..d375cbec6 100644 --- a/ci/winnie/winnie_common.sh +++ b/ci/winnie/winnie_common.sh @@ -12,11 +12,11 @@ export MSYS2_ARG_CONV_EXCL=/config/tags export XML_CATALOG_FILES="/projects/docbook/docbook-5.0.1/catalog.xml" if [[ "${OVERRIDE}" == '' ]] ; then - export GEOS_VER=3.13.0 + export GEOS_VER=3.13.1 export GDAL_VER=3.9.2 export PROJ_VER=8.2.1 - export SFCGAL_VER=1.5.2 - export CGAL_VER=5.6.1 + export SFCGAL_VER=2.1.0 + export CGAL_VER=6.0.1 export ICON_VER=1.17 export ZLIB_VER=1.2.13 export PROTOBUF_VER=3.2.0 @@ -26,12 +26,25 @@ if [[ "${OVERRIDE}" == '' ]] ; then export LZ4_VER=1.9.3 fi; +if [[ ${PCRE_VER} == '' ]]; then + PCRE_VER=10.40 +fi; + export PROTOBUF_VER=3.2.0 export PROTOBUFC_VER=1.2.1 export JSON_VER=0.12 -export PCRE_VER=8.45 + + +if [ -d "${PROJECTS}/pcre2/rel-pcre2-${PCRE_VER}w${OS_BUILD}${GCC_TYPE}" ]; then +export PCRE_PATH=${PROJECTS}/pcre2/rel-pcre2-${PCRE_VER}w${OS_BUILD}${GCC_TYPE} +else +export PCRE_PATH=${PROJECTS}/pcre/rel-${PCRE_VER}w${OS_BUILD}${GCC_TYPE} +fi + + +echo "PCRE_PATH is $PCRE_PATH" #export OS_BUILD=64 #export PGPORT=8442 @@ -52,6 +65,18 @@ fi; echo "LZ4_VER ${LZ4_VER}" +if [[ "${REGRESS_WITHOUT_TOPOLOGY}" == '' ]] ; then + export REGRESS_WITHOUT_TOPOLOGY=0 +fi; + +if [[ "${REGRESS_WITHOUT_RASTER}" == '' ]] ; then + export REGRESS_WITHOUT_RASTER=0 +fi; + +if [[ "${MAKE_EXTENSION}" == '' ]] ; then + export MAKE_EXTENSION=0 +fi; + #set to something even if override is on but not set if [[ "${ZLIB_VER}" == '' ]] ; then @@ -65,11 +90,11 @@ fi; #set to something even if override is on but not set if [[ "${CGAL_VER}" == '' ]] ; then - export CGAL_VER=5.6.1 + export CGAL_VER=6.0.1 fi; ##hard code versions of cgal etc. for now -export CGAL_VER=5.6.1 + BOOST_VER=1.84.0 export BOOST_VER_WU=1_84_0 @@ -123,7 +148,7 @@ export GDAL_DATA="${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYPE}/share/ export PATH="${PGPATH}/bin:${PGPATH}/lib:${PATH}" export PATH="${PROJECTS}/xsltproc:${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/bin:${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin:${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYPE}/bin:${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/lib:${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/include:${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/bin:${PROJ_PATH}/bin:${PROJECTS}/libxml/rel-libxml2-${LIBXML_VER}w${OS_BUILD}${GCC_TYPE}/bin:${PROJECTS}/zlib/rel-zlib-${ZLIB_VER}w${OS_BUILD}${GCC_TYPE}/bin:${PROJECTS}/zlib/rel-zlib-${ZLIB_VER}w${OS_BUILD}${GCC_TYPE}/lib:${PATH}" -export PKG_CONFIG_PATH="${PROJECTS}/sqlite/rel-sqlite3w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/protobuf/rel-${PROTOBUF_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/json-c/rel-${JSON_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJ_PATH}/lib/pkgconfig:${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/pcre/rel-${PCRE_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/zlib/rel-zlib-${ZLIB_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:/mingw/${MINGHOST}/lib/pkgconfig" +export PKG_CONFIG_PATH="${PROJECTS}/sqlite/rel-sqlite3w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/protobuf/rel-${PROTOBUF_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/json-c/rel-${JSON_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJ_PATH}/lib/pkgconfig:${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PCRE_PATH}/lib/pkgconfig:${PROJECTS}/zlib/rel-zlib-${ZLIB_VER}w${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:${PROJECTS}/gtkw${OS_BUILD}${GCC_TYPE}/lib/pkgconfig:/mingw/${MINGHOST}/lib/pkgconfig" export SHLIB_LINK="-static-libstdc++ -lstdc++ -Wl,-Bdynamic -lm" CPPFLAGS="-I${PGPATH}/include -I${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/include" @@ -144,6 +169,11 @@ CPPFLAGS="-I${PGPATH}/include -I${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD} #add protobuf export PATH="${PROJECTS}/protobuf/rel-${PROTOBUF_VER}w${OS_BUILD}${GCC_TYPE}/bin:${PROJECTS}/protobuf/rel-${PROTOBUF_VER}w${OS_BUILD}${GCC_TYPE}/lib:${PATH}" +# add pcre for address_standardizer +if [ -n "$PCRE_PATH" ]; then + export PATH="${PCRE_PATH}/include:${PCRE_PATH}/lib:${PATH}" +fi + echo "PATH AFTER: $PATH" if [[ "${INCLUDE_MINOR_LIB}" == '' ]] ; then ----------------------------------------------------------------------- Summary of changes: ci/winnie/build_postgis.sh | 4 --- ci/winnie/package_postgis.sh | 74 +++++++++++++++++++++--------------------- ci/winnie/regress_postgis.sh | 77 +++++++++++++++++++++++++++++++------------- ci/winnie/winnie_common.sh | 44 +++++++++++++++++++++---- 4 files changed, 130 insertions(+), 69 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 07:09:24 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 14:09:24 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.77c1c9e4864c9ff01a12ef6952b06b9a@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Ah strk - sorry didn't read this before posting my pull request https://gitea.osgeo.org/postgis/postgis/pulls/274 I tried to make the function name match the structure of other function names. So I called it: topology.FixCorruptTopoGeometryColumn We could add a version number to it, but I had planned it work for both upgrade and downgrade. e.g. should we offer the option of topogeometry_small we might need to use it to fix the bigint topogeometries that's what the second casing is for. Regarding the above you have. I realize now that even though you can't cast xmin to int or bigint you could do so by going first thru ::text cast. {{{ select xmin::text::integer from pg_proc where oid = 'topology.st_createtopogeo'::regproc; }}} So I guess it can be done. Though are we absolutely sure that xmin will always be increasing? I'm guessing so except for exceedingly large databases where there is wrap around. I'm assuming that is why they never provided > < operators for tid types and you only have equality. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 07:11:20 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 14:11:20 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.afe542d35e92ca1f296beeeda881a064@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): oh forgot to mention. I think to test out the pg_upgrade issue, you have to have the same library name used, so --with-minor-lib as we put in even our fat version would not catch the pg_upgrade bug unless we build a low and a high version without the --minor-lib flag -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 07:18:04 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 14:18:04 -0000 Subject: [PostGIS] #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 In-Reply-To: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> References: <047.b46aadc639363ed0c4294cf04295054b@osgeo.org> Message-ID: <062.39348b1abc012c94ca7292755e4f4683@osgeo.org> #5983: Data corruption in topology.topoelement and topology.topogeometry after upgrade to 3.6.0 -----------------------+--------------------------- Reporter: packi | Owner: robe Type: defect | Status: new Priority: blocker | Milestone: PostGIS 3.6.1 Component: topology | Version: 3.6.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Replying to [comment:25 strk]: > Replying to [comment:23 robe]: > > > Wouldn't you end up overupdating with that. I was thinking more like > > > > WHERE ( (topogeom).id & 0xFFFFFFFF ) <> (topogeom).id; > > I was thinking more like: > > {{{ > WHERE ( xmin < ( select xmin from pg_proc where oid = 'topology.st_createtopogeo'::regproc ) > }}} > Did you test this out? If I do something like this: {{{ SELECT xmin from pg_proc where xmin < ( select p.xmin from pg_proc AS p where oid = 'topology.st_createtopogeo'::regproc ); }}} I get error: {{{ ERROR: operator does not exist: xid < xid }}} So we would probably need to change it to: {{{ WHERE ( xmin::text::int < ( select xmin::text::int from pg_proc where oid = 'topology.st_createtopogeo'::regproc ) }}} but like I said, I'm sure there is a good reason they didn't define <> operators for xid. Though that would probably be a faster test. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 07:28:33 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 14:28:33 -0000 Subject: [PostGIS] #2161: Documentation tooltips are very irritating In-Reply-To: <049.ce661a90809a5e948edfc762ad884df0@osgeo.org> References: <049.ce661a90809a5e948edfc762ad884df0@osgeo.org> Message-ID: <064.f24c092ac7cb0d1e3d327808be695c9c@osgeo.org> #2161: Documentation tooltips are very irritating ----------------------------+----------------------------- Reporter: autarch | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: documentation | Version: 2.0.x Resolution: worksforme | Keywords: ----------------------------+----------------------------- Changes (by komzpa): * resolution: => worksforme * status: new => closed Comment: Not reproducible on new docs. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 07:30:55 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 14:30:55 -0000 Subject: [PostGIS] #4187: Revise translation html to be chunked In-Reply-To: <046.d34fc699d619be0c13b7e320f6c0b5f4@osgeo.org> References: <046.d34fc699d619be0c13b7e320f6c0b5f4@osgeo.org> Message-ID: <061.0522231f195c48d61a39a9a9cfeb521b@osgeo.org> #4187: Revise translation html to be chunked ----------------------------+----------------------------- Reporter: robe | Owner: robe Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: documentation | Version: 2.4.x Resolution: worksforme | Keywords: ----------------------------+----------------------------- Changes (by komzpa): * resolution: => worksforme * status: new => closed Comment: Available as https://postgis.net/docs/manual-dev/ja/ -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 08:39:30 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 08:39:30 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-165-g520c80895 Message-ID: <20251030153931.326A118B653@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 520c80895c27a4720e9bf58d044f3c3de8db7d94 (commit) from 59d2f3dc7f7bc15f1bb924c71610fbdee61a6ef3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 520c80895c27a4720e9bf58d044f3c3de8db7d94 Author: Darafei Praliaskouski Date: Thu Oct 30 19:39:14 2025 +0400 [doc] how to format SQL code Closes #3692 diff --git a/doc/developer.md b/doc/developer.md index 550f90490..f3518021c 100644 --- a/doc/developer.md +++ b/doc/developer.md @@ -18,10 +18,10 @@ category: Development Docs | `3.6.0` | Minor release (new features, backwards?compatible) | Added new functions | | `3.0.1` | Patch release (bug fixes, data changes) | Small fixes to `3.0.0` | -* SQL Api functions are functions that are exposed to the user in the database. +* SQL API functions are functions that are exposed to the user in the database. They are either SQL, plpgsql, or C backed functions. -* C Api functions are library functions that back SQL Api functions. +* C API functions are library functions that back SQL API functions. Naming of library files ======================== @@ -49,38 +49,36 @@ To take advantage of this feature, when configuring postgis compile, use the swi ## Does and Don'ts -* Don't introduce new SQL Api functions in a Patch release. +* Don't introduce new SQL API functions in a Patch release. * Don't change structure definitions e.g. geometry_columns, geometry/raster type in a patch release. -* Do introduce new SQL Api functions in a Minor release. -* Functions that are not exposed via the SQL Api can be introduced any time. -* Only major versions can remove SQL api functions - or C api functions without stubbing (which we will cover shortly). +* Do introduce new SQL API functions in a Minor release. +* Functions that are not exposed via the SQL API can be introduced any time. +* Only major versions can remove SQL API functions + or C API functions without stubbing (which we will cover shortly). * Only PostGIS first release of a major can introduce functionality that requires a pg_dump / pg_restore. * Don't require newer versions of library in a micro, but you can require new versions in first release of a minor. For example we often drop support for older versions of GEOS and PostgreSQL in a new minor release. - - ## When removing objects impacts upgrade There are several types of removals that impact user upgrades and should be carefully thought thru. -* SQL Api functions -* C Api functions -* Types, Views, Tables are also exposed via SQL Api +* SQL API functions +* C API functions +* Types, Views, Tables are also exposed via SQL API Functions internal to postgis that are never exposed and only used within postgis libraries can be shuffled around to your hearts content. -## UPGRADING C Api functions +## Upgrading C API functions -You should avoid ever removing C Api function in Minor and patch releases of PostGIS. +You should avoid ever removing C API function in Minor and patch releases of PostGIS. -If there is a C Api function that you badly want to remove you need to stub it so the signature still +If there is a C API function that you badly want to remove you need to stub it so the signature still exists but throws an error. These functions should be removed from whatever file @@ -98,7 +96,7 @@ run ALTER EXTENSION or SELECT postgis_extensions_upgrade() in a micro, so taking Note the specification of the version it was removed and the name of the function - * For postgis_sfcgal, deprecated C api functions should go in sfcgal/postgis_sfcgal_legacy.c + * For postgis_sfcgal, deprecated C API functions should go in sfcgal/postgis_sfcgal_legacy.c * For postgis_raster, raster/rt_pg/rtpg_legacy.c * postgis_topology extension has never had any deprecated functions so there is currently no legacy file for it. If there comes a need to deprecate C functions, then a file topology/postgis_topology_legacy.c will be created to store these. @@ -120,12 +118,12 @@ if you try to overlay the old def structures onto the new extension install. So this whole care of legacy functions is to appease pg_upgrade. -## UPGRADING SQL Api functions +## UPGRADING SQL API functions -For most SQL Api functions, nothing special needs to be done beyond +For most SQL API functions, nothing special needs to be done beyond noting a CHANGED in version or AVAILABILITY in the respective .sql.in files. -The SQL Api definitions are found in following places: +The SQL API definitions are found in following places: | Extension | Relevant Files | |-----------|----------------| @@ -149,7 +147,7 @@ The various notes you put in .sql.in files take the following form and precede t * -- Replaces: is both informational and also instructs the perl upgrade script to protect the user from some upgrade pains. You use Replaces instead of just a simple Changed, if you are changing inputs to the function or changing - outputs of the function. So any change to the api + outputs of the function. So any change to the API Such a comment would look something like: @@ -196,8 +194,77 @@ These ones are new in 3.6.0 to handle the very delicate major upgrade of topolog * _postgis_add_column_to_table -Dependency Library Guarding -============================ +### SQL scripting rules so our parsers don?t mangle your changes + +Keep these rules when writing or editing SQL in `postgis/*.sql.in` and upgrade scripts. They match how our Perl generators parse and build upgrades/uninstalls. + +1. **Use `$$` as the DO delimiter** + +* Do not use named delimiters like `$func$`. + +```sql +DO $$ +BEGIN + -- your block +END; +$$ LANGUAGE plpgsql; +``` + +2. **Left-align `CREATE` statements inside `DO`** + +* Anything created in a `DO` block is auto-picked up by uninstall **only if** the `CREATE ...` lines are not indented. + +```sql +DO $$ +BEGIN +CREATE OR REPLACE FUNCTION public.myfunc(...) RETURNS ... +LANGUAGE sql AS $$ SELECT 1 $$; +END; +$$; +-- Good: CREATE starts at column 1 +``` + +3. **When changing signatures or arg names, use the drop hooks** + +* Use `postgis_drop_before.sql` to drop or de-alias old signatures before install/upgrade runs. +* Use `postgis_drop_after.sql` to clean up stragglers after new objects exist. +* Typical cases: + + * adding default args to a function that previously had none, + * renaming argument names that would create ambiguity across versions, + * replacing one signature with another without leaving duplicates. + +```sql +-- postgis_drop_before.sql +DROP FUNCTION IF EXISTS public.myfunc(oldtype, oldtype); + +-- main install/upgrade then creates the new signature(s) +``` + +4. **Record `Availability:` and `Changed:` in the script comments** + +* Add concise lines at the top of each object definition. +* The upgrade generator scans these markers to: + + * decide which upgrades need to ship an object (based on first `Availability:`), + * emit notes into generated upgrade paths about behavior/ABI changes (`Changed:`). + +```sql +-- Availability: 3.7.0 +-- Changed: 3.8.0 behavior on NULL input +CREATE OR REPLACE FUNCTION public.myfunc(...) RETURNS ... +... +``` + +**Quick checklist** + +* `DO` uses `$$`, not `$func$`. +* `CREATE` lines start at column 1 inside `DO`. +* For signature/arg changes, stage drops in `postgis_drop_before.sql` (and `*_after.sql` if needed). +* Keep `Availability:` / `Changed:` lines current and minimal. + + +## Dependency Library Guarding On many occasions, we'll introduce functionality that can only be used if PostGIS is compiled with a dependency library higher than X? Where X is some version of a dependency library. @@ -275,8 +342,8 @@ with lib xxx or higher. Also the function has to be available in the C lib, as s on the C lib side and very rarely on the sql files. -Regression harness privileges -============================= +## Regression harness privileges + Continuous integration workers are frequently configured with sandboxed PostgreSQL roles that cannot create databases or install extensions. The regression harness accepts two ----------------------------------------------------------------------- Summary of changes: doc/developer.md | 115 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 91 insertions(+), 24 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 08:39:45 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 15:39:45 -0000 Subject: [PostGIS] #3692: Write up developer docs on how to format code so doesn't get mangled by our parsers In-Reply-To: <046.8ea292dab3ad4302edf4ea327723982f@osgeo.org> References: <046.8ea292dab3ad4302edf4ea327723982f@osgeo.org> Message-ID: <061.68a7f7f2deaec6103a9eee1cc3a5054d@osgeo.org> #3692: Write up developer docs on how to format code so doesn't get mangled by our parsers ----------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: task | Status: closed Priority: medium | Milestone: Website Management, Bots Component: documentation | Version: master Resolution: fixed | Keywords: ----------------------------+-------------------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"520c80895c27a4720e9bf58d044f3c3de8db7d94/git" 520c808/git]: {{{#!CommitTicketReference repository="git" revision="520c80895c27a4720e9bf58d044f3c3de8db7d94" [doc] how to format SQL code Closes #3692 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 09:21:41 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 09:21:41 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-166-gd0cfdb0e9 Message-ID: <20251030162141.527A018C61C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via d0cfdb0e97f065e1ecbdb70b0de908760b5858ab (commit) from 520c80895c27a4720e9bf58d044f3c3de8db7d94 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d0cfdb0e97f065e1ecbdb70b0de908760b5858ab Author: Darafei Praliaskouski Date: Thu Oct 30 20:21:29 2025 +0400 geometry_columns handles NOT VALID SRID checks without errors Closes #4828 diff --git a/NEWS b/NEWS index 5ba9497a8..d4e6baf0c 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,7 @@ xxxx/xx/xx * Bug Fixes * - #5959, Prevent histogram target overflow when analysing massive tables (Darafei Praliaskouski) + - #4828, geometry_columns handles NOT VALID SRID checks without errors (Darafei Praliaskouski) PostGIS 3.6.0 diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in index c1a57bc0d..dee9101c4 100644 --- a/postgis/postgis.sql.in +++ b/postgis/postgis.sql.in @@ -6398,6 +6398,14 @@ LANGUAGE 'sql' STABLE STRICT PARALLEL SAFE _COST_MEDIUM; -- Changed: 2.5.2 replace use of pg_constraint.consrc with pg_get_constraintdef, consrc removed pg12 CREATE OR REPLACE VIEW geometry_columns AS +WITH constraint_defs AS ( + -- Trim trailing NOT VALID so metadata inference works before constraint validation (#4828). + SELECT connamespace, + conrelid, + conkey, + regexp_replace(pg_get_constraintdef(oid), $$\s+NOT\s+VALID$$, '', 'i') AS consrc + FROM pg_constraint +) SELECT current_database()::character varying(256) AS f_table_catalog, n.nspname AS f_table_schema, c.relname AS f_table_name, @@ -6409,32 +6417,30 @@ SELECT current_database()::character varying(256) AS f_table_catalog, JOIN pg_attribute a ON a.attrelid = c.oid AND NOT a.attisdropped JOIN pg_namespace n ON c.relnamespace = n.oid JOIN pg_type t ON a.atttypid = t.oid - LEFT JOIN ( SELECT s.connamespace, - s.conrelid, - s.conkey, - (regexp_match(s.consrc, $$geometrytype\(\w+\)\s*=\s*'(\w+)'$$, 'i'))[1]::text AS type - FROM (SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc - FROM pg_constraint) AS s - WHERE s.consrc ~* $$geometrytype\(\w+\)\s*=\s*'\w+'$$::text - -) st ON st.connamespace = n.oid AND st.conrelid = c.oid AND (a.attnum = ANY (st.conkey)) - LEFT JOIN ( SELECT s.connamespace, - s.conrelid, - s.conkey, - (regexp_match(s.consrc, $$ndims\(\w+\)\s*=\s*(\d+)$$, 'i'))[1]::integer AS ndims - FROM (SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc - FROM pg_constraint) AS s - WHERE s.consrc ~* $$ndims\(\w+\)\s*=\s*\d+$$::text -) sn ON sn.connamespace = n.oid AND sn.conrelid = c.oid AND (a.attnum = ANY (sn.conkey)) - LEFT JOIN ( SELECT s.connamespace, - s.conrelid, - s.conkey, - (regexp_match(s.consrc, $$srid\(\w+\)\s*=\s*(\d+)$$, 'i'))[1]::integer As srid - FROM (SELECT connamespace, conrelid, conkey, pg_get_constraintdef(oid) As consrc - FROM pg_constraint) AS s - WHERE s.consrc ~* $$srid\(\w+\)\s*=\s*\d+$$::text - -) sr ON sr.connamespace = n.oid AND sr.conrelid = c.oid AND (a.attnum = ANY (sr.conkey)) + LEFT JOIN ( + SELECT s.connamespace, + s.conrelid, + s.conkey, + (regexp_match(s.consrc, $$geometrytype\(\w+\)\s*=\s*'(\w+)'$$, 'i'))[1]::text AS type + FROM constraint_defs AS s + WHERE s.consrc ~* $$geometrytype\(\w+\)\s*=\s*'\w+'$$::text + ) st ON st.connamespace = n.oid AND st.conrelid = c.oid AND (a.attnum = ANY (st.conkey)) + LEFT JOIN ( + SELECT s.connamespace, + s.conrelid, + s.conkey, + (regexp_match(s.consrc, $$ndims\(\w+\)\s*=\s*(\d+)$$, 'i'))[1]::integer AS ndims + FROM constraint_defs AS s + WHERE s.consrc ~* $$ndims\(\w+\)\s*=\s*\d+$$::text + ) sn ON sn.connamespace = n.oid AND sn.conrelid = c.oid AND (a.attnum = ANY (sn.conkey)) + LEFT JOIN ( + SELECT s.connamespace, + s.conrelid, + s.conkey, + (regexp_match(s.consrc, $$srid\(\w+\)\s*=\s*(\d+)$$, 'i'))[1]::integer As srid + FROM constraint_defs AS s + WHERE s.consrc ~* $$srid\(\w+\)\s*=\s*\d+$$::text + ) sr ON sr.connamespace = n.oid AND sr.conrelid = c.oid AND (a.attnum = ANY (sr.conkey)) WHERE (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'm'::"char", 'f'::"char", 'p'::"char"])) AND NOT c.relname = 'raster_columns'::name AND t.typname = 'geometry'::name AND NOT pg_is_other_temp_schema(c.relnamespace) AND has_table_privilege(c.oid, 'SELECT'::text); diff --git a/regress/core/tickets.sql b/regress/core/tickets.sql index 6fd77a19d..e24bcef05 100644 --- a/regress/core/tickets.sql +++ b/regress/core/tickets.sql @@ -1619,6 +1619,19 @@ SELECT f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, t ORDER BY f_table_name, f_geometry_column; DROP TABLE IF EXISTS test5829, test5978; +-- ------------------------------------------------------------------------------------- +-- #4828, geometry_columns should ignore pending NOT VALID SRID checks +CREATE TABLE test4828 ( + geom geometry +); +ALTER TABLE test4828 + ADD CONSTRAINT test4828_srid CHECK (ST_SRID(geom) = 4326) NOT VALID; +SELECT '#4828', srid + FROM geometry_columns + WHERE f_table_name = 'test4828' + AND f_geometry_column = 'geom'; +DROP TABLE IF EXISTS test4828; + -- ------------------------------------------------------------------------------------- -- #5987, ST_GeometryN broken on unitary geoms CREATE TABLE test5987 (geom geometry(Geometry,4326)); diff --git a/regress/core/tickets_expected b/regress/core/tickets_expected index c39981696..6637f2d89 100644 --- a/regress/core/tickets_expected +++ b/regress/core/tickets_expected @@ -492,6 +492,7 @@ public.test5978.geometry SRID:4326 TYPE:POINT DIMS:2 public|test5829|geom|2|4326|GEOMETRY public|test5978|geometry|2|4326|POINT public|test5978|shape|2|4326|POINT +#4828|4326 #5987|LINESTRING(20 20,20.1 20,20.2 19.9)|LINESTRING(20 20,20.1 20,20.2 19.9) #5962|MULTIPOINT((1 1),(3 4))|POINT(1 1) #5754|LINESTRING(0 0,1 1,2 0,3 1,4 0)|LINESTRING(0 0,1 1,2 0,3 1,4 0)|POLYGON((0 0,1 0,1 1,0 1,0 0))|POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1)) ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + postgis/postgis.sql.in | 58 ++++++++++++++++++++++++------------------- regress/core/tickets.sql | 13 ++++++++++ regress/core/tickets_expected | 1 + 4 files changed, 47 insertions(+), 26 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 09:21:48 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 16:21:48 -0000 Subject: [PostGIS] #4828: geometry_columns view breaks when SRID constraint marked NOT VALID In-Reply-To: <045.d1b7eb1a0dac4d183bbf631037dbaaff@osgeo.org> References: <045.d1b7eb1a0dac4d183bbf631037dbaaff@osgeo.org> Message-ID: <060.47ddf5e4bdf509abe29f5cc96ef9e961@osgeo.org> #4828: geometry_columns view breaks when SRID constraint marked NOT VALID ----------------------+-------------------------- Reporter: til | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: Component: postgis | Version: 2.5.x -- EOL Resolution: fixed | Keywords: ----------------------+-------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"d0cfdb0e97f065e1ecbdb70b0de908760b5858ab/git" d0cfdb0e/git]: {{{#!CommitTicketReference repository="git" revision="d0cfdb0e97f065e1ecbdb70b0de908760b5858ab" geometry_columns handles NOT VALID SRID checks without errors Closes #4828 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 09:35:50 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 09:35:50 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-167-g8c0a1555e Message-ID: <20251030163550.8B26E18D36C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 8c0a1555e2d7d4234419b3ddb6af7ecaeedc2f82 (commit) from d0cfdb0e97f065e1ecbdb70b0de908760b5858ab (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8c0a1555e2d7d4234419b3ddb6af7ecaeedc2f82 Author: Darafei Praliaskouski Date: Thu Oct 30 20:35:26 2025 +0400 [doc] Keep the program listings verbatim Closes #5645 diff --git a/NEWS b/NEWS index d4e6baf0c..eb5464cde 100644 --- a/NEWS +++ b/NEWS @@ -23,7 +23,8 @@ xxxx/xx/xx - #5959, Prevent histogram target overflow when analysing massive tables (Darafei Praliaskouski) - #4828, geometry_columns handles NOT VALID SRID checks without errors (Darafei Praliaskouski) - + - #5645, Docs: keep code operators ("=>") intact in translated manuals + by enforcing verbatim CSS (Darafei Praliaskouski) PostGIS 3.6.0 2025/09/01 diff --git a/doc/html/style.css b/doc/html/style.css index 4be89d30f..627de8884 100644 --- a/doc/html/style.css +++ b/doc/html/style.css @@ -149,6 +149,47 @@ pre, .literallayout { border-radius: 1em; } +/* + * Fix #5645: localized manuals apply aggressive word breaking to code tokens, + * splitting operators like "=>" into "= >". Force verbatim behaviour for + * program listings and inline code regardless of :lang overrides. + */ +pre, +code, +kbd, +samp, +.programlisting, +.screen, +.literallayout { + white-space: pre; + word-break: normal; + overflow-wrap: normal; + hyphens: none; + line-break: auto; +} + +pre, +.programlisting, +.screen, +.literallayout { + overflow: auto; +} + +:lang(zh) pre, +:lang(zh-CN) pre, +:lang(zh-Hans) pre, +:lang(ja) pre, +:lang(ko) pre, +:lang(zh) code, +:lang(zh-CN) code, +:lang(zh-Hans) code, +:lang(ja) code, +:lang(ko) code { + white-space: pre !important; + word-break: normal !important; + overflow-wrap: normal !important; +} + div.note { font-size: 0.9em; border-color: #dd5; ----------------------------------------------------------------------- Summary of changes: NEWS | 3 ++- doc/html/style.css | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 09:35:53 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 16:35:53 -0000 Subject: [PostGIS] #5645: Code blocks => being replaced with = > In-Reply-To: <046.5c60fc09a21dfcca3d31b22f3bce2a43@osgeo.org> References: <046.5c60fc09a21dfcca3d31b22f3bce2a43@osgeo.org> Message-ID: <061.52b259e9fb1b02ad27d6cb2b3cbeccce@osgeo.org> #5645: Code blocks => being replaced with = > ----------------------------+--------------------------- Reporter: robe | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: documentation | Version: 3.4.x Resolution: fixed | Keywords: ----------------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"8c0a1555e2d7d4234419b3ddb6af7ecaeedc2f82/git" 8c0a1555/git]: {{{#!CommitTicketReference repository="git" revision="8c0a1555e2d7d4234419b3ddb6af7ecaeedc2f82" [doc] Keep the program listings verbatim Closes #5645 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 09:48:51 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 09:48:51 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-168-g5f1330931 Message-ID: <20251030164852.1EB7C18E3EB@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 5f13309312fb79142c5d870828e17455c6f8f93d (commit) from 8c0a1555e2d7d4234419b3ddb6af7ecaeedc2f82 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5f13309312fb79142c5d870828e17455c6f8f93d Author: Darafei Praliaskouski Date: Thu Oct 30 20:48:35 2025 +0400 Clarify the scope of several Function Reference categories Closes #4332 diff --git a/NEWS b/NEWS index eb5464cde..06b41d6f1 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,8 @@ xxxx/xx/xx - #5702, Allow the compiler to detect the parallelism -flto=auto (Darafei Praliaskouski) - #4798, ST_AsGeoJSON warns about duplicate property keys (Darafei Praliaskouski) - #5950, Document POSTGIS_REGRESS_DB_OWNER for sandboxed regression roles (Darafei Praliaskouski) + - #4332, Clarify the scope of several Function Reference categories (Darafei Praliaskouski) + * Bug Fixes * diff --git a/doc/reference_accessor.xml b/doc/reference_accessor.xml index b75f26317..4cbcd8f74 100644 --- a/doc/reference_accessor.xml +++ b/doc/reference_accessor.xml @@ -1,6 +1,13 @@
    - Geometry Accessors + Geometry Accessors + + These functions expose structural information about an existing geometry + without changing it. They provide access to metadata such as geometry + type, dimensionality, or coordinate components so that spatial + expressions can interrogate complex objects in a controlled way. + + diff --git a/doc/reference_constructor.xml b/doc/reference_constructor.xml index e849926c5..324424a7b 100644 --- a/doc/reference_constructor.xml +++ b/doc/reference_constructor.xml @@ -1,6 +1,12 @@
    - Geometry Constructors + Geometry Constructors + + These functions instantiate new geometry or geography values. They + assemble primitives, coordinate sequences, or existing geometries into + well-formed spatial objects that can participate in subsequent analysis. + + diff --git a/doc/reference_exception.xml b/doc/reference_exception.xml index 51c3301b7..79155219a 100644 --- a/doc/reference_exception.xml +++ b/doc/reference_exception.xml @@ -1,8 +1,12 @@
    - Exceptional Functions - These functions are rarely used functions that should only be used if your data is corrupted in someway. They are used for troubleshooting corruption - and also fixing things that should under normal circumstances, never happen. + Exceptional Functions + + These routines are reserved for diagnosing and repairing data + corruption. They provide last-resort maintenance operations that are not + required during normal spatial workflows. + + diff --git a/doc/reference_lrs.xml b/doc/reference_lrs.xml index 46ceb15ed..570d4daea 100644 --- a/doc/reference_lrs.xml +++ b/doc/reference_lrs.xml @@ -1,6 +1,13 @@
    - Linear Referencing + Linear Referencing + + These functions measure and locate events along linear features. + They support the classic linear referencing workflow of expressing + positions as fractions or measures along routes and of projecting + those measures back into spatial coordinates. + + diff --git a/doc/reference_operator.xml b/doc/reference_operator.xml index 00e219685..8f1bf8655 100644 --- a/doc/reference_operator.xml +++ b/doc/reference_operator.xml @@ -1,6 +1,15 @@
    - Operators + Operators + + These entries document the spatial operators defined by PostGIS. + Operators complement the function catalogue by supplying concise + symbolic predicates for bounding-box interactions and spatial + relationships. Their semantics follow the same geometric rules as the + corresponding functions but are optimised for use in SQL expressions + and index-supported filtering. + +
    Bounding Box Operators ----------------------------------------------------------------------- Summary of changes: NEWS | 2 ++ doc/reference_accessor.xml | 9 ++++++++- doc/reference_constructor.xml | 8 +++++++- doc/reference_exception.xml | 10 +++++++--- doc/reference_lrs.xml | 9 ++++++++- doc/reference_operator.xml | 11 ++++++++++- 6 files changed, 42 insertions(+), 7 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 09:48:53 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 16:48:53 -0000 Subject: [PostGIS] #4332: Improve Doc Function Reference categories In-Reply-To: <048.aa6cb8cd91a6294995f196cedf2c1861@osgeo.org> References: <048.aa6cb8cd91a6294995f196cedf2c1861@osgeo.org> Message-ID: <063.7171959601848e88e370a591e42d77ee@osgeo.org> #4332: Improve Doc Function Reference categories ----------------------------+----------------------------- Reporter: mdavis | Owner: mdavis Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: documentation | Version: master Resolution: fixed | Keywords: ----------------------------+----------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: assigned => closed Comment: In [changeset:"5f13309312fb79142c5d870828e17455c6f8f93d/git" 5f13309/git]: {{{#!CommitTicketReference repository="git" revision="5f13309312fb79142c5d870828e17455c6f8f93d" Clarify the scope of several Function Reference categories Closes #4332 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 10:21:17 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 10:21:17 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-169-gcf5994644 Message-ID: <20251030172117.5A2AC18F962@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via cf5994644e5233da594c17bc3b4fd49a780e72ff (commit) from 5f13309312fb79142c5d870828e17455c6f8f93d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cf5994644e5233da594c17bc3b4fd49a780e72ff Author: Darafei Praliaskouski Date: Thu Oct 30 21:21:02 2025 +0400 [raster] ST_DumpAsPolygons honours PostgreSQL interrupts Closes #4222 diff --git a/NEWS b/NEWS index 06b41d6f1..0c485943c 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ xxxx/xx/xx - #4798, ST_AsGeoJSON warns about duplicate property keys (Darafei Praliaskouski) - #5950, Document POSTGIS_REGRESS_DB_OWNER for sandboxed regression roles (Darafei Praliaskouski) - #4332, Clarify the scope of several Function Reference categories (Darafei Praliaskouski) + - #4222, [raster] ST_DumpAsPolygons honours PostgreSQL interrupts (Darafei Praliaskouski) * Bug Fixes * diff --git a/doc/reference_raster.xml b/doc/reference_raster.xml index cd7ab9b8f..10559043e 100644 --- a/doc/reference_raster.xml +++ b/doc/reference_raster.xml @@ -14169,6 +14169,7 @@ FROM (SELECT ST_SetRotation(rast, 0.1, 0.1) As rast can be used to expand a single raster into multiple POLYGONS/MULTIPOLYGONS. Changed 3.3.0, validation and fixing is disabled to improve performance. May result invalid geometries. + Changed 3.7.0, the polygonization honours PostgreSQL interrupts so cancellations and statement timeouts halt processing promptly. Availability: Requires GDAL 1.7 or higher. If there is a no data value set for a band, pixels with that value will not be returned except in the case of exclude_nodata_value=false. If you only care about count of pixels with a given value in a raster, it is faster to use . diff --git a/raster/rt_core/librtcore.h b/raster/rt_core/librtcore.h index b4395ba2b..ded95f1c9 100644 --- a/raster/rt_core/librtcore.h +++ b/raster/rt_core/librtcore.h @@ -2373,6 +2373,9 @@ rt_util_gdal_register_all(int force_register_all); int rt_util_gdal_driver_registered(const char *drv); +int +rt_util_gdal_progress_func(double dfComplete, const char *pszMessage, void *pProgressArg); + /* wrapper for GDALOpen and GDALOpenShared */ diff --git a/raster/rt_core/rt_gdal.c b/raster/rt_core/rt_gdal.c index 748a8ff12..ff01c1d66 100644 --- a/raster/rt_core/rt_gdal.c +++ b/raster/rt_core/rt_gdal.c @@ -4,6 +4,7 @@ * http://trac.osgeo.org/postgis/wiki/WKTRaster * * Copyright (C) 2021 Paul Ramsey + * Copyright (C) 2025 Darafei Praliaskouski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -55,10 +56,14 @@ typedef struct /* GDAL progress callback for interrupt handling */ /* ---------------------------------------------------------------- */ -static int rt_util_gdal_progress_func( - double dfComplete, - const char *pszMessage, - void *pProgressArg) +/* + * WHY: We surface a single callback so every GDAL routine invoked from the + * raster core can honour PostgreSQL cancellations consistently. Returning + * FALSE forces the GDAL algorithm to unwind immediately when liblwgeom has + * recorded an interrupt request (#4222). + */ +int +rt_util_gdal_progress_func(double dfComplete, const char *pszMessage, void *pProgressArg) { (void)dfComplete; (void)pszMessage; @@ -66,7 +71,7 @@ static int rt_util_gdal_progress_func( if (_lwgeom_interrupt_requested) { // rtwarn("%s interrupted at %g", (const char*)pProgressArg, dfComplete); - _lwgeom_interrupt_requested = 0; + lwgeom_cancel_interrupt(); return FALSE; } else diff --git a/raster/rt_core/rt_geometry.c b/raster/rt_core/rt_geometry.c index 7c997d44f..2c126f4b8 100644 --- a/raster/rt_core/rt_geometry.c +++ b/raster/rt_core/rt_geometry.c @@ -10,6 +10,7 @@ * Copyright (C) 2009-2011 Pierre Racine * Copyright (C) 2009-2011 Mateusz Loskot * Copyright (C) 2008-2009 Sandro Santilli + * Copyright (C) 2025 Darafei Praliaskouski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1136,8 +1137,12 @@ rt_raster_gdal_polygonize( return NULL; } - /* We don't need a raster mask band. Each band has a nodata value. */ - cplerr = GDALFPolygonize(gdal_band, NULL, hLayer, iPixVal, NULL, NULL, NULL); + /* + * Why: We pass the shared interrupt-aware progress callback so GDAL can + * unwind promptly when PostgreSQL requests cancellation (#4222). + */ + cplerr = GDALFPolygonize( + gdal_band, NULL, hLayer, iPixVal, NULL, rt_util_gdal_progress_func, (void *)"GDALFPolygonize"); if (cplerr != CE_None) { rterror("rt_raster_gdal_polygonize: Could not polygonize GDAL band"); diff --git a/raster/test/cunit/cu_gdal.c b/raster/test/cunit/cu_gdal.c index 421bf93f3..aa53fe268 100644 --- a/raster/test/cunit/cu_gdal.c +++ b/raster/test/cunit/cu_gdal.c @@ -4,6 +4,7 @@ * * Copyright (C) 2012 Regents of the University of California * + * Copyright (C) 2025 Darafei Praliaskouski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -277,6 +278,29 @@ static void test_gdal_polygonize() { cu_free_raster(rt); } +static void +test_gdal_polygonize_interrupt(void) +{ + rt_raster rt; + int nPols = 0; + rt_geomval gv = NULL; + + rt = fillRasterToPolygonize(0, 0.0); + CU_ASSERT(rt != NULL); + + /* Why: confirm that the GDAL callback honours liblwgeom interrupts (#4222). */ + lwgeom_request_interrupt(); + gv = rt_raster_gdal_polygonize(rt, 0, TRUE, &nPols); + lwgeom_cancel_interrupt(); + + CU_ASSERT_PTR_NULL(gv); + CU_ASSERT_EQUAL(nPols, 0); + + if (gv) + rtdealloc(gv); + cu_free_raster(rt); +} + static void test_raster_to_gdal() { rt_pixtype pixtype = PT_64BF; rt_raster raster = NULL; @@ -608,6 +632,7 @@ void gdal_suite_setup(void) PG_ADD_TEST(suite, test_gdal_drivers); PG_ADD_TEST(suite, test_gdal_rasterize); PG_ADD_TEST(suite, test_gdal_polygonize); + PG_ADD_TEST(suite, test_gdal_polygonize_interrupt); PG_ADD_TEST(suite, test_raster_to_gdal); PG_ADD_TEST(suite, test_gdal_to_raster); PG_ADD_TEST(suite, test_gdal_warp); ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/reference_raster.xml | 1 + raster/rt_core/librtcore.h | 3 +++ raster/rt_core/rt_gdal.c | 15 ++++++++++----- raster/rt_core/rt_geometry.c | 9 +++++++-- raster/test/cunit/cu_gdal.c | 25 +++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 7 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 10:21:19 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 17:21:19 -0000 Subject: [PostGIS] #4222: ST_DumpAsPolygons not interruptible In-Reply-To: <048.6083b4d7f69db9112d1c01b5cfb6aed4@osgeo.org> References: <048.6083b4d7f69db9112d1c01b5cfb6aed4@osgeo.org> Message-ID: <063.2a78a3450948b48a3f200b8c5b7bb18d@osgeo.org> #4222: ST_DumpAsPolygons not interruptible ----------------------+--------------------------- Reporter: komzpa | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 2.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"cf5994644e5233da594c17bc3b4fd49a780e72ff/git" cf599464/git]: {{{#!CommitTicketReference repository="git" revision="cf5994644e5233da594c17bc3b4fd49a780e72ff" [raster] ST_DumpAsPolygons honours PostgreSQL interrupts Closes #4222 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 10:31:18 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 10:31:18 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-170-g7dc8c00b7 Message-ID: <20251030173118.7E08E190B39@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 7dc8c00b77b76f584ef5746b97a54b72a7d1caee (commit) from cf5994644e5233da594c17bc3b4fd49a780e72ff (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7dc8c00b77b76f584ef5746b97a54b72a7d1caee Author: Darafei Praliaskouski Date: Thu Oct 30 21:31:00 2025 +0400 [doc][topology] Meaning of topology.next_left_edge and topology.next_right_edge links Closes #5109 diff --git a/NEWS b/NEWS index 0c485943c..488f86f81 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,7 @@ xxxx/xx/xx - #5950, Document POSTGIS_REGRESS_DB_OWNER for sandboxed regression roles (Darafei Praliaskouski) - #4332, Clarify the scope of several Function Reference categories (Darafei Praliaskouski) - #4222, [raster] ST_DumpAsPolygons honours PostgreSQL interrupts (Darafei Praliaskouski) + - #5109, Document the meaning of topology.next_left_edge and topology.next_right_edge links (Darafei Praliaskouski) * Bug Fixes * diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml index 01f07538d..a3846708b 100644 --- a/doc/extras_topology.xml +++ b/doc/extras_topology.xml @@ -17,9 +17,27 @@ how is it used, and various FOSS4G tools that support it in PostGIS Topology Wiki All functions and tables associated with this module are installed in a schema called topology. Functions that are defined in SQL/MM standard are prefixed with ST_ and functions specific to PostGIS are not prefixed. - Topology support is build by default starting with PostGIS 2.0, and can be disabled specifying --without-topology configure option at build time as described in + Topology support is build by default starting with PostGIS 2.0, and can be disabled specifying --without-topology configure option at build time as described in -
    +
    + Topology Primitive Tables + The core primitives of any topology are stored in the edge_data, node, and face tables that live in the schema created by . Each row of edge_data represents an oriented edge: it records a directed curve from start_node to end_node together with the identifier of the face encountered on the left of that direction (left_face) and the face encountered on the right (right_face). The same geometric segment may therefore appear twice?once for each orientation?when it belongs to two faces. + The next_left_edge and next_right_edge columns complete this orientation information by encoding how to keep walking around a face. They store signed integers whose absolute value is the identifier of the next oriented edge and whose sign determines whether the stored orientation has to be followed as-is or reversed when traversing. Formally, the following rules hold for every edge e: + + + abs(next_left_edge) is the identifier of the edge reached by continuing around the face that lies to the left of e. If the value is positive the walk continues from the end node of e along the stored orientation of the referenced edge; if it is negative the referenced edge must be followed backwards so that the shared face remains on the walker?s left. + + + abs(next_right_edge) analogously follows the boundary of the face located on the right of e. A positive value means that the next edge is taken with its recorded orientation starting from the end node of e, whereas a negative value instructs to traverse the referenced edge in reverse, starting from its end node, so that the right-hand face is preserved. + + + A zero value indicates that the edge is dangling on the corresponding side (for example an isolated edge whose incident face is the universal face 0). The abs_next_left_edge and abs_next_right_edge columns exposed by the edge view are convenience projections of these absolute values. + + + This representation is a variant of a doubly connected edge list and is exploited by many topology routines. Functions such as and rely on it to reconstruct face boundaries and to diagnose inconsistencies?hence the ?invalid next_left_edge? and ?invalid next_right_edge? diagnostics reported during validation. Constructors like initialise the next_* attributes with trivial self references, while editing routines including and update the links as edges are inserted or removed. Other bulk operations (for example ) may intentionally leave the fields unset, which is why the documentation flags their behaviour explicitly. +
    + +
    Topology Types This section lists the PostgreSQL data types installed by PostGIS Topology. Note we describe the casting behavior of these which is very diff --git a/topology/test/regress/nextedge_signs.sql b/topology/test/regress/nextedge_signs.sql new file mode 100644 index 000000000..1c315086f --- /dev/null +++ b/topology/test/regress/nextedge_signs.sql @@ -0,0 +1,15 @@ +set client_min_messages to ERROR; + +SELECT topology.CreateTopology('signed_edges', 0) > 0; + +SELECT 'E1', topology.AddEdge('signed_edges', 'LINESTRING(0 0, 1 0)'); +SELECT 'E2', topology.AddEdge('signed_edges', 'LINESTRING(1 0, 1 1)'); + +SELECT 'sign-consistency', bool_and(next_left_edge = -next_right_edge) + FROM signed_edges.edge; + +SELECT 'absolute-id', + array_agg(edge_id::text || ':' || abs(next_left_edge)::text ORDER BY edge_id) + FROM signed_edges.edge; + +SELECT topology.DropTopology('signed_edges'); diff --git a/topology/test/regress/nextedge_signs_expected b/topology/test/regress/nextedge_signs_expected new file mode 100644 index 000000000..fd8f26bc5 --- /dev/null +++ b/topology/test/regress/nextedge_signs_expected @@ -0,0 +1,6 @@ +t +E1|1 +E2|2 +sign-consistency|t +absolute-id|{1:1,2:2} +Topology 'signed_edges' dropped diff --git a/topology/test/tests.mk b/topology/test/tests.mk index aa1a67526..383e38ccf 100644 --- a/topology/test/tests.mk +++ b/topology/test/tests.mk @@ -47,6 +47,7 @@ TESTS += \ $(top_srcdir)/topology/test/regress/legacy_query.sql \ $(top_srcdir)/topology/test/regress/legacy_validate.sql \ $(top_srcdir)/topology/test/regress/maketopologyprecise.sql \ + $(top_srcdir)/topology/test/regress/nextedge_signs.sql \ $(top_srcdir)/topology/test/regress/polygonize.sql \ $(top_srcdir)/topology/test/regress/populate_topology_layer.sql \ $(top_srcdir)/topology/test/regress/removeunusedprimitives.sql \ ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + doc/extras_topology.xml | 24 +++++++++++++++++++++--- topology/test/regress/nextedge_signs.sql | 15 +++++++++++++++ topology/test/regress/nextedge_signs_expected | 6 ++++++ topology/test/tests.mk | 1 + 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 topology/test/regress/nextedge_signs.sql create mode 100644 topology/test/regress/nextedge_signs_expected hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 10:31:20 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 17:31:20 -0000 Subject: [PostGIS] #5109: Topology documentation uses unexplained concepts In-Reply-To: <055.1d2c11fdc8a660a13844a7f485220acc@osgeo.org> References: <055.1d2c11fdc8a660a13844a7f485220acc@osgeo.org> Message-ID: <070.a04256240f80664351bad1a5ad81de1a@osgeo.org> #5109: Topology documentation uses unexplained concepts ----------------------------+--------------------------- Reporter: asgerpetersen | Owner: strk Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: documentation | Version: 3.2.x Resolution: fixed | Keywords: ----------------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"7dc8c00b77b76f584ef5746b97a54b72a7d1caee/git" 7dc8c00b/git]: {{{#!CommitTicketReference repository="git" revision="7dc8c00b77b76f584ef5746b97a54b72a7d1caee" [doc][topology] Meaning of topology.next_left_edge and topology.next_right_edge links Closes #5109 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 10:37:59 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 17:37:59 -0000 Subject: [PostGIS] #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) In-Reply-To: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> References: <046.6b8fbad0b2fd11a8f0ef82794c7cad62@osgeo.org> Message-ID: <061.455be4ca79cb72e0af94785e7b466fce@osgeo.org> #6011: st_intersects segfault on ubuntu jammy (postgis 3.6.0, postgresql 18.0) -----------------------------+--------------------------- Reporter: Christoph Berg | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.1 Component: postgis | Version: 3.5.x Resolution: invalid | Keywords: -----------------------------+--------------------------- Comment (by Christoph Berg): Fwiw, I had actually not looked at the geometries involved at all yet. On thing that stands out is the EMPTY in the MULTIPOINT set. Removing that removes the crash. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Oct 30 11:27:24 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 18:27:24 -0000 Subject: [PostGIS] #2181: ST_Buffer returning multipolygon with linestring/polygon input In-Reply-To: <050.1c3ec6a9dcb0a0b8df3ce00ff834a605@osgeo.org> References: <050.1c3ec6a9dcb0a0b8df3ce00ff834a605@osgeo.org> Message-ID: <065.f60590498bc04c209e9457a6498ae913@osgeo.org> #2181: ST_Buffer returning multipolygon with linestring/polygon input -----------------------+---------------------------------------------- Reporter: mcastrog | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS GEOS Component: postgis | Version: 2.0.x Resolution: | Keywords: Buffer, linestring, multipolygon -----------------------+---------------------------------------------- Comment (by komzpa): Filed to FEOS as https://github.com/libgeos/geos/issues/1321 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Oct 30 11:44:48 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 11:44:48 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-171-gafc7eeac4 Message-ID: <20251030184448.A77EE193F1B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via afc7eeac415514ddf0ba5cfe63d42cca7716cf6b (commit) from 7dc8c00b77b76f584ef5746b97a54b72a7d1caee (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit afc7eeac415514ddf0ba5cfe63d42cca7716cf6b Author: Darafei Praliaskouski Date: Thu Oct 30 22:44:10 2025 +0400 [doc] Clean up mentions of legacy Postgres versions diff --git a/doc/administration.xml b/doc/administration.xml index bd99d0dee..e7cf63d1b 100644 --- a/doc/administration.xml +++ b/doc/administration.xml @@ -13,8 +13,8 @@ below how to properly configure it. - As of PostGIS 2.1.3, out-of-db rasters and all raster drivers are disabled by default. In order to re-enable these, you need to set the following environment variables - POSTGIS_GDAL_ENABLED_DRIVERS and POSTGIS_ENABLE_OUTDB_RASTERS in the server environment. For PostGIS 2.2, you can use the more cross-platform approach of setting the corresponding . + Out-of-db rasters and all raster drivers are disabled by default. In order to re-enable these, you need to set the following environment variables + POSTGIS_GDAL_ENABLED_DRIVERS and POSTGIS_ENABLE_OUTDB_RASTERS in the server environment. You can also use the more cross-platform approach of setting the corresponding . If you want to enable offline raster: POSTGIS_ENABLE_OUTDB_RASTERS=1 @@ -27,7 +27,7 @@ If you are on windows, do not quote the driver list Setting environment variables varies depending on OS. For PostgreSQL installed on Ubuntu or Debian via apt-postgresql, the preferred way is to - edit /etc/postgresql/10/main/environment where 10 refers to version of PostgreSQL and main refers to the cluster. + edit /etc/postgresql/MAJOR/CLUSTER/environment where the placeholders refer to the PostgreSQL major version and cluster name. On windows, if you are running as a service, you can set via System variables which for Windows 7 you can get to by right-clicking on Computer->Properties Advanced System Settings or in explorer navigating to Control Panel\All Control Panel Items\System. Then clicking Advanced System Settings ->Advanced->Environment Variables and adding new system variables. @@ -42,8 +42,8 @@ Spatially enable database using EXTENSION - If you are using PostgreSQL 9.1+ and have compiled and installed the extensions/postgis modules, you - can turn a database into a spatial one using the EXTENSION mechanism. + If you have compiled and installed the extensions/postgis modules, you + can turn a database into a spatial one using the EXTENSION mechanism. diff --git a/doc/database_tuning.xml b/doc/database_tuning.xml index 6a3e4ff93..72f55f4f2 100644 --- a/doc/database_tuning.xml +++ b/doc/database_tuning.xml @@ -8,7 +8,7 @@ For general details about optimizing PostgreSQL, refer to Tuning your PostgreSQL Server. - For PostgreSQL 9.4+ configuration can be set at the server level without touching postgresql.conf or postgresql.auto.conf + PostgreSQL configuration can be set at the server level without touching postgresql.conf or postgresql.auto.conf by using the ALTER SYSTEM command. ALTER SYSTEM SET work_mem = '256MB'; -- this forces non-startup configs to take effect for new connections @@ -38,9 +38,8 @@ SHOW work_mem; - This is generally used for table partitioning. The default for this is set to "partition" which is ideal for PostgreSQL 8.4 and above since - it will force the planner to only analyze tables for constraint consideration if they are in an inherited hierarchy - and not pay the planner penalty otherwise. + This is generally used for table partitioning. The default of "partition" forces the planner to only analyze tables for constraint consideration if they are in an inherited hierarchy + and avoids paying the planner penalty otherwise. @@ -52,7 +51,7 @@ SHOW work_mem; - Default: ~128MB in PostgreSQL 9.6 + Default: ~128MB @@ -65,8 +64,8 @@ SHOW work_mem; max_worker_processes - This setting is only available for PostgreSQL 9.4+. For PostgreSQL 9.6+ this setting has additional importance in that it controls the - max number of processes you can have for parallel queries. + controls the maximum number of background processes available to the server and therefore + also bounds how many workers can participate in parallel queries. @@ -146,8 +145,8 @@ SHOW work_mem; max_parallel_workers_per_gather - This setting is only available for PostgreSQL 9.6+ and will only affect PostGIS 2.3+, since only PostGIS 2.3+ supports parallel queries. - If set to higher than 0, then some queries such as those involving relation functions like ST_Intersects can use multiple processes and can run + Parallel query support in modern PostgreSQL and PostGIS uses this setting to decide how many workers + a plan may request. If set to higher than 0, then some queries such as those involving relation functions like ST_Intersects can use multiple processes and can run more than twice as fast when doing so. If you have a lot of processors to spare, you should change the value of this to as many processors as you have. Also make sure to bump up max_worker_processes to at least as high as this number. diff --git a/doc/installation.xml b/doc/installation.xml index de6ec932c..da80070c7 100644 --- a/doc/installation.xml +++ b/doc/installation.xml @@ -613,9 +613,9 @@ sh autogen.sh
    Building PostGIS Extensions and Deploying them - - The PostGIS extensions are built and installed automatically if you are using PostgreSQL 9.1+. - + + The PostGIS extensions are built and installed automatically when PostgreSQL extension support is available. + If you are building from source repository, you need to build the function descriptions first. These get built if you have docbook installed. You can also manually build with the statement: diff --git a/doc/reference_constructor.xml b/doc/reference_constructor.xml index 324424a7b..93d2a06cc 100644 --- a/doc/reference_constructor.xml +++ b/doc/reference_constructor.xml @@ -343,7 +343,7 @@ SELECT gps.track_id, ST_MakeLine(gps.geom ORDER BY gps_time) As geom FROM gps_points As gps GROUP BY track_id; -Prior to PostgreSQL 9, ordering in a subquery can be used. +When ordering within the aggregate is not possible, ordering in a subquery can be used. However, sometimes the query plan may not respect the order of the subquery. SELECT gps.track_id, ST_MakeLine(gps.geom) As geom diff --git a/doc/reference_management.xml b/doc/reference_management.xml index 7c46c2ac7..021cebbd7 100644 --- a/doc/reference_management.xml +++ b/doc/reference_management.xml @@ -267,8 +267,8 @@ SELECT f_geometry_column As col_name, type, srid, coord_dimension As ndims ------------------------------------------------------ my_schema.my_spatial_table.geom effectively removed. --- In PostGIS 2.0+ the above is also equivalent to the standard --- the standard alter table. Both will deregister from geometry_columns +-- The above is also equivalent to the standard +-- ALTER TABLE command. Both will deregister from geometry_columns ALTER TABLE my_schema.my_spatial_table DROP column geom; diff --git a/doc/reference_operator.xml b/doc/reference_operator.xml index 8f1bf8655..405281cb8 100644 --- a/doc/reference_operator.xml +++ b/doc/reference_operator.xml @@ -144,7 +144,7 @@ FROM ( VALUES This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -212,7 +212,7 @@ SELECT ST_Point(1,1) && ST_MakeBox2D(ST_Point(0,0), ST_Point(2,2)) AS overlaps; This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -280,7 +280,7 @@ SELECT ST_MakeBox2D(ST_Point(0,0), ST_Point(2,2)) && ST_Point(1,1) AS overlaps; This operator is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -438,7 +438,7 @@ FROM ( VALUES This operator is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; &T_support; @@ -502,7 +502,7 @@ SELECT ST_MakePoint(1,1,1) &&& ST_3DMakeBox(ST_MakePoint(0,0,0), ST_MakePoint(2, This operator is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; &T_support; @@ -566,7 +566,7 @@ SELECT ST_3DMakeBox(ST_MakePoint(0,0,0), ST_MakePoint(2,2,2)) &&& ST_MakePoint(1 This operator is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; &T_support; @@ -1258,7 +1258,7 @@ FROM This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -1324,7 +1324,7 @@ FROM This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -1390,7 +1390,7 @@ FROM This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -1664,7 +1664,7 @@ FROM This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -1730,7 +1730,7 @@ FROM This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -1796,7 +1796,7 @@ FROM This operand is intended to be used internally by BRIN indexes, more than by users. - Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. Requires PostgreSQL 9.5+. + Availability: 2.3.0 support for Block Range INdexes (BRIN) was introduced. &curve_support; &P_support; @@ -1952,21 +1952,19 @@ Returns the 2D distance between A and B. Description -The <-> operator returns the 2D distance between + The <-> operator returns the 2D distance between two geometries. Used in the "ORDER BY" clause provides index-assisted -nearest-neighbor result sets. For PostgreSQL below 9.5 only gives -centroid distance of bounding boxes and for PostgreSQL 9.5+, does true -KNN distance search giving true distance between geometries, and distance -sphere for geographies. +nearest-neighbor result sets with true KNN distance search for geometries, +and distance on the sphere for geographies. This operand will make use of 2D GiST indexes that may be available on the geometries. It is different from other operators that use spatial indexes in that the spatial index is only used when the operator is in the ORDER BY clause. Index only kicks in if one of the geometries is a constant (not in a subquery/cte). e.g. 'SRID=3005;POINT(1011102 450541)'::geometry instead of a.geom Refer to PostGIS workshop: Nearest-Neighbor Searching for a detailed example. - Enhanced: 2.2.0 -- True KNN ("K nearest neighbor") behavior for geometry and geography for PostgreSQL 9.5+. Note for geography KNN is based on sphere rather than spheroid. For PostgreSQL 9.4 and below, geography support is new but only supports centroid box. - Changed: 2.2.0 -- For PostgreSQL 9.5 users, old Hybrid syntax may be slower, so you'll want to get rid of that hack if you are running your code only on PostGIS 2.2+ 9.5+. See examples below. - Availability: 2.0.0 -- Weak KNN provides nearest neighbors based on geometry centroid distances instead of true distances. Exact results for points, inexact for all other types. Available for PostgreSQL 9.1+ + Enhanced: 2.2.0 -- True KNN ("K nearest neighbor") behavior for geometry and geography. Note for geography KNN is based on sphere rather than spheroid. + Changed: 2.2.0 -- Old hybrid-syntax workarounds may be slower once true KNN is available. See examples below. + Availability: 2.0.0 -- Weak KNN provides nearest neighbors based on geometry centroid distances instead of true distances. Exact results for points, inexact for all other types. @@ -2018,9 +2016,9 @@ ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry limit 10; If you run "EXPLAIN ANALYZE" on the two queries you would see a performance improvement for the second. - -For users running with PostgreSQL < 9.5, use a hybrid query to find the true nearest neighbors. First a CTE query using the index-assisted KNN, then an exact query to get correct ordering: - + +When a plan cannot produce exact distances directly, use a hybrid query to find the true nearest neighbors. First a CTE query using the index-assisted KNN, then an exact query to get correct ordering: + |=| operator returns the 3D distance between two trajectories (See ). This is the same as but as an operator it can be used for doing nearest neighbor searches using an N-dimensional -index (requires PostgreSQL 9.5.0 or higher). +index. This operand will make use of ND GiST indexes that may be available on the geometries. It is different from other operators that use spatial indexes in that the spatial index is only used when the operator is in the ORDER BY clause. Index only kicks in if one of the geometries is a constant (not in a subquery/cte). e.g. 'SRID=3005;LINESTRINGM(0 0 0,0 0 1)'::geometry instead of a.geom - Availability: 2.2.0. Index-supported only available for PostgreSQL 9.5+ + Availability: 2.2.0. @@ -2165,14 +2163,14 @@ Returns the 2D distance between A and B bounding boxes. Description - The <#> operator returns distance between two floating point bounding boxes, possibly reading them from a spatial index (PostgreSQL 9.1+ required). Useful for doing nearest neighbor approximate distance ordering. + The <#> operator returns distance between two floating point bounding boxes, possibly reading them from a spatial index. Useful for doing nearest neighbor approximate distance ordering. This operand will make use of any indexes that may be available on the geometries. It is different from other operators that use spatial indexes in that the spatial index is only used when the operator is in the ORDER BY clause. Index only kicks in if one of the geometries is a constant e.g. ORDER BY (ST_GeomFromText('POINT(1 2)') <#> geom) instead of g1.geom <#>. - Availability: 2.0.0 -- KNN only available for PostgreSQL 9.1+ + Availability: 2.0.0. @@ -2266,7 +2264,7 @@ subquery/cte). e.g. 'SRID=3005;POINT(1011102 450541)'::geometry instead of a.geom - Availability: 2.2.0 -- KNN only available for PostgreSQL 9.1+ + Availability: 2.2.0. diff --git a/doc/reference_output.xml b/doc/reference_output.xml index 7d08befec..795ff71a5 100644 --- a/doc/reference_output.xml +++ b/doc/reference_output.xml @@ -264,8 +264,8 @@ F000000000000000000000000000000000000000000000000'); - The default behavior in PostgreSQL 9.0 has been changed to output bytea in hex encoding. - If your GUI tools require the old behavior, then SET bytea_output='escape' in your database. + PostgreSQL outputs bytea values in hex encoding by default. + If your GUI tools require the old behavior, then SET bytea_output='escape' in your database. Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced. diff --git a/doc/reference_raster.xml b/doc/reference_raster.xml index 10559043e..79d82cec2 100644 --- a/doc/reference_raster.xml +++ b/doc/reference_raster.xml @@ -1612,8 +1612,7 @@ FROM ST_BandMetadata( -- Aggregate the 1st band of a table of like rasters into a single raster -- with as many bands as there are test_types and as many rows (new rasters) as there are mice --- NOTE: The ORDER BY test_type is only supported in PostgreSQL 9.0+ --- for 8.4 and below it usually works to order your data in a subselect (but not guaranteed) +-- NOTE: The ORDER BY test_type clause relies on aggregate ORDER BY support. -- The resulting raster will have a band for each test_type alphabetical by test_type -- For mouse lovers: No mice were harmed in this exercise SELECT @@ -4724,7 +4723,7 @@ SELECT ST_AsText(ST_PixelAsCentroid(rast, 1, 1)) FROM dummy_rast WHERE rid = 1; Examples - --LATERAL syntax requires PostgreSQL 9.3+ + -- Uses LATERAL syntax SELECT x, y, val, ST_AsText(geom) FROM (SELECT dp.* FROM dummy_rast, LATERAL ST_PixelAsCentroids(rast, 1) AS dp WHERE rid = 2) foo; x | y | val | st_astext @@ -7261,7 +7260,7 @@ SELECT rid, (meta).* FROM bar - If you find your transformation support is not working right, you may need to set the environment variable PROJSO to the .so or .dll projection library your PostGIS is using. This just needs to have the name of the file. So for example on windows, you would in Control Panel -> System -> Environment Variables add a system variable called PROJSO and set it to libproj.dll (if you are using proj 4.6.1). You'll have to restart your PostgreSQL service/daemon after this change. + If you find your transformation support is not working right, you may need to set the environment variable PROJSO to the projection library your PostGIS build is using. This just needs to have the name of the file. So for example on windows, you would in Control Panel -> System -> Environment Variables add a system variable called PROJSO and set it to libproj.dll. You'll have to restart your PostgreSQL service/daemon after this change. @@ -10446,7 +10445,7 @@ WHERE t1.rid = 1 AND t2.rid = 2 - Complete example of tiles of a coverage with neighborhood. This query only works with PostgreSQL 9.1 or higher. + Complete example of tiles of a coverage with neighborhood. WITH foo AS ( SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL @@ -10478,7 +10477,7 @@ WHERE t1.rid = 4 GROUP BY t1.rid, t1.rast - Example like the prior one for tiles of a coverage with neighborhood but works with PostgreSQL 9.0. + Example like the prior one for tiles of a coverage with neighborhood but using only basic SQL features. WITH src AS ( SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL @@ -13350,7 +13349,7 @@ FROM foo Examples: Variant 2 - Complete example of tiles of a coverage. This query only works with PostgreSQL 9.1 or higher. + Complete example of tiles of a coverage. WITH foo AS ( @@ -13498,7 +13497,7 @@ FROM foo Examples: Variant 2 - Complete example of tiles of a coverage. This query only works with PostgreSQL 9.1 or higher. + Complete example of tiles of a coverage. WITH foo AS ( @@ -13681,7 +13680,7 @@ FROM foo Examples: Variant 2 - Complete example of tiles of a coverage. This query only works with PostgreSQL 9.1 or higher. + Complete example of tiles of a coverage. WITH foo AS ( diff --git a/doc/using_postgis_dataman.xml b/doc/using_postgis_dataman.xml index 9d281193a..896184c0f 100644 --- a/doc/using_postgis_dataman.xml +++ b/doc/using_postgis_dataman.xml @@ -630,8 +630,7 @@ geometry = ST_GeomFromEWKT(text EWKT); Like the geometry data type, geography data is associated with a spatial reference system via a spatial reference system identifier (SRID). Any geodetic (long/lat based) spatial reference system defined in the spatial_ref_sys table can be used. - (Prior to PostGIS 2.2, the geography type supported only WGS 84 geodetic (SRID:4326)). - You can add your own custom geodetic spatial reference system as described in . + You can add your own custom geodetic spatial reference system as described in . For all spatial reference systems the units returned by measurement functions (e.g. , , , ) @@ -1749,8 +1748,7 @@ CREATE INDEX my_special_pois_geom_gist_nd -- to make the column typmod based. SELECT populate_geometry_columns('myschema.my_special_pois'::regclass); --- If you are using PostGIS 2.0 and for whatever reason, you --- you need the constraint based definition behavior +-- To retain the constraint-based definition behavior -- (such as case of inherited tables where all children do not have the same type and srid) -- set optional use_typmod argument to false SELECT populate_geometry_columns('myschema.my_special_pois'::regclass, false); @@ -2436,7 +2434,7 @@ pgsql2shp [] BRIN Indexes BRIN stands for "Block Range Index". It is a general-purpose - index method introduced in PostgreSQL 9.5. + index method provided by PostgreSQL. BRIN is a lossy index method, meaning that a secondary check is required to confirm that a record matches a given search condition diff --git a/doc/using_raster_dataman.xml b/doc/using_raster_dataman.xml index e225e0020..ef79c1164 100644 --- a/doc/using_raster_dataman.xml +++ b/doc/using_raster_dataman.xml @@ -583,7 +583,7 @@ if (!empty( $_REQUEST['srid'] ) && is_numeric( $_REQUEST['srid']) ){ $input_srid = intval($_REQUEST['srid']); } else { $input_srid = 26986; } -/** The set bytea_output may be needed for PostgreSQL 9.0+, but not for 8.4 **/ +/** The set bytea_output ensures bytea values are returned using escape format. **/ $sql = "set bytea_output='escape'; SELECT ST_AsPNG(ST_Transform( ST_AddBand(ST_Union(rast,1), ARRAY[ST_Union(rast,2),ST_Union(rast,3)]) ----------------------------------------------------------------------- Summary of changes: doc/administration.xml | 10 ++++---- doc/database_tuning.xml | 17 +++++++------- doc/installation.xml | 6 ++--- doc/reference_constructor.xml | 2 +- doc/reference_management.xml | 4 ++-- doc/reference_operator.xml | 54 +++++++++++++++++++++---------------------- doc/reference_output.xml | 4 ++-- doc/reference_raster.xml | 17 +++++++------- doc/using_postgis_dataman.xml | 8 +++---- doc/using_raster_dataman.xml | 2 +- 10 files changed, 59 insertions(+), 65 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 30 12:19:35 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 12:19:35 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-172-ga474eff15 Message-ID: <20251030191935.6E57219545A@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via a474eff150abde9c83b0385cac88cb529779f705 (commit) from afc7eeac415514ddf0ba5cfe63d42cca7716cf6b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a474eff150abde9c83b0385cac88cb529779f705 Author: Darafei Praliaskouski Date: Thu Oct 30 23:19:21 2025 +0400 [doc] Clean up mentions of legacy software versions diff --git a/doc/administration.xml b/doc/administration.xml index e7cf63d1b..da9f063f4 100644 --- a/doc/administration.xml +++ b/doc/administration.xml @@ -155,12 +155,12 @@ environment). If you installed your database using extensions, you'll need to upgrade using the extension model as well. If you installed using the old sql script way, you are advised to switch your install to extensions because the script way is no longer supported. -
    Soft Upgrade 9.1+ using extensions - If you originally installed PostGIS with extensions, then you need to upgrade using extensions as well. Doing a minor upgrade with extensions, is fairly painless. - If you are running PostGIS 3 or above, then you should use the function to upgrade to the latest version you have installed. +
    Soft upgrade using extensions + If you originally installed PostGIS with extensions, then you need to upgrade using extensions as well. Doing a minor upgrade with extensions is fairly painless. + Use the function to upgrade to the latest version you have installed. SELECT postgis_extensions_upgrade(); - If you are running PostGIS 2.5 or lower, then do the following: + If you are upgrading a database that still runs PostGIS 2.5, issue an ALTER EXTENSION followed by postgis_extensions_upgrade() to make sure the legacy postgis_raster objects are folded back into the main extension. ALTER EXTENSION postgis UPDATE; SELECT postgis_extensions_upgrade(); -- This second call is needed to rebundle postgis_raster extension @@ -195,71 +195,12 @@ ALTER EXTENSION postgis_topology UPDATE TO "&last_release_version;next";
    - Soft Upgrade Pre 9.1+ or without extensions + Soft upgrade without extensions - This section applies only to those who installed PostGIS - not using extensions. If you have extensions and try to - upgrade with this approach you'll get messages like: + Extensions have been the supported installation method for many releases. If you still rely on an unpackaged installation, perform a HARD UPGRADE into a database created with extensions and migrate your data there. +
    - can't drop ? because postgis extension depends on it - - NOTE: if you are moving from PostGIS 1.* to PostGIS 2.* or from - PostGIS 2.* prior to r7409, you cannot use this procedure but - would rather need to do a - HARD UPGRADE. - - - - After compiling and installing (make install) you should - find a set of *_upgrade.sql - files in the installation folders. You can list - them all with: - - - ls `pg_config --sharedir`/contrib/postgis-&last_release_version;/*_upgrade.sql - - - Load them all in turn, starting from postgis_upgrade.sql. - - - psql -f postgis_upgrade.sql -d your_spatial_database - - - The same procedure applies to raster, - topology and sfcgal extensions, with upgrade files named - rtpostgis_upgrade.sql, - topology_upgrade.sql and - sfcgal_upgrade.sql respectively. - If you need them: - - - psql -f rtpostgis_upgrade.sql -d your_spatial_database - psql -f topology_upgrade.sql -d your_spatial_database - psql -f sfcgal_upgrade.sql -d your_spatial_database - - You are advised to switch to an extension based install by running - psql -c "SELECT postgis_extensions_upgrade();" - - - - If you can't find the - postgis_upgrade.sql specific for - upgrading your version you are using a version too - early for a soft upgrade and need to do a - HARD UPGRADE. - - - - - The function - should inform you about the need to run this kind of - upgrade using a "procs need upgrade" message. - -
    - -
    - -
    +
    Hard upgrade diff --git a/doc/extras_historytable.xml b/doc/extras_historytable.xml index 89214ff4b..18078427c 100644 --- a/doc/extras_historytable.xml +++ b/doc/extras_historytable.xml @@ -11,7 +11,7 @@ - The history_table was also packaged in PostGIS 1.5, but added to the documentation in PostGIS 2.0. This package is written in plpgsql and located in the extras/history_table of PostGIS source tar balls and source repository. + The history_table extension is written in plpgsql and located in the extras/history_table directory of the PostGIS source tree. If you have a table 'roads', this module will maintain a 'roads_history' side table, which contains all the columns of the parent table, and the following additional columns: history_id | integer | not null default date_added | timestamp without time zone | not null default now() diff --git a/doc/extras_tigergeocoder.xml b/doc/extras_tigergeocoder.xml index c76f7bd6a..92005387e 100644 --- a/doc/extras_tigergeocoder.xml +++ b/doc/extras_tigergeocoder.xml @@ -37,7 +37,7 @@ you can upgrade the scripts using the accompanying upgrade_geocoder.bat Design: The goal of this project is to build a fully functional geocoder that can process an arbitrary United States address string and using normalized TIGER census data, produce a point geometry and rating reflecting the location of the given address and likeliness of the location. The higher the rating number the worse the result. - The reverse_geocode function, introduced in PostGIS 2.0.0 is useful for deriving the street address and cross streets of a GPS location. + The reverse_geocode function is useful for deriving the street address and cross streets of a GPS location. The geocoder should be simple for anyone familiar with PostGIS to install and use, and should be easily installable and usable on all platforms supported by PostGIS. It should be robust enough to function properly despite formatting and spelling errors. It should be extensible enough to be used with future data updates, or alternate data sources with a minimum of coding changes. @@ -51,7 +51,7 @@ you can upgrade the scripts using the accompanying upgrade_geocoder.bat There are a couple other open source geocoders for PostGIS, that unlike tiger geocoder have the advantage of multi-country geocoding support Nominatim - uses OpenStreetMap gazeteer formatted data. It requires osm2pgsql for loading the data, PostgreSQL 8.4+ and PostGIS 1.5+ to function. It is packaged as a webservice interface and seems designed to be called as a webservice. + uses OpenStreetMap gazeteer formatted data. It requires osm2pgsql for loading the data together with PostgreSQL and PostGIS. It is packaged as a webservice interface and seems designed to be called as a webservice. Just like the tiger geocoder, it has both a geocoder and a reverse geocoder component. From the documentation, it is unclear if it has a pure SQL interface like the tiger geocoder, or if a good deal of the logic is implemented in the web interface. GIS Graphy also utilizes PostGIS and like Nominatim works with OpenStreetMap (OSM) data. It comes with a loader to load OSM data and similar to Nominatim is capable of geocoding not just US. Much like Nominatim, it runs as a webservice and relies on Java 1.5, Servlet apps, Solr. GisGraphy is cross-platform and also has a reverse geocoder among some other neat features. @@ -278,7 +278,6 @@ DROP TABLE tiger_data.pa_zip_state_loc; Examples: Basic - The below examples timings are on a 3.0 GHZ single processor Windows 7 machine with 2GB ram running PostgreSQL 9.1rc1/PostGIS 2.0 loaded with all of MA,MN,CA, RI state Tiger data loaded. Exact matches are faster to compute (61ms) SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat, (addy).address As stno, (addy).streetname As street, @@ -418,8 +417,6 @@ Time: 622.939 ms Examples: Basic - The below examples timings are on a 3.0 GHZ single processor Windows 7 machine with 2GB ram running PostgreSQL 9.0/PostGIS 1.5 loaded with all of MA state Tiger data loaded. Currently a bit slow (3000 ms) - Testing on Windows 2003 64-bit 8GB on PostGIS 2.0 PostgreSQL 64-bit Tiger 2011 data loaded -- (41ms) SELECT pprint_addy(addy), st_astext(geomout),rating FROM geocode_intersection( 'Haverford St','Germania St', 'MA', 'Boston', '02130',1); pprint_addy | st_astext | rating @@ -635,7 +632,7 @@ tract_id Availability: 2.0.0 - includes this logic, but if you installed tiger geocoder prior to PostGIS 2.0.0 alpha5, you'll need to run this on the states you have already done + includes this logic, but if you installed the tiger geocoder with older scripts, rerun it on the states you have already processed to get these additional tables. @@ -649,7 +646,7 @@ set STATEDIR="\gisdata\www2.census.gov\geo\pvs\tiger2010st\25_Massachusetts" set TMPDIR=\gisdata\temp\ set UNZIPTOOL="C:\Program Files\7-Zip\7z.exe" set WGETTOOL="C:\wget\wget.exe" -set PGBIN=C:\projects\pg\pg91win\bin\ +set PGBIN=C:\projects\pg\pgwin\bin\ set PGPORT=5432 set PGHOST=localhost set PGUSER=postgres @@ -678,7 +675,7 @@ cd %TMPDIR% TMPDIR="/gisdata/temp/" UNZIPTOOL=unzip WGETTOOL="/usr/bin/wget" -export PGBIN=/usr/pgsql-9.0/bin +export PGBIN=/usr/pgsql-/bin export PGPORT=5432 export PGHOST=localhost export PGUSER=postgres @@ -762,7 +759,7 @@ for z in *.zip; do $UNZIPTOOL -o -d $TMPDIR $z; done set TMPDIR=\gisdata\temp\ set UNZIPTOOL="C:\Program Files\7-Zip\7z.exe" set WGETTOOL="C:\wget\wget.exe" -set PGBIN=C:\Program Files\PostgreSQL\9.4\bin\ +set PGBIN=C:\Program Files\PostgreSQL\\bin\ set PGPORT=5432 set PGHOST=localhost set PGUSER=postgres @@ -783,7 +780,7 @@ cd \gisdata/ftp2.census.gov/geo/tiger/TIGER2015/PLACE TMPDIR="/gisdata/temp/" UNZIPTOOL=unzip WGETTOOL="/usr/bin/wget" -export PGBIN=/usr/lib/postgresql/9.4/bin +export PGBIN=/usr/lib/postgresql//bin -- variables used by psql: https://www.postgresql.org/docs/current/static/libpq-envars.html export PGPORT=5432 export PGHOST=localhost @@ -1355,7 +1352,6 @@ FROM (SELECT address As actual_addr, lon, lat, createtopology -------------- 15 --- 60,902 ms ~ 1 minute on windows 7 desktop running 9.1 (with 5 states tiger data loaded) SELECT tiger.topology_load_tiger('topo_boston', 'place', '2507000'); -- topology_loader_tiger -- 29722 edges holding in temporary. 11108 faces added. 1875 edges of faces added. 20576 nodes added. diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml index a3846708b..640bee1fb 100644 --- a/doc/extras_topology.xml +++ b/doc/extras_topology.xml @@ -12,12 +12,12 @@ Vincent Picavet provides a good synopsis and overview of what is Topology, how is it used, and various FOSS4G tools that support it in PostGIS Topology PGConf EU 2012. An example of a topologically based GIS database is the US Census Topologically Integrated Geographic Encoding and Referencing System (TIGER) database. If you want to experiment with PostGIS topology and need some data, check out . - The PostGIS topology module has existed in prior versions of PostGIS but was never part of the Official PostGIS documentation. - In PostGIS 2.0.0 major cleanup is going on to remove use of all deprecated functions in it, fix known usability issues, better document the features and functions, add new functions, and enhance to closer conform to SQL-MM standards. + The PostGIS topology module has existed for a long time but was not always part of the official documentation. + Extensive cleanup removed deprecated functions, fixed known usability issues, documented the features and functions, added new functionality, and improved SQL-MM compliance. Details of this project can be found at PostGIS Topology Wiki All functions and tables associated with this module are installed in a schema called topology. Functions that are defined in SQL/MM standard are prefixed with ST_ and functions specific to PostGIS are not prefixed. - Topology support is build by default starting with PostGIS 2.0, and can be disabled specifying --without-topology configure option at build time as described in + Topology support is built by default and can be disabled by specifying the --without-topology configure option at build time as described in
    Topology Primitive Tables diff --git a/doc/installation.xml b/doc/installation.xml index da80070c7..bdbdf1611 100644 --- a/doc/installation.xml +++ b/doc/installation.xml @@ -585,24 +585,24 @@ sh autogen.sh successfully. Ready to install." - - As of PostGIS v1.4.0, all the functions have comments generated from the - documentation. If you wish to install these comments into your spatial - databases later, run the command which requires docbook. The postgis_comments.sql and other - package comments files raster_comments.sql, topology_comments.sql are - also packaged in the tar.gz distribution in the doc folder so no need to make comments - if installing from the tar ball. Comments are also included as part of the CREATE EXTENSION install. - + + All the functions have comments generated from the + documentation. If you wish to install these comments into your spatial + databases later, run the command which requires docbook. The postgis_comments.sql and other + package comment files are + also packaged in the tar.gz distribution in the doc folder so no need to make comments + if installing from the tar ball. Comments are also included as part of the CREATE EXTENSION install. + make comments - - Introduced in PostGIS 2.0. This generates html cheat sheets suitable for quick reference or for student handouts. - This requires xsltproc to build and will generate 4 files in doc folder topology_cheatsheet.html, tiger_geocoder_cheatsheet.html, - raster_cheatsheet.html, postgis_cheatsheet.html - + + The make cheatsheets target generates html cheat sheets suitable for quick reference or for student handouts. + This requires xsltproc to build and will generate 4 files in doc folder topology_cheatsheet.html, tiger_geocoder_cheatsheet.html, + raster_cheatsheet.html, postgis_cheatsheet.html + You can download some pre-built ones available in html and pdf from PostGIS / PostgreSQL Study Guides @@ -715,9 +715,9 @@ Schema | topology Description | PostGIS topology spatial types and functions Extension tables spatial_ref_sys, layer, topology can not be explicitly backed up. They can only -be backed up when the respective postgis or postgis_topology extension is backed up, which only seems to happen when you backup the whole database. -As of PostGIS 2.0.1, only srid records not packaged with PostGIS are backed up when the database is backed up so don't go around changing srids we package and expect your changes to be there. Put in a ticket if you find an issue. The structures of extension tables are never backed up since they are created with CREATE EXTENSION -and assumed to be the same for a given version of an extension. These behaviors are built into the current PostgreSQL extension model, so nothing we can do about it. +be backed up when the respective postgis or postgis_topology extension is backed up, which only happens when you back up the whole database. +Only srid records not packaged with PostGIS are captured in backups, so don't change the entries we ship and expect the modifications to persist. Put in a ticket if you find an issue. The structures of extension tables are never backed up since they are created with CREATE EXTENSION +and assumed to be the same for a given version of an extension. These behaviors are built into the current PostgreSQL extension model. If you installed &last_release_version;, without using our wonderful extension system, you can change it to be extension based by @@ -1004,8 +1004,8 @@ All 2 tests passed.
    Installing and Using the address standardizer - The address_standardizer extension used to be a separate package that required separate download. From PostGIS 2.2 on, it is now bundled in. - For more information about the address_standardize, what it does, and how to configure it for your needs, refer to . + The address_standardizer extension is bundled with PostGIS. + For more information about the address_standardizer, what it does, and how to configure it for your needs, refer to . This standardizer can be used in conjunction with the PostGIS packaged tiger geocoder extension as a replacement for the discussed. To use as replacement refer to . You can also use it as a building block for your own geocoder or use it to standardize your addresses for easier compare of addresses. @@ -1013,7 +1013,7 @@ All 2 tests passed. The address standardizer relies on PCRE which is usually already installed on many Nix systems, but you can download the latest at: http://www.pcre.org. If during , PCRE is found, then the address standardizer extension will automatically be built. If you have a custom pcre install you want to use instead, pass to configure --with-pcredir=/path/to/pcre where /path/to/pcre is the root folder for your pcre include and lib directories. - For Windows users, the PostGIS 2.1+ bundle is packaged with the address_standardizer already so no need to compile and can move straight to CREATE EXTENSION step. + Windows installation packages include the address_standardizer so you can move straight to the CREATE EXTENSION step. Once you have installed, you can connect to your database and run the SQL: @@ -1072,7 +1072,7 @@ SELECT 'debbie', declare_sect, pgbin, wget, unzip_command, psql, path_sep, If you don't edit this loader_platform table, it will just contain common case locations of items and you'll have to edit the generated script after the script is generated. - As of PostGIS 2.4.1 the Zip code-5 digit tabulation area zcta5 load step was revised to load current zcta5 data and is part of the when enabled. + The Zip code-5 digit tabulation area zcta5 load step uses current ZCTA data and is part of the when enabled. It is turned off by default because it takes quite a bit of time to load (20 to 60 minutes), takes up quite a bit of disk space, and is not used that often. To enable it, do the following: UPDATE tiger.loader_lookuptables SET load = true WHERE table_name = 'zcta520'; diff --git a/doc/introduction.xml b/doc/introduction.xml index 209707e05..429253b27 100644 --- a/doc/introduction.xml +++ b/doc/introduction.xml @@ -417,7 +417,7 @@ Crowd funding campaigns are campaigns we run to get badly wanted features funded that can service a large number of people. Each campaign is specifically focused on a particular feature or set of features. Each sponsor chips in a small fraction of the needed funding and with enough people/organizations contributing, we have the funds to pay for the work that will help many. If you have an idea for a feature you think many others would be willing to co-fund, please post to the PostGIS newsgroup your thoughts and together we can make it happen. - PostGIS 2.0.0 was the first release we tried this strategy. We used PledgeBank and we got two successful campaigns out of it. + PostGIS has experimented with community fundraising for features in the past. We used PledgeBank and we got two successful campaigns out of it. postgistopology - 10 plus sponsors each contributed $250 USD to build toTopoGeometry function and beef up topology support in 2.0.0. It happened. postgis64windows - 20 someodd sponsors each contributed $100 USD to pay for the work needed to work out PostGIS 64-bit issues on windows. It happened. diff --git a/extensions/postgis/META.json b/extensions/postgis/META.json index f8742511d..82adb35bd 100644 --- a/extensions/postgis/META.json +++ b/extensions/postgis/META.json @@ -1,21 +1,21 @@ { - "abstract" : "PostGIS 2.2 OGC/SQL-MM compliant spatial extender for PostgreSQL", - "release_status" : "stable", - "license" : "gpl_2", - "generated_by" : "Regina O. Obe", - "description" : "This module provides GIS geometry, geography, raster types, functions, and tables", - "version" : "2.2.0", - "resources" : { - "bugtracker" : { - "web" : "http://trac.osgeo.org/postgis" + "abstract": "PostGIS OGC/SQL-MM compliant spatial extender for PostgreSQL", + "release_status": "stable", + "license": "gpl_2", + "generated_by": "Regina O. Obe", + "description": "This module provides GIS geometry, geography, raster types, functions, and tables", + "version": "3.7.0dev", + "resources": { + "bugtracker": { + "web": "http://trac.osgeo.org/postgis" }, - "repository" : { - "type" : "git", - "web" : "http://postgis.net", - "url" : "https://git.osgeo.org/gitea/postgis/postgis.git" + "repository": { + "type": "git", + "web": "http://postgis.net", + "url": "https://git.osgeo.org/gitea/postgis/postgis.git" } }, - "tags" : [ + "tags": [ "gis", "spatial", "geometry", @@ -23,30 +23,30 @@ "geography", "location" ], - "meta-spec" : { - "version" : "1.0.0", - "url" : "http://pgxn.org/meta/spec.txt" + "meta-spec": { + "version": "1.0.0", + "url": "http://pgxn.org/meta/spec.txt" }, - "provides" : { - "spatial_ref_sys" : { - "version" : "2.2.0", - "file" : "sql/spatial_ref_sys.sql", - "abstract" : "Directory of spatial reference systems needed for geometry transformation between different spatial reference systems" + "provides": { + "spatial_ref_sys": { + "version": "3.7.0dev", + "file": "sql/spatial_ref_sys.sql", + "abstract": "Directory of spatial reference systems needed for geometry transformation between different spatial reference systems" }, - "postgis" : { - "abstract" : "PostGIS GIS types, indexes and functions", - "docfile" : "doc/postgis.md", - "file" : "sql/postgis.sql", - "version" : "2.2.0" + "postgis": { + "abstract": "PostGIS GIS types, indexes and functions", + "docfile": "doc/postgis.md", + "file": "sql/postgis.sql", + "version": "3.7.0dev" } }, - "name" : "postgis", - "maintainer" : "PostGIS Steering Committee", - "prereqs" : { - "runtime" : { - "requires" : { - "PostgreSQL" : "9.1.0", - "plpgsql" : 0 + "name": "postgis", + "maintainer": "PostGIS Steering Committee", + "prereqs": { + "runtime": { + "requires": { + "PostgreSQL": "12", + "plpgsql": 0 } } } diff --git a/extensions/postgis_topology/META.json b/extensions/postgis_topology/META.json index 89d90ec1c..f7ea31180 100644 --- a/extensions/postgis_topology/META.json +++ b/extensions/postgis_topology/META.json @@ -1,47 +1,49 @@ { - "name": "postgis_topology", - "abstract": "PostGIS 2.0 Topology OGC/SQL-MM compliant spatial extender for PostgreSQL", - "description": "This module provides GIS Topology geometry types and functions", - "version": "2.0.0", - "release_status": "unstable", - "maintainer": "PostGIS Steering Committee", - "license": "gpl_2", - "provides": { - "postgis_raster": { - "abstract": "PostGIS SQL/MM Topology types and functions", - "version": "2.0.0", - "file": "sql/postgis_topology.sql", - "docfile": "doc/postgis.md" - } - } - "prereqs": { + "name": "postgis_topology", + "abstract": "PostGIS Topology OGC/SQL-MM compliant spatial extender for PostgreSQL", + "description": "This module provides GIS Topology geometry types and functions", + "version": "3.7.0dev", + "release_status": "stable", + "maintainer": "PostGIS Steering Committee", + "license": "gpl_2", + "provides": { + "postgis_raster": { + "abstract": "PostGIS SQL/MM Topology types and functions", + "version": "3.7.0dev", + "file": "sql/postgis_topology.sql", + "docfile": "doc/postgis.md" + } + }, + "prereqs": { "runtime": { "requires": { "plpgsql": 0, - "PostgreSQL": "8.4.0", - "postgis_core": "2.0.0" + "PostgreSQL": "12", + "postgis_core": "3.7.0dev" } } - }, - "generated_by": "Regina O. Obe", - "resources": { - "bugtracker": { - "web": "http://trac.osgeo.org/postgis" - }, - "repository": { - "url": "https://git.osgeo.org/gitea/postgis/postgis.git", - "web": "http://postgis.net", - "type": "git" - } - }, - "meta-spec": { - "version": "1.0.0", - "url": "http://pgxn.org/meta/spec.txt" - }, - "tags": [ - "gis", - "spatial", - "geometry", - "location", "topology", "sql/mm" - ] + }, + "generated_by": "Regina O. Obe", + "resources": { + "bugtracker": { + "web": "http://trac.osgeo.org/postgis" + }, + "repository": { + "url": "https://git.osgeo.org/gitea/postgis/postgis.git", + "web": "http://postgis.net", + "type": "git" + } + }, + "meta-spec": { + "version": "1.0.0", + "url": "http://pgxn.org/meta/spec.txt" + }, + "tags": [ + "gis", + "spatial", + "geometry", + "location", + "topology", + "sql/mm" + ] } ----------------------------------------------------------------------- Summary of changes: doc/administration.xml | 75 ++++---------------------------- doc/extras_historytable.xml | 2 +- doc/extras_tigergeocoder.xml | 18 +++----- doc/extras_topology.xml | 6 +-- doc/installation.xml | 40 ++++++++--------- doc/introduction.xml | 2 +- extensions/postgis/META.json | 68 ++++++++++++++--------------- extensions/postgis_topology/META.json | 82 ++++++++++++++++++----------------- 8 files changed, 116 insertions(+), 177 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 30 12:52:18 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 12:52:18 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-173-gd19e312fc Message-ID: <20251030195218.964B9196627@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via d19e312fccf56ee6b50e1e90f1dfeffadb0eb336 (commit) from a474eff150abde9c83b0385cac88cb529779f705 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d19e312fccf56ee6b50e1e90f1dfeffadb0eb336 Author: Darafei Praliaskouski Date: Thu Oct 30 23:46:20 2025 +0400 [doc] Clean up mentions of legacy software versions diff --git a/doc/administration.xml b/doc/administration.xml index da9f063f4..9756f184b 100644 --- a/doc/administration.xml +++ b/doc/administration.xml @@ -384,7 +384,5 @@ ALTER TABLE spatial_ref_sys ADD PRIMARY KEY(srid));
    - - - +
    diff --git a/doc/extras_tigergeocoder.xml b/doc/extras_tigergeocoder.xml index 92005387e..ffacaeaf3 100644 --- a/doc/extras_tigergeocoder.xml +++ b/doc/extras_tigergeocoder.xml @@ -20,14 +20,14 @@ -If you are using tiger geocoder (tiger_2010), +If you are using the TIGER Geocoder (tiger_2010), you can upgrade the scripts using the accompanying upgrade_geocoder.bat / .sh scripts in extras/tiger. One major change between tiger_2010 and tiger_2011+ is that the county and state tables are no longer broken out by state. If you have data from tiger_2010 and want to replace with tiger_2015, refer to - New in PostGIS 2.2.0 release is support for Tiger 2015 data and inclusion of Address Standardizer as part of PostGIS. - New in PostGIS 2.1.0 release is ability to install tiger geocoder with PostgreSQL extension model if you are running PostgreSQL 9.1+. Refer to for details. + New in PostGIS 2.2.0 release is support for TIGER 2015 data and inclusion of Address Standardizer as part of PostGIS. + New in PostGIS 2.1.0 release is ability to install the TIGER Geocoder with the PostgreSQL extension model. Refer to for details. The function as a drop in replacement for in-built . Refer to for compile and installation instructions. @@ -48,11 +48,11 @@ you can upgrade the scripts using the accompanying upgrade_geocoder.bat - There are a couple other open source geocoders for PostGIS, that unlike tiger geocoder have the advantage of multi-country geocoding support + There are a couple other open source geocoders for PostGIS, that unlike the TIGER Geocoder have the advantage of multi-country geocoding support Nominatim uses OpenStreetMap gazeteer formatted data. It requires osm2pgsql for loading the data together with PostgreSQL and PostGIS. It is packaged as a webservice interface and seems designed to be called as a webservice. - Just like the tiger geocoder, it has both a geocoder and a reverse geocoder component. From the documentation, it is unclear if it has a pure SQL interface like the tiger geocoder, or if a good deal of the logic is implemented in the web interface. + Just like the TIGER Geocoder, it has both a geocoder and a reverse geocoder component. From the documentation, it is unclear if it has a pure SQL interface like the TIGER Geocoder, or if a good deal of the logic is implemented in the web interface. GIS Graphy also utilizes PostGIS and like Nominatim works with OpenStreetMap (OSM) data. It comes with a loader to load OSM data and similar to Nominatim is capable of geocoding not just US. Much like Nominatim, it runs as a webservice and relies on Java 1.5, Servlet apps, Solr. GisGraphy is cross-platform and also has a reverse geocoder among some other neat features. @@ -632,7 +632,7 @@ tract_id Availability: 2.0.0 - includes this logic, but if you installed the tiger geocoder with older scripts, rerun it on the states you have already processed + includes this logic, but if you installed the TIGER Geocoder with older scripts, rerun it on the states you have already processed to get these additional tables.
    @@ -646,7 +646,7 @@ set STATEDIR="\gisdata\www2.census.gov\geo\pvs\tiger2010st\25_Massachusetts" set TMPDIR=\gisdata\temp\ set UNZIPTOOL="C:\Program Files\7-Zip\7z.exe" set WGETTOOL="C:\wget\wget.exe" -set PGBIN=C:\projects\pg\pgwin\bin\ +set PGBIN=C:\projects\pg\pg[version]win\bin\ set PGPORT=5432 set PGHOST=localhost set PGUSER=postgres @@ -675,7 +675,7 @@ cd %TMPDIR% TMPDIR="/gisdata/temp/" UNZIPTOOL=unzip WGETTOOL="/usr/bin/wget" -export PGBIN=/usr/pgsql-/bin +export PGBIN=/usr/pgsql-[version]/bin export PGPORT=5432 export PGHOST=localhost export PGUSER=postgres @@ -759,7 +759,7 @@ for z in *.zip; do $UNZIPTOOL -o -d $TMPDIR $z; done set TMPDIR=\gisdata\temp\ set UNZIPTOOL="C:\Program Files\7-Zip\7z.exe" set WGETTOOL="C:\wget\wget.exe" -set PGBIN=C:\Program Files\PostgreSQL\\bin\ +set PGBIN=C:\Program Files\PostgreSQL\[version]\bin\ set PGPORT=5432 set PGHOST=localhost set PGUSER=postgres @@ -780,7 +780,7 @@ cd \gisdata/ftp2.census.gov/geo/tiger/TIGER2015/PLACE TMPDIR="/gisdata/temp/" UNZIPTOOL=unzip WGETTOOL="/usr/bin/wget" -export PGBIN=/usr/lib/postgresql//bin +export PGBIN=/usr/lib/postgresql/[version]/bin -- variables used by psql: https://www.postgresql.org/docs/current/static/libpq-envars.html export PGPORT=5432 export PGHOST=localhost diff --git a/doc/reference_input.xml b/doc/reference_input.xml index 62ce603dc..c6a264d30 100644 --- a/doc/reference_input.xml +++ b/doc/reference_input.xml @@ -1076,8 +1076,8 @@ ST_GeogFromWKB(E'\\001\\002\\000\\000\\000\\002\\000\\000\\000\\037\\205\\353Q\\ \\312Q\\300\\366{b\\235*!E@\\225|\\354.P\\312Q \\300p\\231\\323e1!E@');
    - In PostgreSQL 9.1+ - standard_conforming_strings is set to on by default, where as in past versions it was set to off. You can change defaults as needed - for a single query or at the database or server level. Below is how you would do it with standard_conforming_strings = on. In this case we escape the ' with standard ansi ', + In PostgreSQL, standard_conforming_strings is set to on by default. You can change the default as needed + for a single query or at the database or server level. Below is how you would do it with standard_conforming_strings = on. In this case we escape the ' with standard ANSI ', but slashes are not escaped set standard_conforming_strings = on; diff --git a/doc/reference_measure.xml b/doc/reference_measure.xml index 4e15fd519..d50c5758c 100644 --- a/doc/reference_measure.xml +++ b/doc/reference_measure.xml @@ -1012,7 +1012,7 @@ SELECT DISTINCT ON (buildings.gid) buildings.gid, parcels.parcel_id The units of length is determined by the spatial reference system of the geometry. For geography types: computation is performed using the inverse geodesic calculation. Units of length are in meters. - If PostGIS is compiled with PROJ version 4.8.0 or later, the spheroid is specified by the SRID, otherwise it is exclusive to WGS84. + The spheroid is specified by the SRID; when no SRID is provided, WGS84 is used. If use_spheroid = false, then the calculation is based on a sphere instead of a spheroid. @@ -1722,7 +1722,7 @@ LINESTRING(0.5 0.00032,0.5 0) non-areal geometries. For linear geometries use . For geometry types, units for perimeter measures are specified by the spatial reference system of the geometry. For geography types, the calculations are performed using the inverse geodesic problem, where perimeter units are in meters. - If PostGIS is compiled with PROJ version 4.8.0 or later, the spheroid is specified by the SRID, otherwise it is exclusive to WGS84. + The spheroid is specified by the SRID; when no SRID is provided, WGS84 is used. If use_spheroid = false, then calculations will approximate a sphere instead of a spheroid. Currently this is an alias for ST_Perimeter2D, but this may change to support higher dimensions. diff --git a/doc/reference_raster.xml b/doc/reference_raster.xml index 79d82cec2..dc1e99c9b 100644 --- a/doc/reference_raster.xml +++ b/doc/reference_raster.xml @@ -14181,7 +14181,7 @@ FROM (SELECT ST_SetRotation(rast, 0.1, 0.1) As rast Examples - -- this syntax requires PostgreSQL 9.3+ + -- this syntax uses a LATERAL join SELECT val, ST_AsText(geom) As geomwkt FROM ( SELECT dp.* diff --git a/extensions/README b/extensions/README index 7f941b69d..16729759e 100644 --- a/extensions/README +++ b/extensions/README @@ -1,16 +1,11 @@ PostGIS Extension for PostgreSQL ================================ -PostgreSQL 9.6 (and up) supports PostGIS extensions. A database can easily be -extended to use PostGIS using the syntax:: +A database can easily be extended to use PostGIS using the syntax:: CREATE EXTENSION postgis; -- Includes raster CREATE EXTENSION postgis_topology; -- Depends on postgis -Requirements ------------- - * PostgreSQL 9.6 or later - Building and installing ----------------------- First, make sure you follow the regular configuration and installation steps, diff --git a/postgis/gserialized_gist_2d.c b/postgis/gserialized_gist_2d.c index 3ac5a3567..06224676f 100644 --- a/postgis/gserialized_gist_2d.c +++ b/postgis/gserialized_gist_2d.c @@ -1077,8 +1077,8 @@ Datum gserialized_gist_consistent_2d(PG_FUNCTION_ARGS) bool result; BOX2DF query_gbox_index; - /* PostgreSQL 8.4 and later require the RECHECK flag to be set here, - rather than being supplied as part of the operator class definition */ + /* PostgreSQL requires the RECHECK flag to be set here, + rather than being supplied as part of the operator class definition */ bool *recheck = (bool *) PG_GETARG_POINTER(4); /* We set recheck to false to avoid repeatedly pulling every "possibly matched" geometry diff --git a/postgis/gserialized_gist_nd.c b/postgis/gserialized_gist_nd.c index 8fe07b0ea..a6e44da63 100644 --- a/postgis/gserialized_gist_nd.c +++ b/postgis/gserialized_gist_nd.c @@ -1087,8 +1087,8 @@ Datum gserialized_gist_consistent(PG_FUNCTION_ARGS) char gidxmem[GIDX_MAX_SIZE]; GIDX *query_gbox_index = (GIDX *)gidxmem; - /* PostgreSQL 8.4 and later require the RECHECK flag to be set here, - rather than being supplied as part of the operator class definition */ + /* PostgreSQL requires the RECHECK flag to be set here, + rather than being supplied as part of the operator class definition */ bool *recheck = (bool *)PG_GETARG_POINTER(4); /* We set recheck to false to avoid repeatedly pulling every "possibly matched" geometry diff --git a/postgis/gserialized_typmod.c b/postgis/gserialized_typmod.c index b07ad9343..308297fa7 100644 --- a/postgis/gserialized_typmod.c +++ b/postgis/gserialized_typmod.c @@ -332,7 +332,7 @@ static uint32 gserialized_typmod_in(ArrayType *arr, int is_geography) /* ** geography_typmod_in(cstring[]) returns int32 ** -** Modified from ArrayGetIntegerTypmods in PostgreSQL 8.3 +** Modified from ArrayGetIntegerTypmods in PostgreSQL */ PG_FUNCTION_INFO_V1(geography_typmod_in); Datum geography_typmod_in(PG_FUNCTION_ARGS) @@ -349,7 +349,7 @@ Datum geography_typmod_in(PG_FUNCTION_ARGS) /* ** geometry_typmod_in(cstring[]) returns int32 ** -** Modified from ArrayGetIntegerTypmods in PostgreSQL 8.3 +** Modified from ArrayGetIntegerTypmods in PostgreSQL */ PG_FUNCTION_INFO_V1(geometry_typmod_in); Datum geometry_typmod_in(PG_FUNCTION_ARGS) diff --git a/postgis/lwgeom_box3d.c b/postgis/lwgeom_box3d.c index 11ba71483..1fbde98e2 100644 --- a/postgis/lwgeom_box3d.c +++ b/postgis/lwgeom_box3d.c @@ -631,7 +631,7 @@ Datum BOX3D_construct(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } -/** needed for sp-gist support PostgreSQL 11+ **/ +/** Needed for SP-GiST support. **/ /***************************************************************************** * BOX3D functions *****************************************************************************/ diff --git a/postgis/lwgeom_box3d.h b/postgis/lwgeom_box3d.h index 80107977e..39ec10f3a 100644 --- a/postgis/lwgeom_box3d.h +++ b/postgis/lwgeom_box3d.h @@ -63,7 +63,7 @@ bool BOX3D_back_internal(BOX3D *box1, BOX3D *box2); bool BOX3D_overback_internal(BOX3D *box1, BOX3D *box2); double BOX3D_distance_internal(BOX3D *box1, BOX3D *box2); -/** needed for sp-gist support PostgreSQL 11+ **/ +/** Needed for SP-GiST support. **/ Datum BOX3D_contains(PG_FUNCTION_ARGS); Datum BOX3D_contained(PG_FUNCTION_ARGS); Datum BOX3D_overlaps(PG_FUNCTION_ARGS); ----------------------------------------------------------------------- Summary of changes: doc/administration.xml | 4 +--- doc/extras_tigergeocoder.xml | 20 ++++++++++---------- doc/reference_input.xml | 4 ++-- doc/reference_measure.xml | 4 ++-- doc/reference_raster.xml | 2 +- extensions/README | 7 +------ postgis/gserialized_gist_2d.c | 4 ++-- postgis/gserialized_gist_nd.c | 4 ++-- postgis/gserialized_typmod.c | 4 ++-- postgis/lwgeom_box3d.c | 2 +- postgis/lwgeom_box3d.h | 2 +- 11 files changed, 25 insertions(+), 32 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Oct 30 13:14:08 2025 From: git at osgeo.org (git at osgeo.org) Date: Thu, 30 Oct 2025 13:14:08 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-174-g3910b8618 Message-ID: <20251030201409.1FB45197513@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 3910b861812e6db7c25004cb3a7f20533403592e (commit) from d19e312fccf56ee6b50e1e90f1dfeffadb0eb336 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3910b861812e6db7c25004cb3a7f20533403592e Author: Darafei Praliaskouski Date: Fri Oct 31 00:13:52 2025 +0400 [doc] Clean up mentions of legacy software versions diff --git a/doc/extras_address_standardizer.xml b/doc/extras_address_standardizer.xml index d80ff7e5f..287151ca4 100644 --- a/doc/extras_address_standardizer.xml +++ b/doc/extras_address_standardizer.xml @@ -314,7 +314,7 @@ into includes in the future for easier maintenance. QUINT - (28). A 5 digit number. Identifies a Zip Code + (28). A 5 digit number. Identifies a ZIP code @@ -387,7 +387,7 @@ into includes in the future for easier maintenance. POSTAL - (token number "13"). (SADS elements "ZIP CODE" , "PLUS 4" ). This attribute is used for both the US Zip and the Canadian Postal Codes. + (token number "13"). (SADS elements "ZIP CODE" , "PLUS 4" ). This attribute is used for both the US ZIP and the Canadian postal codes. diff --git a/doc/extras_tigergeocoder.xml b/doc/extras_tigergeocoder.xml index ffacaeaf3..8ddd36ab8 100644 --- a/doc/extras_tigergeocoder.xml +++ b/doc/extras_tigergeocoder.xml @@ -9,10 +9,10 @@ A plpgsql based geocoder written to work with the TIGER (Topologically Integrated Geographic Encoding and Referencing system ) / Line and Master Address database export released by the US Census Bureau. There are four components to the geocoder: the data loader functions, the address normalizer, the address geocoder, and the reverse geocoder. Although it is designed specifically for the US, a lot of the concepts and functions are applicable and can be adapted to work with other country address and road networks. - The script builds a schema called tiger to house all the tiger related functions, reusable lookup data such as road type prefixes, suffixes, states, various control tables for managing data load, and skeleton base tables from which all the tiger loaded tables inherit from. - Another schema called tiger_data is also created which houses all the census data for each state that the loader downloads from Census site and loads into the database. In the current model, each set of state tables is - prefixed with the state code e.g ma_addr, ma_edges etc with constraints to enforce only that state data. Each of these tables inherits from the tables addr, faces, edges, etc located in the tiger schema. - All the geocode functions only reference the base tables, so there is no requirement that the data schema be called tiger_data or that data can't be further partitioned into other schemas -- e.g a different schema + The script builds a schema called tiger to house all the TIGER-related functions, reusable lookup data such as road type prefixes, suffixes, states, various control tables for managing data load, and skeleton base tables from which all the TIGER-loaded tables inherit. + Another schema called tiger_data is also created which houses all the census data for each state that the loader downloads from the Census site and loads into the database. In the current model, each set of state tables is + prefixed with the state code e.g ma_addr, ma_edges etc with constraints to enforce only that state data. Each of these tables inherits from the tables addr, faces, edges, etc located in the tiger schema. + All the geocode functions only reference the base tables, so there is no requirement that the data schema be called tiger_data or that data can't be further partitioned into other schemas -- e.g. a different schema for each state, as long as all the tables inherit from the tables in the tiger schema. @@ -26,8 +26,7 @@ you can upgrade the scripts using the accompanying upgrade_geocoder.bat - New in PostGIS 2.2.0 release is support for TIGER 2015 data and inclusion of Address Standardizer as part of PostGIS. - New in PostGIS 2.1.0 release is ability to install the TIGER Geocoder with the PostgreSQL extension model. Refer to for details. + You can install the TIGER Geocoder with the PostgreSQL extension model. Refer to for details. The function as a drop in replacement for in-built . Refer to for compile and installation instructions. @@ -841,9 +840,9 @@ rm -f ${TMPDIR}/*.* loader_lookuptables each record defines a kind of table (state, county), whether to process records in it and how to load them in. Defines the steps to import data, stage data, add, removes columns, indexes, and constraints for each. Each table is prefixed with the state and inherits from a table in the tiger schema. e.g. creates tiger_data.ma_faces which inherits from tiger.faces - Enhanced: 2.4.1 zip code 5 tabulation area (zcta5) load step was fixed and when enabled, zcta5 data is loaded as a single table called zcta5_all as part of the nation script load. + Enhanced: 2.4.1 ZIP Code 5 tabulation area (zcta5) load step was fixed and when enabled, zcta5 data is loaded as a single table called zcta5_all as part of the nation script load. Availability: 2.1.0 - If you want zip code 5 tabulation area (zcta5) to be included in your nation script load, do the following: UPDATE tiger.loader_lookuptables SET load = true WHERE table_name = 'zcta510'; + If you want ZIP Code 5 tabulation area (zcta5) to be included in your nation script load, do the following: UPDATE tiger.loader_lookuptables SET load = true WHERE table_name = 'zcta510'; If you were running tiger_2010 version and you want to reload as state with newer tiger data, you'll need to for the very first load generate and run drop statements before you run this script.
    @@ -980,7 +979,7 @@ CREATE INDEX idx_tiger_data_ma_faces_countyfp ON tiger_data.ma_faces USING btree parsed boolean - denotes if address was formed from normalize process. The normalize_address function sets this to true before returning the address. - zip4 last 4 digits of a 9 digit zip code. Availability: PostGIS 2.4.0. + zip4 last 4 digits of a 9 digit ZIP Code. Availability: PostGIS 2.4.0. address_alphanumeric Full street number even if it has alpha characters like 17R. Parsing of this is better using function. Availability: PostGIS 2.4.0. @@ -1084,7 +1083,7 @@ CREATE INDEX idx_tiger_data_ma_faces_countyfp ON tiger_data.ma_faces USING btree parsed boolean - denotes if address was formed from normalize process. The normalize_address function sets this to true before returning the address. - zip4 last 4 digits of a 9 digit zip code. Availability: PostGIS 2.4.0. + zip4 last 4 digits of a 9 digit ZIP Code. Availability: PostGIS 2.4.0. address_alphanumeric Full street number even if it has alpha characters like 17R. Parsing of this is better using function. Availability: PostGIS 2.4.0. diff --git a/doc/performance_tips.xml b/doc/performance_tips.xml index 9d991f600..5b21f5842 100644 --- a/doc/performance_tips.xml +++ b/doc/performance_tips.xml @@ -8,7 +8,7 @@
    Problem description - Current PostgreSQL versions (including 9.6) suffer from a query + Current PostgreSQL versions suffer from a query optimizer weakness regarding TOAST tables. TOAST tables are a kind of "extension room" used to store large (in the sense of data size) values that do not fit into normal data pages (like long texts, images or diff --git a/doc/reference_output.xml b/doc/reference_output.xml index 795ff71a5..f09888e38 100644 --- a/doc/reference_output.xml +++ b/doc/reference_output.xml @@ -1710,7 +1710,7 @@ SELECT ST_AsTWKB(array_agg(geom), array_agg(gid)) FROM mytable; Below is how we currently map PostGIS 2D/3D types to X3D types - The 'options' argument is a bitfield. For PostGIS 2.2+, this is used to denote whether to represent coordinates with X3D GeoCoordinates Geospatial node and also whether to flip the x/y axis. By default, ST_AsX3D outputs in database form (long,lat or X,Y), but X3D default of lat/lon, y/x may be preferred. + The 'options' argument is a bitfield that denotes whether to represent coordinates with the X3D GeoCoordinates geospatial node and whether to flip the x/y axis. By default, ST_AsX3D outputs in database form (long,lat or X,Y), but the X3D default of lat/lon, y/x may be preferred. diff --git a/doc/reference_raster.xml b/doc/reference_raster.xml index dc1e99c9b..3ddd3e373 100644 --- a/doc/reference_raster.xml +++ b/doc/reference_raster.xml @@ -3419,7 +3419,7 @@ FROM dummy_rast; Description Returns the spatial reference identifier of the raster object as defined in the spatial_ref_sys table. - From PostGIS 2.0+ the srid of a non-georeferenced raster/geometry is 0 instead of the prior -1. + Non-georeferenced rasters and geometries use SRID 0. diff --git a/extensions/postgis_extension_helper.sql.in b/extensions/postgis_extension_helper.sql.in index d5f473d16..d9c648683 100644 --- a/extensions/postgis_extension_helper.sql.in +++ b/extensions/postgis_extension_helper.sql.in @@ -27,45 +27,26 @@ DECLARE var_result boolean := false; var_class text := ''; var_is_aggregate boolean := false; - var_sql_list text := ''; - var_pgsql_version integer := pg_catalog.current_setting('server_version_num'); + var_sql_list text := ''; BEGIN var_class := CASE WHEN pg_catalog.lower(param_type) OPERATOR(pg_catalog.=)'function' OR pg_catalog.lower(param_type) OPERATOR(pg_catalog.=) 'aggregate' THEN 'pg_catalog.pg_proc' ELSE '' END; var_is_aggregate := CASE WHEN pg_catalog.lower(param_type) OPERATOR(pg_catalog.=) 'aggregate' THEN true ELSE false END; - IF var_pgsql_version OPERATOR(pg_catalog.<) 110000 THEN - var_sql_list := $sql$SELECT 'ALTER EXTENSION ' OPERATOR(pg_catalog.||) e.extname OPERATOR(pg_catalog.||) ' DROP ' OPERATOR(pg_catalog.||) $3 OPERATOR(pg_catalog.||) ' ' OPERATOR(pg_catalog.||) COALESCE(proc.proname OPERATOR(pg_catalog.||) '(' OPERATOR(pg_catalog.||) oidvectortypes(proc.proargtypes) OPERATOR(pg_catalog.||) ')' ,typ.typname, cd.relname, op.oprname, - cs.typname OPERATOR(pg_catalog.||) ' AS ' OPERATOR(pg_catalog.||) ct.typname OPERATOR(pg_catalog.||) ') ', opcname, opfname) OPERATOR(pg_catalog.||) ';' AS remove_command - FROM pg_catalog.pg_depend As d INNER JOIN pg_catalog.pg_extension As e - ON d.refobjid OPERATOR(pg_catalog.=) e.oid INNER JOIN pg_catalog.pg_class As c ON - c.oid OPERATOR(pg_catalog.=) d.classid - LEFT JOIN pg_catalog.pg_proc AS proc ON proc.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_type AS typ ON typ.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_class As cd ON cd.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_operator As op ON op.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_cast AS ca ON ca.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_type AS cs ON ca.castsource OPERATOR(pg_catalog.=) cs.oid - LEFT JOIN pg_catalog.pg_type AS ct ON ca.casttarget OPERATOR(pg_catalog.=) ct.oid - LEFT JOIN pg_opclass As oc ON oc.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_opfamily As ofa ON ofa.oid OPERATOR(pg_catalog.=) d.objid - WHERE d.deptype OPERATOR(pg_catalog.=) 'e' and e.extname OPERATOR(pg_catalog.=) $1 and c.relname OPERATOR(pg_catalog.=) $2 AND COALESCE(proc.proisagg, false) OPERATOR(pg_catalog.=) $4;$sql$; - ELSE -- for PostgreSQL 11 and above, they removed proc.proisagg among others and replaced with some func type thing - var_sql_list := $sql$SELECT 'ALTER EXTENSION ' OPERATOR(pg_catalog.||) e.extname OPERATOR(pg_catalog.||) ' DROP ' OPERATOR(pg_catalog.||) $3 OPERATOR(pg_catalog.||) ' ' OPERATOR(pg_catalog.||) COALESCE(proc.proname OPERATOR(pg_catalog.||) '(' OPERATOR(pg_catalog.||) oidvectortypes(proc.proargtypes) OPERATOR(pg_catalog.||) ')' ,typ.typname, cd.relname, op.oprname, - cs.typname OPERATOR(pg_catalog.||) ' AS ' OPERATOR(pg_catalog.||) ct.typname OPERATOR(pg_catalog.||) ') ', opcname, opfname) OPERATOR(pg_catalog.||) ';' AS remove_command - FROM pg_catalog.pg_depend As d INNER JOIN pg_catalog.pg_extension As e - ON d.refobjid OPERATOR(pg_catalog.=) e.oid INNER JOIN pg_catalog.pg_class As c ON - c.oid OPERATOR(pg_catalog.=) d.classid - LEFT JOIN pg_catalog.pg_proc AS proc ON proc.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_type AS typ ON typ.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_class As cd ON cd.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_operator As op ON op.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_cast AS ca ON ca.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_catalog.pg_type AS cs ON ca.castsource OPERATOR(pg_catalog.=) cs.oid - LEFT JOIN pg_catalog.pg_type AS ct ON ca.casttarget OPERATOR(pg_catalog.=) ct.oid - LEFT JOIN pg_opclass As oc ON oc.oid OPERATOR(pg_catalog.=) d.objid - LEFT JOIN pg_opfamily As ofa ON ofa.oid OPERATOR(pg_catalog.=) d.objid - WHERE d.deptype OPERATOR(pg_catalog.=) 'e' and e.extname OPERATOR(pg_catalog.=) $1 and c.relname OPERATOR(pg_catalog.=) $2 AND (proc.prokind OPERATOR(pg_catalog.=) 'a') OPERATOR(pg_catalog.=) $4;$sql$; - END IF; + var_sql_list := $sql$SELECT 'ALTER EXTENSION ' OPERATOR(pg_catalog.||) e.extname OPERATOR(pg_catalog.||) ' DROP ' OPERATOR(pg_catalog.||) $3 OPERATOR(pg_catalog.||) ' ' OPERATOR(pg_catalog.||) COALESCE(proc.proname OPERATOR(pg_catalog.||) '(' OPERATOR(pg_catalog.||) oidvectortypes(proc.proargtypes) OPERATOR(pg_catalog.||) ')' ,typ.typname, cd.relname, op.oprname, + cs.typname OPERATOR(pg_catalog.||) ' AS ' OPERATOR(pg_catalog.||) ct.typname OPERATOR(pg_catalog.||) ') ', opcname, opfname) OPERATOR(pg_catalog.||) ';' AS remove_command + FROM pg_catalog.pg_depend As d INNER JOIN pg_catalog.pg_extension As e + ON d.refobjid OPERATOR(pg_catalog.=) e.oid INNER JOIN pg_catalog.pg_class As c ON + c.oid OPERATOR(pg_catalog.=) d.classid + LEFT JOIN pg_catalog.pg_proc AS proc ON proc.oid OPERATOR(pg_catalog.=) d.objid + LEFT JOIN pg_catalog.pg_type AS typ ON typ.oid OPERATOR(pg_catalog.=) d.objid + LEFT JOIN pg_catalog.pg_class As cd ON cd.oid OPERATOR(pg_catalog.=) d.objid + LEFT JOIN pg_operator As op ON op.oid OPERATOR(pg_catalog.=) d.objid + LEFT JOIN pg_catalog.pg_cast AS ca ON ca.oid OPERATOR(pg_catalog.=) d.objid + LEFT JOIN pg_catalog.pg_type AS cs ON ca.castsource OPERATOR(pg_catalog.=) cs.oid + LEFT JOIN pg_catalog.pg_type AS ct ON ca.casttarget OPERATOR(pg_catalog.=) ct.oid + LEFT JOIN pg_opclass As oc ON oc.oid OPERATOR(pg_catalog.=) d.objid + LEFT JOIN pg_opfamily As ofa ON ofa.oid OPERATOR(pg_catalog.=) d.objid + WHERE d.deptype OPERATOR(pg_catalog.=) 'e' and e.extname OPERATOR(pg_catalog.=) $1 and c.relname OPERATOR(pg_catalog.=) $2 AND (proc.prokind OPERATOR(pg_catalog.=) 'a') OPERATOR(pg_catalog.=) $4;$sql$; FOR var_r IN EXECUTE var_sql_list USING param_extension, var_class, param_type, var_is_aggregate LOOP diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h index 6474de8c4..aacb4eab0 100644 --- a/libpgcommon/lwgeom_pg.h +++ b/libpgcommon/lwgeom_pg.h @@ -218,7 +218,7 @@ Datum BOX2D_union(PG_FUNCTION_ARGS); Datum LWGEOM_same(PG_FUNCTION_ARGS); -/** needed for sp-gist support PostgreSQL 11+ **/ +/** needed for SP-GiST support **/ Datum BOX3D_construct(PG_FUNCTION_ARGS); Datum LWGEOM_to_BOX2DF(PG_FUNCTION_ARGS); ----------------------------------------------------------------------- Summary of changes: doc/extras_address_standardizer.xml | 4 +-- doc/extras_tigergeocoder.xml | 19 ++++++----- doc/performance_tips.xml | 2 +- doc/reference_output.xml | 2 +- doc/reference_raster.xml | 2 +- extensions/postgis_extension_helper.sql.in | 51 ++++++++++-------------------- libpgcommon/lwgeom_pg.h | 2 +- 7 files changed, 31 insertions(+), 51 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Oct 30 13:39:32 2025 From: trac at osgeo.org (PostGIS) Date: Thu, 30 Oct 2025 20:39:32 -0000 Subject: [PostGIS] #828: [raster] Loader generates wrong SQL when NODATA for a band is NaN In-Reply-To: <054.6ed770badffdcb00cb6233d52d170998@osgeo.org> References: <054.6ed770badffdcb00cb6233d52d170998@osgeo.org> Message-ID: <069.14cb56f04ba68ef6b5180173133b140b@osgeo.org> #828: [raster] Loader generates wrong SQL when NODATA for a band is NaN ---------------------------+----------------------------- Reporter: jorgearevalo | Owner: jorgearevalo Type: defect | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: raster | Version: master Resolution: fixed | Keywords: loader,nan,gdal ---------------------------+----------------------------- Changes (by komzpa): * resolution: => fixed * status: reopened => closed Comment: Fixed in #4412 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 07:30:03 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 14:30:03 -0000 Subject: [PostGIS] #5832: Intersection test error with curved polygons In-Reply-To: <047.3a042a5979fb8526fe8a2ff4c42bde86@osgeo.org> References: <047.3a042a5979fb8526fe8a2ff4c42bde86@osgeo.org> Message-ID: <062.42650ce6affd66cc5df2a96944c76153@osgeo.org> #5832: Intersection test error with curved polygons ----------------------+-------------------------- Reporter: aaime | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS GEOS Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+-------------------------- Comment (by dbaston): GEOS actually supports PIP on CurvePolygon geometries since 3.13 and returns the correct result for this polygon. Support for MultiSurface / MultiPoint inputs in https://github.com/libgeos/geos/pull/1322. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 12:27:42 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 19:27:42 -0000 Subject: [PostGIS] #5832: Intersection test error with curved polygons In-Reply-To: <047.3a042a5979fb8526fe8a2ff4c42bde86@osgeo.org> References: <047.3a042a5979fb8526fe8a2ff4c42bde86@osgeo.org> Message-ID: <062.7acbfb8926fbcc0e134535367ee1fc84@osgeo.org> #5832: Intersection test error with curved polygons ----------------------+-------------------------- Reporter: aaime | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS GEOS Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+-------------------------- Comment (by robe): @pramsey, Should we have moved this to PostGIS GEOS. Don't you still need to do some work in PostGIS to expose that functionality? In which case that work should happen in 3.7? -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 12:58:23 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 19:58:23 -0000 Subject: [PostGIS] #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate In-Reply-To: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> References: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> Message-ID: <061.a494b91a5d6bb6f8b978ab4337496325@osgeo.org> #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate -----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: critical | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Okay that fixed the stats: After I ran {{{ ALTER EXTENSION postgis UPDATE; -- which brought me from 3.6.0 to 3.7.0dev master analyze nodes; }}} {{{ SELECT _postgis_stats('nodes', 'geom','2') ; }}} Now returns: {{{ {"ndims":2,"size":[97,102],"extent":{"min":[3.2287,50.7289],"max":[7.23561,53.513]},"table_features":133426320,"sample_features":30000,"not_null_features":30000,"histogram_features":30000,"histogram_cells":9894,"cells_covered":30000} }}} before it was giving me garbage numbers. {{{ SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.0927397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); }}} Now instead of 0 gives the expected: 0.07097181809551475 and {{{ EXPLAIN ANALYZE SELECT n.id FROM nodes AS n WHERE n.id = 8646506472 AND ST_Intersects(ST_GeomFromEWKT('SRID=4326;POLYGON((6.1198199 52.612195500000006,6.1198199 53.2038323,7.0927397 53.2038323,7.0927397 52.612195500000006,6.1198199 52.612195500000006))'), n.geom); }}} Is now no longer trying to use the spatial index: {{{ Index Scan using pk_nodes on nodes n (cost=0.57..21.08 rows=1 width=8) (actual time=71.461..71.461 rows=0 loops=1) Index Cond: (id = '8646506472'::bigint) Filter: st_intersects('0103000020E61000000100000005000000D5A35F11B27A184013A1116C5C4E4A40D5A35F11B27A18402A2F432D179A4A40D529EA27F75E1C402A2F432D179A4A40D529EA27F75E1C4013A1116C5C4E4A40D5A35F11B27A184013A1116C5C4E4A40'::geometry, geom) Rows Removed by Filter: 1 Planning Time: 30.506 ms Execution Time: 71.571 ms }}} I'll do another test before and after to confirm it is all working, but I think you fixed it. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 13:03:43 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 20:03:43 -0000 Subject: [PostGIS] #828: [raster] Loader generates wrong SQL when NODATA for a band is NaN In-Reply-To: <054.6ed770badffdcb00cb6233d52d170998@osgeo.org> References: <054.6ed770badffdcb00cb6233d52d170998@osgeo.org> Message-ID: <069.74ff85680bd252cf3f8ca1ab3732fd0a@osgeo.org> #828: [raster] Loader generates wrong SQL when NODATA for a band is NaN ---------------------------+----------------------------- Reporter: jorgearevalo | Owner: jorgearevalo Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: raster | Version: master Resolution: fixed | Keywords: loader,nan,gdal ---------------------------+----------------------------- Changes (by robe): * milestone: PostGIS Fund Me => PostGIS 3.7.0 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 13:04:41 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 20:04:41 -0000 Subject: [PostGIS] #4412: Support NaN as NODATA value in Raster In-Reply-To: <048.8a9f63b314ce5d229989926529d20ff6@osgeo.org> References: <048.8a9f63b314ce5d229989926529d20ff6@osgeo.org> Message-ID: <063.59f6655916cfb0b0fcdf3381032505cd@osgeo.org> #4412: Support NaN as NODATA value in Raster ----------------------+--------------------------- Reporter: komzpa | Owner: Komzpa Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: 2.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by robe): * milestone: PostGIS 2.5.3 => PostGIS 3.7.0 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 13:05:39 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 20:05:39 -0000 Subject: [PostGIS] #4412: Support NaN as NODATA value in Raster In-Reply-To: <048.8a9f63b314ce5d229989926529d20ff6@osgeo.org> References: <048.8a9f63b314ce5d229989926529d20ff6@osgeo.org> Message-ID: <063.a5472dac72d96e6e6a88e2ca66403184@osgeo.org> #4412: Support NaN as NODATA value in Raster ----------------------+--------------------------- Reporter: komzpa | Owner: Komzpa Type: defect | Status: closed Priority: medium | Milestone: PostGIS 2.5.3 Component: postgis | Version: 2.4.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by robe): * milestone: PostGIS 3.7.0 => PostGIS 2.5.3 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 13:06:12 2025 From: trac at osgeo.org (PostGIS) Date: Fri, 31 Oct 2025 20:06:12 -0000 Subject: [PostGIS] #828: [raster] Loader generates wrong SQL when NODATA for a band is NaN In-Reply-To: <054.6ed770badffdcb00cb6233d52d170998@osgeo.org> References: <054.6ed770badffdcb00cb6233d52d170998@osgeo.org> Message-ID: <069.c434727a2e06b3c5edaf7caf3df20de3@osgeo.org> #828: [raster] Loader generates wrong SQL when NODATA for a band is NaN ---------------------------+----------------------------- Reporter: jorgearevalo | Owner: jorgearevalo Type: defect | Status: closed Priority: medium | Milestone: PostGIS 2.5.3 Component: raster | Version: master Resolution: fixed | Keywords: loader,nan,gdal ---------------------------+----------------------------- Changes (by robe): * milestone: PostGIS 3.7.0 => PostGIS 2.5.3 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Oct 31 13:28:45 2025 From: git at osgeo.org (git at osgeo.org) Date: Fri, 31 Oct 2025 13:28:45 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-175-gb185e01e9 Message-ID: <20251031202846.3C15716D158@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via b185e01e95149f17cbfe486f3906dc6f921108e9 (commit) from 3910b861812e6db7c25004cb3a7f20533403592e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b185e01e95149f17cbfe486f3906dc6f921108e9 Author: Darafei Date: Fri Oct 31 20:28:06 2025 +0000 Translated PostGIS Manual using Weblate (Belarusian) Currently translated at 2.3% (137 of 5857 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/be/ diff --git a/doc/po/be/postgis-manual.po b/doc/po/be/postgis-manual.po index 3b1e49857..e86d9a026 100644 --- a/doc/po/be/postgis-manual.po +++ b/doc/po/be/postgis-manual.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-08-21 03:28+0000\n" -"PO-Revision-Date: 2025-10-17 20:47+0000\n" +"PO-Revision-Date: 2025-10-31 20:28+0000\n" "Last-Translator: Darafei \n" "Language-Team: Belarusian \n" @@ -185,7 +185,7 @@ msgstr "" "? ??????????? ?????????)." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Adding PostGIS objects and function definitions into your database is done " "by loading the various sql files located in [prefix]/share/" @@ -195,7 +195,7 @@ msgstr "" "[prefix]/share/contrib, ?? ???? ????????? ?????? ??????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The core PostGIS objects (geometry and geography types, and their support " "functions) are in the postgis.sql script. Raster " @@ -203,11 +203,11 @@ msgid "" "objects are in the topology.sql script." msgstr "" "???????? ??'???? PostGIS (???? geometry ? geography ? ?? ???????) ? " -"postgis.sql. ?????? ? ? rtpostgis.sql. ????????? ? ? topology.sql." +"postgis.sql. ?????? - ? rtpostgis.sql. ????????? - ? topology.sql." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "For a complete set of EPSG coordinate system definition identifiers, you can " "also load the spatial_ref_sys.sql definitions file and " @@ -219,7 +219,7 @@ msgstr "" "spatial_ref_sys. ???? ????????? ?????????? ST_Transform()." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "If you wish to add comments to the PostGIS functions, you can find them in " "the postgis_comments.sql script. Comments can be viewed " @@ -236,12 +236,12 @@ msgid "Run the following Shell commands in your terminal:" msgstr "????????? ? ????????? ????????? ??????? Shell:" #. Tag: title -#, fuzzy, no-c-format +#, no-c-format msgid "Upgrading spatial databases" msgstr "?????????? ??????????? ??? ????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Upgrading existing spatial databases can be tricky as it requires " "replacement or introduction of new PostGIS object definitions." @@ -278,7 +278,7 @@ msgstr "" "???? -Fc ? pg_dump, ?? ??????? ??????? ???????? ???? ??? ??????? ??????????." #. Tag: title -#, fuzzy, no-c-format +#, no-c-format msgid "Soft upgrade" msgstr "?????? ??????????" @@ -325,7 +325,7 @@ msgid "If you are running PostGIS 2.5 or lower, then do the following:" msgstr "???? ? ??? PostGIS 2.5 ??? ?????, ??????? ?????????:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "If you have multiple versions of PostGIS installed, and you don't want to " "upgrade to the latest, you can explicitly specify the version as follows:" @@ -334,27 +334,27 @@ msgstr "" "?????, ????? ??????? ????????? ????????? ?????? ???:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "If you get an error notice something like:" msgstr "???? ?? ???????? ???????????? ??? ???????, ????????:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Then you'll need to backup your database, create a fresh one as described in " " and then restore your backup on " "top of this new database." msgstr "" -"????? ??????? ????? ????, ???????? ?????, ?? ??????? ? , ? ???????? ????? ? ??." +"????? ??????? ?????????? ????? ????, ???????? ?????, ?? ??????? ? , ? ???????? ????? ? ??." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "If you get a notice message like:" msgstr "???? ?? ??????? ???????????? ????????:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Then everything is already up to date and you can safely ignore it. " "UNLESS you're attempting to upgrade from " @@ -368,7 +368,7 @@ msgstr "" "??? ????? ????? ????????:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "If you installed PostGIS originally without a version specified, you can " "often skip the reinstallation of postgis extension before restoring since " @@ -380,7 +380,7 @@ msgstr "" "EXTENSION postgis, ? ??? ?????????? ??????????? ????????? ??????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "If you are upgrading PostGIS extension from a version prior to 3.0.0, you " "will have a new extension postgis_raster which you can " @@ -494,7 +494,7 @@ msgstr "" "???????????, ?? ???????? ???? ? ?????????? ??? ?????? ??????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The dump/reload process is assisted by the postgis_restore script which " "takes care of skipping from the dump all definitions which belong to PostGIS " @@ -502,13 +502,13 @@ msgid "" "database with PostGIS installed without getting duplicate symbol errors or " "bringing forward deprecated objects." msgstr "" -"?????? postgis_restore ????????? ?????????? ? ????? ??? ??????????, ???? " +"?????? postgis_restore ????????? ?????????? ? ???????? ??? ??????????, ???? " "????????? ?? PostGIS (? ??? ???? ??????), ??? ???????? ???????? ????? ? " "????? ? ???? ? ??? ??????????? PostGIS ??? ?????? ? ??? ???????? ?????????? " "??'?????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Supplementary instructions for windows users are available at Windows Hard " @@ -518,36 +518,36 @@ msgstr "" "postgis/wiki/UsersWikiWinUpgrade\">Windows Hard upgrade." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "The Procedure is as follows:" msgstr "????????? ?????????:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Create a \"custom-format\" dump of the database you want to upgrade (let's " "call it olddb) include binary blobs (-b) and verbose (-v) " "output. The user can be the owner of the db, need not be postgres super " "account." msgstr "" -"???????? ???? ? ??????? \"custom\" ??? ???? olddb, " +"???????? ???????? ? ??????? \"custom\" ??? ???? olddb, " "????????? ???????? ??'???? (-b) ? ?????????? ????? (-v). ???????????? ???? " "???? ???????????? ????, ?? ?????????? superuser." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Do a fresh install of PostGIS in a new database -- we'll refer to this " "database as newdb. Please refer to and " "for instructions on how to do this." msgstr "" -"??????? ?????? ????????? PostGIS ? ????? ???? ? ??????? ?? newdbnewdb. ????????????? ? ? ." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The spatial_ref_sys entries found in your dump will be restored, but they " "will not override existing ones in spatial_ref_sys. This is to ensure that " @@ -555,10 +555,10 @@ msgid "" "If for any reason you really want your own overrides of standard entries " "just don't load the spatial_ref_sys.sql file when creating the new db." msgstr "" -"?????? spatial_ref_sys ? ????? ?????? ?????????, ??? ?? ?????????? ????????. " -"???? ????????, ??? ??????????? ? ?????????? ?????? ??????? ? ?????????? " -"????. ???? ??? ???????? ???? ?????????? ??????????? ???????, ?????? ?? " -"?????????? spatial_ref_sys.sql ??? ????????? ????? ????." +"?????? spatial_ref_sys ? ????? ???????? ?????? ?????????, ??? ?? ?????????? " +"????????. ???? ????????, ??? ??????????? ? ?????????? ?????? ??????? ? " +"?????????? ????. ???? ??? ???????? ???? ?????????? ??????????? ???????, " +"?????? ?? ?????????? spatial_ref_sys.sql ??? ????????? ????? ????." #. Tag: para #, fuzzy, no-c-format @@ -588,7 +588,7 @@ msgstr "" "????????? ??????? psql ??????? ? stderr. ?????????? ???." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Errors may arise in the following cases:" msgstr "??????? ???????? ? ????????? ????????:" @@ -610,7 +610,7 @@ msgstr "" "? ???????? ?????????? ???? uninstall_legacy.sql." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Some custom records of spatial_ref_sys in dump file have an invalid SRID " "value. Valid SRID values are bigger than 0 and smaller than 999000. Values " @@ -621,16 +621,16 @@ msgid "" "invariant to hold and possibly also its primary key ( when multiple invalid " "SRIDS get converted to the same reserved SRID value )." msgstr "" -"????????? ???? ??????? ?????? spatial_ref_sys ? ????? ????? ?????????? SRID. " -"????????? SRID ? ????? ?? 0 ? ???? ?? 999000. ???????? 999000..999999 " -"????????????? ??? ?????????? ????????????, ? ???????? > 999999 " -"??????????????. ??? ???? ????? ?????? ?????? ?????????, ??? ????? ???????? " -"> 999999 ?????? ?????????? ? ????????????? ????????, ??? ? ??????? " -"spatial_ref_sys ?????? ???????? ?, ???????, ???????? ???? (???? ???????? " -"??????????? SRID ?????????????? ? ????? ????????????? SRID)." +"????????? ???? ??????? ?????? spatial_ref_sys ? ????? ???????? ????? " +"?????????? SRID. ????????? SRID - ????? ?? 0 ? ???? ?? 999000. ???????? " +"999000..999999 ????????????? ??? ?????????? ????????????, ? ???????? > " +"999999 ??????????????. ??? ???? ????? ?????? ?????? ?????????, ??? ????? " +"???????? > 999999 ?????? ?????????? ? ????????????? ????????, ??? ? " +"??????? spatial_ref_sys ?????? ???????? ?, ???????, ???????? ???? (???? " +"???????? ??????????? SRID ?????????????? ? ????? ????????????? SRID)." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "In order to fix this you should copy your custom SRS to a SRID with a valid " "value (maybe in the 910000..910999 range), convert all your tables to the " @@ -692,7 +692,7 @@ msgstr "" "???????, ???? ???????????, ???????? ? ???????, ????? ???? ??????? ????????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "For general details about optimizing PostgreSQL, refer to postgresql.auto.conf." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "In addition to the Postgres settings, PostGIS has some custom settings which " "are listed in ." msgstr "" -"?????? ????? Postgres, ? PostGIS ???? ???? ?????? ? ???????? ." #. Tag: title -#, fuzzy, no-c-format +#, no-c-format msgid "Startup" msgstr "??????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "These settings are configured in postgresql.conf:" msgstr "????? ????????? ???????????? ? postgresql.conf:" #. Tag: link -#, fuzzy, no-c-format +#, no-c-format msgid "constraint_exclusion" msgstr "constraint_exclusion" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Default: partition" msgstr "?? ?????????: partition" @@ -755,7 +755,7 @@ msgstr "" "?????? ??? ?????? ? ???????? ??????????? ? ?? ?????? ??????? ???????." #. Tag: link -#, fuzzy, no-c-format +#, no-c-format msgid "shared_buffers" msgstr "shared_buffers" @@ -788,12 +788,12 @@ msgstr "" "??????????? ???????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Default: 8" msgstr "?? ?????????: 8" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Sets the maximum number of background processes that the system can support. " "This parameter can only be set at server start." @@ -802,28 +802,28 @@ msgstr "" "?????? ???????." #. Tag: title -#, fuzzy, no-c-format +#, no-c-format msgid "Runtime" msgstr "??? ?????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "work_mem - sets the size of " "memory used for sort operations and complex queries" msgstr "" "work_mem ? ????? ?????? ??? " +"config-resource.html#GUC-WORK-MEM\">work_mem - ????? ?????? ??? " "?????????? ? ????????? ????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Default: 1-4MB" -msgstr "?? ?????????: 1?4 ??" +msgstr "?? ?????????: 1-4 ??" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Adjust up for large dbs, complex queries, lots of RAM" msgstr "???????????? ??? ??????? ???, ????????? ??????? ? ???? ???? RAM" @@ -833,31 +833,31 @@ msgid "Adjust down for many concurrent users or low RAM." msgstr "????????? ??? ??????? ?????????????? ??? ???????? RAM." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "If you have lots of RAM and few developers:" msgstr "???? ???? RAM ? ???? ??????????? ??????????????:" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "maintenance_work_mem " "- the memory size used for VACUUM, CREATE INDEX, etc." msgstr "" "maintenance_work_mem ?" +"config-resource.html#GUC-MAINTENANCE-WORK-MEM\">maintenance_work_mem -" " ?????? ??? VACUUM, CREATE INDEX ? ???." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Default: 16-64MB" -msgstr "?? ?????????: 16?64 ??" +msgstr "?? ?????????: 16-64 ??" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Generally too low - ties up I/O, locks objects while swapping memory" msgstr "" -"???????? ??????? ???? ? ????????? I/O ? ?????? ??'????, ???? ?????????? " +"???????? ??????? ???? - ????????? I/O ? ?????? ??'????, ???? ?????????? " "??????? ??????." #. Tag: para @@ -870,7 +870,7 @@ msgstr "" "??????????????. ???? RAM ???? ? ?????????????? ????:" #. Tag: link -#, fuzzy, no-c-format +#, no-c-format msgid "max_parallel_workers_per_gather" msgstr "max_parallel_workers_per_gather" @@ -893,7 +893,7 @@ msgstr "" "????????? max_worker_processes ?? ??????? ?? ?????? ? ???????." #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "Default: 0" msgstr "?? ?????????: 0" @@ -930,12 +930,12 @@ msgstr "" #. Tag: chapter #, no-c-format msgid "&extras_address_standardizer; &extras_tigergeocoder;" -msgstr "" +msgstr "&extras_address_standardizer; &extras_tigergeocoder;" #. Tag: title #, no-c-format msgid "Address Standardizer" -msgstr "" +msgstr "?????????????? ???????" #. Tag: para #, no-c-format @@ -945,6 +945,10 @@ msgid "" "PAGC PostgreSQL Address Standardizer)." msgstr "" +"???? ???? ??????????????? PAGC (?????????????? ??? ?????? ?????????? - PAGC PostgreSQL Address Standardizer)." #. Tag: para #, no-c-format @@ -953,6 +957,9 @@ msgid "" "address and normalizes it based on a set of rules stored in a table and " "helper lex and gaz tables." msgstr "" +"?????????????? ??????? - ???? ?????? ???????????? ???????, ??? ?????? " +"???????? ????? ? ?????????? ??? ??????? ?????? ???????? ? ??????? ? " +"?????????? ???????? lex ? gaz." #. Tag: para #, no-c-format @@ -965,6 +972,13 @@ msgid "" "contains gaz, lex, and rules tables for US data. This extensions can be " "installed via: CREATE EXTENSION address_standardizer_data_us;" msgstr "" +"??? ??????? ? ???? ?????????? ????????? PostgreSQL ? ?????? " +"address_standardizer, ???? ????? ?????????? ???? CREATE " +"EXTENSION address_standardizer;. ????????? ?? ????????? " +"address_standardizer ???????? ???????? ????????? ????? " +"address_standardizer_data_us, ???? ??????? ??????? gaz, lex ? " +"rules ??? ????? ???. ??? ????? ?????????? ???: CREATE EXTENSION " +"address_standardizer_data_us;" #. Tag: para #, no-c-format @@ -972,6 +986,8 @@ msgid "" "The code for this extension can be found in the PostGIS extensions/" "address_standardizer and is currently self-contained." msgstr "" +"??? ?????? ????????? ??????????? ? PostGIS ? ???????? extensions/" +"address_standardizer ? ????? ???????????????." #. Tag: para #, no-c-format @@ -979,11 +995,13 @@ msgid "" "For installation instructions refer to: ." msgstr "" +"?????????? ?? ???????????: ." #. Tag: title #, no-c-format msgid "How the Parser Works" -msgstr "" +msgstr "?? ?????? ??????" #. Tag: para #, no-c-format @@ -7775,7 +7793,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Introduction" -msgstr "" +msgstr "????????" #. Tag: para #, no-c-format @@ -7808,7 +7826,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Project Steering Committee" -msgstr "" +msgstr "????????? ??????? ???????" #. Tag: para #, no-c-format @@ -7849,7 +7867,7 @@ msgstr "" #. Tag: term #, no-c-format msgid "Darafei Praliaskouski" -msgstr "" +msgstr "??????? ????????????" #. Tag: para #, no-c-format @@ -7889,7 +7907,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Core Contributors Present" -msgstr "" +msgstr "???????? ?????????? (??????????)" #. Tag: term #, no-c-format @@ -7961,7 +7979,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Core Contributors Past" -msgstr "" +msgstr "???????? ?????????? (???????)" #. Tag: term #, no-c-format @@ -8107,7 +8125,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Other Contributors" -msgstr "" +msgstr "????? ??????????" #. Tag: term #, no-c-format @@ -9087,12 +9105,12 @@ msgstr "" #. Tag: title #, no-c-format msgid "Small tables of large geometries" -msgstr "" +msgstr "????????? ??????? ? ??????? ???????????" #. Tag: title #, no-c-format msgid "Problem description" -msgstr "" +msgstr "???????? ????????" #. Tag: para #, no-c-format @@ -9200,7 +9218,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "CLUSTERing on geometry indices" -msgstr "" +msgstr "????????????? ?? ???????? ?????????" #. Tag: para #, no-c-format @@ -9280,7 +9298,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS &last_release_version; Manual" -msgstr "" +msgstr "??????????? PostGIS &last_release_version;" #. Tag: orgname #, no-c-format @@ -9329,7 +9347,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Aggregate Functions" -msgstr "" +msgstr "?????????? ??????? PostGIS" #. Tag: section #, no-c-format @@ -9347,7 +9365,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Window Functions" -msgstr "" +msgstr "???????? ??????? PostGIS" #. Tag: section #, no-c-format @@ -9366,7 +9384,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS SQL-MM Compliant Functions" -msgstr "" +msgstr "??????? PostGIS, ???????????? ? SQL-MM" #. Tag: section #, no-c-format @@ -9383,7 +9401,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Geography Support Functions" -msgstr "" +msgstr "??????? ????????? ????????? PostGIS" #. Tag: para #, no-c-format @@ -9412,7 +9430,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Raster Support Functions" -msgstr "" +msgstr "??????? ????????? ??????? PostGIS" #. Tag: para #, no-c-format @@ -9430,7 +9448,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Geometry / Geography / Raster Dump Functions" -msgstr "" +msgstr "??????? ????????????? ?????????/?????????/??????? PostGIS" #. Tag: section #, no-c-format @@ -9448,7 +9466,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Box Functions" -msgstr "" +msgstr "??????? ????? ? ?????????????? PostGIS" #. Tag: para #, no-c-format @@ -9467,7 +9485,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Functions that support 3D" -msgstr "" +msgstr "??????? PostGIS ? ?????????? 3D" #. Tag: section #, no-c-format @@ -9484,7 +9502,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Curved Geometry Support Functions" -msgstr "" +msgstr "??????? PostGIS ??? ????????????? ?????????" #. Tag: section #, no-c-format @@ -9501,7 +9519,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Polyhedral Surface Support Functions" -msgstr "" +msgstr "??????? PostGIS ??? ??????????? ?????????" #. Tag: section #, no-c-format @@ -9518,7 +9536,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "PostGIS Function Support Matrix" -msgstr "" +msgstr "??????? ????????? ??????? PostGIS" #. Tag: para #, no-c-format @@ -9641,12 +9659,12 @@ msgstr "" #. Tag: title #, no-c-format msgid "New, Enhanced or changed PostGIS Functions" -msgstr "" +msgstr "?????, ?????????? ? ???????? ??????? PostGIS" #. Tag: title #, no-c-format msgid "PostGIS Reference" -msgstr "" +msgstr "???????? PostGIS" #. Tag: para #, no-c-format @@ -9655,6 +9673,9 @@ msgid "" "need. There are other functions which are required support functions to the " "PostGIS objects which are not of use to a general user." msgstr "" +"????? ?????????? ???????, ????, ?????? ?? ???, ??????????? ????????????? " +"PostGIS. ???? ? ????? ??????? ????????? ??'????? PostGIS, ???? ???????? ?? " +"??????????? ???????? ???? ??????????????." #. Tag: para #, no-c-format @@ -9683,12 +9704,12 @@ msgstr "" #. Tag: title #, no-c-format msgid "Geometry Accessors" -msgstr "" +msgstr "??????? ??????? ?? ?????????" #. Tag: refpurpose #, no-c-format msgid "Returns the type of a geometry as text." -msgstr "" +msgstr "?????? ??? ????????? ?? ?????." #. Tag: para #, no-c-format @@ -9696,6 +9717,8 @@ msgid "" "Returns the type of the geometry as a string. Eg: 'LINESTRING', 'POLYGON', " "'MULTIPOINT', etc." msgstr "" +"?????? ??? ????????? ? ???????? ?????. ????.: 'LINESTRING', 'POLYGON', " +"'MULTIPOINT' ? ???." #. Tag: para #, no-c-format @@ -9718,31 +9741,33 @@ msgid "" "Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was " "introduced." msgstr "" +"??????????: 2.0.0 - ????????? ????????? ??????????? ?????????, ???????????? " +"? TIN." #. Tag: para #, no-c-format msgid "&sfs_compliant;" -msgstr "" +msgstr "&sfs_compliant;" #. Tag: para #, no-c-format msgid "&curve_support;" -msgstr "" +msgstr "&curve_support;" #. Tag: para #, no-c-format msgid "&P_support;" -msgstr "" +msgstr "&P_support;" #. Tag: para #, no-c-format msgid "&T_support;" -msgstr "" +msgstr "&T_support;" #. Tag: refpurpose #, no-c-format msgid "Returns the boundary of a geometry." -msgstr "" +msgstr "?????? ???? ?????????." #. Tag: para #, no-c-format @@ -9754,11 +9779,15 @@ msgid "" "representational geometry primitives as discussed in the OGC SPEC, section " "3.12.2." msgstr "" +"?????? ????????? ????????????? ???? ????? ?????????. ????????????? ???? " +"????????? ? ???????? 3.12.3.2 ???????????? OGC. ???????? ????? - ???????? ? " +"????????????? ?????? ????????? ??'???, ???? ????? ???????????? ???? ??????? " +"???????????? ?????????, ?? ??????? ? ???????? 3.12.2 OGC SPEC." #. Tag: para #, no-c-format msgid "Performed by the GEOS module" -msgstr "" +msgstr "??????????? ??????? GEOS" #. Tag: para #, no-c-format @@ -9771,12 +9800,12 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sfs_compliant; OGC SPEC s2.1.1.1" -msgstr "" +msgstr "&sfs_compliant; OGC SPEC s2.1.1.1" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1.17" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM IEC 13249-3: 5.1.17" #. Tag: para #, no-c-format @@ -9804,6 +9833,7 @@ msgstr "" msgid "" ", , " msgstr "" +", , " #. Tag: refpurpose #, no-c-format @@ -9847,7 +9877,7 @@ msgstr "" #. Tag: para #, no-c-format msgid "&M_support;" -msgstr "" +msgstr "&M_support;" #. Tag: para #, no-c-format @@ -9856,6 +9886,9 @@ msgid "" "linkend=\"ST_Y\"/>, , , " "" msgstr "" +", , , , , , " #. Tag: refpurpose #, no-c-format @@ -10092,6 +10125,8 @@ msgid "" ", , , " msgstr "" +", , , " #. Tag: refpurpose #, no-c-format @@ -10146,6 +10181,9 @@ msgid "" "linkend=\"ST_Dump\"/>, , " msgstr "" +", , , , " #. Tag: refpurpose #, no-c-format @@ -10164,7 +10202,7 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 7.1.4" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 7.1.4" #. Tag: para #, no-c-format @@ -10278,18 +10316,19 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sfs_compliant; 2.1.5.1" -msgstr "" +msgstr "&sfs_compliant; 2.1.5.1" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 8.2.3, 8.3.3" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 8.2.3, 8.3.3" #. Tag: para #, no-c-format msgid "" ", , " msgstr "" +", , " #. Tag: refpurpose #, no-c-format @@ -10328,12 +10367,12 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 9.1.5" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 9.1.5" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -10358,7 +10397,7 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 5.1.4" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 5.1.4" #. Tag: refpurpose #, no-c-format @@ -10379,7 +10418,7 @@ msgstr "" #. Tag: para #, no-c-format msgid ", " -msgstr "" +msgstr ", " #. Tag: refpurpose #, no-c-format @@ -10397,7 +10436,7 @@ msgstr "" #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 8.2.6, 8.3.5" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 8.2.6, 8.3.5" #. Tag: para #, no-c-format @@ -10529,11 +10568,13 @@ msgid "" "SQL-MM defines the result of ST_IsEmpty(NULL) to be 0, while PostGIS returns " "NULL." msgstr "" +"SQL-MM ???????? ????? ST_IsEmpty(NULL) ?? 0, ? PostGIS " +"????????? NULL." #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 5.1.7" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 5.1.7" #. Tag: para #, no-c-format @@ -10542,6 +10583,8 @@ msgid "" "ST_GeomFromText('GEOMETRYCOLLECTION(EMPTY)') was allowed. This is now " "illegal in PostGIS 2.0.0 to better conform with SQL/MM standards" msgstr "" +"?????: 2.0.0 - ????? ?????????? ST_GeomFromText('GEOMETRYCOLLECTION(EMPTY)')" +". ????? ???? ?????????? ??? ?????? ???????????? SQL/MM." #. Tag: refpurpose #, no-c-format @@ -10579,24 +10622,27 @@ msgid "" "an exterior ring) then both ST_IsPolygonCW and ST_IsPolygonCCW will return " "false." msgstr "" +"???? ????????? ?????? ?? ??????????? ?????????? (????????? ? ???????), ?? ? " +"ST_IsPolygonCW, ? ST_IsPolygonCCW ??????? false." #. Tag: para #, no-c-format msgid "Availability: 2.4.0" -msgstr "" +msgstr "???????????: 2.4.0" #. Tag: para #, no-c-format msgid "" ", , " msgstr "" +", , " #. Tag: refpurpose #, no-c-format msgid "" "Tests if Polygons have exterior rings oriented clockwise and interior rings " "oriented counter-clockwise." -msgstr "" +msgstr "????????, ?? ??????? ?????? ?? ?????????????, ? ????????? - ???????." #. Tag: para #, no-c-format @@ -10609,21 +10655,24 @@ msgstr "" #. Tag: refpurpose #, no-c-format msgid "Tests if a LineString is closed and simple." -msgstr "" +msgstr "????????, ?? LINESTRING ???????? ? ??????." #. Tag: para -#, no-c-format +#, fuzzy, no-c-format msgid "" "Returns TRUE if this LINESTRING is " "both (ST_StartPoint(g) ~= " "ST_Endpoint(g)) and (does not self " "intersect)." msgstr "" +"?????? TRUE, ???? LINESTRING ?????????? (ST_StartPoint(g) ~= ST_EndPoint(g)) ? (?? ??? ????????????????)." #. Tag: para #, no-c-format msgid "&sqlmm_compliant; SQL-MM 3: 7.1.6" -msgstr "" +msgstr "&sqlmm_compliant; SQL-MM 3: 7.1.6" #. Tag: para #, no-c-format @@ -10631,6 +10680,8 @@ msgid "" "SQL-MM defines the result of ST_IsRing(NULL) to be 0, while " "PostGIS returns NULL." msgstr "" +"SQL-MM ???????? ????? ST_IsRing(NULL) ?? 0, ? PostGIS ????????? " +"NULL." #. Tag: para #, no-c-format @@ -11315,7 +11366,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Bounding Box Functions" -msgstr "" +msgstr "??????? ?????????????? ????????????" #. Tag: para #, no-c-format @@ -12024,7 +12075,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Geometry Constructors" -msgstr "" +msgstr "???????????? ?????????" #. Tag: refpurpose #, no-c-format @@ -13042,7 +13093,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Coverages" -msgstr "" +msgstr "????????" #. Tag: para #, no-c-format @@ -13306,7 +13357,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Geometry Editors" -msgstr "" +msgstr "????????? ?????????" #. Tag: para #, no-c-format @@ -14076,7 +14127,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Technical Background" -msgstr "" +msgstr "????????? ???????" #. Tag: para #, no-c-format @@ -14759,7 +14810,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "Exceptional Functions" -msgstr "" +msgstr "????????? ???????" #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/be/postgis-manual.po | 299 ++++++++++++++++++++++++++------------------ 1 file changed, 175 insertions(+), 124 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Oct 31 17:16:04 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 01 Nov 2025 00:16:04 -0000 Subject: [PostGIS] #5832: Intersection test error with curved polygons In-Reply-To: <047.3a042a5979fb8526fe8a2ff4c42bde86@osgeo.org> References: <047.3a042a5979fb8526fe8a2ff4c42bde86@osgeo.org> Message-ID: <062.104c79d3ab0489b777c2aca9ccba4315@osgeo.org> #5832: Intersection test error with curved polygons ----------------------+-------------------------- Reporter: aaime | Owner: pramsey Type: defect | Status: new Priority: medium | Milestone: PostGIS GEOS Component: postgis | Version: 3.4.x Resolution: | Keywords: ----------------------+-------------------------- Comment (by pramsey): Erm, yeah, kind of scary. Right now all curves are stroked on the postgis side and then handed over to GEOS as linear geometries, and that's true for all functions, so the stroking is all nice and centralized (if curved then stroke()). However, if we are going to start to have partial support for curves on GEOS, that implies either (a) making sure all GEOS use cases do stroking on curves or (b) selectively stroking on the postgis side. But yeah, probably needs to be done, to make the "move to curve" more real. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 20:47:41 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 01 Nov 2025 03:47:41 -0000 Subject: [PostGIS] #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate In-Reply-To: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> References: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> Message-ID: <061.89834aa3e299074f0230ef1c4c3b3778@osgeo.org> #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate -----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: critical | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): Okay I retested and confirmed the same behavior. So I think we just need to backport the changes to 3.6 and 3.5. I'll double-check 3.4. I know 3.3 wasn't impacted by this cause I started with a 3.3 database as my template. {{{ SELECT pg_terminate_backend(pid) FROM pg_stat_activity where datname = 'osm_nl_33'; CREATE DATABASE osm_nl_test TEMPLATE osm_nl_33; \c osm_nl_test analyze nodes; SELECT postgis_full_version(); -- POSTGIS="3.3.9dev 3.3.7-53-g9a6079a60" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.6.0" LIBXML="2.9.14" LIBJSON="0.18" LIBPROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)" SELECT _postgis_stats('nodes', 'geom','2') ; -- {"ndims":2,"size":[96,103],"extent":{"min":[3.32454,50.725],"max":[7.22931,53.8452]},"table_features":133481792,"sample_features":30000,"not_null_features":30000,"histogram_features":29999,"histogram_cells":9888,"cells_covered":29999} SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.0927397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); -- 0.0735942255590728 UPDATE pg_extension SET extversion = 'ANY'; ALTER EXTENSION postgis UPDATE TO "3.6.0"; analyze nodes; SELECT postgis_full_version(); -- POSTGIS="3.6.0 3.6.0" [EXTENSION] PGSQL="160" GEOS="3.15.0dev- CAPI-1.21.0" PROJ="9.6.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 9.6.0) LIBXML="2.9.14" LIBJSON="0.18" LIBPROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)" SELECT _postgis_stats('nodes', 'geom','2') ; -- {"ndims":2,"size":[-2147483648,-2147483648],"extent":{"min":[3.34292,50.7306],"max":[7.23458,53.553]},"table_features":133608672,"sample_features":30000,"not_null_features":30000,"histogram_features":30000,"histogram_cells":0,"cells_covered":0} SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.0927397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); -- 0 ALTER EXTENSION postgis UPDATE TO "3.7.0dev"; SELECT postgis_full_version(); -- POSTGIS="3.7.0dev 3.6.0rc2-175-gb185e01e9" [EXTENSION] PGSQL="160" GEOS="3.15.0dev-CAPI-1.21.0" PROJ="9.6.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 9.6.0) LIBXML="2.9.14" LIBJSON="0.18" LIBPROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)" analyze nodes; SELECT _postgis_stats('nodes', 'geom','2') ; -- {"ndims":2,"size":[98,101],"extent":{"min":[3.20275,50.7382],"max":[7.26312,53.5539]},"table_features":133429664,"sample_features":30000,"not_null_features":30000,"histogram_features":29999,"histogram_cells":9898,"cells_covered":29999} SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.0927397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); -- 0.07800694427262457 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Fri Oct 31 21:21:19 2025 From: trac at osgeo.org (PostGIS) Date: Sat, 01 Nov 2025 04:21:19 -0000 Subject: [PostGIS] #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate In-Reply-To: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> References: <046.75677ad63d74709c6ed20baed0392698@osgeo.org> Message-ID: <061.c426e66480da51f6767925d1a02747b2@osgeo.org> #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate -----------------------+--------------------------- Reporter: robe | Owner: pramsey Type: defect | Status: new Priority: critical | Milestone: PostGIS 3.4.5 Component: postgis | Version: 3.5.x Resolution: | Keywords: -----------------------+--------------------------- Comment (by robe): I was mistaken 3.4 looks a little messed up too but not as messed up as 3.5 and 3.6. {{{ -- I did a analyze check before upgrade from 3.3 to 3.4 and it looked okay UPDATE pg_extension SET extversion = 'ANY' WHERE extname = 'postgis'; ALTER EXTENSION postgis UPDATE TO "3.4.2"; SELECT postgis_full_version(); -- POSTGIS="3.4.2 c19ce56" [EXTENSION] PGSQL="160" GEOS="3.15.0dev- CAPI-1.21.0" (compiled against GEOS 3.12.1) analyze nodes; SELECT _postgis_stats('nodes', 'geom','2'); -- {"ndims":2,"size":[1,1],"extent":{"min":[3.35799,50.7174],"max":[7.22904,53.6371]},"table_features":133295792,"sample_features":30000,"not_ null_features":30000,"histogram_features":30000,"histogram_cells":1,"cells_covered":30000} SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.0927 397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); -- 0.050928621419270834 (1 row) }}} But since the selectivity is not 0, it used the right plans which is why I probably didn't notice. I reran analyze again to see if it would improve the selectivity correctness. and change was not that different {{{ 0.05216378173828125 {"ndims":2,"size":[1,1],"extent":{"min":[3.3428,50.7134],"max":[7.22912,53.5528]},"table_features":133346496,"sample_features":30000,"not_n ull_features":30000,"histogram_features":30000,"histogram_cells":1,"cells_covered":30000} }}} Then I upgraded to 3.5.4 {{{ ALTER EXTENSION postgis UPDATE TO "3.5.4"; SELECT postgis_full_version(); -- POSTGIS="3.5.4 3.5.4" [EXTENSION] PGSQL="160" GEOS="3.15.0dev- CAPI-1.21.0" PROJ="9.6.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.or g USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 9.6.0) LIBXML="2.9.14" LIBJSON="0.18" LIBP ROTOBUF="1.5.1" WAGYU="0.5.0 (Internal)" (1 row) analyze nodes; SELECT _postgis_stats('nodes', 'geom','2') ; -- {"ndims":2,"size":[-2147483648,-2147483648],"extent":{"min":[2.87586,50.6011],"max":[7.25607,53.8865]},"table_features":133392376,"sample_f eatures":30000,"not_null_features":30000,"histogram_features":30000,"histogram_cells":0,"cells_covered":0} (1 row) SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.092 7397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); -- 0 (1 row) ALTER EXTENSION postgis UPDATE TO "3.7.0dev"; analyze nodes; SELECT _postgis_stats('nodes', 'geom','2'); -- {"ndims":2,"size":[96,102],"extent":{"min":[3.35549,50.7377],"max":[7.26203,53.5679]},"table_features":133439184,"sample_features":30000,"n ot_null_features":30000,"histogram_features":29998,"histogram_cells":9792,"cells_covered":29998} SELECT _postgis_selectivity ('nodes', 'geom', ST_GeomFromEWKT('SRID=4326;POLYGON((6.11982 52.6121955,6.11982 53.2038323,7.0927 397 53.2038323,7.0927397 52.6121955,6.11982 52.6121955))'), '2'); -- 0.07374775973540136 }}} and as you see real crapola starts at 3.5 and then upgrading to 3.7, looks good again. So I think we need to backport to 3.4, 3.5, and 3.6 and then we can close this ticket out. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.