[Git][debian-gis-team/geos][experimental] 10 commits: Rebuild with GCC 13 from experimental.

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Thu Jun 15 04:16:15 BST 2023



Bas Couwenberg pushed to branch experimental at Debian GIS Project / geos


Commits:
416027a3 by Bas Couwenberg at 2023-06-14T11:48:30+02:00
Rebuild with GCC 13 from experimental.

- - - - -
0721859f by Bas Couwenberg at 2023-06-14T12:10:15+02:00
Revert "Rebuild with GCC 13 from experimental."

This reverts commit 416027a342c42b9935c7a3d753b756fc389c4f80.

- - - - -
a8e816e4 by Bas Couwenberg at 2023-06-14T22:03:52+02:00
New upstream version 3.12.0~beta2
- - - - -
1d82afce by Bas Couwenberg at 2023-06-14T22:04:03+02:00
Update upstream source from tag 'upstream/3.12.0_beta2'

Update to upstream version '3.12.0~beta2'
with Debian dir c22fd67a950a3ab7275956b433d86ba7009a3fb3
- - - - -
db753eb1 by Bas Couwenberg at 2023-06-14T22:04:21+02:00
New upstream beta release.

- - - - -
b8319a2b by Bas Couwenberg at 2023-06-14T22:06:10+02:00
Drop patches, applied upstream.

- - - - -
7246407c by Bas Couwenberg at 2023-06-14T22:07:27+02:00
Update copyright file.

- - - - -
de1060f1 by Bas Couwenberg at 2023-06-14T22:09:49+02:00
Update symbols for other architectures.

- - - - -
f5fc9d0d by Bas Couwenberg at 2023-06-14T22:43:38+02:00
Update symbols for amd64.

- - - - -
17978372 by Bas Couwenberg at 2023-06-14T22:43:38+02:00
Set distribution to experimental.

- - - - -


23 changed files:

- NEWS.md
- Version.txt
- capi/geos_c.h.in
- capi/geos_ts_c.cpp
- debian/changelog
- debian/copyright
- debian/libgeos-c1v5.symbols
- debian/libgeos3.12.0.symbols
- − debian/patches/0001-Remove-defunct-doxygen-entry.patch
- − debian/patches/series
- − debian/patches/spelling-errors.patch
- examples/README.md
- + examples/capi_indexed_predicate.c
- examples/capi_strtree.c
- include/geos/coverage/CoverageRingEdges.h
- include/geos/geom/Geometry.h
- include/geos/geom/HeuristicOverlay.h
- release.md
- src/coverage/CoverageBoundarySegmentFinder.cpp
- src/geom/Geometry.cpp
- src/geom/HeuristicOverlay.cpp
- tests/unit/geom/DimensionTest.cpp
- + tests/unit/geom/HeuristicOverlayTest.cpp


Changes:

=====================================
NEWS.md
=====================================
@@ -74,6 +74,7 @@ xxxx-xx-xx
   - Reduce artifacts in single-sided Buffers: (GH-665 #810 and #712, Sandro Santilli)
   - GeoJSONReader: Fix 2D empty geometry creation (GH-909, Mike Taves)
   - GEOSClipByRect: Fix case with POINT EMPTY (GH-913, Mike Taves)
+  - Support mixed GeometryCollection in overlay ops (GH-797, Paul Ramsey)
 
 - Changes:
   - Remove Orientation.isCCW exception to simplify logic and align with JTS (GH-878, Martin Davis)


=====================================
Version.txt
=====================================
@@ -5,7 +5,7 @@ GEOS_VERSION_MINOR=12
 GEOS_VERSION_PATCH=0
 
 # OPTIONS: "", "dev", "rc1" etc.
-GEOS_PATCH_WORD=beta1
+GEOS_PATCH_WORD=beta2
 
 # GEOS CAPI Versions
 #


=====================================
capi/geos_c.h.in
=====================================
@@ -263,7 +263,7 @@ typedef void (*GEOSQueryCallback)(void *item, void *userdata);
 * \param distance the distance between the items here
 * \param userdata extra data for the calculation
 *
-* \return zero if distance calculation succeeded, non-zero otherwise
+* \return 1 if distance calculation succeeds, 0 otherwise
 *
 * \see GEOSSTRtree_nearest_generic
 * \see GEOSSTRtree_iterate


=====================================
capi/geos_ts_c.cpp
=====================================
@@ -391,7 +391,7 @@ inline auto execute(
                                   decltype(std::declval<F>()())>::type errval,
         F&& f) -> decltype(errval) {
     if (extHandle == nullptr) {
-        throw std::runtime_error("GEOS context handle is unintialized, call initGEOS");
+        throw std::runtime_error("GEOS context handle is uninitialized, call initGEOS");
     }
 
     GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
@@ -415,7 +415,7 @@ inline auto execute(
 template<typename F, typename std::enable_if<!std::is_void<decltype(std::declval<F>()())>::value, std::nullptr_t>::type = nullptr>
 inline auto execute(GEOSContextHandle_t extHandle, F&& f) -> decltype(f()) {
     if (extHandle == nullptr) {
-        throw std::runtime_error("context handle is unintialized, call initGEOS");
+        throw std::runtime_error("context handle is uninitialized, call initGEOS");
     }
 
     GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);


=====================================
debian/changelog
=====================================
@@ -1,9 +1,12 @@
-geos (3.12.0~beta1-1~exp2) UNRELEASED; urgency=medium
+geos (3.12.0~beta2-1~exp1) experimental; urgency=medium
 
-  * Add upstream patch to fix test failure.
+  * New upstream beta release.
   * Bump debhelper compat to 13.
+  * Drop patches, applied upstream.
+  * Update copyright file.
+  * Update symbols for other architectures.
 
- -- Bas Couwenberg <sebastic at debian.org>  Fri, 09 Jun 2023 06:09:23 +0200
+ -- Bas Couwenberg <sebastic at debian.org>  Wed, 14 Jun 2023 22:09:51 +0200
 
 geos (3.12.0~beta1-1~exp1) experimental; urgency=medium
 


=====================================
debian/copyright
=====================================
@@ -35,10 +35,6 @@ Files: include/geos/vend/json.hpp
 Copyright: 2013-2019, Niels Lohmann <http://nlohmann.me>
 License: Expat
 
-Files: src/coverage/CoverageBoundarySegmentFinder.cpp
-Copyright: 2022, Martin Davis
-License: EPL-2.0 or EDL-1.0
-
 Files: src/deps/ryu/*
 Copyright: 2018, Ulf Adams
 License: Apache-2.0 or BSL-1.0
@@ -161,314 +157,3 @@ License: zlib
  .
  3. This notice may not be removed or altered from any source
  distribution.
-
-License: EDL-1.0
- Eclipse Distribution License - v 1.0
- .
- Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
- .
- All rights reserved.
- .
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- .
-   Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
- .
-   Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
- .
-   Neither the name of the Eclipse Foundation, Inc. nor the names of its
-   contributors may be used to endorse or promote products derived from this
-   software without specific prior written permission.
- .
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-License: EPL-2.0
- Eclipse Public License - v 2.0
- .
-     THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
-     PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
-     OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
- .
- 1. DEFINITIONS
- .
- "Contribution" means:
- .
-   a) in the case of the initial Contributor, the initial content
-      Distributed under this Agreement, and
- .
-   b) in the case of each subsequent Contributor:
-      i) changes to the Program, and
-      ii) additions to the Program;
-   where such changes and/or additions to the Program originate from
-   and are Distributed by that particular Contributor. A Contribution
-   "originates" from a Contributor if it was added to the Program by
-   such Contributor itself or anyone acting on such Contributor's behalf.
-   Contributions do not include changes or additions to the Program that
-   are not Modified Works.
- .
- "Contributor" means any person or entity that Distributes the Program.
- .
- "Licensed Patents" mean patent claims licensable by a Contributor which
- are necessarily infringed by the use or sale of its Contribution alone
- or when combined with the Program.
- .
- "Program" means the Contributions Distributed in accordance with this
- Agreement.
- .
- "Recipient" means anyone who receives the Program under this Agreement
- or any Secondary License (as applicable), including Contributors.
- .
- "Derivative Works" shall mean any work, whether in Source Code or other
- form, that is based on (or derived from) the Program and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship.
- .
- "Modified Works" shall mean any work in Source Code or other form that
- results from an addition to, deletion from, or modification of the
- contents of the Program, including, for purposes of clarity any new file
- in Source Code form that contains any contents of the Program. Modified
- Works shall not include works that contain only declarations,
- interfaces, types, classes, structures, or files of the Program solely
- in each case in order to link to, bind by name, or subclass the Program
- or Modified Works thereof.
- .
- "Distribute" means the acts of a) distributing or b) making available
- in any manner that enables the transfer of a copy.
- .
- "Source Code" means the form of a Program preferred for making
- modifications, including but not limited to software source code,
- documentation source, and configuration files.
- .
- "Secondary License" means either the GNU General Public License,
- Version 2.0, or any later versions of that license, including any
- exceptions or additional permissions as identified by the initial
- Contributor.
- .
- 2. GRANT OF RIGHTS
- .
-   a) Subject to the terms of this Agreement, each Contributor hereby
-   grants Recipient a non-exclusive, worldwide, royalty-free copyright
-   license to reproduce, prepare Derivative Works of, publicly display,
-   publicly perform, Distribute and sublicense the Contribution of such
-   Contributor, if any, and such Derivative Works.
- .
-   b) Subject to the terms of this Agreement, each Contributor hereby
-   grants Recipient a non-exclusive, worldwide, royalty-free patent
-   license under Licensed Patents to make, use, sell, offer to sell,
-   import and otherwise transfer the Contribution of such Contributor,
-   if any, in Source Code or other form. This patent license shall
-   apply to the combination of the Contribution and the Program if, at
-   the time the Contribution is added by the Contributor, such addition
-   of the Contribution causes such combination to be covered by the
-   Licensed Patents. The patent license shall not apply to any other
-   combinations which include the Contribution. No hardware per se is
-   licensed hereunder.
- .
-   c) Recipient understands that although each Contributor grants the
-   licenses to its Contributions set forth herein, no assurances are
-   provided by any Contributor that the Program does not infringe the
-   patent or other intellectual property rights of any other entity.
-   Each Contributor disclaims any liability to Recipient for claims
-   brought by any other entity based on infringement of intellectual
-   property rights or otherwise. As a condition to exercising the
-   rights and licenses granted hereunder, each Recipient hereby
-   assumes sole responsibility to secure any other intellectual
-   property rights needed, if any. For example, if a third party
-   patent license is required to allow Recipient to Distribute the
-   Program, it is Recipient's responsibility to acquire that license
-   before distributing the Program.
- .
-   d) Each Contributor represents that to its knowledge it has
-   sufficient copyright rights in its Contribution, if any, to grant
-   the copyright license set forth in this Agreement.
- .
-   e) Notwithstanding the terms of any Secondary License, no
-   Contributor makes additional grants to any Recipient (other than
-   those set forth in this Agreement) as a result of such Recipient's
-   receipt of the Program under the terms of a Secondary License
-   (if permitted under the terms of Section 3).
- .
- 3. REQUIREMENTS
- .
- 3.1 If a Contributor Distributes the Program in any form, then:
- .
-   a) the Program must also be made available as Source Code, in
-   accordance with section 3.2, and the Contributor must accompany
-   the Program with a statement that the Source Code for the Program
-   is available under this Agreement, and informs Recipients how to
-   obtain it in a reasonable manner on or through a medium customarily
-   used for software exchange; and
- .
-   b) the Contributor may Distribute the Program under a license
-   different than this Agreement, provided that such license:
-      i) effectively disclaims on behalf of all other Contributors all
-      warranties and conditions, express and implied, including
-      warranties or conditions of title and non-infringement, and
-      implied warranties or conditions of merchantability and fitness
-      for a particular purpose;
- .
-      ii) effectively excludes on behalf of all other Contributors all
-      liability for damages, including direct, indirect, special,
-      incidental and consequential damages, such as lost profits;
- .
-      iii) does not attempt to limit or alter the recipients' rights
-      in the Source Code under section 3.2; and
- .
-      iv) requires any subsequent distribution of the Program by any
-      party to be under a license that satisfies the requirements
-      of this section 3.
- .
- 3.2 When the Program is Distributed as Source Code:
- .
-   a) it must be made available under this Agreement, or if the
-   Program (i) is combined with other material in a separate file or
-   files made available under a Secondary License, and (ii) the initial
-   Contributor attached to the Source Code the notice described in
-   Exhibit A of this Agreement, then the Program may be made available
-   under the terms of such Secondary Licenses, and
- .
-   b) a copy of this Agreement must be included with each copy of
-   the Program.
- .
- 3.3 Contributors may not remove or alter any copyright, patent,
- trademark, attribution notices, disclaimers of warranty, or limitations
- of liability ("notices") contained within the Program from any copy of
- the Program which they Distribute, provided that Contributors may add
- their own appropriate notices.
- .
- 4. COMMERCIAL DISTRIBUTION
- .
- Commercial distributors of software may accept certain responsibilities
- with respect to end users, business partners and the like. While this
- license is intended to facilitate the commercial use of the Program,
- the Contributor who includes the Program in a commercial product
- offering should do so in a manner which does not create potential
- liability for other Contributors. Therefore, if a Contributor includes
- the Program in a commercial product offering, such Contributor
- ("Commercial Contributor") hereby agrees to defend and indemnify every
- other Contributor ("Indemnified Contributor") against any losses,
- damages and costs (collectively "Losses") arising from claims, lawsuits
- and other legal actions brought by a third party against the Indemnified
- Contributor to the extent caused by the acts or omissions of such
- Commercial Contributor in connection with its distribution of the Program
- in a commercial product offering. The obligations in this section do not
- apply to any claims or Losses relating to any actual or alleged
- intellectual property infringement. In order to qualify, an Indemnified
- Contributor must: a) promptly notify the Commercial Contributor in
- writing of such claim, and b) allow the Commercial Contributor to control,
- and cooperate with the Commercial Contributor in, the defense and any
- related settlement negotiations. The Indemnified Contributor may
- participate in any such claim at its own expense.
- .
- For example, a Contributor might include the Program in a commercial
- product offering, Product X. That Contributor is then a Commercial
- Contributor. If that Commercial Contributor then makes performance
- claims, or offers warranties related to Product X, those performance
- claims and warranties are such Commercial Contributor's responsibility
- alone. Under this section, the Commercial Contributor would have to
- defend claims against the other Contributors related to those performance
- claims and warranties, and if a court requires any other Contributor to
- pay any damages as a result, the Commercial Contributor must pay
- those damages.
- .
- 5. NO WARRANTY
- .
- EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
- PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
- BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
- IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
- TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
- PURPOSE. Each Recipient is solely responsible for determining the
- appropriateness of using and distributing the Program and assumes all
- risks associated with its exercise of rights under this Agreement,
- including but not limited to the risks and costs of program errors,
- compliance with applicable laws, damage to or loss of data, programs
- or equipment, and unavailability or interruption of operations.
- .
- 6. DISCLAIMER OF LIABILITY
- .
- EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
- PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
- SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
- PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
- EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGES.
- .
- 7. GENERAL
- .
- If any provision of this Agreement is invalid or unenforceable under
- applicable law, it shall not affect the validity or enforceability of
- the remainder of the terms of this Agreement, and without further
- action by the parties hereto, such provision shall be reformed to the
- minimum extent necessary to make such provision valid and enforceable.
- .
- If Recipient institutes patent litigation against any entity
- (including a cross-claim or counterclaim in a lawsuit) alleging that the
- Program itself (excluding combinations of the Program with other software
- or hardware) infringes such Recipient's patent(s), then such Recipient's
- rights granted under Section 2(b) shall terminate as of the date such
- litigation is filed.
- .
- All Recipient's rights under this Agreement shall terminate if it
- fails to comply with any of the material terms or conditions of this
- Agreement and does not cure such failure in a reasonable period of
- time after becoming aware of such noncompliance. If all Recipient's
- rights under this Agreement terminate, Recipient agrees to cease use
- and distribution of the Program as soon as reasonably practicable.
- However, Recipient's obligations under this Agreement and any licenses
- granted by Recipient relating to the Program shall continue and survive.
- .
- Everyone is permitted to copy and distribute copies of this Agreement,
- but in order to avoid inconsistency the Agreement is copyrighted and
- may only be modified in the following manner. The Agreement Steward
- reserves the right to publish new versions (including revisions) of
- this Agreement from time to time. No one other than the Agreement
- Steward has the right to modify this Agreement. The Eclipse Foundation
- is the initial Agreement Steward. The Eclipse Foundation may assign the
- responsibility to serve as the Agreement Steward to a suitable separate
- entity. Each new version of the Agreement will be given a distinguishing
- version number. The Program (including Contributions) may always be
- Distributed subject to the version of the Agreement under which it was
- received. In addition, after a new version of the Agreement is published,
- Contributor may elect to Distribute the Program (including its
- Contributions) under the new version.
- .
- Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
- receives no rights or licenses to the intellectual property of any
- Contributor under this Agreement, whether expressly, by implication,
- estoppel or otherwise. All rights in the Program not expressly granted
- under this Agreement are reserved. Nothing in this Agreement is intended
- to be enforceable by any entity that is not a Contributor or Recipient.
- No third-party beneficiary rights are created under this Agreement.
- .
- Exhibit A - Form of Secondary Licenses Notice
- .
- "This Source Code may also be made available under the following
- Secondary Licenses when the conditions for such availability set forth
- in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
- version(s), and exceptions or additional permissions here}."
- .
-   Simply including a copy of this Agreement, including this Exhibit A
-   is not sufficient to license the Source Code under Secondary Licenses.
- .
-   If it is not possible or desirable to put the notice in a particular
-   file, then You may include the notice in a location (such as a LICENSE
-   file in a relevant directory) where a recipient would be likely to
-   look for such a notice.
- .
-   You may add additional accurate notices of copyright ownership.


=====================================
debian/libgeos-c1v5.symbols
=====================================
@@ -1,4 +1,4 @@
-# SymbolsHelper-Confirmed: 3.12.0~beta1 amd64
+# SymbolsHelper-Confirmed: 3.12.0~beta1 amd64 arm64 armel armhf hurd-i386 i386 ia64 m68k mipsel powerpc ppc64 ppc64el riscv64 s390x sh4 sparc64 x32
 libgeos_c.so.1 #PACKAGE# #MINVER#
 * Build-Depends-Package: libgeos-dev
  GEOSArea at Base 3.4.2
@@ -625,6 +625,7 @@ libgeos_c.so.1 #PACKAGE# #MINVER#
  (optional=templinst)_ZNSt12_Vector_baseIPN4geos4geom10LineStringESaIS3_EED2Ev at Base 3.12.0~beta1
  (optional=templinst|arch=!mipsel)_ZNSt6vectorIN4geos5index7strtree15TemplateSTRNodeIPvNS2_14EnvelopeTraitsEEESaIS6_EE17_M_realloc_insertIJRPKS6_SC_EEEvN9__gnu_cxx17__normal_iteratorIPS6_S8_EEDpOT_ at Base 3.10.0
  (optional=templinst)_ZNSt6vectorIN4geos5index7strtree15TemplateSTRNodeIPvNS2_14EnvelopeTraitsEEESaIS6_EE17_M_realloc_insertIJS4_RKNS0_4geom8EnvelopeEEEEvN9__gnu_cxx17__normal_iteratorIPS6_S8_EEDpOT_ at Base 3.10.0
+ (optional=templinst|arch=!amd64 !x32|subst)_ZNSt6vectorIN4geos5index7strtree15TemplateSTRNodeIPvNS2_14EnvelopeTraitsEEESaIS6_EE7reserveE{size_t}@Base 3.12.0~beta1
  _ZNSt6vectorIPKN4geos4geom10CoordinateESaIS4_EE17_M_realloc_insertIJRKS4_EEEvN9__gnu_cxx17__normal_iteratorIPS4_S6_EEDpOT_ at Base 3.7.0
  (optional=templinst)_ZNSt6vectorIPKN4geos4geom10CoordinateESaIS4_EE17_M_realloc_insertIJS4_EEEvN9__gnu_cxx17__normal_iteratorIPS4_S6_EEDpOT_ at Base 3.12.0~beta1
  (optional=templinst)_ZNSt6vectorIPKN4geos4geom8GeometryESaIS4_EE17_M_realloc_insertIJS4_EEEvN9__gnu_cxx17__normal_iteratorIPS4_S6_EEDpOT_ at Base 3.12.0~beta1
@@ -635,9 +636,11 @@ libgeos_c.so.1 #PACKAGE# #MINVER#
  (optional=templinst)_ZNSt6vectorISt10unique_ptrIN4geos4geom7PolygonESt14default_deleteIS3_EESaIS6_EED2Ev at Base 3.9.0
  (optional=templinst)_ZNSt6vectorISt10unique_ptrIN4geos4geom8GeometryESt14default_deleteIS3_EESaIS6_EE17_M_realloc_insertIJRPNS2_10LineStringEEEEvN9__gnu_cxx17__normal_iteratorIPS6_S8_EEDpOT_ at Base 3.12.0~beta1
  (optional=templinst)_ZNSt6vectorISt10unique_ptrIN4geos4geom8GeometryESt14default_deleteIS3_EESaIS6_EE17_M_realloc_insertIJS6_EEEvN9__gnu_cxx17__normal_iteratorIPS6_S8_EEDpOT_ at Base 3.12.0~beta1
+ (optional=templinst|arch=!amd64 !arm64 !ia64 !ppc64 !ppc64el !riscv64 !s390x !sparc64)_ZNSt6vectorISt10unique_ptrIN4geos4geom8GeometryESt14default_deleteIS3_EESaIS6_EE7reserveEj at Base 3.12.0~beta1
  (optional=templinst)_ZNSt6vectorISt10unique_ptrIN4geos4geom8GeometryESt14default_deleteIS3_EESaIS6_EE7reserveEm at Base 3.12.0~beta1
  (optional=templinst)_ZNSt6vectorISt10unique_ptrIN4geos4geom8GeometryESt14default_deleteIS3_EESaIS6_EED1Ev at Base 3.9.0
  (optional=templinst)_ZNSt6vectorISt10unique_ptrIN4geos4geom8GeometryESt14default_deleteIS3_EESaIS6_EED2Ev at Base 3.9.0
+ (optional=templinst|arch=!amd64 !arm64 !ia64 !ppc64 !ppc64el !riscv64 !s390x !sparc64)_ZNSt6vectorIdSaIdEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPdS1_EEjRKd at Base 3.12.0~beta1
  (optional=templinst)_ZNSt6vectorIdSaIdEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPdS1_EEmRKd at Base 3.12.0~beta1
  (optional=templinst)_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev at Base 3.4.2
  (optional=templinst)_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev at Base 3.4.2


=====================================
debian/libgeos3.12.0.symbols
=====================================
The diff for this file was not included because it is too large.

=====================================
debian/patches/0001-Remove-defunct-doxygen-entry.patch deleted
=====================================
@@ -1,24 +0,0 @@
-Description: Remove defunct doxygen entry
-Author: Paul Ramsey <pramsey at cleverelephant.ca>
-Origin: https://github.com/libgeos/geos/commit/bf3216ecc34cd0a026af7a5f9a636400f252a456
-Bug: https://lists.osgeo.org/pipermail/geos-devel/2023-June/010929.html
-
---- a/include/geos/coverage/CoverageRingEdges.h
-+++ b/include/geos/coverage/CoverageRingEdges.h
-@@ -72,16 +72,6 @@ private:
- 
- public:
- 
--    /**
--    * Create a new instance for a given coverage.
--    *
--    * @param coverage the set of polygonal geometries in the coverage
--    * @return the edges of the coverage
--    */
--    // static std::unique_ptr<CoverageRingEdges> create(
--    //     std::vector<const Geometry*>& coverage);
--
--
-     CoverageRingEdges(std::vector<const Geometry*>& coverage)
-         : m_coverage(coverage)
-     {


=====================================
debian/patches/series deleted
=====================================
@@ -1,2 +0,0 @@
-spelling-errors.patch
-0001-Remove-defunct-doxygen-entry.patch


=====================================
debian/patches/spelling-errors.patch deleted
=====================================
@@ -1,26 +0,0 @@
-Description: Fix spelling errors.
- * unintialized -> uninitialized
-Author: Bas Couwenberg <sebastic at debian.org>
-Forwarded: https://github.com/libgeos/geos/pull/920
-Applied-Upstream: https://github.com/libgeos/geos/commit/f7de298feaefb5a3afa73c12fed2ae66d6d4ef36
-
---- a/capi/geos_ts_c.cpp
-+++ b/capi/geos_ts_c.cpp
-@@ -391,7 +391,7 @@ inline auto execute(
-                                   decltype(std::declval<F>()())>::type errval,
-         F&& f) -> decltype(errval) {
-     if (extHandle == nullptr) {
--        throw std::runtime_error("GEOS context handle is unintialized, call initGEOS");
-+        throw std::runtime_error("GEOS context handle is uninitialized, call initGEOS");
-     }
- 
-     GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
-@@ -415,7 +415,7 @@ inline auto execute(
- template<typename F, typename std::enable_if<!std::is_void<decltype(std::declval<F>()())>::value, std::nullptr_t>::type = nullptr>
- inline auto execute(GEOSContextHandle_t extHandle, F&& f) -> decltype(f()) {
-     if (extHandle == nullptr) {
--        throw std::runtime_error("context handle is unintialized, call initGEOS");
-+        throw std::runtime_error("context handle is uninitialized, call initGEOS");
-     }
- 
-     GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);


=====================================
examples/README.md
=====================================
@@ -4,6 +4,7 @@
 * `capi_read_ts` uses the "re-entrant" C API (threadsafe) to read two WKT geometries, calculate the intersection and print the result
 * `capi_prepared` uses the standard C API to read one WKT geometry, and fill it with a point grid, applying a high performance "prepared" geometry to speed up intersection testing
 * `capi_strtree` uses the standard C API to build a random collection of points, and then search that collection quickly to find the nearest to a query point
+* `capi_indexed_predicate` uses the standard C API API to build an STRtree index on a custom class, and then query that index with a prepared geometry, returning a list of matching items
 * `cpp_read` uses the C++ API to read two WKT geometries, calculate the intersection and print the result
 * `cpp_strtree` uses the C++ API to build an STRtree index on a custom class, and then query that index
 


=====================================
examples/capi_indexed_predicate.c
=====================================
@@ -0,0 +1,219 @@
+/*
+* # GEOS C API example 4
+*
+* Build a spatial index and search it for all points
+* completely contained in arbitrary query polygon.
+*
+* cc -I/usr/local/include capi_indexed_predicate.c -o capi_indexed_predicate -L/usr/local/lib -lgeos_c
+*/
+
+/* System headers */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+/* Only the CAPI header is required */
+#include <geos_c.h>
+
+/*
+* GEOS requires two message handlers to return
+* error and notice message to the calling program.
+*
+*   typedef void(* GEOSMessageHandler) (const char *fmt,...)
+*
+* Here we stub out an example that just prints the
+* messages to stdout.
+*/
+static void
+geos_message_handler(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf (fmt, ap);
+    va_end(ap);
+}
+
+/*
+* An application will want to index items, which have
+* some attributes and a geometry part.
+*/
+typedef struct
+{
+    GEOSGeometry* geom;
+    size_t id;
+} item_t;
+
+/*
+* A user data struct to pass to the index callback function
+*/
+typedef struct
+{
+    const GEOSPreparedGeometry* prepgeom;
+    item_t** items;
+    size_t  nItems;
+    size_t  szItems;
+} userdata_t;
+
+/*
+* Userdata both holds our output list of found items and
+* our input PreparedGeometry for fast spatial tests.
+*/
+userdata_t *
+userdata_init(GEOSGeometry* geom)
+{
+    userdata_t* ud = malloc(sizeof(userdata_t));
+    ud->prepgeom = GEOSPrepare(geom);
+    ud->nItems = 0;
+    ud->szItems = 16;
+    ud->items = malloc(sizeof(item_t*) * ud->szItems);
+    return ud;
+}
+
+/*
+* Free the items list and the PreparedGeometry
+*/
+void
+userdata_free(userdata_t* ud)
+{
+    GEOSPreparedGeom_destroy(ud->prepgeom);
+    free(ud->items);
+    free(ud);
+}
+
+
+/*
+* Generate a random item with a location in the range of
+* POINT(0..range, 0..range). Caller must free.
+*/
+static item_t *
+item_random(double range)
+{
+    item_t* item = malloc(sizeof(item_t));
+    double x = range * rand() / RAND_MAX;
+    double y = range * rand() / RAND_MAX;
+    /* Make a point in the point grid */
+    item->geom = GEOSGeom_createPointFromXY(x, y);
+    item->id = rand();
+    return item;
+}
+
+/*
+* Free an item and its geometry.
+*/
+void
+item_free(item_t* item)
+{
+    if (item && item->geom) GEOSGeom_destroy(item->geom);
+    if (item) free(item);
+}
+
+/*
+* Utility function to write out contents of item
+*/
+void
+item_print(const item_t* item)
+{
+    double x, y;
+    GEOSGeomGetX(item->geom, &x);
+    GEOSGeomGetY(item->geom, &y);
+    printf("item %10zu (%g, %g)\n", item->id, x, y);
+}
+
+/*
+* Item query callback for GEOSSTRtree_query()
+*/
+void
+itemQueryCallback(void* item, void* userdata)
+{
+    userdata_t* ud = (userdata_t*)userdata;
+    item_t* indexitem = (item_t*)item;
+    if (GEOSPreparedIntersects(ud->prepgeom, indexitem->geom)) {
+        if (ud->nItems == ud->szItems) {
+            ud->szItems *= 2;
+            ud->items = realloc(ud->items, sizeof(item_t*) * ud->szItems);
+        }
+        ud->items[ud->nItems++] = indexitem;
+    }
+    return;
+}
+
+
+int main()
+{
+    /* Send notice and error messages to our stdout handler */
+    initGEOS(geos_message_handler, geos_message_handler);
+
+    /* How many random items to add to our index */
+    const size_t nItems = 10000;
+    /* The coordinate range of the random locations (0->100.0) */
+    const double range = 100.0;
+    /* Set the seed for rand() */
+    srand(time(NULL));
+
+    /*
+    * The tree doesn't take ownership of inputs, it just
+    * holds pointers, so we keep a list of allocated items
+    * handy in an array for future clean-up
+    */
+    item_t* items[nItems];
+    /*
+    * The create parameter for the tree is not the
+    * number of inputs, it is the number of entries
+    * per node. 10 is a good default number to use.
+    */
+    GEOSSTRtree* tree = GEOSSTRtree_create(10);
+    for (size_t i = 0; i < nItems; i++) {
+        /* Make a random point */
+        item_t* item = item_random(range);
+        /* Store away a reference so we can free it after */
+        items[i] = item;
+        /* Add an entry for it to the tree */
+        GEOSSTRtree_insert(tree, item->geom, item);
+    }
+
+    /* Prepare to read geometries in as text */
+    GEOSWKTReader* reader = GEOSWKTReader_create();
+
+    /* Set up a query rectangle for index query */
+    const char* wkt_bounds = "POLYGON((20 20, 20 24, 24 24, 24 23, 21 23, 21 21, 24 21, 24 20, 20 20))";
+    GEOSGeometry* geom_query = GEOSWKTReader_read(reader, wkt_bounds);
+
+    /* Set up the prepared geometry for the exact tests */
+    userdata_t* ud = userdata_init(geom_query);
+
+    /* Find all items that touch the bounds */
+    /* For non-rectangular query geometry, this will be an over-determined set */
+    GEOSSTRtree_query(
+        tree,              // STRTree to query
+        geom_query,        // GEOSGeometry query bounds
+        itemQueryCallback, // Callback to process index entries that pass query
+        ud);             // Userdata to hand to the callback
+
+    /* Print out the items we found */
+    printf("Found %zu items in the polygon: %s\n", ud->nItems, wkt_bounds);
+    for (size_t i = 0; i < ud->nItems; i++) {
+        item_print(ud->items[i]);
+    }
+
+    /* Done with the found items and prepared geometry now */
+    userdata_free(ud);
+
+    /* Free the query bounds geometry */
+    GEOSGeom_destroy(geom_query);
+
+    /* Freeing the tree does not free the tree inputs */
+    GEOSSTRtree_destroy(tree);
+
+    /* Free all the items in our random item list */
+    for (size_t i = 0; i < nItems; i++) {
+        item_free(items[i]);
+    }
+
+    /* Clean up the global context */
+    finishGEOS();
+
+    /* Done */
+    return 0;
+}


=====================================
examples/capi_strtree.c
=====================================
@@ -2,13 +2,17 @@
 * # GEOS C API example 3
 *
 * Build a spatial index and search it for a
-* nearest pair.
+* nearest neighbor and for a query bounds.
+*
+* cc -I/usr/local/include capi_strtree.c -o capi_strtree -L/usr/local/lib -lgeos_c
 */
 
-/* To print to stdout */
+/* System headers */
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#include <math.h>
+#include <time.h>
 
 /* Only the CAPI header is required */
 #include <geos_c.h>
@@ -32,17 +36,63 @@ geos_message_handler(const char* fmt, ...)
 }
 
 /*
-* Generate a random point in the range of
-* POINT(0..range, 0..range). Caller must
-* free.
+* An application will want to index items, which have
+* some attributes and a geometry part.
+*/
+typedef struct
+{
+    GEOSGeometry* geom;
+    size_t id;
+} item_t;
+
+/*
+* Generate a random item with a location in the range of
+* POINT(0..range, 0..range). Caller must free.
 */
-static GEOSGeometry*
-geos_random_point(double range)
+static item_t *
+random_item(double range)
 {
+    item_t* item = malloc(sizeof(item_t));
     double x = range * rand() / RAND_MAX;
     double y = range * rand() / RAND_MAX;
     /* Make a point in the point grid */
-    return GEOSGeom_createPointFromXY(x, y);
+    item->geom = GEOSGeom_createPointFromXY(x, y);
+    item->id = rand();
+    return item;
+}
+
+/*
+* Free an item and its geometry.
+*/
+void
+free_item(item_t* item)
+{
+    if (item && item->geom) GEOSGeom_destroy(item->geom);
+    if (item) free(item);
+}
+
+/*
+* Item distance callback for GEOSSTRtree_nearest_generic()
+*/
+int
+itemDistanceCallback(const void* item1, const void* item2, double* distance, void* userdata)
+{
+    item_t* obj1 = (item_t*)item1;
+    item_t* obj2 = (item_t*)item2;
+    return GEOSDistance(obj1->geom, obj2->geom, distance);
+}
+
+/*
+* Item query callback for GEOSSTRtree_query()
+*/
+void
+itemQueryCallback(void* item, void* userdata)
+{
+    double x, y;
+    item_t* i = (item_t*)item;
+    GEOSGeomGetX(i->geom, &x);
+    GEOSGeomGetY(i->geom, &y);
+    printf("Found item %10zu at (%g, %g)\n", i->id, x, y);
 }
 
 
@@ -51,65 +101,94 @@ int main()
     /* Send notice and error messages to our stdout handler */
     initGEOS(geos_message_handler, geos_message_handler);
 
-    /* How many points to add to our random field */
-    const size_t npoints = 10000;
-    /* The coordinate range of the field (0->100.0) */
+    /* How many random items to add to our index */
+    const size_t nItems = 10000;
+    /* The coordinate range of the random locations (0->100.0) */
     const double range = 100.0;
+    /* Set the seed for rand() */
+    srand(time(NULL));
 
     /*
-    * The tree doesn't take ownership of inputs just
-    * holds references, so we keep our point field
-    * handy in an array
+    * The tree doesn't take ownership of inputs, it just
+    * holds pointers, so we keep a list of allocated items
+    * handy in an array for future clean-up
     */
-    GEOSGeometry* geoms[npoints];
+    item_t* items[nItems];
     /*
     * The create parameter for the tree is not the
     * number of inputs, it is the number of entries
     * per node. 10 is a good default number to use.
     */
     GEOSSTRtree* tree = GEOSSTRtree_create(10);
-    for (size_t i = 0; i < npoints; i++) {
+    for (size_t i = 0; i < nItems; i++) {
         /* Make a random point */
-        GEOSGeometry* geom = geos_random_point(range);
+        item_t* item = random_item(range);
         /* Store away a reference so we can free it after */
-        geoms[i] = geom;
+        items[i] = item;
         /* Add an entry for it to the tree */
-        GEOSSTRtree_insert(tree, geom, geom);
+        GEOSSTRtree_insert(tree, item->geom, item);
     }
 
-    /* Random point to compare to the field */
-    GEOSGeometry* geom_random = geos_random_point(range);
-    /* Nearest point in the field to our test point */
-    const GEOSGeometry* geom_nearest = GEOSSTRtree_nearest(tree, geom_random);
-
-    /* Convert results to WKT */
+    /* Prepare to write some geometries out as text */
     GEOSWKTWriter* writer = GEOSWKTWriter_create();
     /* Trim trailing zeros off output */
     GEOSWKTWriter_setTrim(writer, 1);
     GEOSWKTWriter_setRoundingPrecision(writer, 3);
-    char* wkt_random = GEOSWKTWriter_write(writer, geom_random);
-    char* wkt_nearest = GEOSWKTWriter_write(writer, geom_nearest);
-    GEOSWKTWriter_destroy(writer);
 
-    /* Print answer */
+    /* Prepare to read some geometries in as text */
+    GEOSWKTReader* reader = GEOSWKTReader_create();
+
+    /* Random item to query the index with */
+    item_t* item_random = random_item(range);
+    /* Nearest item in the index to our random item */
+    const item_t* item_nearest = GEOSSTRtree_nearest_generic(
+        tree,                 // STRTree to query
+        item_random,          // Item to use in search
+        item_random->geom,    // Geometry to seed search
+        itemDistanceCallback, // Callback to process nearest object
+        NULL);                // Userdata to hand to the callback
+
+    /* Convert geometry to WKT */
+    char* wkt_random  = GEOSWKTWriter_write(writer, item_random->geom);
+    char* wkt_nearest = GEOSWKTWriter_write(writer, item_nearest->geom);
+
+    /* Print random query point and nearest point */
     printf(" Random Point: %s\n", wkt_random);
     printf("Nearest Point: %s\n", wkt_nearest);
 
-    /* Clean up all allocated objects */
-    /* Destroying tree does not destroy inputs */
-    GEOSSTRtree_destroy(tree);
-    GEOSGeom_destroy(geom_random);
-    /* Destroy all the points in our random field */
-    for (size_t i = 0; i < npoints; i++) {
-        GEOSGeom_destroy(geoms[i]);
-    }
-    /*
-    * Don't forget to free memory allocated by the
-    * printing functions!
-    */
+    /* Don't forget to free memory allocated for WKT! */
     GEOSFree(wkt_random);
     GEOSFree(wkt_nearest);
 
+    /* Set up a query rectangle for index query */
+    const char* wkt_bounds = "POLYGON((20 20, 22 20, 22 22, 20 22, 20 20))";
+    GEOSGeometry* geom_query = GEOSWKTReader_read(reader, wkt_bounds);
+
+    /* Find all items that touch the bounds */
+    /* For non-rectangular query geometry, this will be an over-determined set */
+    GEOSSTRtree_query(
+        tree,              // STRTree to query
+        geom_query,        // GEOSGeometry query bounds
+        itemQueryCallback, // Callback to process index entries that pass query
+        NULL);             // Userdata to hand to the callback
+
+    /* Free the query bounds geometry */
+    GEOSGeom_destroy(geom_query);
+
+    /* Free the WKT writer and reader */
+    GEOSWKTWriter_destroy(writer);
+    GEOSWKTReader_destroy(reader);
+
+    /* Freeing the tree does not free the tree inputs */
+    GEOSSTRtree_destroy(tree);
+
+    /* Free all the items in our random item list */
+    for (size_t i = 0; i < nItems; i++) {
+        free_item(items[i]);
+    }
+    /* Free our working random item */
+    free_item(item_random);
+
     /* Clean up the global context */
     finishGEOS();
 


=====================================
include/geos/coverage/CoverageRingEdges.h
=====================================
@@ -72,16 +72,6 @@ private:
 
 public:
 
-    /**
-    * Create a new instance for a given coverage.
-    *
-    * @param coverage the set of polygonal geometries in the coverage
-    * @return the edges of the coverage
-    */
-    // static std::unique_ptr<CoverageRingEdges> create(
-    //     std::vector<const Geometry*>& coverage);
-
-
     CoverageRingEdges(std::vector<const Geometry*>& coverage)
         : m_coverage(coverage)
     {


=====================================
include/geos/geom/Geometry.h
=====================================
@@ -364,6 +364,9 @@ public:
         return isDimensionStrict(Dimension::A);
     }
 
+    bool isMixedDimension() const;
+    bool isMixedDimension(Dimension::DimensionType* baseDim) const;
+
     bool isCollection() const {
         int t = getGeometryTypeId();
         return t == GEOS_GEOMETRYCOLLECTION ||


=====================================
include/geos/geom/HeuristicOverlay.h
=====================================
@@ -20,16 +20,80 @@
 #pragma once
 
 #include <geos/export.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/Dimension.h>
+
+
 #include <memory> // for unique_ptr
+#include <vector>
 
-namespace geos {
-namespace geom { // geos::geom
 
+namespace geos {
+namespace geom {
 class Geometry;
+class GeometryFactory;
+}
+}
+
+
+namespace geos {
+namespace geom { // geos::geom
 
 std::unique_ptr<Geometry> GEOS_DLL
 HeuristicOverlay(const Geometry* g0, const Geometry* g1, int opCode);
 
+class StructuredCollection {
+
+public:
+
+    StructuredCollection(const Geometry* g)
+        : factory(g->getFactory())
+        , pt_union(nullptr)
+        , line_union(nullptr)
+        , poly_union(nullptr)
+    {
+        readCollection(g);
+        unionByDimension();
+    };
+
+    StructuredCollection()
+        : factory(nullptr)
+        , pt_union(nullptr)
+        , line_union(nullptr)
+        , poly_union(nullptr)
+    {};
+
+    void readCollection(const Geometry* g);
+    const Geometry* getPolyUnion()  const { return poly_union.get(); }
+    const Geometry* getLineUnion()  const { return line_union.get(); }
+    const Geometry* getPointUnion() const { return pt_union.get(); }
+
+    std::unique_ptr<Geometry> doUnion(const StructuredCollection& a) const;
+    std::unique_ptr<Geometry> doIntersection(const StructuredCollection& a) const;
+    std::unique_ptr<Geometry> doSymDifference(const StructuredCollection& a) const;
+    std::unique_ptr<Geometry> doDifference(const StructuredCollection& a) const;
+    std::unique_ptr<Geometry> doUnaryUnion() const;
+
+    static void toVector(const Geometry* g, std::vector<const Geometry*>& v);
+    void unionByDimension(void);
+
+
+private:
+
+    const GeometryFactory* factory;
+    std::vector<const Geometry*> pts;
+    std::vector<const Geometry*> lines;
+    std::vector<const Geometry*> polys;
+    std::unique_ptr<Geometry> pt_union;
+    std::unique_ptr<Geometry> line_union;
+    std::unique_ptr<Geometry> poly_union;
+
+};
+
+
+
+
+
 } // namespace geos::geom
 } // namespace geos
 


=====================================
release.md
=====================================
@@ -73,6 +73,7 @@ xxxx-xx-xx
   - Reduce artifacts in single-sided Buffers: (GH-665 #810 and #712, Sandro Santilli)
   - GeoJSONReader: Fix 2D empty geometry creation (GH-909, Mike Taves)
   - GEOSClipByRect: Fix case with POINT EMPTY (GH-913, Mike Taves)
+  - Support mixed GeometryCollection in overlay ops (GH-797, Paul Ramsey)
 
 - Changes:
   - Remove Orientation.isCCW exception to simplify logic and align with JTS (GH-878, Martin Davis)


=====================================
src/coverage/CoverageBoundarySegmentFinder.cpp
=====================================
@@ -1,14 +1,16 @@
-/*
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
  * Copyright (c) 2022 Martin Davis.
  *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
- * and the Eclipse Distribution License is available at
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
  *
- * http://www.eclipse.org/org/documents/edl-v10.php.
- */
+ **********************************************************************/
 
 #include <geos/coverage/CoverageBoundarySegmentFinder.h>
 #include <geos/geom/CoordinateSequence.h>


=====================================
src/geom/Geometry.cpp
=====================================
@@ -160,6 +160,34 @@ Geometry::getCentroid() const
     return std::unique_ptr<Point>(getFactory()->createPoint(centPt));
 }
 
+/* public */
+bool
+Geometry::isMixedDimension() const
+{
+    Dimension::DimensionType baseDim = Dimension::DONTCARE;
+    return isMixedDimension(&baseDim);
+}
+
+/* public */
+bool
+Geometry::isMixedDimension(Dimension::DimensionType* baseDim) const
+{
+    if (isCollection()) {
+        for (std::size_t i = 0; i < getNumGeometries(); i++) {
+            if (getGeometryN(i)->isMixedDimension(baseDim))
+                return true;
+        }
+        return false;
+    }
+    else {
+        if (*baseDim == Dimension::DONTCARE) {
+            *baseDim = getDimension();
+            return false;
+        }
+        return *baseDim != getDimension();
+    }
+}
+
 /*public*/
 bool
 Geometry::getCentroid(CoordinateXY& ret) const


=====================================
src/geom/HeuristicOverlay.cpp
=====================================
@@ -25,6 +25,14 @@
 
 #include <geos/geom/HeuristicOverlay.h>
 #include <geos/operation/overlayng/OverlayNGRobust.h>
+#include <geos/util/IllegalArgumentException.h>
+#include <geos/geom/Dimension.h>
+#include <geos/geom/MultiPoint.h>
+#include <geos/geom/MultiLineString.h>
+#include <geos/geom/MultiPolygon.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/GeometryCollection.h>
+#include <geos/io/WKTWriter.h>
 
 namespace geos {
 namespace geom { // geos::geom
@@ -37,48 +45,355 @@ HeuristicOverlay(const Geometry* g0, const Geometry* g1, int opCode)
 {
     std::unique_ptr<Geometry> ret;
 
-/**************************************************************************/
-
-/*
-* overlayng::OverlayNGRobust carries out the following steps
-*
-* 1. Perform overlay operation using PrecisionModel(float).
-*    If no exception return result.
-* 2. Perform overlay operation using SnappingNoder(tolerance), starting
-*    with a very very small tolerance and increasing it for 5 iterations.
-*    The SnappingNoder moves only nodes that are within tolerance of
-*    other nodes and lines, leaving all the rest undisturbed, for a very
-*    clean result, if it manages to create one.
-*    If a result is found with no exception, return.
-* 3. Perform overlay operation using a PrecisionModel(scale), which
-*    uses a SnapRoundingNoder. Every vertex will be noded to the snapping
-*    grid, resulting in a modified geometry. The SnapRoundingNoder approach
-*    reliably produces results, assuming valid inputs.
-*
-* Running overlayng::OverlayNGRobust at this stage should guarantee
-* that none of the other heuristics are ever needed.
-*/
-        if (g0 == nullptr && g1 == nullptr) {
-            return std::unique_ptr<Geometry>(nullptr);
+    /*
+    * overlayng::OverlayNGRobust does not currently handle
+    * GeometryCollection (collections of mixed dimension)
+    * so we handle that case here.
+    */
+    if ((g0->isMixedDimension() && !g0->isEmpty()) ||
+        (g1->isMixedDimension() && !g1->isEmpty()))
+    {
+        StructuredCollection s0(g0);
+        StructuredCollection s1(g1);
+        switch (opCode) {
+        case OverlayNG::UNION:
+            return s0.doUnion(s1);
+        case OverlayNG::DIFFERENCE:
+            return s0.doDifference(s1);
+        case OverlayNG::SYMDIFFERENCE:
+            return s0.doSymDifference(s1);
+        case OverlayNG::INTERSECTION:
+            return s0.doIntersection(s1);
         }
-        else if (g0 == nullptr) {
-            // Use a unary union for the one-parameter case, as the pairwise
-            // union with one parameter is very intolerant to invalid
-            // collections and multi-polygons.
-            ret = OverlayNGRobust::Union(g1);
+    }
+
+    /*
+    * overlayng::OverlayNGRobust carries out the following steps
+    *
+    * 1. Perform overlay operation using PrecisionModel(float).
+    *    If no exception return result.
+    * 2. Perform overlay operation using SnappingNoder(tolerance), starting
+    *    with a very very small tolerance and increasing it for 5 iterations.
+    *    The SnappingNoder moves only nodes that are within tolerance of
+    *    other nodes and lines, leaving all the rest undisturbed, for a very
+    *    clean result, if it manages to create one.
+    *    If a result is found with no exception, return.
+    * 3. Perform overlay operation using a PrecisionModel(scale), which
+    *    uses a SnapRoundingNoder. Every vertex will be noded to the snapping
+    *    grid, resulting in a modified geometry. The SnapRoundingNoder approach
+    *    reliably produces results, assuming valid inputs.
+    *
+    * Running overlayng::OverlayNGRobust at this stage should guarantee
+    * that none of the other heuristics are ever needed.
+    */
+    if (g0 == nullptr && g1 == nullptr) {
+        return std::unique_ptr<Geometry>(nullptr);
+    }
+    else if (g0 == nullptr) {
+        // Use a unary union for the one-parameter case, as the pairwise
+        // union with one parameter is very intolerant to invalid
+        // collections and multi-polygons.
+        ret = OverlayNGRobust::Union(g1);
+    }
+    else if (g1 == nullptr) {
+        // Use a unary union for the one-parameter case, as the pairwise
+        // union with one parameter is very intolerant to invalid
+        // collections and multi-polygons.
+        ret = OverlayNGRobust::Union(g0);
+    }
+    else {
+        ret = OverlayNGRobust::Overlay(g0, g1, opCode);
+    }
+
+    return ret;
+}
+
+/* public */
+void
+StructuredCollection::readCollection(const Geometry* g)
+{
+    if (!factory) factory = g->getFactory();
+    if (g->isCollection()) {
+        for (std::size_t i = 0; i < g->getNumGeometries(); i++) {
+            readCollection(g->getGeometryN(i));
         }
-        else if (g1 == nullptr) {
-            // Use a unary union for the one-parameter case, as the pairwise
-            // union with one parameter is very intolerant to invalid
-            // collections and multi-polygons.
-            ret = OverlayNGRobust::Union(g0);
+    }
+    else {
+        if (g->isEmpty()) return;
+        switch (g->getGeometryTypeId()) {
+            case GEOS_POINT:
+                pts.push_back(g);
+                break;
+            case GEOS_LINESTRING:
+                lines.push_back(g);
+                break;
+            case GEOS_POLYGON:
+                polys.push_back(g);
+                break;
+            default:
+                throw util::IllegalArgumentException("cannot process unexpected collection");
+        }
+    }
+}
+
+/* public static */
+void
+StructuredCollection::toVector(const Geometry* g, std::vector<const Geometry*>& v)
+{
+    if (!g || g->isEmpty()) return;
+    if (g->isCollection()) {
+        for (std::size_t i = 0; i < g->getNumGeometries(); i++) {
+            toVector(g->getGeometryN(i), v);
         }
-        else {
-            ret = OverlayNGRobust::Overlay(g0, g1, opCode);
+    }
+    else {
+        switch (g->getGeometryTypeId()) {
+            case GEOS_POINT:
+            case GEOS_LINESTRING:
+            case GEOS_POLYGON:
+                v.push_back(g);
+                break;
+            default:
+                return;
         }
+    }
+}
+
+
+/* public */
+void
+StructuredCollection::unionByDimension(void)
+{
+    /*
+    * Remove duplication within each dimension, so that there
+    * is only one object covering any particular space within
+    * that dimension.
+    * This makes reasoning about the collection-on-collection
+    * operations a little easier later on.
+    */
+    std::unique_ptr<MultiPoint> pt_col = factory->createMultiPoint(pts);
+    std::unique_ptr<MultiLineString> line_col = factory->createMultiLineString(lines);
+    std::unique_ptr<MultiPolygon> poly_col = factory->createMultiPolygon(polys);
+
+    pt_union = OverlayNGRobust::Union(static_cast<const Geometry*>(pt_col.get()));
+    line_union = OverlayNGRobust::Union(static_cast<const Geometry*>(line_col.get()));
+    poly_union = OverlayNGRobust::Union(static_cast<const Geometry*>(poly_col.get()));
+
+    // io::WKTWriter w;
+    // std::cout << "line_col " << w.write(*line_col) << std::endl;
+    // std::cout << "line_union " << w.write(*line_union) << std::endl;
+
+    if (! pt_union->isPuntal())
+        throw util::IllegalArgumentException("union of points not puntal");
+    if (! line_union->isLineal())
+        throw util::IllegalArgumentException("union of lines not lineal");
+    if (! poly_union->isPolygonal())
+        throw util::IllegalArgumentException("union of polygons not polygonal");
+}
+
+/* public */
+std::unique_ptr<Geometry>
+StructuredCollection::doUnaryUnion() const
+{
+    /*
+    * Before output, we clean up the components to remove spatial
+    * duplication. Points that lines pass through. Lines that are covered
+    * by polygonal areas already. Provides a "neater" output that still
+    * covers all the area it should.
+    */
+    std::unique_ptr<Geometry> pts_less_lines = OverlayNGRobust::Overlay(
+        pt_union.get(),
+        line_union.get(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> pts_less_polys_lines = OverlayNGRobust::Overlay(
+        pts_less_lines.get(),
+        poly_union.get(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> lines_less_polys = OverlayNGRobust::Overlay(
+        line_union.get(),
+        poly_union.get(),
+        OverlayNG::DIFFERENCE);
+
+    std::vector<const Geometry*> geoms;
+    toVector(pts_less_polys_lines.get(), geoms);
+    toVector(lines_less_polys.get(), geoms);
+    toVector(poly_union.get(), geoms);
+
+    return factory->buildGeometry(geoms.begin(), geoms.end());
+}
+
+
+/* public */
+std::unique_ptr<Geometry>
+StructuredCollection::doUnion(const StructuredCollection& a) const
+{
+
+    auto poly_union_poly = OverlayNGRobust::Overlay(
+        a.getPolyUnion(),
+        poly_union.get(),
+        OverlayNG::UNION);
+
+    auto line_union_line = OverlayNGRobust::Overlay(
+        a.getLineUnion(),
+        line_union.get(),
+        OverlayNG::UNION);
+
+    auto pt_union_pt = OverlayNGRobust::Overlay(
+        a.getPointUnion(),
+        pt_union.get(),
+        OverlayNG::UNION);
+
+    StructuredCollection c;
+    c.readCollection(poly_union_poly.get());
+    c.readCollection(line_union_line.get());
+    c.readCollection(pt_union_pt.get());
+    c.unionByDimension();
+    return c.doUnaryUnion();
+}
+
+
+std::unique_ptr<Geometry>
+StructuredCollection::doIntersection(const StructuredCollection& a) const
+{
+    std::unique_ptr<Geometry> poly_inter_poly = OverlayNGRobust::Overlay(
+        poly_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> poly_inter_line = OverlayNGRobust::Overlay(
+        poly_union.get(),
+        a.getLineUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> poly_inter_pt = OverlayNGRobust::Overlay(
+        poly_union.get(),
+        a.getPointUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> line_inter_poly = OverlayNGRobust::Overlay(
+        line_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> line_inter_line = OverlayNGRobust::Overlay(
+        line_union.get(),
+        a.getLineUnion(),
+        OverlayNG::INTERSECTION);
 
-        return ret;
+    std::unique_ptr<Geometry> line_inter_pt = OverlayNGRobust::Overlay(
+        line_union.get(),
+        a.getPointUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> pt_inter_pt = OverlayNGRobust::Overlay(
+        pt_union.get(),
+        a.getPointUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> pt_inter_line = OverlayNGRobust::Overlay(
+        pt_union.get(),
+        a.getLineUnion(),
+        OverlayNG::INTERSECTION);
+
+    std::unique_ptr<Geometry> pt_inter_poly = OverlayNGRobust::Overlay(
+        pt_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::INTERSECTION);
+
+    // io::WKTWriter w;
+    // std::cout << "poly_inter_poly " << w.write(*poly_inter_poly) << std::endl;
+    // std::cout << "poly_union.get() " << w.write(poly_union.get()) << std::endl;
+    // std::cout << "a.getLineUnion() " << w.write(a.getLineUnion()) << std::endl;
+    // std::cout << "poly_inter_line " << w.write(*poly_inter_line) << std::endl;
+    // std::cout << "poly_inter_pt " << w.write(*poly_inter_pt) << std::endl;
+    // std::cout << "line_inter_line " << w.write(*line_inter_line) << std::endl;
+    // std::cout << "line_inter_pt " << w.write(*line_inter_pt) << std::endl;
+    // std::cout << "pt_inter_pt " << w.write(*pt_inter_pt) << std::endl;
+
+    StructuredCollection c;
+    c.readCollection(poly_inter_poly.get());
+    c.readCollection(poly_inter_line.get());
+    c.readCollection(poly_inter_pt.get());
+    c.readCollection(line_inter_poly.get());
+    c.readCollection(line_inter_line.get());
+    c.readCollection(line_inter_pt.get());
+    c.readCollection(pt_inter_poly.get());
+    c.readCollection(pt_inter_line.get());
+    c.readCollection(pt_inter_pt.get());
+    c.unionByDimension();
+    return c.doUnaryUnion();
 }
 
+
+std::unique_ptr<Geometry>
+StructuredCollection::doDifference(const StructuredCollection& a) const
+{
+    std::unique_ptr<Geometry> poly_diff_poly = OverlayNGRobust::Overlay(
+        poly_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> line_diff_poly = OverlayNGRobust::Overlay(
+        line_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> pt_diff_poly = OverlayNGRobust::Overlay(
+        pt_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> line_diff_poly_line = OverlayNGRobust::Overlay(
+        line_diff_poly.get(),
+        a.getLineUnion(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> pt_diff_poly_line = OverlayNGRobust::Overlay(
+        pt_diff_poly.get(),
+        line_diff_poly_line.get(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> pt_diff_poly_line_pt = OverlayNGRobust::Overlay(
+        pt_diff_poly_line.get(),
+        a.getPointUnion(),
+        OverlayNG::DIFFERENCE);
+
+    StructuredCollection c;
+    c.readCollection(poly_diff_poly.get());
+    c.readCollection(line_diff_poly_line.get());
+    c.readCollection(pt_diff_poly_line_pt.get());
+    c.unionByDimension();
+    return c.doUnaryUnion();
+}
+
+std::unique_ptr<Geometry>
+StructuredCollection::doSymDifference(const StructuredCollection& a) const
+{
+    std::unique_ptr<Geometry> poly_symdiff_poly = OverlayNGRobust::Overlay(
+        poly_union.get(),
+        a.getPolyUnion(),
+        OverlayNG::SYMDIFFERENCE);
+
+    std::unique_ptr<Geometry> line_symdiff_line = OverlayNGRobust::Overlay(
+        line_union.get(),
+        a.getLineUnion(),
+        OverlayNG::DIFFERENCE);
+
+    std::unique_ptr<Geometry> pt_symdiff_pt = OverlayNGRobust::Overlay(
+        pt_union.get(),
+        a.getPointUnion(),
+        OverlayNG::DIFFERENCE);
+
+    StructuredCollection c;
+    c.readCollection(poly_symdiff_poly.get());
+    c.readCollection(line_symdiff_line.get());
+    c.readCollection(pt_symdiff_pt.get());
+    c.unionByDimension();
+    return c.doUnaryUnion();
+}
+
+
 } // namespace geos::geom
 } // namespace geos


=====================================
tests/unit/geom/DimensionTest.cpp
=====================================
@@ -5,6 +5,7 @@
 #include <tut/tut.hpp>
 // geos
 #include <geos/geom/Dimension.h>
+#include <geos/io/WKTReader.h>
 #include <geos/util/IllegalArgumentException.h>
 #include <geos/util.h>
 
@@ -137,5 +138,21 @@ void object::test<5>
     }
 }
 
+template<>
+template<>
+void object::test<6>
+()
+{
+    using geos::geom::Dimension;
+    geos::io::WKTReader reader;
+    auto geom = reader.read("GEOMETRYCOLLECTION(POINT(1 1), LINESTRING(2 2, 3 3))");
+    Dimension::DimensionType d = geom->getDimension();
+    // std::cout << d << std::endl;
+    // getDimension() finds the highest dimension in the collection
+    ensure(d == Dimension::L);
+}
+
+
+
 } // namespace tut
 


=====================================
tests/unit/geom/HeuristicOverlayTest.cpp
=====================================
@@ -0,0 +1,207 @@
+//
+// Test Suite for geos::geom::HeuristicOverlay
+
+#include <tut/tut.hpp>
+
+// geos
+#include <geos/algorithm/hull/ConcaveHull.h>
+#include <geos/constants.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/HeuristicOverlay.h>
+#include <geos/io/WKTReader.h>
+#include <geos/io/WKTWriter.h>
+#include <geos/operation/overlayng/OverlayNG.h>
+#include <utility.h>
+
+// std
+#include <string>
+#include <memory>
+
+namespace tut {
+//
+// Test Group
+//
+
+using geos::operation::overlayng::OverlayNG;
+
+struct test_heuristic_data {
+
+    WKTReader reader_;
+    WKTWriter writer_;
+
+    test_heuristic_data() {}
+
+    void checkOverlay(
+        const std::string& wkt1,
+        const std::string& wkt2,
+        int opCode,
+        const std::string& wkt_expected)
+    {
+        std::unique_ptr<Geometry> g1 = reader_.read(wkt1);
+        std::unique_ptr<Geometry> g2 = reader_.read(wkt2);
+        std::unique_ptr<Geometry> expected = reader_.read(wkt_expected);
+        std::unique_ptr<Geometry> actual = HeuristicOverlay(g1.get(), g2.get(), opCode);
+
+        // std::cout << "expected:" << std::endl << writer_.write(*expected) << std::endl;
+        // std::cout << "actual:" << std::endl << writer_.write(*actual) << std::endl;
+
+        ensure_equals_geometry(expected.get(), actual.get());
+    }
+
+
+};
+
+typedef test_group<test_heuristic_data> group;
+typedef group::object object;
+
+group test_heuristic_data("geos::geom::HeuristicOverlay");
+
+//
+// Test Cases
+//
+
+//
+// These tests exercise the special cast code in HeuristicOverlay
+// for GeometryCollection in which the contents are "mixed dimension",
+// such as points and lines or lines and polygons in the same collection.
+// For those cases the result of the overlay might be a matter of
+// interpretation, depending on the inputs and the opinions of the
+// end user. The implementation just tries to generate a visually
+// defensible, simplified answer.
+//
+
+template<>
+template<>
+void object::test<1> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(1 1, 2 2))",
+        "GEOMETRYCOLLECTION(POINT(10 10), LINESTRING(11 11, 12 12))",
+        OverlayNG::UNION,
+        "GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(1 1, 2 2), POINT(10 10), LINESTRING(11 11, 12 12))"
+        );
+}
+
+template<>
+template<>
+void object::test<2> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(1 1, 2 2))",
+        "POLYGON((-10 -10, -10 10, 10 10, 10 -10, -10 -10))",
+        OverlayNG::UNION,
+        "POLYGON((-10 -10, -10 10, 10 10, 10 -10, -10 -10))"
+        );
+}
+
+template<>
+template<>
+void object::test<3> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POINT(0.5 0.5), LINESTRING(0 0, 2 2), POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))",
+        "GEOMETRYCOLLECTION(LINESTRING(0.5 0.5, 0.5 4), POINT(2 0))",
+        OverlayNG::UNION,
+        "GEOMETRYCOLLECTION (POINT (2 0), LINESTRING (0.5 1, 0.5 4), LINESTRING (1 1, 2 2), POLYGON ((0 1, 1 1, 1 0, 0 0, 0 1)))"
+        );
+}
+
+template<>
+template<>
+void object::test<4> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)), LINESTRING(20 20, 30 30))",
+        "GEOMETRYCOLLECTION(POLYGON((9 9, 21 9, 21 21, 9 21, 9 9)), POINT(5 5))",
+        OverlayNG::DIFFERENCE,
+        "GEOMETRYCOLLECTION (LINESTRING (21 21, 30 30), POLYGON ((10 0, 0 0, 0 10, 9 10, 9 9, 10 9, 10 0)))"
+        );
+}
+
+template<>
+template<>
+void object::test<5> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)), LINESTRING(20 20, 30 30))",
+        "GEOMETRYCOLLECTION(POLYGON((9 9, 21 9, 21 21, 9 21, 9 9)), POINT(5 5))",
+        OverlayNG::INTERSECTION,
+        "GEOMETRYCOLLECTION (POINT (5 5), LINESTRING(20 20, 21 21), POLYGON ((10 10, 10 9, 9 9, 9 10, 10 10)))"
+        );
+}
+
+template<>
+template<>
+void object::test<6> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)), LINESTRING(20 20, 30 30))",
+        "GEOMETRYCOLLECTION(POLYGON((9 9, 21 9, 21 21, 9 21, 9 9)), POINT(5 5))",
+        OverlayNG::SYMDIFFERENCE,
+        "GEOMETRYCOLLECTION (LINESTRING (21 21, 30 30), POLYGON ((0 0, 0 10, 9 10, 9 9, 10 9, 10 0, 0 0)), POLYGON ((9 10, 9 21, 21 21, 21 9, 10 9, 10 10, 9 10)))"
+        );
+}
+
+
+template<>
+template<>
+void object::test<7> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))",
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))",
+        OverlayNG::UNION,
+        "POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))"
+        );
+}
+
+template<>
+template<>
+void object::test<8> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))",
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)), POINT(20 20))",
+        OverlayNG::DIFFERENCE,
+        "GEOMETRYCOLLECTION EMPTY"
+        );
+}
+
+template<>
+template<>
+void object::test<9> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))",
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))",
+        OverlayNG::INTERSECTION,
+        "POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))"
+        );
+}
+
+
+template<>
+template<>
+void object::test<10> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)), POINT EMPTY, MULTIPOINT(4 4, 11 11), LINESTRING(5 5, 6 6))",
+        "GEOMETRYCOLLECTION(POLYGON((2 2, 12 2, 12 12, 2 12, 2 2)), LINESTRING EMPTY, MULTIPOINT(4 4, 11 11), LINESTRING(5 6, 6 5))",
+        OverlayNG::INTERSECTION,
+        "GEOMETRYCOLLECTION (POINT (11 11), POLYGON ((10 10, 10 2, 2 2, 2 10, 10 10)))"
+        );
+}
+
+template<>
+template<>
+void object::test<11> ()
+{
+    checkOverlay(
+        "GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)), POINT EMPTY, MULTIPOINT(4 4, 11 11), LINESTRING(5 5, 6 6))",
+        "GEOMETRYCOLLECTION(POLYGON((2 2, 12 2, 12 12, 2 12, 2 2)), LINESTRING EMPTY, MULTIPOINT(4 4, 11 11), LINESTRING(5 6, 6 5))",
+        OverlayNG::UNION,
+        "POLYGON ((2 12, 12 12, 12 2, 10 2, 10 0, 0 0, 0 10, 2 10, 2 12))"
+        );
+}
+
+} // namespace tut



View it on GitLab: https://salsa.debian.org/debian-gis-team/geos/-/compare/5998dc09e2e5397c2ecae9fdc429537c6a1839cb...17978372ff4d6fa3354964f10d99050a4f039aa8

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/geos/-/compare/5998dc09e2e5397c2ecae9fdc429537c6a1839cb...17978372ff4d6fa3354964f10d99050a4f039aa8
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20230615/20c5391a/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list