You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2023/11/23 15:20:50 UTC

(sis) branch main updated (fafbe8a7b6 -> b9cb14901d)

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

desruisseaux pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/sis.git


    from fafbe8a7b6 Merge branch 'geoapi-3.1'
     add 0a359acef9 feat(Shapefile): add shp bbox filter, add dbf field selection filter
     add 544f7f9d2b Add a `DataStores.readGridCoverage(…)` convenience method.
     add d39d9c6c94 Add a little bit of context when the parsing fail over the dash character, for example as in "away-from" axis direction. Reduce rounding errors in `GridGeometry.toString()`.
     add ffcd9d444d Workaround for the parsing of WKT having some of the axis directions added in latest ISO 19111 revision.
     add 53319506d0 feat(Shapefile): optimize bbox filter and field selection, declare store in registry
     add d1ba389db2 Upgrade dependencies.
     add 4c9052a8f1 feat(Shapefile): implement featureset bounding box and count methods, several small fix in reader iterator
     add 93a7dcb4d3 Automatically install the parent `pom.xml` file.
     add 1c54d069b5 Fix misleading or interchanged localized resources.
     add 078f89d40d Add basic support for Braced URI Literal in the XPath expression given to `FilterFactory.property(String)`.
     add 67ece65ce1 Store the reason why the mandatory boolean value of a quality conformance result is missing. This is a partial replacement for a feature supported since SIS 0.3 but removed in SIS 1.4 because of https://issues.apache.org/jira/browse/SIS-586
     add 5fe5c77070 Do not generate anymore the French version of developer-guide. It has been deleted from the web site, because unmaintained.
     add 4981887586 Add "Obligation" and "Nil reason" columns in metadata `TreeTableView`.
     add 3d379f9aad Add support for nil date and nil URI in metadata.
     add dfc7aff69f Remove `NilDate`. It was not working because this class is mutable, so metadata make copies of it and those copies were not `NilObject`.
     add c0a92a7311 Add `MetadataStandard.asNilReasonMap(…)` method, together with support for classes that cannot implement the `NilObject` interface. As a side-effect of this work, other map views were refactored for putting more common code in the `PropertyMap` base class.
     add 0c561c5971 feat(Shapefile): add DBF writer and test case
     add fad33a63ee `TreeTableView` delegates the handling of `NilReason` to `NilReasonMap`. This is necessary for objects that cannot be represented as `NilObject`.
     add 6841fb91cf In `DefaultConformanceResult`, retrofit the handling of nil reasons into the `nilReasons()` map.
     add 125396eed4 Move into NilReasonMap the decision about whether to create NilObject or not. The rational for the removal of NilReason.isSupported(Class) is that we want an exception to be thrown when trying to use NilReason on an illegal type.
     add ceff560423 feat(Shapefile): fuse DBFField and DBFFieldEncoder, prepare store writing support
     add 6c716e3896 Apply the same technic than `DefaultConformanceResult` to other mandatory properties of type `Integer`. This is related to https://issues.apache.org/jira/browse/SIS-590
     add 2bbbb61932 Trivial comment formatting.
     add 79369245e4 Declare `nilReasons` as transient for avoiding JAXB in subclasses to inherit it.
     add 14e7273208 Add support for writing image with bands in different order than RGB.
     add faf0d27a25 Renaming of a CSS style used in the the developer guide, and spelling fixes.
     add 41663b06b8 Empirical threshold adjustment for a random (but rare) test failure.
     add bec9e14795 Calculation of mask derived from `java.awt.Shape` needs to be done in pixel coordinates rather grid cell coordinates.
     add 465d924558 Replace our custom `JAVA_OPTS` environment variable by the standard `JDK_JAVA_OPTIONS`. https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html#using-the-jdk_java_options-launcher-environment-variable
     add c03f90289c Flush the error stream before to exist the SIS command-line application. Otherwise error messages are lost.
     add aa6e471d74 chore(Build): add missing gradle wrapper configuration
     add c13e1339eb Partial support of `WritableAggregate` in GeoTIFF store. For now, only adding resources is supported, not removing them.
     add 603c5713cc Add a "translate" sub-command to the "sis" command line. This sub-command rewrites a raster in another format.
     add 0ac8c06a94 If an envelope cannot be transformed for metadata purpose, consider that as a warning rather than a fatal error. It happens when the CRS is an engineering CRS with no geodetic, projected, vertical or temporal component.
     add e818303189 feat(Shapefile): update shapefile header on close, some work on store writing support
     add 34df6c938d Allow `StoreListeners` argument to be null.
     add 4e6074db4e In XPath parsing, the "Q{namespace}name" syntax should be translated to "namespace:name", not "namespace/name".
     add 3adfcd615c Import order in preparation for merge.
     add fb00d38fa4 Merge branch 'geoapi-4.0' into geoapi-3.1. The main work are on Shapefile, GeoTIFF and metadata "nil reasons".
     new b9cb14901d Merge branch 'geoapi-3.1'. The main works are in Shapefile, GeoTIFF and metadata "nil values".

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/sis/buildtools/book/Assembler.java  |  14 +-
 .../apache/sis/buildtools/book/CodeColorizer.java  |   2 +-
 .../apache/sis/buildtools/book/package-info.java   |   2 +-
 .../org.apache.sis.console/main/module-info.java   |   3 +-
 .../main/org/apache/sis/console/Command.java       |   4 +-
 .../main/org/apache/sis/console/CommandRunner.java |  26 +
 .../org/apache/sis/console/Commands.properties     |   1 +
 .../org/apache/sis/console/Commands_fr.properties  |  17 +-
 .../main/org/apache/sis/console/HelpCommand.java   |   3 +-
 .../main/org/apache/sis/console/Option.java        |   8 +-
 .../main/org/apache/sis/console/Options.properties |   3 +-
 .../org/apache/sis/console/Options_fr.properties   |  23 +-
 .../org/apache/sis/console/TransformCommand.java   |   6 +-
 .../org/apache/sis/console/TranslateCommand.java   | 105 ++++
 .../main/org/apache/sis/console/package-info.java  |  11 +-
 .../org.apache.sis.feature/main/module-info.java   |   5 +-
 .../org/apache/sis/coverage/CoverageCombiner.java  |   8 +-
 .../org/apache/sis/coverage/RegionOfInterest.java  |   2 +-
 .../sis/coverage/grid/GridCoverageProcessor.java   |  21 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   2 +-
 .../org/apache/sis/filter/AssociationValue.java    |  12 +-
 .../apache/sis/filter/DefaultFilterFactory.java    |  14 +-
 .../main/org/apache/sis/filter/PropertyValue.java  |  36 +-
 .../apache/sis/filter/internal/FunctionNames.java  |  12 +
 .../main/org/apache/sis/filter/internal/XPath.java | 193 +++++--
 .../main/org/apache/sis/filter/package-info.java   |   2 +-
 .../test/org/apache/sis/filter/XPathTest.java      |  40 +-
 .../org.apache.sis.metadata/main/module-info.java  |   1 +
 .../org/apache/sis/metadata/AbstractMetadata.java  | 122 ++++-
 .../main/org/apache/sis/metadata/IndexMap.java     |  33 +-
 .../org/apache/sis/metadata/InformationMap.java    |  31 +-
 .../org/apache/sis/metadata/MetadataColumn.java    |  67 +++
 .../org/apache/sis/metadata/MetadataStandard.java  |  78 ++-
 .../apache/sis/metadata/ModifiableMetadata.java    |  21 +-
 .../main/org/apache/sis/metadata/NameMap.java      |  34 +-
 .../main/org/apache/sis/metadata/NilReasonMap.java | 209 ++++++++
 .../org/apache/sis/metadata/PropertyAccessor.java  |  43 +-
 .../main/org/apache/sis/metadata/PropertyMap.java  | 265 +++++++---
 .../main/org/apache/sis/metadata/TreeNode.java     | 228 ++++++--
 .../org/apache/sis/metadata/TreeNodeChildren.java  |  64 ++-
 .../org/apache/sis/metadata/TreeTableView.java     |  47 +-
 .../main/org/apache/sis/metadata/TypeMap.java      |  33 +-
 .../apache/sis/metadata/ValueExistencePolicy.java  |  12 +
 .../main/org/apache/sis/metadata/ValueMap.java     | 228 +-------
 .../apache/sis/metadata/internal/Resources.java    |   2 +-
 .../sis/metadata/internal/Resources.properties     |   2 +-
 .../sis/metadata/internal/Resources_fr.properties  |   2 +-
 .../iso/DefaultExtendedElementInformation.java     |  22 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   |  22 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |  27 +-
 .../sis/metadata/iso/citation/DefaultCitation.java |  22 +-
 .../sis/metadata/iso/citation/DefaultContact.java  |  22 +-
 .../iso/citation/DefaultResponsibility.java        |  22 +-
 .../iso/constraint/DefaultConstraints.java         |  22 +-
 .../iso/content/DefaultCoverageDescription.java    |  22 +-
 .../DefaultFeatureCatalogueDescription.java        |  22 +-
 .../iso/content/DefaultImageDescription.java       |  22 +-
 .../iso/content/DefaultRangeDimension.java         |  22 +-
 .../DefaultDigitalTransferOptions.java             |  22 +-
 .../metadata/iso/distribution/DefaultMedium.java   |  22 +-
 .../iso/identification/AbstractIdentification.java |  22 +-
 .../DefaultAggregateInformation.java               |  22 +-
 .../iso/identification/DefaultBrowseGraphic.java   |  22 +-
 .../iso/identification/DefaultCoupledResource.java |  22 +-
 .../identification/DefaultDataIdentification.java  |  22 +-
 .../DefaultRepresentativeFraction.java             |  22 +-
 .../DefaultServiceIdentification.java              |  22 +-
 .../metadata/iso/identification/DefaultUsage.java  |  22 +-
 .../sis/metadata/iso/lineage/DefaultLineage.java   |  22 +-
 .../metadata/iso/lineage/DefaultProcessStep.java   |  22 +-
 .../sis/metadata/iso/lineage/DefaultSource.java    |  22 +-
 .../maintenance/DefaultMaintenanceInformation.java |  22 +-
 .../sis/metadata/iso/quality/AbstractElement.java  |  22 +-
 .../iso/quality/DefaultConformanceResult.java      |  48 +-
 .../sis/metadata/iso/quality/package-info.java     |   3 +-
 .../sis/metadata/iso/spatial/DefaultDimension.java |  44 +-
 .../metadata/iso/spatial/DefaultGCPCollection.java |  44 +-
 .../spatial/DefaultGridSpatialRepresentation.java  |  44 +-
 .../sis/metadata/iso/spatial/package-info.java     |   2 +-
 .../main/org/apache/sis/metadata/package-info.java |  27 +-
 .../apache/sis/metadata/sql/util/package-info.java |   2 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |  22 +-
 .../org/apache/sis/util/iso/DefaultMemberName.java |  22 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |  22 +-
 .../org/apache/sis/util/iso/DefaultRecordType.java |  22 +-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |  22 +-
 .../main/org/apache/sis/util/iso/Names.java        |   2 +
 .../org/apache/sis/xml/NilInternationalString.java |   2 +-
 .../main/org/apache/sis/xml/NilReason.java         |  49 +-
 .../main/org/apache/sis/xml/ValueConverter.java    |   4 +-
 .../main/org/apache/sis/xml/XPointer.java          |   2 +-
 .../apache/sis/xml/bind/FinalClassExtensions.java  |   2 +-
 .../org/apache/sis/xml/bind/gco/GO_Boolean.java    |  13 +
 .../org/apache/sis/xml/bind/gco/GO_Integer.java    |  13 +
 .../org/apache/sis/xml/bind/gco/PropertyType.java  |  51 +-
 .../main/org/apache/sis/xml/package-info.java      |   2 +-
 .../org/apache/sis/metadata/NilReasonMapTest.java  | 102 ++++
 .../org/apache/sis/metadata/TreeTableViewTest.java | 103 +++-
 .../metadata/iso/quality/AbstractElementTest.java  |   2 +-
 .../quality/AbstractPositionalAccuracyTest.java    |   5 +-
 .../iso/quality/DefaultConformanceResultTest.java  | 118 +++++
 .../iso/quality/DefaultDomainConsistencyTest.java  |   2 +-
 .../iso/quality/DefaultEvaluationMethodTest.java   |  12 +-
 .../iso/quality/DefaultQuantitativeResultTest.java |   2 +-
 .../sis/metadata/iso/quality/ScopeCodeTest.java    |   4 +-
 .../test/org/apache/sis/xml/NilReasonTest.java     |  75 +--
 .../test/org/apache/sis/xml/test/TestCase.java     |  12 +
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   8 +
 .../sis/parameter/AbstractParameterDescriptor.java |  22 +-
 .../sis/parameter/DefaultParameterDescriptor.java  |  23 +-
 .../parameter/DefaultParameterDescriptorGroup.java |  22 +-
 .../sis/parameter/DefaultParameterValue.java       |  22 +-
 .../sis/parameter/DefaultParameterValueGroup.java  |  22 +-
 .../sis/referencing/AbstractIdentifiedObject.java  |  22 +-
 .../sis/referencing/AbstractReferenceSystem.java   |  22 +-
 .../apache/sis/referencing/AuthorityFactories.java |   2 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |  22 +-
 .../sis/referencing/crs/AbstractDerivedCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |  22 +-
 .../sis/referencing/crs/DefaultEngineeringCRS.java |  22 +-
 .../sis/referencing/crs/DefaultGeocentricCRS.java  |  22 +-
 .../sis/referencing/crs/DefaultGeodeticCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |  22 +-
 .../sis/referencing/crs/DefaultImageCRS.java       |  22 +-
 .../sis/referencing/crs/DefaultParametricCRS.java  |  22 +-
 .../sis/referencing/crs/DefaultProjectedCRS.java   |  22 +-
 .../sis/referencing/crs/DefaultTemporalCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultVerticalCRS.java    |  22 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  |  22 +-
 .../apache/sis/referencing/cs/DefaultAffineCS.java |  22 +-
 .../sis/referencing/cs/DefaultCartesianCS.java     |  22 +-
 .../cs/DefaultCoordinateSystemAxis.java            |  22 +-
 .../sis/referencing/cs/DefaultCylindricalCS.java   |  22 +-
 .../sis/referencing/cs/DefaultEllipsoidalCS.java   |  22 +-
 .../apache/sis/referencing/cs/DefaultLinearCS.java |  22 +-
 .../sis/referencing/cs/DefaultParametricCS.java    |  22 +-
 .../apache/sis/referencing/cs/DefaultPolarCS.java  |  22 +-
 .../sis/referencing/cs/DefaultSphericalCS.java     |  22 +-
 .../apache/sis/referencing/cs/DefaultTimeCS.java   |  22 +-
 .../sis/referencing/cs/DefaultUserDefinedCS.java   |  22 +-
 .../sis/referencing/cs/DefaultVerticalCS.java      |  22 +-
 .../sis/referencing/datum/AbstractDatum.java       |  22 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    |  22 +-
 .../referencing/datum/DefaultEngineeringDatum.java |  22 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |  22 +-
 .../sis/referencing/datum/DefaultImageDatum.java   |  22 +-
 .../referencing/datum/DefaultParametricDatum.java  |  22 +-
 .../referencing/datum/DefaultPrimeMeridian.java    |  22 +-
 .../referencing/datum/DefaultTemporalDatum.java    |  22 +-
 .../referencing/datum/DefaultVerticalDatum.java    |  22 +-
 .../sis/referencing/internal/MergedProperties.java |   4 +-
 .../operation/AbstractCoordinateOperation.java     |  22 +-
 .../operation/AbstractSingleOperation.java         |  22 +-
 .../operation/DefaultConcatenatedOperation.java    |  22 +-
 .../referencing/operation/DefaultConversion.java   |  22 +-
 .../operation/DefaultOperationMethod.java          |  22 +-
 .../operation/DefaultPassThroughOperation.java     |  22 +-
 .../operation/DefaultTransformation.java           |  22 +-
 .../sis/referencing/util/AxisDirections.java       |   8 +
 .../referencing/operation/matrix/SolverTest.java   |   2 +-
 .../transform/CartesianToSphericalTest.java        |   2 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |  36 +-
 .../sis/storage/geotiff/GeoTiffStoreProvider.java  |   5 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    |   6 +-
 .../org/apache/sis/storage/geotiff/Reader.java     |   8 +
 .../apache/sis/storage/geotiff/WritableStore.java  |  83 +++
 .../org/apache/sis/storage/geotiff/Writer.java     |  16 +
 .../sis/storage/geotiff/writer/TileMatrix.java     |  21 +-
 .../org/apache/sis/storage/gpx/Description.java    |   2 +-
 .../apache/sis/io/stream/HyperRectangleWriter.java |  98 ++--
 .../sis/io/stream/SubsampledRectangleWriter.java   | 331 ++++++++++++
 .../main/org/apache/sis/storage/DataStores.java    |  60 ++-
 .../main/org/apache/sis/storage/FeatureQuery.java  |   4 +-
 .../apache/sis/storage/RasterLoadingStrategy.java  |   5 +-
 .../sis/storage/aggregate/GroupAggregate.java      |   6 +-
 .../apache/sis/storage/base/MetadataBuilder.java   |  39 +-
 .../apache/sis/storage/base/SimpleAggregate.java   |  57 ++
 .../org/apache/sis/storage/base/URIDataStore.java  |   2 +
 .../sis/storage/base/WritableAggregateSupport.java | 118 +++++
 .../WritableGridCoverageSupport.java}              |  29 +-
 .../main/org/apache/sis/storage/csv/Store.java     |   7 +-
 .../org/apache/sis/storage/esri/RasterStore.java   |   7 +-
 .../org/apache/sis/storage/esri/WritableStore.java |   6 +-
 .../apache/sis/storage/image/SingleImageStore.java |   5 +-
 .../apache/sis/storage/image/WorldFileStore.java   |   6 +-
 .../apache/sis/storage/image/WritableResource.java |   6 +-
 .../org/apache/sis/storage/internal/Resources.java |   6 +
 .../sis/storage/internal/Resources.properties      |   1 +
 .../sis/storage/internal/Resources_fr.properties   |   1 +
 ...est.java => SubsampledRectangleWriterTest.java} | 118 ++---
 .../main/org/apache/sis/util/CharSequences.java    |   8 +
 .../apache/sis/util/collection/TableColumn.java    |  29 +-
 .../main/org/apache/sis/util/resources/Errors.java |   2 +-
 .../apache/sis/util/resources/Errors.properties    |   2 +-
 .../apache/sis/util/resources/Errors_fr.properties |   2 +-
 .../org/apache/sis/util/resources/Vocabulary.java  |   5 +
 .../sis/util/resources/Vocabulary.properties       |   1 +
 .../sis/util/resources/Vocabulary_fr.properties    |   1 +
 .../org/apache/sis/util/CharSequencesTest.java     |   1 +
 gradle/wrapper/gradle-wrapper.jar                  | Bin 0 -> 63721 bytes
 gradle/wrapper/gradle-wrapper.properties           |   7 +
 gradlew                                            | 249 +++++++++
 gradlew.bat                                        |  92 ++++
 .../org.apache.sis.storage.DataStoreProvider       |   2 +-
 .../main/module-info.java                          |   3 +
 .../storage/shapefile/ListingPropertyVisitor.java  |  79 +++
 .../sis/storage/shapefile/ShapefileProvider.java   |   4 +-
 .../sis/storage/shapefile/ShapefileStore.java      | 573 +++++++++++++++++++--
 .../apache/sis/storage/shapefile/dbf/DBFField.java | 264 +++++++++-
 .../sis/storage/shapefile/dbf/DBFFieldEncoder.java | 206 --------
 .../sis/storage/shapefile/dbf/DBFHeader.java       |  50 +-
 .../sis/storage/shapefile/dbf/DBFReader.java       |  38 +-
 .../{shp/ShapeWriter.java => dbf/DBFWriter.java}   |  44 +-
 .../shapefile/shp/ShapeGeometryEncoder.java        | 303 ++++++-----
 .../sis/storage/shapefile/shp/ShapeHeader.java     |  18 +-
 .../sis/storage/shapefile/shp/ShapeReader.java     |  21 +-
 .../sis/storage/shapefile/shp/ShapeRecord.java     |  34 +-
 .../sis/storage/shapefile/shp/ShapeWriter.java     |  51 +-
 .../{shp/ShapeWriter.java => shx/IndexWriter.java} |  39 +-
 .../sis/storage/shapefile/ShapefileStoreTest.java  | 109 ++++
 .../sis/storage/shapefile/dbf/DBFIOTest.java       | 100 +++-
 .../sis/storage/shapefile/shp/ShapeIOTest.java     |  72 ++-
 netbeans-project/ivy.xml                           |   8 +-
 netbeans-project/nbproject/project.xml             |   3 +
 optional/src/org.apache.sis.gui/bundle/bin/sis     |   4 +-
 optional/src/org.apache.sis.gui/bundle/bin/sis.bat |   2 +-
 optional/src/org.apache.sis.gui/bundle/bin/sisfx   |   4 +-
 .../src/org.apache.sis.gui/bundle/bin/sisfx.bat    |   2 +-
 parent/README.md                                   |   8 +
 .../style/Style.java => parent/build.gradle.kts    |  14 +-
 parent/pom.xml                                     |   2 +-
 settings.gradle.kts                                |   9 +-
 233 files changed, 5938 insertions(+), 2296 deletions(-)
 create mode 100644 endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TranslateCommand.java
 create mode 100644 endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/MetadataColumn.java
 create mode 100644 endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/NilReasonMap.java
 create mode 100644 endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/NilReasonMapTest.java
 create mode 100644 endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/DefaultConformanceResultTest.java
 create mode 100644 endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/WritableStore.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/SubsampledRectangleWriter.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/SimpleAggregate.java
 create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/WritableAggregateSupport.java
 rename endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/{internal/WritableResourceSupport.java => base/WritableGridCoverageSupport.java} (91%)
 copy endorsed/src/org.apache.sis.storage/test/org/apache/sis/io/stream/{HyperRectangleWriterTest.java => SubsampledRectangleWriterTest.java} (56%)
 create mode 100644 gradle/wrapper/gradle-wrapper.jar
 create mode 100644 gradle/wrapper/gradle-wrapper.properties
 create mode 100755 gradlew
 create mode 100644 gradlew.bat
 copy {endorsed/src/org.apache.sis.storage.netcdf => incubator/src/org.apache.sis.storage.shapefile}/main/META-INF/services/org.apache.sis.storage.DataStoreProvider (82%)
 create mode 100644 incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ListingPropertyVisitor.java
 delete mode 100644 incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/dbf/DBFFieldEncoder.java
 copy incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/{shp/ShapeWriter.java => dbf/DBFWriter.java} (55%)
 copy incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/{shp/ShapeWriter.java => shx/IndexWriter.java} (61%)
 create mode 100644 parent/README.md
 copy endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/style/Style.java => parent/build.gradle.kts (74%)


(sis) 01/01: Merge branch 'geoapi-3.1'. The main works are in Shapefile, GeoTIFF and metadata "nil values".

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b9cb14901d4f3b6ba40a7ff92174347d12ae6951
Merge: fafbe8a7b6 fb00d38fa4
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Thu Nov 23 16:08:22 2023 +0100

    Merge branch 'geoapi-3.1'.
    The main works are in Shapefile, GeoTIFF and metadata "nil values".

 .../org/apache/sis/buildtools/book/Assembler.java  |  14 +-
 .../apache/sis/buildtools/book/CodeColorizer.java  |   2 +-
 .../apache/sis/buildtools/book/package-info.java   |   2 +-
 .../org.apache.sis.console/main/module-info.java   |   3 +-
 .../main/org/apache/sis/console/Command.java       |   4 +-
 .../main/org/apache/sis/console/CommandRunner.java |  26 +
 .../org/apache/sis/console/Commands.properties     |   1 +
 .../org/apache/sis/console/Commands_fr.properties  |  17 +-
 .../main/org/apache/sis/console/HelpCommand.java   |   3 +-
 .../main/org/apache/sis/console/Option.java        |   8 +-
 .../main/org/apache/sis/console/Options.properties |   3 +-
 .../org/apache/sis/console/Options_fr.properties   |  23 +-
 .../org/apache/sis/console/TransformCommand.java   |   6 +-
 .../org/apache/sis/console/TranslateCommand.java   | 105 ++++
 .../main/org/apache/sis/console/package-info.java  |  11 +-
 .../org.apache.sis.feature/main/module-info.java   |   5 +-
 .../org/apache/sis/coverage/CoverageCombiner.java  |   8 +-
 .../org/apache/sis/coverage/RegionOfInterest.java  |   2 +-
 .../sis/coverage/grid/GridCoverageProcessor.java   |  21 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   2 +-
 .../org/apache/sis/filter/AssociationValue.java    |  12 +-
 .../apache/sis/filter/DefaultFilterFactory.java    |  14 +-
 .../main/org/apache/sis/filter/PropertyValue.java  |  36 +-
 .../apache/sis/filter/internal/FunctionNames.java  |  12 +
 .../main/org/apache/sis/filter/internal/XPath.java | 193 +++++--
 .../main/org/apache/sis/filter/package-info.java   |   2 +-
 .../test/org/apache/sis/filter/XPathTest.java      |  40 +-
 .../org.apache.sis.metadata/main/module-info.java  |   1 +
 .../org/apache/sis/metadata/AbstractMetadata.java  | 122 ++++-
 .../main/org/apache/sis/metadata/IndexMap.java     |  33 +-
 .../org/apache/sis/metadata/InformationMap.java    |  31 +-
 .../org/apache/sis/metadata/MetadataColumn.java    |  67 +++
 .../org/apache/sis/metadata/MetadataStandard.java  |  78 ++-
 .../apache/sis/metadata/ModifiableMetadata.java    |  21 +-
 .../main/org/apache/sis/metadata/NameMap.java      |  34 +-
 .../main/org/apache/sis/metadata/NilReasonMap.java | 209 ++++++++
 .../org/apache/sis/metadata/PropertyAccessor.java  |  43 +-
 .../main/org/apache/sis/metadata/PropertyMap.java  | 265 +++++++---
 .../main/org/apache/sis/metadata/TreeNode.java     | 228 ++++++--
 .../org/apache/sis/metadata/TreeNodeChildren.java  |  64 ++-
 .../org/apache/sis/metadata/TreeTableView.java     |  47 +-
 .../main/org/apache/sis/metadata/TypeMap.java      |  33 +-
 .../apache/sis/metadata/ValueExistencePolicy.java  |  12 +
 .../main/org/apache/sis/metadata/ValueMap.java     | 228 +-------
 .../apache/sis/metadata/internal/Resources.java    |   2 +-
 .../sis/metadata/internal/Resources.properties     |   2 +-
 .../sis/metadata/internal/Resources_fr.properties  |   2 +-
 .../iso/DefaultExtendedElementInformation.java     |  22 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   |  22 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |  27 +-
 .../sis/metadata/iso/citation/DefaultCitation.java |  22 +-
 .../sis/metadata/iso/citation/DefaultContact.java  |  22 +-
 .../iso/citation/DefaultResponsibility.java        |  22 +-
 .../iso/constraint/DefaultConstraints.java         |  22 +-
 .../iso/content/DefaultCoverageDescription.java    |  22 +-
 .../DefaultFeatureCatalogueDescription.java        |  22 +-
 .../iso/content/DefaultImageDescription.java       |  22 +-
 .../iso/content/DefaultRangeDimension.java         |  22 +-
 .../DefaultDigitalTransferOptions.java             |  22 +-
 .../metadata/iso/distribution/DefaultMedium.java   |  22 +-
 .../iso/identification/AbstractIdentification.java |  22 +-
 .../DefaultAggregateInformation.java               |  22 +-
 .../iso/identification/DefaultBrowseGraphic.java   |  22 +-
 .../iso/identification/DefaultCoupledResource.java |  22 +-
 .../identification/DefaultDataIdentification.java  |  22 +-
 .../DefaultRepresentativeFraction.java             |  22 +-
 .../DefaultServiceIdentification.java              |  22 +-
 .../metadata/iso/identification/DefaultUsage.java  |  22 +-
 .../sis/metadata/iso/lineage/DefaultLineage.java   |  22 +-
 .../metadata/iso/lineage/DefaultProcessStep.java   |  22 +-
 .../sis/metadata/iso/lineage/DefaultSource.java    |  22 +-
 .../maintenance/DefaultMaintenanceInformation.java |  22 +-
 .../sis/metadata/iso/quality/AbstractElement.java  |  22 +-
 .../iso/quality/DefaultConformanceResult.java      |  48 +-
 .../sis/metadata/iso/quality/package-info.java     |   3 +-
 .../sis/metadata/iso/spatial/DefaultDimension.java |  44 +-
 .../metadata/iso/spatial/DefaultGCPCollection.java |  44 +-
 .../spatial/DefaultGridSpatialRepresentation.java  |  44 +-
 .../sis/metadata/iso/spatial/package-info.java     |   2 +-
 .../main/org/apache/sis/metadata/package-info.java |  27 +-
 .../apache/sis/metadata/sql/util/package-info.java |   2 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |  22 +-
 .../org/apache/sis/util/iso/DefaultMemberName.java |  22 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |  22 +-
 .../org/apache/sis/util/iso/DefaultRecordType.java |  22 +-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |  22 +-
 .../main/org/apache/sis/util/iso/Names.java        |   2 +
 .../org/apache/sis/xml/NilInternationalString.java |   2 +-
 .../main/org/apache/sis/xml/NilReason.java         |  49 +-
 .../main/org/apache/sis/xml/ValueConverter.java    |   4 +-
 .../main/org/apache/sis/xml/XPointer.java          |   2 +-
 .../apache/sis/xml/bind/FinalClassExtensions.java  |   2 +-
 .../org/apache/sis/xml/bind/gco/GO_Boolean.java    |  13 +
 .../org/apache/sis/xml/bind/gco/GO_Integer.java    |  13 +
 .../org/apache/sis/xml/bind/gco/PropertyType.java  |  51 +-
 .../main/org/apache/sis/xml/package-info.java      |   2 +-
 .../org/apache/sis/metadata/NilReasonMapTest.java  | 102 ++++
 .../org/apache/sis/metadata/TreeTableViewTest.java | 103 +++-
 .../metadata/iso/quality/AbstractElementTest.java  |   2 +-
 .../quality/AbstractPositionalAccuracyTest.java    |   5 +-
 .../iso/quality/DefaultConformanceResultTest.java  | 118 +++++
 .../iso/quality/DefaultDomainConsistencyTest.java  |   2 +-
 .../iso/quality/DefaultEvaluationMethodTest.java   |  12 +-
 .../iso/quality/DefaultQuantitativeResultTest.java |   2 +-
 .../sis/metadata/iso/quality/ScopeCodeTest.java    |   4 +-
 .../test/org/apache/sis/xml/NilReasonTest.java     |  75 +--
 .../test/org/apache/sis/xml/test/TestCase.java     |  12 +
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   8 +
 .../sis/parameter/AbstractParameterDescriptor.java |  22 +-
 .../sis/parameter/DefaultParameterDescriptor.java  |  23 +-
 .../parameter/DefaultParameterDescriptorGroup.java |  22 +-
 .../sis/parameter/DefaultParameterValue.java       |  22 +-
 .../sis/parameter/DefaultParameterValueGroup.java  |  22 +-
 .../sis/referencing/AbstractIdentifiedObject.java  |  22 +-
 .../sis/referencing/AbstractReferenceSystem.java   |  22 +-
 .../apache/sis/referencing/AuthorityFactories.java |   2 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |  22 +-
 .../sis/referencing/crs/AbstractDerivedCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |  22 +-
 .../sis/referencing/crs/DefaultEngineeringCRS.java |  22 +-
 .../sis/referencing/crs/DefaultGeocentricCRS.java  |  22 +-
 .../sis/referencing/crs/DefaultGeodeticCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |  22 +-
 .../sis/referencing/crs/DefaultImageCRS.java       |  22 +-
 .../sis/referencing/crs/DefaultParametricCRS.java  |  22 +-
 .../sis/referencing/crs/DefaultProjectedCRS.java   |  22 +-
 .../sis/referencing/crs/DefaultTemporalCRS.java    |  22 +-
 .../sis/referencing/crs/DefaultVerticalCRS.java    |  22 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  |  22 +-
 .../apache/sis/referencing/cs/DefaultAffineCS.java |  22 +-
 .../sis/referencing/cs/DefaultCartesianCS.java     |  22 +-
 .../cs/DefaultCoordinateSystemAxis.java            |  22 +-
 .../sis/referencing/cs/DefaultCylindricalCS.java   |  22 +-
 .../sis/referencing/cs/DefaultEllipsoidalCS.java   |  22 +-
 .../apache/sis/referencing/cs/DefaultLinearCS.java |  22 +-
 .../sis/referencing/cs/DefaultParametricCS.java    |  22 +-
 .../apache/sis/referencing/cs/DefaultPolarCS.java  |  22 +-
 .../sis/referencing/cs/DefaultSphericalCS.java     |  22 +-
 .../apache/sis/referencing/cs/DefaultTimeCS.java   |  22 +-
 .../sis/referencing/cs/DefaultUserDefinedCS.java   |  22 +-
 .../sis/referencing/cs/DefaultVerticalCS.java      |  22 +-
 .../sis/referencing/datum/AbstractDatum.java       |  22 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    |  22 +-
 .../referencing/datum/DefaultEngineeringDatum.java |  22 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |  22 +-
 .../sis/referencing/datum/DefaultImageDatum.java   |  22 +-
 .../referencing/datum/DefaultParametricDatum.java  |  22 +-
 .../referencing/datum/DefaultPrimeMeridian.java    |  22 +-
 .../referencing/datum/DefaultTemporalDatum.java    |  22 +-
 .../referencing/datum/DefaultVerticalDatum.java    |  22 +-
 .../sis/referencing/internal/MergedProperties.java |   4 +-
 .../operation/AbstractCoordinateOperation.java     |  22 +-
 .../operation/AbstractSingleOperation.java         |  22 +-
 .../operation/DefaultConcatenatedOperation.java    |  22 +-
 .../referencing/operation/DefaultConversion.java   |  22 +-
 .../operation/DefaultOperationMethod.java          |  22 +-
 .../operation/DefaultPassThroughOperation.java     |  22 +-
 .../operation/DefaultTransformation.java           |  22 +-
 .../sis/referencing/util/AxisDirections.java       |   8 +
 .../referencing/operation/matrix/SolverTest.java   |   2 +-
 .../transform/CartesianToSphericalTest.java        |   2 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |  36 +-
 .../sis/storage/geotiff/GeoTiffStoreProvider.java  |   5 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    |   6 +-
 .../org/apache/sis/storage/geotiff/Reader.java     |   8 +
 .../apache/sis/storage/geotiff/WritableStore.java  |  83 +++
 .../org/apache/sis/storage/geotiff/Writer.java     |  16 +
 .../sis/storage/geotiff/writer/TileMatrix.java     |  21 +-
 .../org/apache/sis/storage/gpx/Description.java    |   2 +-
 .../apache/sis/io/stream/HyperRectangleWriter.java |  98 ++--
 .../sis/io/stream/SubsampledRectangleWriter.java   | 331 ++++++++++++
 .../main/org/apache/sis/storage/DataStores.java    |  60 ++-
 .../main/org/apache/sis/storage/FeatureQuery.java  |   4 +-
 .../apache/sis/storage/RasterLoadingStrategy.java  |   5 +-
 .../sis/storage/aggregate/GroupAggregate.java      |   6 +-
 .../apache/sis/storage/base/MetadataBuilder.java   |  39 +-
 .../apache/sis/storage/base/SimpleAggregate.java   |  57 ++
 .../org/apache/sis/storage/base/URIDataStore.java  |   2 +
 .../sis/storage/base/WritableAggregateSupport.java | 118 +++++
 .../WritableGridCoverageSupport.java}              |  29 +-
 .../main/org/apache/sis/storage/csv/Store.java     |   7 +-
 .../org/apache/sis/storage/esri/RasterStore.java   |   7 +-
 .../org/apache/sis/storage/esri/WritableStore.java |   6 +-
 .../apache/sis/storage/image/SingleImageStore.java |   5 +-
 .../apache/sis/storage/image/WorldFileStore.java   |   6 +-
 .../apache/sis/storage/image/WritableResource.java |   6 +-
 .../org/apache/sis/storage/internal/Resources.java |   6 +
 .../sis/storage/internal/Resources.properties      |   1 +
 .../sis/storage/internal/Resources_fr.properties   |   1 +
 .../io/stream/SubsampledRectangleWriterTest.java   | 192 +++++++
 .../main/org/apache/sis/util/CharSequences.java    |   8 +
 .../apache/sis/util/collection/TableColumn.java    |  29 +-
 .../main/org/apache/sis/util/resources/Errors.java |   2 +-
 .../apache/sis/util/resources/Errors.properties    |   2 +-
 .../apache/sis/util/resources/Errors_fr.properties |   2 +-
 .../org/apache/sis/util/resources/Vocabulary.java  |   5 +
 .../sis/util/resources/Vocabulary.properties       |   1 +
 .../sis/util/resources/Vocabulary_fr.properties    |   1 +
 .../org/apache/sis/util/CharSequencesTest.java     |   1 +
 gradle/wrapper/gradle-wrapper.jar                  | Bin 0 -> 63721 bytes
 gradle/wrapper/gradle-wrapper.properties           |   7 +
 gradlew                                            | 249 +++++++++
 gradlew.bat                                        |  92 ++++
 .../org.apache.sis.storage.DataStoreProvider       |   4 +
 .../main/module-info.java                          |   3 +
 .../storage/shapefile/ListingPropertyVisitor.java  |  79 +++
 .../sis/storage/shapefile/ShapefileProvider.java   |   4 +-
 .../sis/storage/shapefile/ShapefileStore.java      | 573 +++++++++++++++++++--
 .../apache/sis/storage/shapefile/dbf/DBFField.java | 264 +++++++++-
 .../sis/storage/shapefile/dbf/DBFFieldEncoder.java | 206 --------
 .../sis/storage/shapefile/dbf/DBFHeader.java       |  50 +-
 .../sis/storage/shapefile/dbf/DBFReader.java       |  38 +-
 .../{shp/ShapeWriter.java => dbf/DBFWriter.java}   |  44 +-
 .../shapefile/shp/ShapeGeometryEncoder.java        | 303 ++++++-----
 .../sis/storage/shapefile/shp/ShapeHeader.java     |  18 +-
 .../sis/storage/shapefile/shp/ShapeReader.java     |  21 +-
 .../sis/storage/shapefile/shp/ShapeRecord.java     |  34 +-
 .../sis/storage/shapefile/shp/ShapeWriter.java     |  51 +-
 .../{shp/ShapeWriter.java => shx/IndexWriter.java} |  39 +-
 .../sis/storage/shapefile/ShapefileStoreTest.java  | 109 ++++
 .../sis/storage/shapefile/dbf/DBFIOTest.java       | 100 +++-
 .../sis/storage/shapefile/shp/ShapeIOTest.java     |  72 ++-
 netbeans-project/ivy.xml                           |   8 +-
 netbeans-project/nbproject/project.xml             |   3 +
 optional/src/org.apache.sis.gui/bundle/bin/sis     |   4 +-
 optional/src/org.apache.sis.gui/bundle/bin/sis.bat |   2 +-
 optional/src/org.apache.sis.gui/bundle/bin/sisfx   |   4 +-
 .../src/org.apache.sis.gui/bundle/bin/sisfx.bat    |   2 +-
 parent/README.md                                   |   8 +
 .../module-info.java => parent/build.gradle.kts    |  20 +-
 parent/pom.xml                                     |   2 +-
 settings.gradle.kts                                |   9 +-
 233 files changed, 6082 insertions(+), 2234 deletions(-)

diff --cc endorsed/src/org.apache.sis.feature/main/module-info.java
index ceec296980,7018c1308f..a8270aa1d2
--- a/endorsed/src/org.apache.sis.feature/main/module-info.java
+++ b/endorsed/src/org.apache.sis.feature/main/module-info.java
@@@ -41,14 -41,11 +41,16 @@@ module org.apache.sis.feature 
      exports org.apache.sis.filter;
      exports org.apache.sis.index.tree;
  
 +    exports org.apache.sis.pending.geoapi.filter to
 +            org.apache.sis.storage,
 +            org.apache.sis.storage.sql,
++            org.apache.sis.storage.shapefile,       // In the "incubator" sub-project.
 +            org.apache.sis.portrayal;
 +
      exports org.apache.sis.filter.internal to
              org.apache.sis.storage,
              org.apache.sis.storage.sql,
+             org.apache.sis.storage.shapefile,       // In the "incubator" sub-project.
 -            org.apache.sis.cql,                     // In the "incubator" sub-project.
              org.apache.sis.portrayal;
  
      exports org.apache.sis.feature.internal to
@@@ -63,7 -60,9 +65,8 @@@
              org.apache.sis.storage,
              org.apache.sis.storage.xml,
              org.apache.sis.storage.sql,
-             org.apache.sis.storage.netcdf;
+             org.apache.sis.storage.netcdf,
 -            org.apache.sis.storage.shapefile,       // In the "incubator" sub-project.
 -            org.apache.sis.cql;                     // In the "incubator" sub-project.
++            org.apache.sis.storage.shapefile;       // In the "incubator" sub-project.
  
      exports org.apache.sis.geometry.wrapper.j2d to
              org.apache.sis.gui;                     // In the "optional" sub-project.
diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/AssociationValue.java
index 9ec6cc3477,3b8242bf4c..c3ae920f32
--- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/AssociationValue.java
+++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/AssociationValue.java
@@@ -24,17 -24,17 +24,17 @@@ import java.util.Optional
  import org.apache.sis.feature.Features;
  import org.apache.sis.feature.builder.FeatureTypeBuilder;
  import org.apache.sis.feature.builder.PropertyTypeBuilder;
+ import org.apache.sis.filter.internal.XPath;
  import org.apache.sis.math.FunctionProperty;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.FeatureAssociationRole;
 -import org.opengis.feature.FeatureType;
 -import org.opengis.feature.PropertyType;
 -import org.opengis.feature.PropertyNotFoundException;
 -import org.opengis.filter.Expression;
 -import org.opengis.filter.ValueReference;
 +// Specific to the main branch:
 +import org.opengis.util.ScopedName;
 +import org.apache.sis.feature.AbstractFeature;
 +import org.apache.sis.feature.AbstractIdentifiedType;
 +import org.apache.sis.feature.DefaultAssociationRole;
 +import org.apache.sis.feature.DefaultFeatureType;
 +import org.apache.sis.pending.geoapi.filter.Name;
 +import org.apache.sis.pending.geoapi.filter.ValueReference;
  
  
  /**
diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/DefaultFilterFactory.java
index b7273dbe8f,4b8a162e81..b16688724f
--- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/DefaultFilterFactory.java
+++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/DefaultFilterFactory.java
@@@ -55,9 -51,9 +55,9 @@@ import org.apache.sis.pending.geoapi.fi
   *
   * @author  Johann Sorel (Geomatys)
   * @author  Martin Desruisseaux (Geomatys)
-  * @version 1.4
+  * @version 1.5
   *
 - * @param  <R>  the type of resources (e.g. {@link org.opengis.feature.Feature}) to use as inputs.
 + * @param  <R>  the type of resources (e.g. {@link AbstractFeature}) to use as inputs.
   * @param  <G>  base class of geometry objects. The implementation-neutral type is GeoAPI {@link Geometry},
   *              but this factory allows the use of other implementations such as JTS
   *              {@link org.locationtech.jts.geom.Geometry} or ESRI {@link com.esri.core.geometry.Geometry}.
diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/PropertyValue.java
index 5284b66341,6b77bf77e6..99b42b947d
--- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/PropertyValue.java
+++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/PropertyValue.java
@@@ -102,10 -97,11 +102,11 @@@ abstract class PropertyValue<V> extend
       * @throws IllegalArgumentException if the given XPath is not supported.
       */
      @SuppressWarnings("unchecked")
-     static <V> ValueReference<AbstractFeature,V> create(String xpath, final Class<V> type) {
 -    static <V> ValueReference<Feature,V> create(final String xpath, final Class<V> type) {
++    static <V> ValueReference<AbstractFeature,V> create(final String xpath, final Class<V> type) {
+         final var parsed = new XPath(xpath);
+         List<String> path = parsed.path;
          boolean isVirtual = false;
-         List<String> path = XPath.split(xpath);
- split:  if (path != null) {
+         if (parsed.isAbsolute) {
              /*
               * If the XPath is like "/∗/property" where the root "/" is the feature instance,
               * we interpret that as meaning "property of a feature of any type", which means
diff --cc endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/internal/FunctionNames.java
index 1d0a1e9380,4cacfb13fe..d0d511fc53
--- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/internal/FunctionNames.java
+++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/filter/internal/FunctionNames.java
@@@ -27,10 -27,22 +27,22 @@@ import org.apache.sis.filter.sqlmm.SQLM
   * @author  Martin Desruisseaux (Geomatys)
   */
  public final class FunctionNames extends Static {
 -    /** Value of {@link org.opengis.filter.NullOperator#getOperatorType()}. */
++    /** Value of {@code NullOperator.getOperatorType()}. */
+     public static final String PROPERTY_IS_NULL = "PROPERTY_IS_NULL";
+ 
 -    /** Value of {@link org.opengis.filter.NilOperator#getOperatorType()}. */
++    /** Value of {@code NilOperator.getOperatorType()}. */
+     public static final String PROPERTY_IS_NIL = "PROPERTY_IS_NIL";
+ 
 -    /** Value of {@link org.opengis.filter.LikeOperator#getOperatorType()}. */
++    /** Value of {@code LikeOperator.getOperatorType()}. */
+     public static final String PROPERTY_IS_LIKE = "PROPERTY_IS_LIKE";
+ 
+     /** Value of {@link org.opengis.filter.BetweenComparisonOperator#getOperatorType()}. */
+     public static final String PROPERTY_IS_BETWEEN = "PROPERTY_IS_BETWEEN";
+ 
 -    /** Value of {@link org.opengis.filter.Literal#getFunctionName()}. */
 +    /** Value of {@code Literal.getFunctionName()}. */
      public static final String Literal = "Literal";
  
 -    /** Value of {@link org.opengis.filter.ValueReference#getFunctionName()}. */
 +    /** Value of {@code ValueReference.getFunctionName()}. */
      public static final String ValueReference = "ValueReference";
  
      /** The "Add" (+) arithmetic expression. */
diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/package-info.java
index 37f80d5989,36725fa120..8f07e02aa2
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/package-info.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/package-info.java
@@@ -67,7 -67,7 +67,6 @@@
  //  @XmlJavaTypeAdapter(DQM_Measure.class),             // Not directly referenced, but a "weak" association exists.
      @XmlJavaTypeAdapter(DQM_Parameter.class),
      @XmlJavaTypeAdapter(DQM_SourceReference.class),
-     @XmlJavaTypeAdapter(GO_Boolean.class),
 -    @XmlJavaTypeAdapter(DQM_ValueStructure.class),
      @XmlJavaTypeAdapter(GO_Temporal.class),
      @XmlJavaTypeAdapter(GO_DateTime.class),
      @XmlJavaTypeAdapter(GO_GenericName.class),
diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/package-info.java
index 86982e69fc,b49daea01c..c98cf18e67
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/package-info.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/package-info.java
@@@ -30,10 -31,10 +31,10 @@@
   * defined in the {@link org.opengis.metadata} package and sub-packages. That standard is identified in SIS by the
   * {@link org.apache.sis.metadata.MetadataStandard#ISO_19115} constant. Other standards are defined as well,
   * for example the {@link org.apache.sis.metadata.MetadataStandard#ISO_19123} constant stands for the standards
 - * defined by the interfaces in the {@link org.opengis.coverage} package and sub-packages.
 + * defined by the interfaces in the {@code org.opengis.coverage} package and sub-packages.
   *
-  * <p>For each interface, the collection of declared getter methods defines its <cite>properties</cite>
-  * (or <cite>attributes</cite>). If a {@link org.opengis.annotation.UML} annotation is attached to the getter method,
+  * <p>For each interface, the collection of declared getter methods defines its <dfn>properties</dfn>
+  * (or <dfn>attributes</dfn>). If a {@link org.opengis.annotation.UML} annotation is attached to the getter method,
   * the identifier declared in that annotation is taken as the property name. This is typically the name defined by the
   * International Standard from which the interface is derived. Otherwise (if there is no {@code UML} annotation)
   * the property name is inferred from the method name like what the <cite>Java Beans</cite> framework does.</p>
diff --cc endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/ScopeCodeTest.java
index c3b725e6fb,bf708118a7..c14d0206d2
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/ScopeCodeTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/ScopeCodeTest.java
@@@ -23,11 -23,11 +23,11 @@@ import org.opengis.metadata.maintenance
  import org.junit.Test;
  import org.apache.sis.xml.test.TestCase;
  
- import static org.junit.Assert.*;
+ import static org.junit.jupiter.api.Assertions.*;
  import static org.apache.sis.metadata.Assertions.assertXmlEquals;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.metadata.maintenance.Scope;
 +// Specific to the main branch:
 +import org.opengis.metadata.quality.Scope;
  
  
  /**
diff --cc endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/NilReasonTest.java
index 559156295f,1d86c8b4dc..d97bdf1c2c
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/NilReasonTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/NilReasonTest.java
@@@ -27,11 -28,10 +28,10 @@@ import org.apache.sis.util.ArraysExt
  import org.junit.Test;
  import org.apache.sis.test.TestCase;
  
- import static org.junit.Assert.*;
- import static org.opengis.test.Assert.assertInstanceOf;
+ import static org.junit.jupiter.api.Assertions.*;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.metadata.citation.Responsibility;
 +// Specific to the main branch:
 +import org.opengis.metadata.citation.ResponsibleParty;
  
  
  /**
diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/AxisDirections.java
index 2697121021,2efa62e0c6..0b8293bd1c
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/AxisDirections.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/AxisDirections.java
@@@ -87,9 -90,17 +87,17 @@@ public final class AxisDirections exten
       * For an observer at the centre of the object this will be towards its right.
       * Added in ISO 19111:2019 (was not in ISO 19111:2007).
       */
 -    @UML(identifier="starboard", obligation=CONDITIONAL, specification=ISO_19162)
 +    @UML(identifier="starboard", obligation=CONDITIONAL, specification=UNSPECIFIED)
      public static final AxisDirection STARBOARD = AxisDirection.valueOf("STARBOARD");
  
+     /**
+      * Port direction.
+      * For an observer at the centre of the object this will be towards its left.
+      * Added in ISO 19111:2019 (was not in ISO 19111:2007).
+      */
 -    @UML(identifier="port", obligation=CONDITIONAL, specification=ISO_19162)
++    @UML(identifier="port", obligation=CONDITIONAL, specification=UNSPECIFIED)
+     public static final AxisDirection PORT = AxisDirection.valueOf("PORT");
+ 
      /**
       * Direction of geographic angles (bearing).
       * Added in ISO 19111:2019 (was not in ISO 19111:2007).
diff --cc endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
index 8a0a0420ff,4d22dfe327..e69005946b
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
@@@ -172,14 -171,10 +171,10 @@@ abstract class RasterStore extends PRJD
              builder.addFormatName(formatName);
              listeners.warning(e);
          }
 -        builder.addResourceScope(ScopeCode.COVERAGE, null);
 +        builder.addResourceScope(ScopeCode.valueOf("COVERAGE"), null);
          builder.addLanguage(Locale.ENGLISH, encoding, MetadataBuilder.Scope.METADATA);
          builder.addSpatialRepresentation(null, gridGeometry, true);
-         try {
-             builder.addExtent(gridGeometry.getEnvelope());
-         } catch (TransformException e) {
-             listeners.warning(e);
-         }
+         builder.addExtent(gridGeometry.getEnvelope(), listeners);
          /*
           * Do not invoke `getSampleDimensions()` because computing sample dimensions without statistics
           * may cause the loading of the full image. Even if `GridCoverage.getSampleDimensions()` exists
diff --cc endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
index b5b714edcb,6da2247bb3..19acd4ed95
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStore.java
@@@ -536,10 -534,10 +534,10 @@@ loop:   for (int convention=0;; convent
                  }
              }
              builder.addFormatName(format);                          // Does nothing if `format` is null.
 -            builder.addResourceScope(ScopeCode.COVERAGE, null);
 +            builder.addResourceScope(ScopeCode.valueOf("COVERAGE"), null);
              builder.addSpatialRepresentation(null, getGridGeometry(MAIN_IMAGE), true);
              if (gridGeometry.isDefined(GridGeometry.ENVELOPE)) {
-                 builder.addExtent(gridGeometry.getEnvelope());
+                 builder.addExtent(gridGeometry.getEnvelope(), listeners);
              }
              addTitleOrIdentifier(builder);
              builder.setISOStandards(false);
diff --cc incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ListingPropertyVisitor.java
index 0000000000,c3f55427fd..c165bf1df0
mode 000000,100644..100644
--- a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ListingPropertyVisitor.java
+++ b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ListingPropertyVisitor.java
@@@ -1,0 -1,82 +1,79 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ package org.apache.sis.storage.shapefile;
+ 
+ import java.util.Collection;
 -import org.opengis.util.CodeList;
+ import org.apache.sis.filter.internal.FunctionNames;
+ import org.apache.sis.filter.internal.Visitor;
+ 
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.filter.BetweenComparisonOperator;
 -import org.opengis.filter.Filter;
 -import org.opengis.filter.Expression;
 -import org.opengis.filter.ValueReference;
 -import org.opengis.filter.ComparisonOperatorName;
 -import org.opengis.filter.LikeOperator;
 -import org.opengis.filter.LogicalOperator;
++// Specific to the main branch:
++import org.apache.sis.filter.Filter;
++import org.apache.sis.filter.Expression;
++import org.apache.sis.pending.geoapi.filter.BetweenComparisonOperator;
++import org.apache.sis.pending.geoapi.filter.ValueReference;
++import org.apache.sis.pending.geoapi.filter.ComparisonOperatorName;
++import org.apache.sis.pending.geoapi.filter.LogicalOperator;
+ 
+ 
+ /**
+  * Expression visitor that returns a list of all Feature attributs requiered by this expression.
+  *
+  * @author Johann Sorel (Geomatys)
+  */
+ final class ListingPropertyVisitor extends Visitor<Object,Collection<String>> {
+ 
+     public static final ListingPropertyVisitor VISITOR = new ListingPropertyVisitor();
+ 
+     protected ListingPropertyVisitor() {
+         setLogicalHandlers((f, names) -> {
+             final LogicalOperator<Object> filter = (LogicalOperator<Object>) f;
+             for (Filter<Object> child : filter.getOperands()) {
+                 visit(child, names);
+             }
+         });
+         setFilterHandler(ComparisonOperatorName.valueOf(FunctionNames.PROPERTY_IS_BETWEEN), (f, names) -> {
+             final BetweenComparisonOperator<Object> filter = (BetweenComparisonOperator<Object>) f;
+             visit(filter.getExpression(),    names);
+             visit(filter.getLowerBoundary(), names);
+             visit(filter.getUpperBoundary(), names);
+         });
+         setFilterHandler(ComparisonOperatorName.valueOf(FunctionNames.PROPERTY_IS_LIKE), (f, names) -> {
 -            final LikeOperator<Object> filter = (LikeOperator<Object>) f;
 -            visit(filter.getExpressions().get(0), names);
++            visit(f.getExpressions().get(0), names);
+         });
+         setExpressionHandler(FunctionNames.ValueReference, (e, names) -> {
+             final ValueReference<Object,?> expression = (ValueReference<Object,?>) e;
+             final String propName = expression.getXPath();
+             if (!propName.trim().isEmpty()) {
+                 names.add(propName);
+             }
+         });
+     }
+ 
+     @Override
 -    protected void typeNotFound(final CodeList<?> type, final Filter<Object> filter, final Collection<String> names) {
++    protected void typeNotFound(final Enum<?> type, final Filter<Object> filter, final Collection<String> names) {
+         for (final Expression<? super Object, ?> f : filter.getExpressions()) {
+             visit(f, names);
+         }
+     }
+ 
+     @Override
+     protected void typeNotFound(final String type, final Expression<Object, ?> expression, final Collection<String> names) {
+         for (final Expression<? super Object, ?> p : expression.getParameters()) {
+             visit(p, names);
+         }
+     }
+ }
diff --cc incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
index 04774dfc66,f17560575a..68984f7c48
--- 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
@@@ -34,8 -44,12 +44,11 @@@ import java.util.concurrent.locks.Reent
  import java.util.function.Consumer;
  import java.util.function.Predicate;
  import java.util.function.UnaryOperator;
+ import java.util.logging.Level;
+ import java.util.logging.Logger;
  import java.util.stream.Stream;
  import java.util.stream.StreamSupport;
+ 
 -import org.opengis.util.CodeList;
  import org.opengis.geometry.Envelope;
  import org.opengis.metadata.Metadata;
  import org.opengis.parameter.ParameterValueGroup;
@@@ -67,11 -91,30 +90,30 @@@ import org.apache.sis.storage.shapefile
  import org.apache.sis.storage.shapefile.shp.ShapeHeader;
  import org.apache.sis.storage.shapefile.shp.ShapeReader;
  import org.apache.sis.storage.shapefile.shp.ShapeRecord;
+ import org.apache.sis.storage.shapefile.shp.ShapeType;
+ import org.apache.sis.storage.shapefile.shp.ShapeWriter;
+ import org.apache.sis.storage.shapefile.shx.IndexWriter;
  import org.apache.sis.util.collection.BackingStoreException;
+ import org.locationtech.jts.geom.Geometry;
+ import org.locationtech.jts.geom.LineString;
+ import org.locationtech.jts.geom.MultiLineString;
+ import org.locationtech.jts.geom.MultiPoint;
+ import org.locationtech.jts.geom.MultiPolygon;
+ import org.locationtech.jts.geom.Point;
+ import org.locationtech.jts.geom.Polygon;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.FeatureType;
 -import org.opengis.feature.PropertyType;
 -import org.opengis.feature.AttributeType;
 -import org.opengis.filter.Expression;
 -import org.opengis.filter.Filter;
 -import org.opengis.filter.Literal;
 -import org.opengis.filter.LogicalOperator;
 -import org.opengis.filter.LogicalOperatorName;
 -import org.opengis.filter.SpatialOperatorName;
 -import org.opengis.filter.ValueReference;
 +// Specific to the main branch:
 +import org.apache.sis.feature.AbstractFeature;
 +import org.apache.sis.feature.DefaultFeatureType;
++import org.apache.sis.feature.AbstractIdentifiedType;
++import org.apache.sis.feature.DefaultAttributeType;
++import org.apache.sis.filter.Expression;
++import org.apache.sis.filter.Filter;
++import org.apache.sis.pending.geoapi.filter.Literal;
++import org.apache.sis.pending.geoapi.filter.LogicalOperator;
++import org.apache.sis.pending.geoapi.filter.LogicalOperatorName;
++import org.apache.sis.pending.geoapi.filter.SpatialOperatorName;
++import org.apache.sis.pending.geoapi.filter.ValueReference;
  
  
  /**
@@@ -147,10 -190,61 +189,61 @@@ public final class ShapefileStore exten
          return featureSetView.getEnvelope();
      }
  
+     @Override
 -    public void updateType(FeatureType featureType) throws DataStoreException {
++    public void updateType(DefaultFeatureType featureType) throws DataStoreException {
+         featureSetView.updateType(featureType);
+     }
+ 
+     @Override
 -    public void add(Iterator<? extends Feature> iterator) throws DataStoreException {
++    public void add(Iterator<? extends AbstractFeature> iterator) throws DataStoreException {
+         featureSetView.add(iterator);
+     }
+ 
+     @Override
 -    public void removeIf(Predicate<? super Feature> predicate) throws DataStoreException {
++    public void removeIf(Predicate<? super AbstractFeature> predicate) throws DataStoreException {
+         featureSetView.removeIf(predicate);
+     }
+ 
+     @Override
 -    public void replaceIf(Predicate<? super Feature> predicate, UnaryOperator<Feature> unaryOperator) throws DataStoreException {
++    public void replaceIf(Predicate<? super AbstractFeature> predicate, UnaryOperator<AbstractFeature> unaryOperator) throws DataStoreException {
+         featureSetView.replaceIf(predicate, unaryOperator);
+     }
+ 
      private class AsFeatureSet extends AbstractFeatureSet implements WritableFeatureSet {
  
-         private AsFeatureSet() {
+         private final Rectangle2D.Double filter;
+         private final Set<String> dbfProperties;
+         private final boolean readShp;
+ 
+         /**
+          * Extracted informations
+          */
+         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;
++        private DefaultFeatureType type;
+ 
+         /**
+          * @param filter optional shape filter, must be in data CRS
+          * @param properties dbf properties to read, null for all properties
+          */
+         private AsFeatureSet(Rectangle2D.Double filter, boolean readShp, Set<String> properties) {
              super(null);
+             this.readShp = readShp;
+             this.filter = filter;
+             this.dbfProperties = properties;
+         }
+ 
+         /**
+          * @return true if this view reads all data without any filter.
+          */
+         private boolean isDefaultView() {
+             return filter == null && dbfProperties == null && readShp;
          }
  
          @Override
@@@ -227,9 -344,34 +343,34 @@@
              return type;
          }
  
+         @Override
+         public Optional<Envelope> getEnvelope() throws DataStoreException {
+             getType();//force loading headers
+             if (shpHeader != null && filter == null) {
+                 final GeneralEnvelope env = new GeneralEnvelope(crs);
+                 env.setRange(0, shpHeader.bbox.getMinimum(0), shpHeader.bbox.getMaximum(0));
+                 env.setRange(1, shpHeader.bbox.getMinimum(1), shpHeader.bbox.getMaximum(1));
+                 return Optional.of(env);
+             }
+             return super.getEnvelope();
+         }
+ 
+         @Override
+         public OptionalLong getFeatureCount() {
+             try {
+                 getType();//force loading headers
+                 if (dbfHeader != null && filter == null) {
+                     return OptionalLong.of(dbfHeader.nbRecord);
+                 }
+             } catch (DataStoreException ex) {
+                 //do nothing
+             }
+             return super.getFeatureCount();
+         }
+ 
          @Override
 -        public Stream<Feature> features(boolean parallel) throws DataStoreException {
 -            final FeatureType type = getType();
 +        public Stream<AbstractFeature> features(boolean parallel) throws DataStoreException {
 +            final DefaultFeatureType type = getType();
              final ShapeReader shpreader;
              final DBFReader dbfreader;
              try {
@@@ -238,28 -380,73 +379,73 @@@
              } catch (IOException ex) {
                  throw new DataStoreException("Faild to open shp and dbf files.", ex);
              }
-             final DBFHeader header = dbfreader.getHeader();
  
-             final Spliterator spliterator = new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
-                 @Override
-                 public boolean tryAdvance(Consumer action) {
-                     try {
-                         final ShapeRecord shpRecord = shpreader.next();
-                         if (shpRecord == null) return false;
-                         final DBFRecord dbfRecord = dbfreader.next();
-                         final AbstractFeature next = type.newInstance();
-                         next.setPropertyValue(GEOMETRY_NAME, shpRecord.geometry);
-                         for (int i = 0; i < header.fields.length; i++) {
-                             next.setPropertyValue(header.fields[i].fieldName, dbfRecord.fields[i]);
+             final Spliterator spliterator;
+             if (readShp && dbfPropertiesIndex.length > 0) {
+                 //read both shp and dbf
+                 final DBFHeader header = dbfreader.getHeader();
+ 
+                 spliterator = new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
+                     @Override
+                     public boolean tryAdvance(Consumer action) {
+                         try {
+                             final ShapeRecord shpRecord = shpreader.next();
+                             if (shpRecord == null) return false;
+                             //move dbf to record offset, some shp record might have been skipped because of filter
+                             dbfreader.moveToOffset(header.headerSize + (shpRecord.recordNumber-1) * header.recordSize);
+                             final DBFRecord dbfRecord = dbfreader.next();
 -                            final Feature next = type.newInstance();
++                            final AbstractFeature next = type.newInstance();
+                             next.setPropertyValue(GEOMETRY_NAME, shpRecord.geometry);
+                             for (int i = 0; i < dbfPropertiesIndex.length; i++) {
+                                 next.setPropertyValue(header.fields[dbfPropertiesIndex[i]].fieldName, dbfRecord.fields[i]);
+                             }
+                             action.accept(next);
+                             return true;
+                         } catch (IOException ex) {
+                             throw new BackingStoreException(ex.getMessage(), ex);
                          }
-                         action.accept(next);
-                         return true;
-                     } catch (IOException ex) {
-                         throw new BackingStoreException(ex.getMessage(), ex);
                      }
-                 }
-             };
+                 };
+             } else if (readShp) {
+                 //read only the shp
+                 spliterator = new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
+                     @Override
+                     public boolean tryAdvance(Consumer action) {
+                         try {
+                             final ShapeRecord shpRecord = shpreader.next();
+                             if (shpRecord == null) return false;
 -                            final Feature next = type.newInstance();
++                            final AbstractFeature next = type.newInstance();
+                             next.setPropertyValue(GEOMETRY_NAME, shpRecord.geometry);
+                             action.accept(next);
+                             return true;
+                         } catch (IOException ex) {
+                             throw new BackingStoreException(ex.getMessage(), ex);
+                         }
+                     }
+                 };
+             } else {
+                 //read only dbf
+                 final DBFHeader header = dbfreader.getHeader();
+                 spliterator = new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
+                     @Override
+                     public boolean tryAdvance(Consumer action) {
+                         try {
+                             final DBFRecord dbfRecord = dbfreader.next();
+                             if (dbfRecord == null) return false;
 -                            final Feature next = type.newInstance();
++                            final AbstractFeature next = type.newInstance();
+                             for (int i = 0; i < dbfPropertiesIndex.length; i++) {
+                                 next.setPropertyValue(header.fields[dbfPropertiesIndex[i]].fieldName, dbfRecord.fields[i]);
+                             }
+                             action.accept(next);
+                             return true;
+                         } catch (IOException ex) {
+                             throw new BackingStoreException(ex.getMessage(), ex);
+                         }
+                     }
+                 };
+             }
+ 
 -            final Stream<Feature> stream = StreamSupport.stream(spliterator, false);
 +            final Stream<AbstractFeature> stream = StreamSupport.stream(spliterator, false);
              return stream.onClose(new Runnable() {
                  @Override
                  public void run() {
@@@ -274,23 -461,210 +460,212 @@@
  
          }
  
+         @Override
+         public FeatureSet subset(Query query) throws UnsupportedQueryException, DataStoreException {
+             //try to optimise the query for common cases
+             opti:
+             if (query instanceof FeatureQuery) {
+                 final FeatureQuery fq = (FeatureQuery) query;
+                 FeatureQuery.NamedExpression[] projection = fq.getProjection();
 -                Filter<? super Feature> selection = fq.getSelection();
++                Filter<? super AbstractFeature> selection = fq.getSelection();
+ 
+                 if (selection == null && projection == null) {
+                     //no optimisation
+                     break opti;
+                 }
+ 
+                 //force loading
 -                final FeatureType type = getType();
++                final DefaultFeatureType type = getType();
+ 
+                 //extract bbox
+                 Envelope bbox = null;
+                 if (selection != null) {
+                     //run optimizations
+                     final Optimization optimization = new Optimization();
+                     optimization.setFeatureType(type);
+                     selection = optimization.apply(selection);
+                     final Entry<Envelope, Filter> split = extractBbox(selection);
+                     bbox = split.getKey();
+                     selection = split.getValue();
+                 }
+ 
+                 //extract field names
+                 boolean simpleSelection = true; //true if there are no alias and all expressions are ValueReference
+                 Set<String> properties = null;
+                 if (projection != null) {
+                     properties = new HashSet<>();
+                     if (selection!=null) ListingPropertyVisitor.VISITOR.visit((Filter) selection, properties);
+                     for (FeatureQuery.NamedExpression ne : projection) {
+                         ListingPropertyVisitor.VISITOR.visit((Expression) ne.expression, properties);
+                         simpleSelection &= (ne.alias == null);
+                         simpleSelection &= (ne.expression.getFunctionName().tip().toString().equals(FunctionNames.ValueReference));
+                     }
+ 
+                     //if link fields are referenced, add target fields
+                     if (properties.contains(AttributeConvention.IDENTIFIER)) simpleSelection &= !properties.add(idField);
+                     if (properties.contains(AttributeConvention.GEOMETRY)) simpleSelection &= !properties.add(GEOMETRY_NAME);
+                     if (properties.contains(AttributeConvention.ENVELOPE)) simpleSelection &= !properties.add(GEOMETRY_NAME);
+                 }
+ 
+                 final boolean readShp = projection == null || properties.contains(GEOMETRY_NAME);
+                 Rectangle2D.Double area = null;
+                 if (bbox != null) {
+                     try {
+                         bbox = Envelopes.transform(bbox, crs);
+                     } catch (TransformException ex) {
+                         throw new DataStoreException("Failed to transform bbox filter", ex);
+                     }
+                     area = new Rectangle2D.Double(bbox.getMinimum(0), bbox.getMinimum(1), bbox.getSpan(0), bbox.getSpan(1));
+ 
+                     //combine this area with the one we already have since this is a subset
+                     if (filter != null) {
+                         area = (Rectangle2D.Double) area.createIntersection(filter);
+                     }
+                 }
+ 
+                 final AsFeatureSet fs = new AsFeatureSet(area, readShp, properties);
+                 //see if there are elements we could not handle
+                 final FeatureQuery subQuery = new FeatureQuery();
+                 boolean needSubProcessing = false;
+                 if (fq.getLimit().isPresent()){
+                     needSubProcessing = true;
+                     subQuery.setLimit(fq.getLimit().getAsLong());
+                 }
+                 if (fq.getLinearResolution() != null) {
+                     needSubProcessing = true;
+                     subQuery.setLinearResolution(fq.getLinearResolution());
+                 }
+                 if (fq.getOffset() != 0) {
+                     needSubProcessing = true;
+                     subQuery.setOffset(fq.getOffset());
+                 }
++                /* Unsupported on the main branch.
+                 if (fq.getSortBy() != null) {
+                     needSubProcessing = true;
+                     subQuery.setSortBy(fq.getSortBy());
+                 }
++                */
+                 if (selection != null) {
+                     needSubProcessing = true;
+                     subQuery.setSelection(selection);
+                 }
+                 if (!simpleSelection) {
+                     needSubProcessing = true;
+                     subQuery.setProjection(projection);
+                 }
+ 
+                 return needSubProcessing ? fs.parentSubSet(subQuery) : fs;
+             }
+ 
+             return super.subset(query);
+         }
+ 
+         private FeatureSet parentSubSet(Query query) throws DataStoreException {
+             return super.subset(query);
+         }
+ 
          @Override
 -        public void updateType(FeatureType newType) throws DataStoreException {
 +        public void updateType(DefaultFeatureType newType) throws DataStoreException {
-             throw new UnsupportedOperationException("Not supported yet.");
+             if (true) throw new UnsupportedOperationException("Not supported yet.");
+ 
+             if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
+             if (Files.exists(shpPath)) {
+                 throw new DataStoreException("Update type is possible only when files do not exist. It can be used to create a new shapefile but not to update one.");
+             }
+ 
+             final ShapeHeader shpHeader = new ShapeHeader();
+             final DBFHeader dbfHeader = new DBFHeader();
+             Charset charset = StandardCharsets.UTF_8;
+             CoordinateReferenceSystem crs = CommonCRS.WGS84.normalizedGeographic();
+ 
 -            for (PropertyType pt : newType.getProperties(true)) {
 -                if (pt instanceof AttributeType) {
 -                    final AttributeType at = (AttributeType) pt;
++            for (AbstractIdentifiedType pt : newType.getProperties(true)) {
++                if (pt instanceof DefaultAttributeType) {
++                    final DefaultAttributeType at = (DefaultAttributeType) pt;
+                     final Class valueClass = at.getValueClass();
+                     if (Geometry.class.isAssignableFrom(valueClass)) {
+                         if (shpHeader.shapeType != 0) {
+                             throw new DataStoreException("Shapefile format can only contain one geometry");
+                         }
+                         if (Point.class.isAssignableFrom(valueClass)) shpHeader.shapeType = ShapeType.VALUE_POINT;
+                         else if (MultiPoint.class.isAssignableFrom(valueClass)) shpHeader.shapeType = ShapeType.VALUE_MULTIPOINT;
+                         else if (LineString.class.isAssignableFrom(valueClass) || MultiLineString.class.isAssignableFrom(valueClass)) shpHeader.shapeType = ShapeType.VALUE_POLYLINE;
+                         else if (Polygon.class.isAssignableFrom(valueClass) || MultiPolygon.class.isAssignableFrom(valueClass)) shpHeader.shapeType = ShapeType.VALUE_POLYGON;
+                         else throw new DataStoreException("Unsupported geometry type " + valueClass);
+ 
+                         Object cdt = at.characteristics().get(AttributeConvention.CRS_CHARACTERISTIC);
+                         if (cdt instanceof CoordinateReferenceSystem) {
+                             crs = (CoordinateReferenceSystem) cdt;
+                         }
+ 
+                     } else if (String.class.isAssignableFrom(valueClass)) {
+ 
+                     } else if (Integer.class.isAssignableFrom(valueClass)) {
+ 
+                     } else if (Long.class.isAssignableFrom(valueClass)) {
+ 
+                     } else if (Float.class.isAssignableFrom(valueClass)) {
+ 
+                     } else if (Double.class.isAssignableFrom(valueClass)) {
+ 
+                     } else if (LocalDate.class.isAssignableFrom(valueClass)) {
+ 
+                     } else {
+                         LOGGER.log(Level.WARNING, "Shapefile writing, field {0} is not supported", pt.getName());
+                     }
+                 } else {
+                     LOGGER.log(Level.WARNING, "Shapefile writing, field {0} is not supported", pt.getName());
+                 }
+             }
+ 
+             //write shapefile
+             try (ShapeWriter writer = new ShapeWriter(ShpFiles.openWriteChannel(files.shpFile))) {
+                 writer.write(shpHeader);
+             } catch (IOException ex){
+                 throw new DataStoreException("Failed to create shapefile (shp).", ex);
+             }
+ 
+             //write shx
+             try (IndexWriter writer = new IndexWriter(ShpFiles.openWriteChannel(files.shxFile))) {
+                 writer.write(shpHeader);
+             } catch (IOException ex){
+                 throw new DataStoreException("Failed to create shapefile (shx).", ex);
+             }
+ 
+             //write dbf
+             try (DBFWriter writer = new DBFWriter(ShpFiles.openWriteChannel(files.dbfFile))) {
+                 writer.write(dbfHeader);
+             } catch (IOException ex){
+                 throw new DataStoreException("Failed to create shapefile (dbf).", ex);
+             }
+ 
+             //write cpg
+             try {
+                 CpgFiles.write(charset, files.cpgFile);
+             } catch (IOException ex) {
+                 throw new DataStoreException("Failed to create shapefile (cpg).", ex);
+             }
+ 
+             //write prj
+             //todo
+ 
+ 
          }
  
          @Override
 -        public void add(Iterator<? extends Feature> features) throws DataStoreException {
 +        public void add(Iterator<? extends AbstractFeature> features) throws DataStoreException {
+             if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
              throw new UnsupportedOperationException("Not supported yet.");
          }
  
          @Override
 -        public void removeIf(Predicate<? super Feature> filter) throws DataStoreException {
 +        public void removeIf(Predicate<? super AbstractFeature> filter) throws DataStoreException {
+             if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
              throw new UnsupportedOperationException("Not supported yet.");
          }
  
          @Override
 -        public void replaceIf(Predicate<? super Feature> filter, UnaryOperator<Feature> updater) throws DataStoreException {
 +        public void replaceIf(Predicate<? super AbstractFeature> filter, UnaryOperator<AbstractFeature> updater) throws DataStoreException {
+             if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
              throw new UnsupportedOperationException("Not supported yet.");
          }
      }
@@@ -382,4 -756,98 +757,98 @@@
          }
      }
  
+ 
+     /**
+      * Will only split bbox with direct value reference to the geometry.
+      *
+      * @param filter to split, not null
+      * @return entry with key is a BBox filter and value what remains of the filter.
+      *        each filter can be null but not both.
+      */
+     private static Entry<Envelope,Filter> extractBbox(Filter<?> filter) {
+ 
 -        final CodeList operatorType = filter.getOperatorType();
++        final Enum operatorType = filter.getOperatorType();
+ 
+         if (SpatialOperatorName.BBOX.equals(operatorType)) {
+             Envelope env = isDirectBbox(filter);
+             if (env != null) {
+                 return new AbstractMap.SimpleImmutableEntry<>(env, null);
+             } else {
+                 return new AbstractMap.SimpleImmutableEntry<>(null, filter);
+             }
+ 
+         } else if (LogicalOperatorName.AND.equals(operatorType)) {
+ 
+             boolean rebuildAnd = false;
+             List<Filter<?>> lst = (List<Filter<?>>) ((LogicalOperator<?>)filter).getOperands();
+             Envelope bbox = null;
+             for (int i = 0; i < lst.size(); i++) {
+                 final Filter<?> f = lst.get(i);
+                 final Entry<Envelope, Filter> split = extractBbox(f);
+                 Envelope cdtBbox = split.getKey();
+                 Filter cdtOther = split.getValue();
+                 if (cdtBbox != null) {
+                     if (bbox == null) {
+                         bbox = cdtBbox;
+                     } else {
+                         throw new RuntimeException("Combine bbox");
+                     }
+ 
+                     //see if we need to rebuild the AND filter
+                     if (cdtOther != f) {
+                         if (!rebuildAnd) {
+                             rebuildAnd = true;
+                             lst = new ArrayList<>(lst);
+                         }
+                         //replace in list
+                         if (cdtOther != null) {
+                             lst.set(i, cdtOther);
+                         } else {
+                             lst.remove(i);
+                             i--;
+                         }
+                     }
+                 }
+             }
+ 
+             if (rebuildAnd) {
+                 if (lst.isEmpty()) {
+                     filter = null;
+                 } else if (lst.size() == 1) {
+                     filter = lst.get(0);
+                 } else {
+                     filter = DefaultFilterFactory.forFeatures().and((List)lst);
+                 }
+             }
+ 
+             return new AbstractMap.SimpleImmutableEntry<>(bbox, filter);
+         } else {
+             //can do nothing
+             return new AbstractMap.SimpleImmutableEntry<>(null, filter);
+         }
+     }
+ 
+     /**
+      * Returns envelope if the other expression is a direct value reference.
+      * @param bbox
+      * @return filter envelope
+      */
+     private static Envelope isDirectBbox(Filter<?> bbox) {
+         Envelope env = null;
+         for (Expression exp : bbox.getExpressions()) {
+             if (exp instanceof ValueReference) {
+                 final ValueReference<Object,?> expression = (ValueReference<Object,?>) exp;
+                 final String propName = expression.getXPath();
+                 if ( !(GEOMETRY_NAME.equals(propName) || AttributeConvention.GEOMETRY.equals(propName))) {
+                     return null;
+                 }
+             } else if (exp instanceof Literal) {
+                 Object value = ((Literal) exp).getValue();
+                 env = Geometries.wrap(value).get().getEnvelope();
+             }
+         }
+         return env;
+     }
+ 
+ 
  }
diff --cc incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
index 9eb5e07bea,cfa9d2645e..5dbc92b826
--- 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
@@@ -87,4 -94,107 +93,107 @@@ public class ShapefileStoreTest 
              assertFalse(iterator.hasNext());
          }
      }
+ 
+     /**
+      * Test optimized envelope filter.
+      */
+     @Test
+     public void testEnvelopeFilter() throws URISyntaxException, DataStoreException {
+         final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/point.shp");
+         final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()));
+ 
 -        final FilterFactory<Feature, Object, Object> ff = DefaultFilterFactory.forFeatures();
++        final DefaultFilterFactory<AbstractFeature, Object, Object> ff = DefaultFilterFactory.forFeatures();
+ 
+         final GeneralEnvelope env = new GeneralEnvelope(CommonCRS.WGS84.normalizedGeographic());
+         env.setRange(0, 2, 3);
+         env.setRange(1, 42, 43);
+ 
+         final FeatureQuery query = new FeatureQuery();
+         query.setSelection(ff.bbox(ff.property("geometry"), env));
+         FeatureSet featureset = store.subset(query);
+         //ensure we obtained an optimized version
+         assertEquals("org.apache.sis.storage.shapefile.ShapefileStore$AsFeatureSet", featureset.getClass().getName());
+ 
 -        try (Stream<Feature> stream = featureset.features(false)) {
 -            Iterator<Feature> iterator = stream.iterator();
++        try (Stream<AbstractFeature> stream = featureset.features(false)) {
++            Iterator<AbstractFeature> iterator = stream.iterator();
+             assertTrue(iterator.hasNext());
 -            Feature feature = iterator.next();
++            AbstractFeature feature = iterator.next();
+             assertEquals(2L, feature.getPropertyValue("id"));
+             assertEquals("text2", feature.getPropertyValue("text"));
+             assertEquals(40L, feature.getPropertyValue("integer"));
+             assertEquals(60.0, feature.getPropertyValue("float"));
+             assertEquals(LocalDate.of(2023, 10, 28), feature.getPropertyValue("date"));
+             Point pt2 = (Point) feature.getPropertyValue("geometry");
+ 
+             assertFalse(iterator.hasNext());
+         }
+     }
+ 
+     /**
+      * Test optimized field selection.
+      */
+     @Test
+     public void testFieldFilter() throws URISyntaxException, DataStoreException {
+         final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/point.shp");
+         final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()));
+ 
+ 
+         final FeatureQuery query = new FeatureQuery();
+         query.setProjection("text", "float");
+         FeatureSet featureset = store.subset(query);
+         //ensure we obtained an optimized version
+         assertEquals("org.apache.sis.storage.shapefile.ShapefileStore$AsFeatureSet", featureset.getClass().getName());
+ 
 -        try (Stream<Feature> stream = featureset.features(false)) {
 -            Iterator<Feature> iterator = stream.iterator();
++        try (Stream<AbstractFeature> stream = featureset.features(false)) {
++            Iterator<AbstractFeature> iterator = stream.iterator();
+             assertTrue(iterator.hasNext());
 -            Feature feature1 = iterator.next();
++            AbstractFeature feature1 = iterator.next();
+             assertEquals("text1", feature1.getPropertyValue("text"));
+             assertEquals(20.0, feature1.getPropertyValue("float"));
+ 
+             assertTrue(iterator.hasNext());
 -            Feature feature2 = iterator.next();
++            AbstractFeature feature2 = iterator.next();
+             assertEquals("text2", feature2.getPropertyValue("text"));
+             assertEquals(60.0, feature2.getPropertyValue("float"));
+ 
+             assertFalse(iterator.hasNext());
+         }
+     }
+ 
+     /**
+      * Test creating a new shapefile.
+      */
+     @Ignore
+     @Test
+     public void testCreate() throws URISyntaxException, DataStoreException {
+         //todo
+     }
+ 
+     /**
+      * Test adding features to a shapefile.
+      */
+     @Ignore
+     @Test
+     public void testAddFeatures() throws URISyntaxException, DataStoreException {
+         //todo
+     }
+ 
+     /**
+      * Test remove features from a shapefile.
+      */
+     @Ignore
+     @Test
+     public void testRemoveFeatures() throws URISyntaxException, DataStoreException {
+         //todo
+     }
+ 
+     /**
+      * Test replacing features in a shapefile.
+      */
+     @Ignore
+     @Test
+     public void testReplaceFeatures() throws URISyntaxException, DataStoreException {
+         //todo
+     }
+ 
  }
diff --cc netbeans-project/ivy.xml
index 6dfb805b1a,536f6fffc6..fcc8fc0de2
--- a/netbeans-project/ivy.xml
+++ b/netbeans-project/ivy.xml
@@@ -11,10 -11,8 +11,10 @@@
  <ivy-module version="2.0">
      <info organisation="org.apache" module="sis"/>
      <dependencies defaultconf="default">
 +        <dependency org="org.opengis"            name="geoapi"                  rev="3.0.2"/>
 +        <dependency org="org.opengis"            name="geoapi-conformance"      rev="3.0.2"/>
          <dependency org="javax.measure"          name="unit-api"                rev="2.1.3"/>
-         <dependency org="org.glassfish.jaxb"     name="jaxb-runtime"            rev="4.0.3"/>
+         <dependency org="org.glassfish.jaxb"     name="jaxb-runtime"            rev="4.0.4"/>
          <dependency org="org.eclipse"            name="yasson"                  rev="3.0.3"/>
          <dependency org="com.esri.geometry"      name="esri-geometry-api"       rev="2.2.4"/>
          <dependency org="org.locationtech.jts"   name="jts-core"                rev="1.19.0"/>
diff --cc settings.gradle.kts
index d26ccc2bee,60f13a1608..6c83faf896
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@@ -21,6 -21,8 +21,7 @@@ val geoapiVersion = "3.0.2
   * The sub-projects to include in the build.
   * They are directory names relative to this file.
   */
 -include("geoapi")
+ include("parent")
  include("endorsed")
  include("incubator")
  if (System.getenv("PATH_TO_FX") != null) {
@@@ -56,10 -59,10 +57,10 @@@ dependencyResolutionManagement 
       */
      versionCatalogs {
          create("libs") {
 -            library("geoapi",        "org.opengis",            "geoapi-pending")      .version {strictly(geoapiVersion)}
 +            library("geoapi",        "org.opengis",            "geoapi")              .version {strictly(geoapiVersion)}
              library("units",         "javax.measure",          "unit-api")            .version {strictly("[2.1, 3.0[");  prefer("2.1.3")}
              library("jaxb.api",      "jakarta.xml.bind",       "jakarta.xml.bind-api").version {strictly("[4.0, 5.0[");  prefer("4.0.1")}
-             library("jaxb.impl",     "org.glassfish.jaxb",     "jaxb-runtime")        .version {strictly("[4.0, 5.0[");  prefer("4.0.3")}
+             library("jaxb.impl",     "org.glassfish.jaxb",     "jaxb-runtime")        .version {strictly("[4.0, 5.0[");  prefer("4.0.4")}
              library("yasson",        "org.eclipse",            "yasson")              .version {strictly("[3.0, 4.0[");  prefer("3.0.3")}
              library("jts.core",      "org.locationtech.jts",   "jts-core")            .version {strictly("[1.15, 2.0["); prefer("1.19.0")}
              library("esri.geometry", "com.esri.geometry",      "esri-geometry-api")   .version {strictly("[2.0, 3.0[");  prefer("2.2.4")}