This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 2b14e1bac60d9d6deb7fcd4084977891fcd065f4
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Mon Aug 12 13:24:26 2024 +0200

    Recognize more geometry types in SQL database.
    Derived from fixes by Johann Sorel.
---
 .../apache/sis/geometry/wrapper/GeometryType.java  | 178 ++++++++++++++++-----
 .../apache/sis/geometry/wrapper/esri/Factory.java  |   2 +-
 .../apache/sis/geometry/wrapper/j2d/Factory.java   |   2 +-
 .../sis/geometry/wrapper/GeometryTypeTest.java     |  25 ++-
 .../apache/sis/storage/sql/feature/Database.java   |   2 +-
 .../sis/storage/sql/feature/SpatialSchema.java     |   5 +-
 6 files changed, 163 insertions(+), 51 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryType.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryType.java
index bfdb51bfef..b338f9e50e 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryType.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/GeometryType.java
@@ -29,6 +29,7 @@ import org.apache.sis.util.privy.Constants;
 /**
  * Implementation-neutral description of the type of geometry.
  * The name of each enumeration value is the name in WKT format.
+ * The ordinal value is the binary code, ignoring thousands.
  *
  * @author  Martin Desruisseaux (Geomatys)
  *
@@ -40,7 +41,7 @@ public enum GeometryType {
      *
      * @see Geometries#rootClass
      */
-    GEOMETRY("Geometry"),
+    GEOMETRY("Geometry", false),
 
     /**
      * Zero-dimensional geometry containing a single point.
@@ -49,7 +50,7 @@ public enum GeometryType {
      *
      * @see Geometries#pointClass
      */
-    POINT("Point"),
+    POINT("Point", false),
 
     /**
      * Sequence of points connected by straight, non-self intersecting line 
pieces.
@@ -57,7 +58,7 @@ public enum GeometryType {
      *
      * @see Geometries#polylineClass
      */
-    LINESTRING("LineString"),
+    LINESTRING("LineString", false),
 
     /**
      * Geometry with a positive area (two-dimensional).
@@ -65,27 +66,123 @@ public enum GeometryType {
      *
      * @see Geometries#polygonClass
      */
-    POLYGON("Polygon"),
+    POLYGON("Polygon", false),
 
     /**
      * Set of points.
      */
-    MULTIPOINT("MultiPoint"),
+    MULTIPOINT("MultiPoint", true),
 
     /**
-     * Set of linestrings.
+     * Set of line strings.
      */
-    MULTILINESTRING("MultiLineString"),
+    MULTILINESTRING("MultiLineString", true),
 
     /**
      * Set of polygons.
      */
-    MULTIPOLYGON("MultiPolygon"),
+    MULTIPOLYGON("MultiPolygon", true),
 
     /**
      * Set of geometries of any type except other geometry collection.
      */
-    GEOMETRYCOLLECTION("GeometryCollection");
+    GEOMETRYCOLLECTION("GeometryCollection", true),
+
+    /**
+     * Curve with circular interpolation between points.
+     */
+    CIRCULARSTRING("CircularString", false),
+
+    /**
+     * Contiguous curves such that adjacent curves are joined at their end 
points.
+     */
+    COMPOUNDCURVE("CompoundCurve", true),
+
+    /**
+     * Planar surface consisting of a single patch.
+     */
+    CURVEPOLYGON("CurvePolygon", false),
+
+    /**
+     * Geometry collection made of curves.
+     */
+    MULTICURVE("MultiCurve", true),
+
+    /**
+     * Geometry collection made of surfaces.
+     */
+    MULTISURFACE("MultiSurface", true),
+
+    /**
+     * 1-dimensional geometry usually stored as a sequence of points.
+     * The subtype specifies the form of the interpolation between points.
+     */
+    CURVE("Curve", false),
+
+    /**
+     * 2-dimensional geometry associated with one exterior ring and zero or 
more interior rings.
+     */
+    SURFACE("Surface", false),
+
+    /**
+     * Surface composed of contiguous surfaces connected along their common 
boundary.
+     */
+    POLYHEDRALSURFACE("PolyhedralSurface", true),
+
+    /**
+     * Polyhedral surface composed only of triangles.
+     */
+    TIN("Tin", true),
+
+    /**
+     * Polygon with exactly four points (the last point being the same as the 
first point).
+     */
+    TRIANGLE("Triangle", false),
+
+    /**
+     * A circular curve in which the last point is the same as the first point.
+     */
+    CIRCLE("Circle", false),
+
+    /**
+     * Curve for the shortest distance on a sphere or ellipsoid.
+     */
+    GEODESICSTRING("GeodesicString", false),
+
+    /**
+     * Elliptical curve.
+     */
+    ELLIPTICALCURVE("EllipticalCurve", false),
+
+    /**
+     * Nurbs curve.
+     */
+    NURBSCURVE("NurbsCurve", false),
+
+    /**
+     * Clothoid.
+     */
+    CLOTHOID("Clothoid", false),
+
+    /**
+     * Curve describing a spiral.
+     */
+    SPIRALCURVE("SpiralCurve", false),
+
+    /**
+     * Surface made of other surfaces.
+     */
+    COMPOUNDSURFACE("CompoundSurface", true),
+
+    /**
+     * Brep solid.
+     */
+    BREPSOLID("BrepSolid", false);
+
+    /**
+     * All enumeration values, fetched at construction time for avoiding array 
copies.
+     */
+    private static final GeometryType[] VALUES = values();
 
     /**
      * Camel-case name of this geometry type.
@@ -93,6 +190,13 @@ public enum GeometryType {
      */
     public final String name;
 
+    /**
+     * Whether this geometry type is some sort of collection.
+     * Some of those types are {@link #MULTIPOINT}, {@link #MULTILINESTRING},
+     * {@link #MULTIPOLYGON} or {@link #GEOMETRYCOLLECTION}.
+     */
+    public final boolean isCollection;
+
     /**
      * The geometry types as ISO 19103 type names, created when first needed.
      * For a given enumeration value, all {@code typeNames} values are 
identical
@@ -111,9 +215,11 @@ public enum GeometryType {
      * Creates a new enumeration value.
      *
      * @param  name  camel-case name of the geometry.
+     * @param  isCollection  whether this geometry type is some sort of 
collection.
      */
-    private GeometryType(final String name) {
+    private GeometryType(final String name, final boolean isCollection) {
         this.name = name;
+        this.isCollection = isCollection;
         typeNames = new EnumMap<>(GeometryLibrary.class);
     }
 
@@ -167,14 +273,22 @@ public enum GeometryType {
     }
 
     /**
-     * Returns {@code true} if this geometry type is some sort of collection.
-     * Those types are {@link #MULTIPOINT}, {@link #MULTILINESTRING},
-     * {@link #MULTIPOLYGON} or {@link #GEOMETRYCOLLECTION}.
+     * Returns the enumeration value for the given WKB type, or {@code null} 
if unknown.
+     * Types for geometries having <var>Z</var> and <var>M</var> are replaced 
by 2D types.
      *
-     * @return whether this geometry type is some kind of collections.
+     * @param  type  WKB geometry type.
+     * @return enumeration value for the given type, or {@code null} if the 
given type is not recognized.
+     *
+     * @see #binaryType()
      */
-    public final boolean isCollection() {
-        return ordinal() >= MULTIPOINT.ordinal();
+    public static GeometryType forBinaryType(int type) {
+        if (type >= 1000 && type < 4000) {
+            type %= 1000;
+        }
+        if (type >= 0 && type < VALUES.length) {
+            return VALUES[type];
+        }
+        return null;
     }
 
     /**
@@ -204,31 +318,17 @@ public enum GeometryType {
     }
 
     /**
-     * Returns the enumeration value for the given WKB type, or {@code null} 
if unknown.
-     * Types for geometries having <var>Z</var> and <var>M</var> are replaced 
by 2D types.
+     * Returns {@code true} if the given name is one of the enumerated 
geometry types, ignoring case.
      *
-     * @param  type  WKB geometry type.
-     * @return enumeration value for the given type, or {@code null} if the 
given type is not recognized.
-     *
-     * @see #binaryType()
+     * @param  name  the name to test.
+     * @return whether the given name is one of the enumerated geometry types, 
ignoring case.
      */
-    public static GeometryType forBinaryType(int type) {
-        if (type >= 1000 && type < 4000) {
-            type %= 1000;
-        }
-        switch (type) {
-            default: return null;
-            case 0:  return GEOMETRY;
-            case 1:  return POINT;
-            case 2:  return LINESTRING;
-            case 3:  return POLYGON;
-            case 4:  return MULTIPOINT;
-            case 5:  return MULTILINESTRING;
-            case 6:  return MULTIPOLYGON;
-            case 7:  return GEOMETRYCOLLECTION;
-        //  case 13: return CURVE;
-        //  case 14: return SURFACE;
-        //  case 15: return POLYHEDRALSURFACE;
+    public static boolean isKnown(final String name) {
+        for (GeometryType value : VALUES) {
+            if (value.name().equalsIgnoreCase(name)) {
+                return true;
+            }
         }
+        return false;
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/esri/Factory.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/esri/Factory.java
index 0b513f3691..856966f9ba 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/esri/Factory.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/esri/Factory.java
@@ -251,7 +251,7 @@ public final class Factory extends Geometries<Geometry> {
             }
             if (geometry == null) {
                 final MultiPath path = isPolygon ? new Polygon() : new 
Polyline();
-                if (type.isCollection()) {
+                if (type.isCollection) {
                     for (final Object component : data) {
                         path.add((MultiPath) component, false);
                     }
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/j2d/Factory.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/j2d/Factory.java
index 35e01829ba..d8b831efd0 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/j2d/Factory.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/geometry/wrapper/j2d/Factory.java
@@ -288,7 +288,7 @@ public final class Factory extends Geometries<Shape> {
                 if (!isFloat) break;
             }
             final Path2D path = createPath(isFloat, 20);
-            if (type.isCollection()) {
+            if (type.isCollection) {
                 for (final Object component : data) {
                     path.append((Shape) component, false);
                 }
diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/geometry/wrapper/GeometryTypeTest.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/geometry/wrapper/GeometryTypeTest.java
index 94d06fa593..b28426063d 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/geometry/wrapper/GeometryTypeTest.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/geometry/wrapper/GeometryTypeTest.java
@@ -62,13 +62,24 @@ public final class GeometryTypeTest extends TestCase {
     }
 
     /**
-     * Tests {@link GeometryType#forBinaryType(int)} and verifies {@link 
GeometryType#binaryType()} values.
+     * Tests {@link GeometryType#forBinaryType(int)}.
      */
     @Test
-    public void testBinaryType() {
-        for (final GeometryType type : GeometryType.values()) {
-            assertSame(type, GeometryType.forBinaryType(type.binaryType()), 
type.name());
-        }
+    public void testForBinaryType() {
+        assertSame(GeometryType.GEOMETRY,           
GeometryType.forBinaryType( 0));
+        assertSame(GeometryType.POINT,              
GeometryType.forBinaryType( 1));
+        assertSame(GeometryType.LINESTRING,         
GeometryType.forBinaryType( 2));
+        assertSame(GeometryType.POLYGON,            
GeometryType.forBinaryType( 3));
+        assertSame(GeometryType.MULTIPOINT,         
GeometryType.forBinaryType( 4));
+        assertSame(GeometryType.MULTILINESTRING,    
GeometryType.forBinaryType( 5));
+        assertSame(GeometryType.MULTIPOLYGON,       
GeometryType.forBinaryType( 6));
+        assertSame(GeometryType.GEOMETRYCOLLECTION, 
GeometryType.forBinaryType( 7));
+        assertSame(GeometryType.CURVE,              
GeometryType.forBinaryType(13));
+        assertSame(GeometryType.SURFACE,            
GeometryType.forBinaryType(14));
+        assertSame(GeometryType.POLYHEDRALSURFACE,  
GeometryType.forBinaryType(15));
+        assertSame(GeometryType.TRIANGLE,           
GeometryType.forBinaryType(17));
+        assertSame(GeometryType.GEODESICSTRING,     
GeometryType.forBinaryType(19));
+        assertSame(GeometryType.BREPSOLID,          
GeometryType.forBinaryType(25));
     }
 
     /**
@@ -76,8 +87,8 @@ public final class GeometryTypeTest extends TestCase {
      */
     @Test
     public void testForName() {
-        assertSame(GeometryType.MULTIPOLYGON, 
GeometryType.forName("multi_Polygon"));
-        assertSame(GeometryType.MULTIPOLYGON, 
GeometryType.forName("MULTIPOLYGON"));
+        assertSame(GeometryType.MULTIPOLYGON,       
GeometryType.forName("multi_Polygon"));
+        assertSame(GeometryType.MULTIPOLYGON,       
GeometryType.forName("MULTIPOLYGON"));
         assertSame(GeometryType.GEOMETRYCOLLECTION, 
GeometryType.forName("GEOMETRY_COLLECTION"));
         assertSame(GeometryType.GEOMETRYCOLLECTION, 
GeometryType.forName("GeomCollection"));
     }
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java
index 71503d3fd3..379a96a11a 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/Database.java
@@ -584,7 +584,7 @@ public class Database<G> extends Syntax  {
      */
     @SuppressWarnings("fallthrough")
     protected ValueGetter<?> getMapping(final Column columnDefinition) {
-        if ("geometry".equalsIgnoreCase(columnDefinition.typeName)) {
+        if (GeometryType.isKnown(columnDefinition.typeName)) {
             return forGeometry(columnDefinition);
         }
         switch (columnDefinition.type) {
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
index 857530ca9b..a20176fc5b 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SpatialSchema.java
@@ -35,10 +35,11 @@ package org.apache.sis.storage.sql.feature;
 public enum SpatialSchema {
     /**
      * Table and column names as specified by Geopackage. This is the same 
thing as {@link #SQL_MM}
-     * except for table names and for the case (Geopackage uses lower case).
+     * except for table names, for the case (Geopackage uses lower case) and 
for the addition of a
+     * {@code geometry_type_name} column.
      */
     GEOPACKAGE("gpkg_spatial_ref_sys", "srs_id", "organization", 
"organization_coordsys_id", "definition",
-               "gpkg_geometry_columns", "table_catalog", "table_schema", 
"table_name", "column_name", null),
+               "gpkg_geometry_columns", "table_catalog", "table_schema", 
"table_name", "column_name", "geometry_type_name"),
 
     /**
      * Table and column names as specified by ISO-13249 SQL/MM. This is the 
same thing as {@link #SIMPLE_FEATURE}

Reply via email to