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);
