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 47053a8ff3defb6ba75ce74d7c59f06e547cd4d2
Merge: 98bc0dfa20 eb20f53e20
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sun Dec 17 11:22:16 2023 +0100

    Merge branch 'geoapi-3.1'.
    Contains: shapefile writer, JShell, bug fixes.

 .../main/org/apache/sis/console/AboutCommand.java  |   10 +-
 .../main/org/apache/sis/console/Command.java       |   26 +-
 .../main/org/apache/sis/console/CommandRunner.java |  127 +-
 .../apache/sis/console/FormattedOutputCommand.java |   25 +-
 .../org/apache/sis/console/IdentifierCommand.java  |   12 +-
 .../main/org/apache/sis/console/InfoCommand.java   |    2 +-
 .../org/apache/sis/console/MetadataCommand.java    |    5 +-
 .../main/org/apache/sis/console/Option.java        |    5 +
 .../main/org/apache/sis/console/Options.properties |    7 +-
 .../org/apache/sis/console/Options_fr.properties   |    7 +-
 .../apache/sis/console/ResourcesDownloader.java    |    3 +-
 .../main/org/apache/sis/console/SIS.java           |   69 +-
 .../org/apache/sis/console/TransformCommand.java   |   49 +-
 .../org/apache/sis/console/TranslateCommand.java   |    4 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   14 +-
 .../org/apache/sis/feature/FeatureOperations.java  |    3 +-
 .../apache/sis/metadata/internal/Identifiers.java  |   27 +
 .../apache/sis/metadata/internal/NameMeaning.java  |    4 +-
 .../sis/metadata/internal/ReferencingServices.java |   35 +-
 .../apache/sis/metadata/internal/Resources.java    |    9 +-
 .../sis/metadata/internal/Resources.properties     |    2 +-
 .../sis/metadata/internal/Resources_fr.properties  |    2 +-
 .../sis/metadata/iso/extent/DefaultExtent.java     |    4 +-
 .../iso/extent/DefaultGeographicBoundingBox.java   |    4 +-
 .../iso/extent/DefaultSpatialTemporalExtent.java   |    4 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |    4 +-
 .../metadata/iso/extent/DefaultVerticalExtent.java |    4 +-
 .../iso/extent/NotSpatioTemporalException.java     |   86 ++
 .../sis/metadata/iso/extent/package-info.java      |    2 +-
 .../apache/sis/xml/bind/IdentifierMapAdapter.java  |    2 +-
 .../sis/xml/bind/ModifiableIdentifierMap.java      |    2 +-
 .../sis/xml/bind/NonMarshalledAuthority.java       |    2 +-
 .../sis/xml/CharSequenceSubstitutionTest.java      |   19 +-
 .../test/org/apache/sis/xml/LegacyCodesTest.java   |   98 +-
 .../org/apache/sis/xml/MarshallerPoolTest.java     |    2 +-
 .../test/org/apache/sis/xml/NamespacesTest.java    |   15 +-
 .../apache/sis/xml/NilReasonMarshallingTest.java   |   41 +-
 .../test/org/apache/sis/xml/TransformerTest.java   |   28 +-
 .../apache/sis/xml/TransformingNamespacesTest.java |    4 +-
 .../org/apache/sis/xml/UUIDMarshallingTest.java    |   35 +-
 .../org/apache/sis/xml/ValueConverterTest.java     |    2 +-
 .../org/apache/sis/xml/XLinkMarshallingTest.java   |    9 +-
 .../test/org/apache/sis/xml/XLinkTest.java         |   96 +-
 .../test/org/apache/sis/xml/XPointerTest.java      |    2 +-
 .../org/apache/sis/geometry/EnvelopeReducer.java   |    2 +
 .../apache/sis/geometry/WraparoundAdjustment.java  |    4 +-
 .../main/org/apache/sis/io/wkt/AbstractParser.java |    3 +-
 .../org/apache/sis/io/wkt/FormattableObject.java   |   17 +-
 .../main/org/apache/sis/io/wkt/Formatter.java      |   60 +-
 .../main/org/apache/sis/io/wkt/WKTDictionary.java  |    2 +-
 .../main/org/apache/sis/io/wkt/WKTFormat.java      |   12 +-
 .../main/org/apache/sis/io/wkt/package-info.java   |    2 +-
 .../sis/parameter/DefaultParameterValue.java       |    1 +
 .../org/apache/sis/parameter/ParameterFormat.java  |   11 +-
 .../main/org/apache/sis/parameter/Parameters.java  |    6 +-
 .../main/org/apache/sis/referencing/CRS.java       |   31 +-
 .../apache/sis/referencing/IdentifiedObjects.java  |    4 +-
 .../sis/referencing/ImmutableIdentifier.java       |    2 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |    4 +
 .../sis/referencing/crs/DefaultGeodeticCRS.java    |    1 +
 .../cs/DefaultCoordinateSystemAxis.java            |    6 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    |    1 +
 .../sis/referencing/factory/CacheRecord.java       |    5 +-
 .../referencing/factory/CommonAuthorityCode.java   |    3 +-
 .../factory/ConcurrentAuthorityFactory.java        |   24 +-
 .../referencing/factory/sql/EPSGDataAccess.java    |    2 +-
 .../sis/referencing/factory/sql/SQLTranslator.java |   14 +-
 .../apache/sis/referencing/internal/Resources.java |   33 +-
 .../sis/referencing/internal/Resources.properties  |    5 +-
 .../referencing/internal/Resources_fr.properties   |    5 +-
 .../referencing/internal/ServicesForMetadata.java  |   84 +-
 .../operation/transform/MathTransformProvider.java |   35 +-
 .../sis/referencing/util/ReferencingUtilities.java |   18 +-
 .../test/org/apache/sis/io/wkt/FormatterTest.java  |   11 -
 .../internal/ServicesForMetadataTest.java          |   30 +-
 .../referencing/util/j2d/ShapeUtilitiesViewer.java |    5 +-
 .../sis/storage/netcdf/base/RasterResource.java    |    2 +-
 .../org/apache/sis/storage/gpx/WritableStore.java  |    2 +-
 .../services/java.nio.file.spi.FileTypeDetector    |    2 +-
 .../org.apache.sis.storage/main/module-info.java   |    2 +-
 .../sis/io/stream/ChannelImageOutputStream.java    |    2 -
 .../main/org/apache/sis/io/stream/IOUtilities.java |   62 +-
 .../apache/sis/io/stream/OutputStreamAdapter.java  |    2 +-
 .../main/org/apache/sis/storage/DataOptionKey.java |   47 +-
 .../org/apache/sis/storage/DataStoreProvider.java  |   10 +-
 .../org/apache/sis/storage/DataStoreRegistry.java  |    3 +-
 .../main/org/apache/sis/storage/ProbeReader.java   |    2 +-
 .../org/apache/sis/storage/StorageConnector.java   |   10 +-
 .../apache/sis/storage/base/MetadataBuilder.java   |  193 ++-
 .../org/apache/sis/storage/base/PRJDataStore.java  |   44 +-
 .../org/apache/sis/storage/base/URIDataStore.java  |  203 ++-
 .../main/org/apache/sis/storage/csv/Store.java     |    3 +-
 .../org/apache/sis/storage/csv/StoreProvider.java  |    2 +-
 .../org/apache/sis/storage/esri/RasterStore.java   |    4 +-
 .../apache/sis/storage/esri/RawRasterStore.java    |    3 +-
 .../sis/storage/esri/RawRasterStoreProvider.java   |    5 +-
 .../apache/sis/storage/folder/WritableStore.java   |    3 +-
 .../apache/sis/storage/image/WorldFileStore.java   |   20 +-
 .../apache/sis/storage/image/WritableStore.java    |    7 +
 .../internal}/InputStreamAdapter.java              |   15 +-
 .../org/apache/sis/storage/internal/Resources.java |    5 +
 .../sis/storage/internal/Resources.properties      |    1 +
 .../sis/storage/internal/Resources_fr.properties   |    1 +
 .../internal}/RewindableLineReader.java            |    2 +-
 .../{internal => services}/StoreTypeDetector.java  |    2 +-
 .../apache/sis/storage/services/package-info.java  |   19 +-
 .../main/org/apache/sis/storage/wkt/Store.java     |    2 +
 .../main/org/apache/sis/storage/xml/Store.java     |    1 +
 .../org/apache/sis/io/stream/IOUtilitiesTest.java  |   15 +-
 .../org/apache/sis/storage/DataOptionKeyTest.java  |   33 +-
 .../apache/sis/storage/StorageConnectorTest.java   |   81 +-
 .../test/org/apache/sis/storage/esri/BIL.prj       |    7 +
 .../test/org/apache/sis/storage/esri/BIP.prj       |    7 +
 .../test/org/apache/sis/storage/esri/BSQ.prj       |    7 +
 .../internal}/RewindableLineReaderTest.java        |   39 +-
 .../org/apache/sis/io/IdentifiedObjectFormat.java  |    3 +-
 .../main/org/apache/sis/measure/AbstractUnit.java  |    3 +-
 .../main/org/apache/sis/measure/UnitFormat.java    |   62 +-
 .../main/org/apache/sis/measure/UnitRegistry.java  |    3 +-
 .../main/org/apache/sis/pending/jdk/JDK21.java     |   62 +
 .../main/org/apache/sis/setup/OptionKey.java       |   28 +-
 .../main/org/apache/sis/setup/package-info.java    |    2 +-
 .../main/org/apache/sis/system/DataDirectory.java  |    3 +-
 .../main/org/apache/sis/system/Environment.java    |   87 ++
 .../main/org/apache/sis/util/ArraysExt.java        |   83 +-
 .../main/org/apache/sis/util/Printable.java        |   42 +
 .../org/apache/sis/util/internal/Constants.java    |    5 +
 .../apache/sis/util/internal/DefinitionURI.java    |   81 +-
 .../main/org/apache/sis/util/internal/Strings.java |   11 +
 .../main/org/apache/sis/util/resources/Errors.java |    5 +
 .../apache/sis/util/resources/Errors.properties    |    1 +
 .../apache/sis/util/resources/Errors_fr.properties |    1 +
 .../sis/util/resources/IndexedResourceBundle.java  |    2 +-
 .../org/apache/sis/measure/UnitFormatTest.java     |  117 +-
 .../test/org/apache/sis/setup/OptionKeyTest.java   |    4 +-
 .../test/org/apache/sis/util/ArraysExtTest.java    |   26 +-
 .../sis/util/internal/DefinitionURITest.java       |  190 +--
 .../main/module-info.java                          |    7 +-
 .../storage/shapefile/DataStoreQueryException.java |   50 -
 .../shapefile/DataStoreQueryResultException.java   |   50 -
 .../shapefile/DbaseFileNotFoundException.java      |   50 -
 .../sis/storage/shapefile/InputFeatureStream.java  |  379 ------
 .../shapefile/InputFeatureStream.properties        |    9 -
 .../shapefile/InputFeatureStream_fr.properties     |    9 -
 .../shapefile/InvalidDbaseFileFormatException.java |   34 -
 .../shapefile/InvalidShapefileFormatException.java |   50 -
 .../apache/sis/storage/shapefile/ShapeFile.java    |  206 ----
 .../sis/storage/shapefile/ShapeTypeEnum.java       |   73 --
 .../shapefile/ShapefileNotFoundException.java      |   50 -
 .../sis/storage/shapefile/ShapefileProvider.java   |   24 +
 .../sis/storage/shapefile/ShapefileStore.java      |  105 +-
 .../shapefile/{jdbc/sql => cpg}/package-info.java  |    5 +-
 .../apache/sis/storage/shapefile/dbf/DBFField.java |  147 ++-
 .../sis/storage/shapefile/dbf/DBFHeader.java       |   63 +-
 .../sis/storage/shapefile/dbf/DBFReader.java       |   48 +-
 .../sis/storage/shapefile/dbf/DBFWriter.java       |   39 +-
 .../dbf/{DBFRecord.java => package-info.java}      |   28 +-
 .../storage/shapefile/internal/AutoChecker.java    |  184 ---
 ...nvalidRecordNumberForDirectAccessException.java |   62 -
 .../SQLNoDirectAccessAvailableException.java       |   47 -
 .../internal/SQLShapefileNotFoundException.java    |   47 -
 .../shapefile/internal/ShapefileByteReader.java    |  463 -------
 .../internal/ShapefileByteReader.properties        |   36 -
 .../internal/ShapefileByteReader_fr.properties     |   36 -
 .../shapefile/internal/ShapefileDescriptor.java    |  198 ---
 .../storage/shapefile/internal/package-info.java   |   22 -
 .../shapefile/jdbc/AbstractDbase3ByteReader.java   |  281 -----
 .../jdbc/AbstractDbase3ByteReader.properties       |   14 -
 .../jdbc/AbstractDbase3ByteReader_fr.properties    |   14 -
 .../sis/storage/shapefile/jdbc/AbstractJDBC.java   |  158 ---
 .../storage/shapefile/jdbc/AbstractJDBC.properties |   23 -
 .../shapefile/jdbc/AbstractJDBC_fr.properties      |    1 -
 .../storage/shapefile/jdbc/CommonByteReader.java   |  129 --
 .../shapefile/jdbc/CommonByteReader.properties     |    3 -
 .../sis/storage/shapefile/jdbc/DBFDriver.java      |  141 ---
 .../shapefile/jdbc/DBase3FieldDescriptor.java      |  146 ---
 .../jdbc/DBase3FieldDescriptor.properties          |    7 -
 .../jdbc/DBase3FieldDescriptor_fr.properties       |    1 -
 .../sis/storage/shapefile/jdbc/DBaseDataType.java  |   99 --
 .../storage/shapefile/jdbc/Dbase3ByteReader.java   |  132 --
 .../storage/shapefile/jdbc/MappedByteReader.java   |  307 -----
 .../shapefile/jdbc/MappedByteReader.properties     |   30 -
 .../shapefile/jdbc/MappedByteReader_fr.properties  |   30 -
 .../jdbc/SQLConnectionClosedException.java         |   64 -
 .../jdbc/SQLInvalidDbaseFileFormatException.java   |   47 -
 .../jdbc/connection/AbstractConnection.java        |  414 -------
 .../jdbc/connection/AbstractConnection.properties  |    6 -
 .../connection/AbstractConnection_fr.properties    |    6 -
 .../shapefile/jdbc/connection/DBFConnection.java   |  332 -----
 .../jdbc/connection/DBFConnection.properties       |   49 -
 .../jdbc/connection/DBFConnection_fr.properties    |   39 -
 .../connection/SQLClosingIOFailureException.java   |   64 -
 .../shapefile/jdbc/connection/package-info.java    |   19 -
 .../jdbc/metadata/AbstractDatabaseMetaData.java    |  202 ---
 .../jdbc/metadata/DBFDatabaseMetaData.java         | 1300 --------------------
 .../jdbc/metadata/DBFResultSetMataData.java        |  473 -------
 .../jdbc/metadata/DBFResultSetMataData.properties  |   14 -
 .../metadata/DBFResultSetMataData_fr.properties    |    4 -
 .../shapefile/jdbc/metadata/package-info.java      |   21 -
 .../jdbc/resultset/AbstractResultSet.java          |  703 -----------
 .../jdbc/resultset/AbstractResultSet.properties    |    1 -
 .../jdbc/resultset/AbstractResultSet_fr.properties |    1 -
 .../jdbc/resultset/BuiltInMemoryResultSet.java     |  192 ---
 ...iltInMemoryResultSetForCatalogNamesListing.java |   51 -
 ...DBFBuiltInMemoryResultSetForColumnsListing.java |  460 -------
 ...ltInMemoryResultSetForColumnsListing.properties |    8 -
 ...nMemoryResultSetForColumnsListing_fr.properties |    8 -
 .../DBFBuiltInMemoryResultSetForSchemaListing.java |   51 -
 .../DBFBuiltInMemoryResultSetForTablesListing.java |   88 --
 ...iltInMemoryResultSetForTablesListing.properties |    2 -
 ...uiltInMemoryResultSetForTablesTypesListing.java |   74 --
 ...MemoryResultSetForTablesTypesListing.properties |    2 -
 .../jdbc/resultset/DBFRecordBasedResultSet.java    |  609 ---------
 .../resultset/DBFRecordBasedResultSet.properties   |   28 -
 .../DBFRecordBasedResultSet_fr.properties          |   28 -
 .../shapefile/jdbc/resultset/DBFResultSet.java     |  965 ---------------
 .../jdbc/resultset/DBFResultSet.properties         |   10 -
 .../jdbc/resultset/DBFResultSet_fr.properties      |    4 -
 .../resultset/SQLIllegalColumnIndexException.java  |   77 --
 .../jdbc/resultset/SQLNoResultException.java       |   64 -
 .../jdbc/resultset/SQLNoSuchFieldException.java    |   77 --
 .../jdbc/resultset/SQLNotDateException.java        |   90 --
 .../jdbc/resultset/SQLNotNumericException.java     |   90 --
 .../shapefile/jdbc/resultset/package-info.java     |   21 -
 .../storage/shapefile/jdbc/sql/ClauseResolver.java |  391 ------
 .../shapefile/jdbc/sql/ClauseResolver.properties   |   25 -
 .../jdbc/sql/ClauseResolver_fr.properties          |   16 -
 .../jdbc/sql/ConditionalClauseResolver.java        |   39 -
 .../storage/shapefile/jdbc/sql/CrudeSQLParser.java |  137 ---
 .../shapefile/jdbc/sql/CrudeSQLParser.properties   |   12 -
 .../jdbc/sql/SQLIllegalParameterException.java     |   90 --
 .../jdbc/sql/SQLInvalidStatementException.java     |   64 -
 .../sql/SQLUnsupportedParsingFeatureException.java |   64 -
 .../jdbc/statement/AbstractStatement.java          |  304 -----
 .../shapefile/jdbc/statement/DBFStatement.java     |  240 ----
 .../jdbc/statement/DBFStatement.properties         |   22 -
 .../jdbc/statement/DBFStatement_fr.properties      |   12 -
 .../apache/sis/storage/shapefile/package-info.java |   23 +-
 .../shapefile/shp/ShapeGeometryEncoder.java        |  151 ++-
 .../sis/storage/shapefile/shp/ShapeHeader.java     |   15 +-
 .../sis/storage/shapefile/shp/ShapeReader.java     |   29 +
 .../sis/storage/shapefile/shp/ShapeRecord.java     |   55 +-
 .../sis/storage/shapefile/shp/ShapeType.java       |   83 +-
 .../sis/storage/shapefile/shp/ShapeWriter.java     |   48 +-
 .../shapefile/{jdbc => shp}/package-info.java      |   14 +-
 .../sis/storage/shapefile/shx/IndexReader.java     |   27 +-
 .../sis/storage/shapefile/shx/IndexWriter.java     |   37 +-
 .../{jdbc/statement => shx}/package-info.java      |    6 +-
 .../shapefile/ABRALicenseePt_4326_clipped.dbf      |  Bin 5861 -> 0 bytes
 .../shapefile/ABRALicenseePt_4326_clipped.prj      |    1 -
 .../shapefile/ABRALicenseePt_4326_clipped.shp      |  Bin 184 -> 0 bytes
 .../shapefile/ABRALicenseePt_4326_clipped.shx      |  Bin 124 -> 0 bytes
 .../test/org/apache/sis/storage/shapefile/NOTES.md |   12 -
 .../sis/storage/shapefile/ShapeFileTest.java       |  210 ----
 .../sis/storage/shapefile/ShapefileStoreTest.java  |   90 +-
 .../shapefile/SignedBikeRoute_4326_clipped.dbf     |  Bin 7363 -> 0 bytes
 .../shapefile/SignedBikeRoute_4326_clipped.prj     |    1 -
 .../shapefile/SignedBikeRoute_4326_clipped.shp     |  Bin 1148 -> 0 bytes
 .../shapefile/SignedBikeRoute_4326_clipped.shx     |  Bin 148 -> 0 bytes
 .../org/apache/sis/storage/shapefile/Snippets.java |  108 ++
 .../sis/storage/shapefile/dbf/DBFIOTest.java       |   46 +-
 .../apache/sis/storage/shapefile/dbf/Snippets.java |   95 ++
 .../jdbc/AbstractTestBaseForInternalJDBC.java      |   73 --
 .../storage/shapefile/jdbc/DBFConnectionTest.java  |   93 --
 .../storage/shapefile/jdbc/DBFResultSetTest.java   |  206 ----
 .../storage/shapefile/jdbc/DBFStatementTest.java   |   98 --
 .../apache/sis/storage/shapefile/jdbc/README.md    |   60 -
 .../shapefile/jdbc/sql/WhereClauseTest.java        |  147 ---
 .../sis/storage/shapefile/shp/ShapeIOTest.java     |    4 +-
 .../apache/sis/storage/shapefile/shp/Snippets.java |   81 ++
 .../src/org.apache.sis.gui/bundle/conf/imports.jsh |    1 +
 271 files changed, 3081 insertions(+), 13990 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TransformCommand.java
index af72ada778,8b4b6aff11..142eb6cd41
--- 
a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TransformCommand.java
+++ 
b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/TransformCommand.java
@@@ -77,11 -77,9 +77,10 @@@ import org.apache.sis.metadata.iso.exte
  import org.apache.sis.util.resources.Vocabulary;
  import org.apache.sis.util.resources.Errors;
  import org.apache.sis.util.logging.Logging;
- import org.apache.sis.setup.OptionKey;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.referencing.ObjectDomain;
 +// Specific to the main branch:
 +import org.apache.sis.referencing.DefaultObjectDomain;
 +import org.apache.sis.referencing.internal.Legacy;
  
  
  /**
diff --cc 
endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/FeatureOperations.java
index 581603f674,b968487d00..65348b637d
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/FeatureOperations.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/feature/FeatureOperations.java
@@@ -27,10 -27,16 +27,11 @@@ import org.apache.sis.util.Static
  import org.apache.sis.util.UnconvertibleObjectException;
  import org.apache.sis.util.collection.WeakHashSet;
  import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.internal.Strings;
  import org.apache.sis.setup.GeometryLibrary;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.Operation;
 -import org.opengis.feature.PropertyType;
 -import org.opengis.feature.AttributeType;
 -import org.opengis.feature.FeatureAssociationRole;
 -import org.opengis.filter.Expression;
 +// Specific to the main branch:
 +import org.apache.sis.filter.Expression;
  
  
  /**
@@@ -220,9 -218,9 +221,9 @@@ public final class FeatureOperations ex
          }
          ArgumentChecks.ensureNonEmpty("singleAttributes", singleAttributes);
          if (singleAttributes.length == 1) {
-             if ((prefix == null || prefix.isEmpty()) && (suffix == null || 
suffix.isEmpty())) {
+             if (Strings.isNullOrEmpty(prefix) && 
Strings.isNullOrEmpty(suffix)) {
 -                final PropertyType at = singleAttributes[0];
 -                if (!(at instanceof FeatureAssociationRole)) {
 +                final AbstractIdentifiedType at = singleAttributes[0];
 +                if (!(at instanceof DefaultAssociationRole)) {
                      return link(identification, at);
                  }
              }
diff --cc 
endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
index 011f395dd4,5384d11d9e..7683b6426f
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
@@@ -29,10 -29,10 +29,13 @@@ import org.apache.sis.util.internal.Con
  import org.apache.sis.util.internal.CollectionsExt;
  import org.apache.sis.metadata.iso.citation.Citations;
  import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.resources.Vocabulary;
+ import org.apache.sis.xml.NilObject;
+ import org.apache.sis.xml.NilReason;
  
 +// Specific to the main branch:
 +import org.opengis.referencing.ReferenceIdentifier;
 +
  
  /**
   * Methods working on {@link Identifier} instances.
diff --cc 
endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/CharSequenceSubstitutionTest.java
index 1047a72035,9fb08ea251..0ea0e60226
--- 
a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/CharSequenceSubstitutionTest.java
+++ 
b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/CharSequenceSubstitutionTest.java
@@@ -81,9 -79,9 +80,9 @@@ public final class CharSequenceSubstitu
                  "</gmd:MD_ReferenceSystem>";
  
          final ReferenceSystemMetadata md = 
unmarshal(ReferenceSystemMetadata.class, expected);
 -        final Identifier id = md.getName();
 +        final ReferenceIdentifier id = md.getName();
-         assertEquals("codespace", "L101", id.getCodeSpace());
-         assertEquals("code", "EPSG:4326", id.getCode());
+         assertEquals("L101", id.getCodeSpace(), "codespace");
+         assertEquals("EPSG:4326", id.getCode(), "code");
      }
  
      /**
@@@ -108,9 -106,9 +107,9 @@@
                  "  </mcc:codeSpace>\n" +
                  "</mcc:MD_Identifier>";
  
 -        final Identifier id = unmarshal(Identifier.class, expected);
 +        final DefaultIdentifier id = unmarshal(DefaultIdentifier.class, 
expected);
-         assertEquals("codespace", "L101", id.getCodeSpace());
-         assertEquals("code", "EPSG:4326", id.getCode());
+         assertEquals("L101", id.getCodeSpace(), "codespace");
+         assertEquals("EPSG:4326", id.getCode(), "code");
      }
  
      /**
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
index f44de79245,22429fc32c..de4e24cc57
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
@@@ -753,16 -753,11 +753,16 @@@ public final class IdentifiedObjects ex
          if (identifier == null) {
              return null;
          }
 -        String cs = identifier.getCodeSpace();
 +        String cs = null;
 +        if (identifier instanceof ReferenceIdentifier) {
 +            cs = ((ReferenceIdentifier) identifier).getCodeSpace();
 +        }
-         if (cs == null || cs.isEmpty()) {
+         if (Strings.isNullOrEmpty(cs)) {
              cs = Identifiers.getIdentifier(identifier.getAuthority(), true);
          }
 -        return NameMeaning.toURN(type, cs, identifier.getVersion(), 
identifier.getCode());
 +        return NameMeaning.toURN(type, cs,
 +                (identifier instanceof ReferenceIdentifier) ? 
((ReferenceIdentifier) identifier).getVersion() : null,
 +                identifier.getCode());
      }
  
      /**
@@@ -799,11 -794,8 +799,11 @@@
              return identifier.toString();
          }
          final String code = identifier.getCode();
 -        String cs = identifier.getCodeSpace();
 +        String cs = null;
 +        if (identifier instanceof ReferenceIdentifier) {
 +            cs = ((ReferenceIdentifier) identifier).getCodeSpace();
 +        }
-         if (cs == null || cs.isEmpty()) {
+         if (Strings.isNullOrEmpty(cs)) {
              cs = Citations.toCodeSpace(identifier.getAuthority());
          }
          if (cs != null) {
diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ServicesForMetadata.java
index 2caff2fe07,5e65868b06..6431f96a16
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ServicesForMetadata.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/ServicesForMetadata.java
@@@ -67,29 -67,10 +68,28 @@@ import org.apache.sis.util.Exceptions
  import org.apache.sis.util.Utilities;
  import org.apache.sis.util.internal.Constants;
  import org.apache.sis.util.resources.Vocabulary;
- import org.apache.sis.util.resources.Errors;
  import org.apache.sis.util.logging.Logging;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.metadata.Identifier;
 +// Specific to the main branch:
 +import java.util.Map;
 +import org.opengis.util.NoSuchIdentifierException;
 +import org.opengis.util.TypeName;
 +import org.opengis.referencing.ReferenceIdentifier;
 +import org.opengis.referencing.crs.CRSFactory;
 +import org.opengis.referencing.cs.CSFactory;
 +import org.opengis.referencing.cs.CoordinateSystemAxis;
 +import org.opengis.referencing.operation.MathTransformFactory;
 +import org.opengis.referencing.operation.OperationMethod;
 +import org.opengis.referencing.operation.SingleOperation;
 +import org.opengis.referencing.datum.Datum;
 +import org.opengis.referencing.datum.DatumFactory;
 +import org.apache.sis.metadata.internal.NameToIdentifier;
 +import org.apache.sis.util.Deprecable;
 +import org.apache.sis.referencing.cs.DefaultParametricCS;
 +import org.apache.sis.referencing.datum.DefaultParametricDatum;
 +import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 +import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 +import org.apache.sis.metadata.iso.citation.DefaultCitation;
  
  
  /**
diff --cc 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
index 12398e3986,c2863733cb..dc84ef0523
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
@@@ -3246,9 -3296,22 +3287,10 @@@ parse:      for (int i = 0; i < length;
                  for (ResponsibleParty r : c.getCitedResponsibleParties()) {
                      addIfNotPresent(citation.getCitedResponsibleParties(), r);
                  }
 -                for (OnlineResource r : c.getOnlineResources()) {
 -                    addIfNotPresent(citation.getOnlineResources(), r);
 -                }
                  
citation.getPresentationForms().addAll(c.getPresentationForms());
              }
+             @SuppressWarnings("LocalVariableHidesMemberVariable")
              final DefaultDataIdentification identification = identification();
 -            for (Extent e : info.getExtents()) {
 -                addIfNotPresent(identification.getExtents(), e);
 -            }
 -            for (Resolution r : info.getSpatialResolutions()) {
 -                addIfNotPresent(identification.getSpatialResolutions(), r);
 -            }
 -            for (Duration r : info.getTemporalResolutions()) {
 -                addIfNotPresent(identification.getTemporalResolutions(), r);
 -            }
              for (Format r : info.getResourceFormats()) {
                  addCompression(r.getFileDecompressionTechnique());
                  // Ignore format name (see Javadoc).
@@@ -3256,18 -3319,10 +3298,19 @@@
              for (Constraints r : info.getResourceConstraints()) {
                  addIfNotPresent(identification.getResourceConstraints(), r);
              }
 -            
identification.getTopicCategories().addAll(info.getTopicCategories());
 -            
identification.getSpatialRepresentationTypes().addAll(info.getSpatialRepresentationTypes());
 +            if (info instanceof DataIdentification) {
 +                final DataIdentification di = (DataIdentification) info;
 +                for (Extent e : di.getExtents()) {
 +                    addIfNotPresent(identification.getExtents(), e);
 +                }
 +                for (Resolution r : di.getSpatialResolutions()) {
 +                    addIfNotPresent(identification.getSpatialResolutions(), 
r);
 +                }
 +                
identification.getTopicCategories().addAll(di.getTopicCategories());
 +                
identification.getSpatialRepresentationTypes().addAll(di.getSpatialRepresentationTypes());
 +            }
          }
+         @SuppressWarnings("LocalVariableHidesMemberVariable")
          final DefaultMetadata metadata = metadata();
          for (ContentInformation info : component.getContentInfo()) {
              addIfNotPresent(metadata.getContentInfo(), info);
@@@ -3311,30 -3369,45 +3354,45 @@@
      public boolean mergeMetadata(final Object source, final Locale locale) {
          flush();
          final ModifiableMetadata target;
+         /*
+          * In the following `instanceof` checks, objects closer to root 
should be tested first.
+          * For example, we should finish the checks of all `Metadata` 
elements before to check
+          * if the object is a sub-element of a `Metadata` element. This 
ordering is because an
+          * implementation may implement many interfaces: the main element 
together with some of
+          * its sub-elements. We want to use the object with most information. 
Furthermore, the
+          * main object may not use a type (e.g. `Citation`) for the same 
sub-element than what
+          * the code below assumes.
+          */
               if (source instanceof Metadata)                    target = 
metadata();
          else if (source instanceof DataIdentification)          target = 
identification();
+         else if (source instanceof GridSpatialRepresentation)   target = 
gridRepresentation();
+         else if (source instanceof CoverageDescription)         target = 
coverageDescription();
+         else if (source instanceof FeatureCatalogueDescription) target = 
featureDescription();
+         else if (source instanceof AcquisitionInformation)      target = 
acquisition();
+         else if (source instanceof Lineage)                     target = 
lineage();
+         else if (source instanceof Distribution)                target = 
distribution();
          else if (source instanceof Citation)                    target = 
citation();
+         else if (source instanceof Extent)                      target = 
extent();
+         else if (source instanceof LegalConstraints)            target = 
constraints();
          else if (source instanceof Series)                      target = 
series();
 -        else if (source instanceof Responsibility)              target = 
responsibility();
 -        else if (source instanceof Party)                       target = 
party();
 -        else if (source instanceof AttributeGroup)              target = 
attributeGroup();
 +        else if (source instanceof DefaultResponsibleParty)     target = 
responsibility();
 +        else if (source instanceof AbstractParty)               target = 
party();
-         else if (source instanceof LegalConstraints)            target = 
constraints();
-         else if (source instanceof Extent)                      target = 
extent();
-         else if (source instanceof AcquisitionInformation)      target = 
acquisition();
-         else if (source instanceof Platform)                    target = 
platform();
-         else if (source instanceof FeatureCatalogueDescription) target = 
featureDescription();
-         else if (source instanceof CoverageDescription)         target = 
coverageDescription();
 +        else if (source instanceof DefaultAttributeGroup)       target = 
attributeGroup();
          else if (source instanceof SampleDimension)             target = 
sampleDimension();
-         else if (source instanceof GridSpatialRepresentation)   target = 
gridRepresentation();
          else if (source instanceof GCPCollection)               target = 
groundControlPoints();
-         else if (source instanceof Distribution)                target = 
distribution();
          else if (source instanceof Format)                      target = 
format();
-         else if (source instanceof Lineage)                     target = 
lineage();
+         else if (source instanceof Platform)                    target = 
platform();
          else if (source instanceof ProcessStep)                 target = 
processStep();
          else if (source instanceof Processing)                  target = 
processing();
-         else return false;
+         else if (source instanceof ReferenceSystem) {
+             addReferenceSystem((ReferenceSystem) source);
+             return true;
+         } else {
+             return false;
+         }
          final Merger merger = new Merger(locale);
          merger.copy(source, target);
+         useParentElements();
          return true;
      }
  
diff --cc 
incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
index a08f310fb5,9a77f574bc..b656460dfd
--- 
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
@@@ -185,8 -205,11 +204,11 @@@ public final class ShapefileStore exten
          return featureSetView.getMetadata();
      }
  
+     /**
+      * {@inheritDoc }
+      */
      @Override
 -    public FeatureType getType() throws DataStoreException {
 +    public DefaultFeatureType getType() throws DataStoreException {
          return featureSetView.getType();
      }
  
@@@ -195,8 -221,11 +220,11 @@@
          return featureSetView.subset(query);
      }
  
+     /**
+      * {@inheritDoc }
+      */
      @Override
 -    public Stream<Feature> features(boolean parallel) throws 
DataStoreException {
 +    public Stream<AbstractFeature> features(boolean parallel) throws 
DataStoreException {
          return featureSetView.features(parallel);
      }
  
@@@ -205,23 -237,35 +236,35 @@@
          return featureSetView.getEnvelope();
      }
  
+     /**
+      * {@inheritDoc }
+      */
      @Override
 -    public void updateType(FeatureType featureType) throws DataStoreException 
{
 +    public void updateType(DefaultFeatureType featureType) throws 
DataStoreException {
          featureSetView.updateType(featureType);
      }
  
+     /**
+      * {@inheritDoc }
+      */
      @Override
 -    public void add(Iterator<? extends Feature> iterator) throws 
DataStoreException {
 +    public void add(Iterator<? extends AbstractFeature> iterator) throws 
DataStoreException {
          featureSetView.add(iterator);
      }
  
+     /**
+      * {@inheritDoc }
+      */
      @Override
 -    public void removeIf(Predicate<? super Feature> predicate) throws 
DataStoreException {
 +    public void removeIf(Predicate<? super AbstractFeature> predicate) throws 
DataStoreException {
          featureSetView.removeIf(predicate);
      }
  
+     /**
+      * {@inheritDoc }
+      */
      @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);
      }
  
@@@ -416,11 -463,11 +462,11 @@@
                              //move dbf to record offset, some shp record 
might have been skipped because of filter
                              long offset = (long)header.headerSize + 
((long)(shpRecord.recordNumber-1)) * ((long)header.recordSize);
                              dbfreader.moveToOffset(offset);
-                             final DBFRecord dbfRecord = dbfreader.next();
+                             final Object[] 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]);
+                                 
next.setPropertyValue(header.fields[dbfPropertiesIndex[i]].fieldName, 
dbfRecord[i]);
                              }
                              action.accept(next);
                              return true;
@@@ -453,11 -500,11 +499,11 @@@
                      @Override
                      public boolean tryAdvance(Consumer action) {
                          try {
-                             final DBFRecord dbfRecord = dbfreader.next();
+                             final Object[] 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]);
+                                 
next.setPropertyValue(header.fields[dbfPropertiesIndex[i]].fieldName, 
dbfRecord[i]);
                              }
                              action.accept(next);
                              return true;
@@@ -1094,10 -1140,9 +1141,9 @@@
  
          }
  
 -        private void write(Feature feature) throws IOException {
 +        private void write(AbstractFeature feature) throws IOException {
              inc++; //number starts at 1
              final ShapeRecord shpRecord = new ShapeRecord();
-             final DBFRecord dbfRecord = new DBFRecord();
              final long recordStartPosition = shpWriter.getSteamPosition();
  
              if (defaultGeomName == null) {
diff --cc 
incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
index b2676508bc,4ea5bcbb25..2c8c04de8e
--- 
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
@@@ -44,10 -47,12 +47,12 @@@ import static org.junit.jupiter.api.Ass
  import org.junit.Ignore;
  import org.junit.Test;
  
 -// Specific to the geoapi-3.1 and geoapi-4.0 branches:
 -import org.opengis.feature.AttributeType;
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.FeatureType;
 -import org.opengis.filter.BinaryComparisonOperator;
 -import org.opengis.filter.FilterFactory;
 +// Specific to the main branch:
 +import org.apache.sis.feature.AbstractFeature;
 +import org.apache.sis.feature.DefaultFeatureType;
 +import org.apache.sis.feature.DefaultAttributeType;
++import org.apache.sis.filter.DefaultFilterFactory;
++import org.apache.sis.filter.Filter;
  
  
  /**
@@@ -216,9 -221,8 +221,8 @@@ public class ShapefileStoreTest 
              }
  
              {// check created type
 -                FeatureType type = store.getType();
 +                DefaultFeatureType type = store.getType();
                  assertEquals(name, type.getName().toString());
-                 System.out.println(type.toString());
                  assertEquals(9, type.getProperties(true).size());
                  assertNotNull(type.getProperty("sis:identifier"));
                  assertNotNull(type.getProperty("sis:envelope"));
@@@ -244,13 -250,12 +250,12 @@@
      /**
       * Test adding features to a shapefile.
       */
-     @Ignore
      @Test
      public void testAddFeatures() throws URISyntaxException, 
DataStoreException, IOException {
-         final Path temp = Files.createTempFile("test", ".shp");
-         Files.delete(temp);
+         final Path folder = Files.createTempDirectory("shapefileTest");
+         final Path temp = folder.resolve("test.shp");
          try (final ShapefileStore store = new ShapefileStore(temp)) {
 -            FeatureType type = createType();
 +            DefaultFeatureType type = createType();
              store.updateType(type);
              type = store.getType();
  
@@@ -267,22 -275,68 +275,68 @@@
      /**
       * Test remove features from a shapefile.
       */
-     @Ignore
      @Test
-     public void testRemoveFeatures() throws URISyntaxException, 
DataStoreException {
-         //todo
+     public void testRemoveFeatures() throws DataStoreException, IOException {
+         final Path folder = Files.createTempDirectory("shapefileTest");
+         final Path temp = folder.resolve("test.shp");
+         try (final ShapefileStore store = new ShapefileStore(temp)) {
 -            FeatureType type = createType();
++            DefaultFeatureType type = createType();
+             store.updateType(type);
+             type = store.getType();
 -            Feature feature1 = createFeature1(type);
 -            Feature feature2 = createFeature2(type);
++            AbstractFeature feature1 = createFeature1(type);
++            AbstractFeature feature2 = createFeature2(type);
+             store.add(List.of(feature1, feature2).iterator());
+ 
+             //remove first feature
 -            final FilterFactory<Feature, Object, Object> ff = 
DefaultFilterFactory.forFeatures();
 -            final BinaryComparisonOperator<Feature> filter = 
ff.equal(ff.property("id"), ff.literal(1));
++            final DefaultFilterFactory<AbstractFeature, Object, Object> ff = 
DefaultFilterFactory.forFeatures();
++            final Filter<AbstractFeature> filter = 
ff.equal(ff.property("id"), ff.literal(1));
+             store.removeIf(filter);
+ 
+             Object[] result = store.features(false).toArray();
+             assertEquals(1, result.length);
+             assertEquals(feature2, result[0]);
+         } finally {
+             deleteDirectory(folder);
+         }
      }
  
      /**
       * Test replacing features in a shapefile.
       */
-     @Ignore
      @Test
-     public void testReplaceFeatures() throws URISyntaxException, 
DataStoreException {
-         //todo
+     public void testReplaceFeatures() throws DataStoreException, IOException {
+         final Path folder = Files.createTempDirectory("shapefileTest");
+         final Path temp = folder.resolve("test.shp");
+         try (final ShapefileStore store = new ShapefileStore(temp)) {
 -            FeatureType type = createType();
++            DefaultFeatureType type = createType();
+             store.updateType(type);
+             type = store.getType();
 -            Feature feature1 = createFeature1(type);
 -            Feature feature2 = createFeature2(type);
++            AbstractFeature feature1 = createFeature1(type);
++            AbstractFeature feature2 = createFeature2(type);
+             store.add(List.of(feature1, feature2).iterator());
+ 
+             //remove first feature
 -            final FilterFactory<Feature, Object, Object> ff = 
DefaultFilterFactory.forFeatures();
 -            final BinaryComparisonOperator<Feature> filter = 
ff.equal(ff.property("id"), ff.literal(1));
 -            store.replaceIf(filter, new UnaryOperator<Feature>() {
++            final DefaultFilterFactory<AbstractFeature, Object, Object> ff = 
DefaultFilterFactory.forFeatures();
++            final Filter<AbstractFeature> filter = 
ff.equal(ff.property("id"), ff.literal(1));
++            store.replaceIf(filter, new UnaryOperator<AbstractFeature>() {
+                 @Override
 -                public Feature apply(Feature feature) {
++                public AbstractFeature apply(AbstractFeature feature) {
+                     feature.setPropertyValue("id",45);
+                     return feature;
+                 }
+             });
+ 
+             Object[] result = store.features(false).toArray();
+             assertEquals(2, result.length);
 -            Feature f1 = (Feature) result[0];
++            AbstractFeature f1 = (AbstractFeature) result[0];
+             assertEquals(45, f1.getPropertyValue("id"));
+             assertEquals(feature2, result[1]);
+         } finally {
+             deleteDirectory(folder);
+         }
      }
  
 -    private static FeatureType createType() {
 +    private static DefaultFeatureType createType() {
          final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
          ftb.setName("test");
          ftb.addAttribute(Integer.class).setName("id");
diff --cc 
incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java
index 0000000000,99f9057133..64f8f10b9a
mode 000000,100644..100644
--- 
a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java
+++ 
b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java
@@@ -1,0 -1,106 +1,108 @@@
+ /*
+  * 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.io.IOException;
+ import java.nio.file.Paths;
+ import java.util.List;
+ import java.util.stream.Stream;
+ import org.apache.sis.feature.builder.FeatureTypeBuilder;
+ import org.apache.sis.filter.DefaultFilterFactory;
+ import org.apache.sis.geometry.GeneralEnvelope;
+ import org.apache.sis.referencing.CommonCRS;
+ import org.apache.sis.storage.DataStoreException;
+ import org.apache.sis.storage.FeatureQuery;
+ import org.locationtech.jts.geom.Coordinate;
+ import org.locationtech.jts.geom.GeometryFactory;
+ import org.locationtech.jts.geom.Point;
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.FeatureType;
 -import org.opengis.filter.BinarySpatialOperator;
 -import org.opengis.filter.FilterFactory;
++
++// Specific to the main branch:
++import org.apache.sis.feature.AbstractFeature;
++import org.apache.sis.feature.DefaultFeatureType;
++import org.apache.sis.filter.Filter;
++
+ 
+ /**
+  *
+  * @author Johann Sorel (Geomatys)
+  */
+ final class Snippets {
+ 
+     public void read() throws IllegalArgumentException, DataStoreException, 
IOException{
+         // @start region="read"
+         //open datastore
+         try (ShapefileStore store = new 
ShapefileStore(Paths.get("/path/to/file.shp"))) {
+ 
+             //print feature type
+             System.out.println(store.getType());
+ 
+             //print all features
 -            try (Stream<Feature> features = store.features(false)) {
++            try (Stream<AbstractFeature> features = store.features(false)) {
+                 features.forEach(System.out::println);
+             }
+ 
+             //print only features in envelope and only selected attributes
+             GeneralEnvelope bbox = new 
GeneralEnvelope(CommonCRS.WGS84.normalizedGeographic());
+             bbox.setRange(0, -10, 30);
+             bbox.setRange(1, 45, 55);
 -            FilterFactory<Feature, Object, Object> ff = 
DefaultFilterFactory.forFeatures();
 -            BinarySpatialOperator<Feature> bboxFilter = 
ff.bbox(ff.property("geometry"), bbox);
++            DefaultFilterFactory<AbstractFeature, Object, Object> ff = 
DefaultFilterFactory.forFeatures();
++            Filter<AbstractFeature> bboxFilter = 
ff.bbox(ff.property("geometry"), bbox);
+ 
+             FeatureQuery query = new FeatureQuery();
+             query.setProjection("att1", "att4", "att5");
+             query.setSelection(bboxFilter);
+ 
+             //print selected features
 -            try (Stream<Feature> features = 
store.subset(query).features(false)) {
++            try (Stream<AbstractFeature> features = 
store.subset(query).features(false)) {
+                 features.forEach(System.out::println);
+             }
+ 
+         }
+         // @end
+ 
+     }
+ 
+     public void write() throws IllegalArgumentException, DataStoreException, 
IOException{
+         // @start region="write"
+         //open a channel
+         try (ShapefileStore store = new 
ShapefileStore(Paths.get("/path/to/file.shp"))) {
+ 
+             //define the feature type
+             FeatureTypeBuilder ftb = new FeatureTypeBuilder();
+             ftb.setName("test");
+             ftb.addAttribute(Integer.class).setName("id");
+             ftb.addAttribute(String.class).setName("text");
+             
ftb.addAttribute(Point.class).setName("geometry").setCRS(CommonCRS.WGS84.geographic());
 -            FeatureType type = ftb.build();
++            DefaultFeatureType type = ftb.build();
+ 
+             store.updateType(type);
+             type = store.getType();
+ 
+             //create features
+             GeometryFactory gf = new GeometryFactory();
 -            Feature feature = type.newInstance();
++            AbstractFeature feature = type.newInstance();
+             feature.setPropertyValue("geometry", gf.createPoint(new 
Coordinate(10,20)));
+             feature.setPropertyValue("id", 1);
+             feature.setPropertyValue("text", "some text 1");
+ 
+             //add feature in the store
+             store.add(List.of(feature).iterator());
+         }
+         // @end
+     }
+ 
+ }

Reply via email to