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

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

commit d82902e84713937df35f033773357b4ddbfff2d8
Author: jsorel <[email protected]>
AuthorDate: Wed May 6 23:42:05 2026 +0200

    fix(Shapefile): always generate an incremental feature identifier
---
 .../apache/sis/storage/shapefile/ShapefileStore.java   | 18 +++---------------
 .../sis/storage/shapefile/ShapefileStoreTest.java      |  6 +++++-
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
index 62d013bba7..cee805ad31 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
@@ -308,10 +308,6 @@ public final class ShapefileStore extends DataStore 
implements WritableFeatureSe
         private int[] dbfPropertiesIndex;
         private ShapeHeader shpHeader;
         private DBFHeader dbfHeader;
-        /**
-         * Name of the field used as identifier, may be null.
-         */
-        private String idField;
         private CoordinateReferenceSystem crs;
         private FeatureType type;
 
@@ -339,7 +335,7 @@ public final class ShapefileStore extends DataStore 
implements WritableFeatureSe
          */
         private boolean mustGenerateId() throws DataStoreException {
             try {
-                return getType().getProperty(AttributeConvention.IDENTIFIER) 
instanceof AttributeType;
+                return getType().getProperty(AttributeConvention.IDENTIFIER) 
!= null;
             } catch (PropertyNotFoundException ex) {
                 return false;
             }
@@ -418,7 +414,6 @@ public final class ShapefileStore extends DataStore 
implements WritableFeatureSe
                     try (DBFReader reader = new 
DBFReader(ShpFiles.openReadChannel(dbfFile), charset, timezone, null)) {
                         final DBFHeader header = reader.getHeader();
                         this.dbfHeader = header;
-                        boolean hasId = false;
 
                         if (readProperties == null) {
                             dbfPropertiesIndex = new int[header.fields.length];
@@ -436,13 +431,7 @@ public final class ShapefileStore extends DataStore 
implements WritableFeatureSe
                             dbfPropertiesIndex[idx] = i;
                             idx++;
 
-                            final AttributeTypeBuilder atb = 
ftb.addAttribute(field.valueClass).setName(field.fieldName);
-                            //no official but 'id' field is common
-                            if (!hasId && 
"id".equalsIgnoreCase(field.fieldName) || 
"identifier".equalsIgnoreCase(field.fieldName)) {
-                                idField = field.fieldName;
-                                
atb.addRole(AttributeRole.IDENTIFIER_COMPONENT);
-                                hasId = true;
-                            }
+                            
ftb.addAttribute(field.valueClass).setName(field.fieldName);
                         }
                         //the properties collection may have contain other 
names, for links or geometry, trim those
                         dbfPropertiesIndex = Arrays.copyOf(dbfPropertiesIndex, 
idx);
@@ -455,7 +444,7 @@ public final class ShapefileStore extends DataStore 
implements WritableFeatureSe
                 }
 
                 //create a computed identifier field
-                if (readProperties == null && idField == null) {
+                if (readProperties == null || 
readProperties.contains(AttributeConvention.IDENTIFIER)) {
                     ftb.addAttribute(Integer.class)
                        .setName(AttributeConvention.IDENTIFIER_PROPERTY)
                        .addRole(AttributeRole.IDENTIFIER_COMPONENT);
@@ -656,7 +645,6 @@ public final class ShapefileStore extends DataStore 
implements WritableFeatureSe
                     }
 
                     //if link fields are referenced, add target fields
-                    if (properties.contains(AttributeConvention.IDENTIFIER) && 
idField != null) simpleSelection &= !properties.add(idField);
                     if (properties.contains(AttributeConvention.GEOMETRY)) 
simpleSelection &= !properties.add(GEOMETRY_NAME);
                     if (properties.contains(AttributeConvention.ENVELOPE)) 
simpleSelection &= !properties.add(GEOMETRY_NAME);
                 }
diff --git 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
index d6cdaefcf6..afd74e99a4 100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
@@ -288,6 +288,9 @@ public class ShapefileStoreTest {
 
             Object[] result = store.features(false).toArray();
             assertEquals(1, result.length);
+
+            //because of incremental id, feature2 will now have sis:identifer=0
+            feature2.setPropertyValue(AttributeConvention.IDENTIFIER, 0);
             assertEquals(feature2, result[0]);
         }
     }
@@ -334,7 +337,6 @@ public class ShapefileStoreTest {
         try (final ShapefileStore store = new 
ShapefileStore(Paths.get(url.toURI()))) {
 
             final FeatureType type = store.getType();
-            System.out.println(type);
             final PropertyType generatedID = 
type.getProperty(AttributeConvention.IDENTIFIER);
             assertTrue(generatedID instanceof AttributeType);
             assertEquals(5, type.getProperties(true).size());
@@ -367,6 +369,7 @@ public class ShapefileStoreTest {
     private static Feature createFeature1(FeatureType type) {
         Feature feature = type.newInstance();
         feature.setPropertyValue("geometry", GF.createPoint(new 
Coordinate(10,20)));
+        feature.setPropertyValue(AttributeConvention.IDENTIFIER, 0);
         feature.setPropertyValue("id", 1);
         feature.setPropertyValue("text", "some text 1");
         feature.setPropertyValue("integer", 123);
@@ -378,6 +381,7 @@ public class ShapefileStoreTest {
     private static Feature createFeature2(FeatureType type) {
         Feature feature = type.newInstance();
         feature.setPropertyValue("geometry", GF.createPoint(new 
Coordinate(30,40)));
+        feature.setPropertyValue(AttributeConvention.IDENTIFIER, 1);
         feature.setPropertyValue("id", 2);
         feature.setPropertyValue("text", "some text 2");
         feature.setPropertyValue("integer", 456);

Reply via email to