You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by am...@apache.org on 2019/11/15 15:45:02 UTC

[sis] branch refactor/sql-store updated (71a39a3 -> 716f0b7)

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

amanin pushed a change to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git.


    from 71a39a3  chore(*): add missing headers on source files.
     add 2aecabd  Renamed GeodeticCalculator.createCircularRegion2D(…) as createGeodesicCircle2D(…).
     add efb5039  Document better the algorithm source and the accuracy.
     add 1146ab5  Rename dφ as mcosα and dλ as msinα. The previous name were misleading since they were not displacements in degrees, but displacements in some conformal projection. The difference is a cos(φ) factor on northing values.
     add 7d277eb  Take flattening in account when computing (∂y/∂φ)⁻¹.
     add 4b6bb5f  Omit redundant sinα0 field.
     add 6baf41f  Convenience method for repeating a character at the end of a StringBuilder.
     add aacd07f  Create a ClenshawSummation helper class for applying the Clenshaw summation technic (recommended by Karney) on Karney equation 25. This technic has been applied in other places in Apache SIS since it happen often in map projections. Before this class, we used an OpenOffice spreadsheet for performing this summation. But Karney equation 25 is more difficult because of its dependency to another term, the third flattening factor. Using an OpenOffice spreadsheet was no longer [...]
     add 59d8460  Apply Clenshaw summation on Karney equation 25.
     add 98080c7  Now that the development of geodesic distance is completed, set STORE_LOCAL_VARIABLES debug flag to false.
     add 31042ac  Adjustment in the way iteration tolerance is determined.
     add 919c2f2  Use the same latitude difference threshold for geodesic and rhumb line distances.
     add e7a95a2  fix(NetCDF): Remove subsampling doublon when preparing grid geometry for reading.
     add 26efb3d  chore(Feature): minor fix on a javadoc sentence.
     add ff8e769  Reduce the number of distinct constants by replacing some additions by subtractions.
     add e3d94ef  Initial draft of Rhumb Line distance calculated using formulas published by: G.G. Bennett, 1996. Practical Rhumb Line Calculations on the Spheroid. J. Navigation 49(1), 112--119. https://doi.org/10.1017/S0373463300013151
     add b8aa208  Add tests for the rhumb line equatorial case.
     add ad6c9d8  Rewrite Bennett equation 1 by merging ΔΨ = Ψ(φ₂) - Ψ(φ₁) in a single step. It reduces the number of calls to Math.log and Math.pow.
     add dc53abf  Apply Clenshaw summation on Bennett (1996) equation 2.
     add 1101a6c  Replace sin or cos(atan2(Δλ, ΔΨ)) by more direct equivalence.
     add 8c9cf96  Add tests for the spherical case of rhumb line.
     add dba1bd6  Replace authalic radius by semi-major axis length in GeodeticCalculator. The intent is to allow GeodesicsOnEllipsoid to delegate to its parent class in the equatorial case.
     add d42ec44  Delegate to parent class for geodesic distance on equator.
     add 101aa25  Make computation of rhumb line robust to the case where longitude difference is greater than 180°. Minor formatting.
     add 9a32072  Partially revert "Omit redundant sinα0 field." This reverts parts of commit 4b6bb5fd7844d977e14957a5d618b8f91873d4f7. The reason is that the merging sinα0 into msinα2 was dangerous. It makes the code more difficult to analyse and was a cause of bug in createGeodesicPath2D(…), where msinα2 was updated by different ways than through α0 computation.
     add 4a0bac3  More accurate rhumb line distance in test cases using values computed by Karney's online calculator.
     add 071aae3  Test rhumb line azimuth.
     add 07448ca  Replace checked exceptions by unchecked exceptions in GeodeticCalculator API.
     add f2591a4  Replace RuntimeException by GeodeticException where appropriate.
     add 8811433  JTS : make CRS key constant public
     add e94684c  Filter : fix sort by comparator on Iterable types
     add e6a19fd  Documentation updates.
     add be6e5d5  Rename Node.name() as getName() in order to implement Function.getName().
     add 3cecdda  Rename AbstractFunction as NamedFunction with the following modifications: - `name` and `fallback` field replaced by methods to override, since they are often fixed values for a given class. - `equals(Object)` and `hashCode()` implementations inherited from parent class. - Verification that `parameters` argument contains only non-null values.
     add 43187e6  Avoid direct reference to Java Topology Suite (JTS) library from the ST_Transform class. Instead, use the Geometries intenal class which will delegate to JTS, ESRI or Java2D depending which libraries are on the classpath. This commit also relaxes restrictions on type of arguments (first expression may not be an instance of FeatureExpression, and second expression does not need to be a literal).
     add 7daf0a9  CQL : add AntLR filter parser
     add 804cd1a  CQL : move all antlr specific methods in internal package
     add 4a864d9  Filter ; add comparison filter tests
     add 1518f6c  Filter : add Temporal filter function classes
     add aab81c7  Filter : add ST_Centroid and ST_Buffer
     add 0da1c1c  Fix the version number of Java Topology Suite (JTS) dependency.
     add 99cac87  More arguments verification at SimpleQuery construction time and `toString()` adjustments.
     add 218845d  Clarify which exception may be thrown if result type of expressions can not be determined.
     add e553027  When creating the FeatureType for a query or an expression, provide the FeatureTypeBuilder where the properties can be appended directly.
     add 4877df8  Improve error message if the feature type of filtered data can not be determined.
     add a4a4228  Avoid direct dependency to Java Topology Suite (JTS) library, and adjust exceptions.
     add 2d7e4a4  OGC filter specification mandates that the default value of `matchCase` parameter is true.
     add c51c8cc  Better handling of temporal types in comparisons.
     add 86e4d51  Initial implementation of TemporalFunction.
     add b4d7b41  More tests about temporal functions.
     add 5961fbc  Verify also the ComparisonFunction name during tests, and verify at least one of the two expression operands. Recycle some previously created objects, and add comments about what is being tested in TemporalFunctionTest.
     add 25a4935  Minor reformating and test refactoring. Some module of CQL reviews will be done later (hopefully), among other for avoiding dependency to AntLR, delegate geometry parsing to JTS/ESRI library and for trying to avoid direct dependency to JTS. In the meantime, the module is available on geoapi=4.0 branch for experiment but will be excluded from Apache SIS 1.0 release.
     add a206c7b  Hide SQLMM class from public API (the function that it provides are available through DefaultFilterFactory) and refactor tests.
     add 154e065  Update dependencies.
     add 90949f7  Reduce the amount of HSQL-specific changes to SQL statements. We do not need anymore to omit "UNIQUE" keywords or to rename "CHR" as "CHAR". Avoid the "CREATE CACHED TABLE" statement by setting a default value instead.
     add bceb569  Remove the MORE_WORDS hack. It is no longer needed since we avoid using the HSQLDB-specific "CREATE CACHED TABLE" statement. A comment has been added to the `addReplacement(String, String)` method for allowing us to reintroduce this hack if we need it again in the future.
     add 1c8d8b1  Update links in documentation.
     add e0fa493  Minor documentation update.
     add 25af314  Spelling change: implementor -> implementer.
     add 4d20d15  Avoid a NullPointerException which may happen with non-standard logging configuration. The null logging Level has been observed when using HSQL.
     add bd753fe  Provide more details in the documentation about how to upgrade the EPSG geodetic dataset.
     add 53cbe72  Fix the SIS-377 fix: standard foot (0.3048 meter) shall not be confused with US survey foot. See https://issues.apache.org/jira/browse/SIS-377
     add cc55302  Update documentation about upgrading the EPSG database and update the list of sections in CoordinateReferenceSystems.java.
     add 8b31096  chore(Build): set explicit dependencies for JAXB api and engine.
     add 2972cce  fix(referencing): remove useless jaxb dependency, already handled by sis-metadata.
     add b9b440d  Merge branch 'chore/jaxb-dependency' into geoapi-4.0 with modifications: - Implementation.INTERNAL keep for now with removal is deferred at a later time: https://issues.apache.org/jira/browse/SIS-469 - All OGCNamespacePrefixMapper removed instead of only one, in order to keep Implementation.INTERNAL and ENDORSED equivalent. - Jakarata dependency with provided scope for allowing Java 8 to use its internal JAXB implementation.
     add 1f6356a  Add a note about JAXB being distributed under Eclipse Distribution License license.
     add 17e09ca  Make the sis-javafx module optional. That module is built only if the PATH_TO_FX environment variable is set. See https://openjfx.io/openjfx-docs/#install-javafx for more information.
     add 599ef94  Remove spurious warnings about "org.apache.sis.xml.defaultNamespace" property.
     add 2114e9d  Modify the NetBeans project configuration for making it compatible with Java 11. We dropped the JavaFX sources from now (they are still present as an optional Maven module).
     add ae989c9  Add a note saying that Apache SIS can be built with Java version higher than 10. https://issues.apache.org/jira/browse/SIS-438
     add 9abaedd  Remove a version number which is already declared in dependency management.
     add d22d15f  Rename ChangeListener as StoreListener and ChangeEvent as StoreEvent. https://issues.apache.org/jira/browse/SIS-421
     add 962ee26  Replace hard-coded string value by a new constant in the Modules class.
     add b4b8bc3  Shapefile loggers should be package names, not class names.
     add 4f46eeb  Prepare replacement of WarningListeners by StoreListeners. https://issues.apache.org/jira/browse/SIS-421
     add 237a0a0  Replace the use of WarningListeners by StoreListeners in DataStore implementations. https://issues.apache.org/jira/browse/SIS-421
     add 8201633  Replace null argument by call to convenience StoreListeners.warning(…) method.
     add d756a19  Deprecate WarningListener, replaced by the more generic StoreListener. In module that do not depend on org.apache.sis.storage, use java.util.logging.Filter.
     add 26e5a8a  Keep longer logger configuration for DataStores, and avoid the "internal" word in logger name.
     add 7663ff9  Edit project description.
     add fe2cbc1  Throws an exception on attempt to use a closed StorageConnector. This is necessary for avoiding NullPointerException later.
     add 5aa174a  Safety against a wrong parameter type specified by user.
     add b2326a1  Clarification in documentation about where is located the iterator current position in the window.
     add 59b2a4b  Change approach regarding MetadataCopier: throws IllegalArgumentException if the user specify an implementation class instead than interface. The previous approach was to fix automagically the user argument, but it would not work for some cases like implementations backed by java.lang.reflect.Proxy. We are better to let users know soon that they should specify an interface.
     add ced338e  Provides a way to setup the "SpatialMetadata" data source programmatically. https://issues.apache.org/jira/browse/SIS-395
     add 9e45485  Get synchronization lock only once for a whole WKT string to format.
     add 414235b  Move ImmutableIdentifier from org.apache.sis.metadata.iso package to org.apache.sis.referencing package. This is an anticipation for Jigsaw modularisation in a future version.
     add 1f3d2d6  Split the test in a case focusing on vertical extent and in a case for the larger metadata test file.
     add add9c3c  Update documentation to better reflect the state of MD_ReferenceSystem support at XML marshalling time. It appears that https://issues.apache.org/jira/browse/SIS-431 is already mostly done, but it was not clear from the javadoc comments.
     add 54d6f5d  Spelling fix: marshall -> marshal.
     add d6817fa  Upgrade some Apache SIS version numbers from 0.8 to 1.0 in preparation for release candidate.
     add 9f6d579  Update README file.
     add 97bbd5c  Fix HTML errors.
     add b94b082  First round of removal of classes/methods deprecated in SIS 1.0. This commit removes only the classes and methods having no dependencies in SIS.
     add 25e21ce  Remove the deprecated WarningListeners class and interface.
     add 3f0bf11  Delete deprecated DistanceUtils class (replaced by GeodeticCalculator) and remove LatLonPointRadius from public API.
     add 7762360  Bug fix: MetadataCopier.copy(type, metadata) should accept a type which is a super-type of the interface implemented by the given metadata instance.
     add 1387466  Remove the deprecated ModifiableMetadata.unmodifiable() method.
     add 1cbed34  Remove more deprecated methods: DefaultEllipsoid.orthodromicDistance, XML.DEFAULT_NAMESPACE.
     add e016ebd  Bug fix: Comparison with `ANY` returned `true` while `false` was expected.
     add 11a09b8  Rename "ModifiableMetadata.transition" to "transitionTo". The previous name was a bit ambiguous.
     add 82991de  API change before 1.0 release: Reverse the argument order in DataStore.addListener/removeListener. The intent is to be consistent with similar methods elsewhere in SIS, which put the Class<T> argument first.
     add 48d2fc1  Clarification about whether a DataStore.getFoo() method can return null. Contain one last-minute API change before 1.0 release: getOpenParameters() return Optional.
     add 0dc29ec  Upgrade version numbers from 1.0 to 1.1 on classes that are not part of Apache SIS 1.0 release.
     add ef215fb  Upgrade the build requirement from Java 10 to Java 11 (but keep the result executable on Java 8). This upgrade allows us to remove a hack for javadoc generation under Java 10.
     add ec4f7b6  Add a test for an issue reported when running units of measurement TCK.
     add 1c2643b  Adjustement to the build for Apache SIS 1.0 release: - Add explicitly a transitive dependency required for javadoc generation. - Add a	public class (empty for now) in Japanese profile for preventing empty javadoc. - Remove Ant tasks that were specifics to Subversion branches and tags. - Adjust version numbers.
     add 8b80a97  Identity unit conversion should preserve negative zero. When the value is used in a map projection parameter, the sign has implications in the concatenated transforms chain. The final result is numerically equivalent, but intermediate steps may differ depending on the parameter sign.
     add 8bc9157  Last configuration and documentation fixes ported from Apache SIS 1.0-RC1.
     add efdf7d8  Fix copyright year (error identified by Alexis) and URL to Maven.
     add 7c07889  Updates paths and properties to new syntax or location.
     add 6274488  Reduce the numbers of authorities declared in the ESRI-specific projections: limit to ESRI, OGC and Proj4.
     add d650236  feat (sis-referencing & internal) : implement cylindrical and conic satellite-tracking projections from Snyder's 'Map Projections - a working Manual'. Don't compute derivatives yet. Very few tests.
     add c9746c3  feat (sis-referencing & internal) : add test for cylindrical satellite-tracking projection and refactor of the ConicSatelliteTracking classe to use methods instead of lambda expressions
     add 2b94c39  feat (referencing) : add some tests for satellite-tracking projections from tables 38 and 39 of Snyder's Manual (page 238). Fix the condition of the while loop when applying Newton method.
     add a8a3962  feat&refactor (referencing- satellite tracking) : refactor to extract terms from transform/inverseTransform methods AND try to compute Jacobian Matrix. Tests not passed for the conic satellite tracking projection yet. Refactor should be lead to compute L coefficient and its derivative in a method.
     add 47873d4  fix (referencing satellite-tracking projections) : fix the Jacobian matrix in both satellite-tracking projections by inverting m01 and m10 in order to have the partial derivative of x on the matrix's first line and of y on the second line.
     add 8c2d72d  refactor (referencing satellite-tracking projections) : Method used by both (cylindrical and conic) direct transformation of the Satellite-tracking projections to  compute the L coefficient and its partial derivate dL_dφ if queried. Test passed for both transformation and testDerivativeOnSphere.
     add 4f9f695  Merge remote-tracking branch 'Satellite_Tracking_Projection' into geoapi-4.0. Some refactoring to come in next commits.
     add ea466fa  Reformatting: - Format copyright header in the same way than other files. - Rearrange some import order and remove some empty lines. - Set version number to 1.1.
     add 64a587b  Apply some algebraic simplifications on formulas, then merge ConicSatelliteTracking and CylindricalSatelliteTracking in a single SatelliteTracking class. Those cylindrical and conical forms have a lot in common, which make them easier to manage by `if (isConic)` statements. Reduce the number of fields as a consequence of the merge and algebraic simplification. Adjust the type of exception thrown, or whether an exception is thrown instead of setting values to NaN (policy  [...]
     add 130cec1  Apply some algebraic rearrangements and update the documentation about which Snyder formulas are used. Verify the validity of latitude arguments compared to satellite orbit inclination. Tune the tolerance factors used in tests.
     add 574a501  Adjust formatting of angular value of zero. Fix typo in person name.
     add 195b528  Register the SatelliteTracking projection. This commit completes https://issues.apache.org/jira/browse/SIS-452
     add 47cbce0  When an additional offset needs to be added to the pixel stride, scanline stride, plane stride, etc., express that offset in byte units instead than sample units. This change fixes https://issues.apache.org/jira/browse/SIS-476
     add 5c02092  Coverage : fix a null pointer on sample dimension creation when name is undefined
     add 1ff7519  fix(Referencing): improve common CRS suggestion to return base geographic system when possible.
     add d3672ef  Remove obsolete documentation.
     add 6a8e917  Check for arithmetic overflows.
     add 88db100  Referencing objects implement java.util.Formattable.
     add 692ba84  Minor documentation fixes.
     add bdce53d  Clarification in javadoc.
     add 8916572  Make the build compatible with Java 12+. We do not yet require Java 13 at build time, but this is something we may do. https://lists.apache.org/thread.html/da2026376fe0c92b3434c489bb5c35f55e436c1f20eddb777da28d01@%3Cdev.sis.apache.org%3E
     add fb28872  Documentation updates for synchronization with code changes.
     add efa8203  Adjust the style and formatting of <div class="note">...</div>.
     add 5913110  Remplace <div class="section"> HTML tags by <h2> or <h4> standard tags. We avoided those tags previously because it was not clear at which number we should start. But Java 13 now fix those numbers with implicit value depending on the context (whether we are documenting a class or a method), and the compiler verifies those numbers. Since those numbers are now clearly defined, we can rely on them and remove the previous conservative apprach.
     add c63edcc  Actually the <h4> numbering in Javadoc seems to be incompatible with the numbers expected by Java 11. Require Java 13 for building Apache SIS (but still produce code executable on Java 8) so we can write Javadoc comments compliant with most recent Java version.
     add 52a543d  Use {@systemProperty} javadoc tag (new in Java 12) where we are defining system properties.
     add adfaee7  Upgrade some dependencies.
     add a941f05  Consolidation of the way we check if some tests are enabled.
     add d1ee6aa  Inserts table of parameter names for every `ParameterDescriptor` declaration in the provider package. Those tables are generated automatically by `ParameterNameTableGenerator` from runtime information. The intent is to make easier to maintain the parameter declarations when new projections are added, since we use the existing parameters as templates.
     add 42ed8a4  Add additional information about parameter: value domain, default value, whether it is optional.
     add d28ce40  Correction in the report of default values.
     add a8e2cbb  Initial implementation of Orthographic projection (spherical formulas) implemented from Wikipedia and Snyder equations. https://issues.apache.org/jira/browse/SIS-223 - not yet completed because missing ellipsoidal formulas. This work implied revisiting the way we copy names and identifiers from an existing ParameterDescriptor for creating a new ParameterDescriptor.
     add d33105c  Consolidation of reference to Wikipedia or MathWorld.
     add dd58ea3  Fix "llegalArgumentException: Argument ‘count’ shall not be negative" when invoking GridGeometry.toString().
     add be44417  'sis' command should resolve symbolic link.
     add 9581e07  Fix SampleDimension formatting bugs: - Was missing name of sample dimensions after the first one. - Formatting of bands without categories was not helpful.
     add 609bbd9  More explicit exception when there is overlapping range, and make this exception non-fatal in netCDF reader.
     add 31758f6  Avoid range collision if the minimum or maximum value in a netCDF file is equals to a pad/fill value.
     add 64f0021  Documentation updates and finer checks of overlapping ranges in netCDF files.
     add 13b98e3  Add an checked exception for data not found for other reason than illegal name. The reason of interest in this commit is disjoint extent.
     add c68512d  Implement ellipsoidal formulas of Orthographic projection from the formulas published in EPSG guidance notes. https://issues.apache.org/jira/browse/SIS-223
     add 25fbf74  When computing inverse projection, temporarily disable the setting of out-of-domain coordinates to NaN. We use the Inverter class as a flag for identifying those situations.
     add f4c4b9c  CoverageResource : add GridCoverageResource subset method and Coverage Query
     add e4606ae  Provide a default implementation for GridCoverageResource.subset(Query). Not yet in public API; pending the gain of more experience.
     add bec5a17  CoverageSubset clip the area to read to the area of interest specified in the query.
     add d044b3f  Rename some non-standard @SuppressWarnings to value recognized by NetBeans.
     add bcff144  Fix javadoc errors when building with Java 13.
     add 02e7b0c  More accurate exception when query does not intercept data.
     add 9c79f39  If the locale starts with a # character (e.g. "#fra"), skip the "#" character.
     add 0e4d884  DataStore : add additional store metadata informations, Capability.CREATE and resource types
     add 0aefac6  Restart the javafx module: remove dependencies to Swing and icons (we may bring them back from history later if desired). Start the refactoring of classes. The controls (resource viewer, metadata viewer, etc.) will get major changes in next commits.
     add 8b95369  Add Aggregate to the list of resource types produced by some data stores.
     add d95803e  Revert to the previous pom.xml setting for JavaFX where the full installation must be provided by user. For developping that module, use the NetBeans Ant project instead provided that the user does the required setup.
     add cea54a4  Remove the resource tree management and data loading from ResourceView. They are replaced by ResourceTree.
     add c7a6e01  Filter : add between filter implementation
     add f97e125  Improve the use of background threads, enable "drag and drop" and allow to close resources.
     add bd1fe00  Filter: add capabilities classes, still need to commplete tests and equals/hash/serialization
     add a28a3fc  Consolidate ResourceTree. Begins refactoring of ResourceExplorer.
     add 89f5d43  Close the data stores when ask to close them and when the application stop.
     add f1f225f  When a resource is selected in the TreeView, update the MetadataOverview accordingly.
     add 14bf170  Reconnect the MetadataOverview panel to the small map showing data position on world.
     add 3cbf651  Add scroll pane and more dynamic inclusion/exclusion of sections in metadata overview.
     add 607b211  Consolidation, improve documentation and complete some internationalization.
     add 1fa914b  Rename Form as MetadataSection.
     add ab418a8  Handle bounding boxes crossing the anti-meridian.
     add 62f3cb5  Remove the loading of GridGeometry in metadata overview panel. For some formats this is a significant cost since it may force the loading of a localization grid.
     add 3fe5b0a  Remove for now the contact section since it was not completed.
     add 59a4311  Make grid dimensions more tolerant to missing information.
     add 7cd909e  Move MetadataOverview back to its own package. The intent is to make easier to split the sections in separated classes.
     add 8b566c3  Move MetadataOverview inner classes as top-level classes.
     add 8818eb9  Add Google Summer of Code credits.
     add 3637132  Rename MetadataOverview as MetadataSummary and put those metadata in a "summary" tab. Move also the world map in the "metadata" package; it was forgotten in previous commit and is necessary for avoiding a NullPointerException.
     add 042c7e9  Connect MetadataSummary to MetadataTree. The tree view is provided in a separated tab.
     add ac48b98  Consolidation: - Remove CollectionsExt.nonEmptyIterator, replaced by cleaner use of nonNull(Collection). - Remove (text != null && !(text = text.trim()).isEmpty()) statement (they were many), replaced by a call to new internal method Strings.trimOrNull(String). - Add an IdentifiedObjects.getDisplayName method as use it where we intended to have a name for displaying purpose.
     add eff5800  Adjustment in the construction of titles to show to user.
     add 942ecdf  Upgrade Maven dependency.
     add ab93f5a  Show the stack trace when we failed to load a resource.
     add f2311f5  Fix rendering of map in the east hemisphere and when crossing anti-meridian.
     add eae5ae1  Filter : prepare PropertyIsLike filter implementation
     add 20e2995  Filter : add spatial filter classes, not implemented yet, this allows more CQL tests to be activated
     add 41e610d  First revision of FeatureTable. Data are loaded in a background thread by pages of 100 features. The work is not complete: the loading of next page is not yet delayed until first needed.
     add cb86b7f  Avoid a broken link for now (for avoiding a compilation error).
     add 52089a1  Filter : add SQL/MM ST_Simplify and ST_SimplifyPreserveTopology functions
     add 17aabb3  Filter : implement and tests for spatial functions
     add 2ee44e7  Move Feature.Loader in a top-level class for more code readability.
     add 77d3a63  Load only a small number of features, with more features loaded only when needed.
     add cd32723  Filter : add spatial function serialization tests
     add de47cb2  Simplify FeatureLoader by replacing the `Initial` inner class by an `initializer` field. Fix a resource leak: Stream was not closed if the `estimatedSize` was actually exact.
     add 7e1fe6f  Show the exception in the table when an error occurred while loading the data.
     add 941ef8a  Handle small image loading in a separated class for making easier to share.
     add 7718619  If a feature contains multi-valued properties, make possible to see their values on demand.
     add 8043e5e  Define FeatureTable content as a property and add warning in documentation about what can be modified.
     add bc605ab  Add some notes about further work that needs to be done.
     add 6a6a650  Begin refactoring of CRSChooser.
     add 6b11704  CRSChooser builds its list of CRS in a background thread. Filtering delegated to JavaFX FilteredList class.
     add b0b38a0  Refactor CRSChooser as a Dialog subclass.
     add 5f84c5b  Fix an IndexOutOfBoundsException when showing an empty list of features. Avoid drawing a line on image border when rectangle cross anti-meridian.
     add 30ef29f  Factor out the CRS filter predicate in a separated class. Put an hourglass icon while loading CRS tabular data.
     add adafeb6  Coverage : add GridCoverage implementation based on a RenderedImage
     new 15e88bb  Merge branch 'geoapi-4.0' into refactor/sql-store
     new c490618  fix(*): fix merge
     new 65e7ddd  refactor(Feature): Merge duplicate bbox and intersection operators (SQLMM and Filter encoding)
     new 716f0b7  chore(Feature): add cross-CRS test for intersection operator.

The 4 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:
 NOTICE                                             |  13 +-
 README                                             |  30 +-
 application/pom.xml                                |  17 +-
 application/sis-console/pom.xml                    |   9 +
 application/sis-console/src/main/artifact/README   |   6 +-
 application/sis-console/src/main/artifact/bin/sis  |   5 +-
 .../sis-console/src/main/artifact/lib/README       |   1 +
 .../java/org/apache/sis/console/AboutCommand.java  |   2 +-
 .../main/java/org/apache/sis/console/Command.java  |   8 +-
 .../apache/sis/console/ResourcesDownloader.java    |   2 +-
 .../org/apache/sis/console/TransformCommand.java   |   3 +-
 .../java/org/apache/sis/console/package-info.java  |   4 +-
 application/sis-javafx/doc/readme.txt              |  19 +
 application/sis-javafx/pom.xml                     |  45 +-
 .../apache/sis/gui/{Main.java => DataViewer.java}  |  89 ++-
 .../org/apache/sis/gui/dataset/ExpandableList.java | 425 +++++++++++
 .../apache/sis/gui/dataset/ExpandedFeature.java    | 214 ++++++
 .../org/apache/sis/gui/dataset/FeatureList.java    | 340 +++++++++
 .../org/apache/sis/gui/dataset/FeatureLoader.java  | 346 +++++++++
 .../org/apache/sis/gui/dataset/FeatureTable.java   | 479 +++++++++---
 .../apache/sis/gui/dataset/ResourceExplorer.java   | 135 ++++
 .../org/apache/sis/gui/dataset/ResourceTree.java   | 783 ++++++++++++++++----
 .../org/apache/sis/gui/dataset}/package-info.java  |  19 +-
 .../sis/gui/metadata/IdentificationInfo.java       | 346 +++++++++
 .../org/apache/sis/gui/metadata/MetadataNode.java  | 228 ------
 .../apache/sis/gui/metadata/MetadataOverview.java  | 430 -----------
 .../apache/sis/gui/metadata/MetadataSummary.java   | 339 +++++++++
 .../org/apache/sis/gui/metadata/MetadataTree.java  | 332 +++++++++
 .../sis/gui/metadata/RepresentationInfo.java       | 123 ++++
 .../org/apache/sis/gui/metadata/ResourceView.java  | 399 ----------
 .../java/org/apache/sis/gui/metadata/Section.java  | 289 ++++++++
 .../org/apache/sis/gui/metadata}/package-info.java |  16 +-
 .../java/org/apache/sis/gui}/package-info.java     |  14 +-
 .../apache/sis/gui/referencing/AuthorityCodes.java | 459 ++++++++++++
 .../org/apache/sis/gui/referencing/CRSButton.java  |  79 --
 .../org/apache/sis/gui/referencing/CRSChooser.java | 249 +++++--
 .../org/apache/sis/gui/referencing/CRSTable.java   | 349 ---------
 .../java/org/apache/sis/gui/referencing/Code.java  |  94 ++-
 .../org/apache/sis/gui/referencing/CodeFilter.java | 110 +++
 .../org/apache/sis/gui/referencing/WKTPane.java    | 188 ++++-
 .../apache/sis/gui/referencing}/package-info.java  |  13 +-
 .../apache/sis/internal/gui/BackgroundThreads.java |  94 +++
 .../apache/sis/internal/gui/ExceptionReporter.java | 198 +++++
 .../org/apache/sis/internal/gui/FXUtilities.java   |  91 ---
 .../org/apache/sis/internal/gui/FontGlyphs.java    | 143 ----
 .../sis/internal/gui/IdentityValueFactory.java     |  74 ++
 .../org/apache/sis/internal/gui/RecentChoices.java |  95 +++
 .../apache/sis/internal/gui/ResourceLoader.java    | 262 +++++++
 .../org/apache/sis/internal/gui/Resources.java     | 204 +++++-
 .../apache/sis/internal/gui/Resources.properties   |  42 +-
 .../sis/internal/gui/Resources_fr.properties       |  42 +-
 .../java/org/apache/sis/internal/gui/Styles.java   |  98 +++
 .../org/apache/sis/internal/gui/package-info.java  |   5 +-
 .../org/apache/sis/gui/referencing/CRSChooser.fxml |  30 -
 .../org/apache/sis/gui/referencing/proj_conic.png  | Bin 591 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_geo.png    | Bin 834 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_square.png | Bin 519 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_stereo.png | Bin 959 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_utm.png    | Bin 681 -> 0 bytes
 .../org/apache/sis/services/LocationServlet.java   |  13 +-
 core/pom.xml                                       |   1 +
 .../src/main/ant/prepare-release.xml               |  26 +-
 .../org/apache/sis/internal/doclet/Doclet.java     |  45 +-
 .../org/apache/sis/internal/doclet/Include.java    |   2 +-
 .../org/apache/sis/internal/doclet/Taglet.java     |  23 +-
 .../apache/sis/internal/unopkg/package-info.java   |   4 +-
 {storage/sis-xmlstore => core/sis-cql}/pom.xml     |  75 +-
 .../main/antlr4/org/apache/sis/internal/cql/CQL.g4 | 280 +++++++
 .../src/main/java/org/apache/sis/cql/CQL.java      | 752 +++++++++++++++++++
 .../main/java/org/apache/sis/cql/CQLException.java |  37 +-
 .../org/apache/sis/cql/FilterToCQLVisitor.java     | 660 +++++++++++++++++
 .../java/org/apache/sis/internal/cql/AntlrCQL.java |  98 +++
 .../test/java/org/apache/sis/cql/CQLTestCase.java  |  60 ++
 .../test/java/org/apache/sis/cql/CQLTestSuite.java |  33 +-
 .../org/apache/sis/cql/ExpressionReadingTest.java  | 613 ++++++++++++++++
 .../org/apache/sis/cql/ExpressionWritingTest.java  | 339 +++++++++
 .../java/org/apache/sis/cql/FilterReadingTest.java | 808 +++++++++++++++++++++
 .../java/org/apache/sis/cql/FilterWritingTest.java | 401 ++++++++++
 .../java/org/apache/sis/coverage/Category.java     |   8 +-
 .../java/org/apache/sis/coverage/CategoryList.java |   8 +-
 .../coverage/IllegalSampleDimensionException.java  |  62 ++
 .../org/apache/sis/coverage/SampleDimension.java   |  13 +-
 .../org/apache/sis/coverage/SampleRangeFormat.java | 148 ++--
 .../main/java/org/apache/sis/coverage/ToNaN.java   |   6 +-
 .../org/apache/sis/coverage/grid/GridCoverage.java |   2 +-
 .../apache/sis/coverage/grid/GridDerivation.java   |  26 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   2 +-
 .../apache/sis/coverage/grid/ImageRenderer.java    |   2 +-
 .../java/org/apache/sis/coverage/package-info.java |   2 +-
 .../apache/sis/feature/AbstractAssociation.java    |   4 +-
 .../org/apache/sis/feature/AbstractAttribute.java  |  11 +-
 .../org/apache/sis/feature/AbstractFeature.java    |  16 +-
 .../apache/sis/feature/AbstractIdentifiedType.java |   4 +-
 .../apache/sis/feature/CharacteristicTypeMap.java  |   2 +-
 .../apache/sis/feature/DefaultAssociationRole.java |   2 +-
 .../apache/sis/feature/DefaultAttributeType.java   |   8 +-
 .../org/apache/sis/feature/DefaultFeatureType.java |  10 +-
 .../org/apache/sis/feature/EnvelopeOperation.java  |   2 +-
 .../java/org/apache/sis/feature/FeatureFormat.java |   6 +-
 .../org/apache/sis/feature/FeatureOperations.java  |  10 +-
 .../main/java/org/apache/sis/feature/Features.java |  35 +
 .../apache/sis/feature/MultiValuedAssociation.java |   2 +-
 .../apache/sis/feature/MultiValuedAttribute.java   |   2 +-
 .../apache/sis/feature/SingletonAssociation.java   |   4 +-
 .../org/apache/sis/feature/SingletonAttribute.java |   4 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |   9 -
 .../apache/sis/feature/builder/TypeBuilder.java    |   2 +-
 .../java/org/apache/sis/feature/package-info.java  |   6 +-
 .../org/apache/sis/filter/AbstractFunction.java    | 141 ----
 .../org/apache/sis/filter/ArithmeticFunction.java  |  61 +-
 .../java/org/apache/sis/filter/BinaryFunction.java |  30 +-
 .../java/org/apache/sis/filter/CRSMatching.java    |  81 ++-
 .../java/org/apache/sis/filter/Capabilities.java   | 437 +++++++++++
 .../org/apache/sis/filter/ComparisonFunction.java  | 503 ++++++++++---
 .../java/org/apache/sis/filter/DefaultBBOX.java    |  91 ++-
 .../apache/sis/filter/DefaultFilterFactory.java    | 317 ++++----
 .../java/org/apache/sis/filter/DefaultLike.java    | 101 +++
 .../org/apache/sis/filter/DefaultObjectId.java     |   4 +-
 .../java/org/apache/sis/filter/DefaultSortBy.java  |   4 +-
 .../org/apache/sis/filter/FilterByIdentifier.java  |   6 +-
 .../sis/filter/InvalidExpressionException.java     |  92 +++
 .../java/org/apache/sis/filter/LeafExpression.java |  59 +-
 .../org/apache/sis/filter/LogicalFunction.java     |  12 +-
 .../java/org/apache/sis/filter/NamedFunction.java  | 210 ++++++
 .../src/main/java/org/apache/sis/filter/Node.java  |  20 +-
 .../src/main/java/org/apache/sis/filter/SQLMM.java |  76 +-
 .../main/java/org/apache/sis/filter/ST_Buffer.java |  99 +++
 .../java/org/apache/sis/filter/ST_Centroid.java    |  96 +++
 .../java/org/apache/sis/filter/ST_Envelope.java    |  17 +-
 .../java/org/apache/sis/filter/ST_Intersects.java  |  46 +-
 .../java/org/apache/sis/filter/ST_Simplify.java    | 112 +++
 .../sis/filter/ST_SimplifyPreserveTopology.java    | 112 +++
 .../java/org/apache/sis/filter/ST_Transform.java   | 217 ++++--
 .../org/apache/sis/filter/SpatialFunction.java     | 786 ++++++++++++++++++++
 .../org/apache/sis/filter/TemporalFunction.java    | 722 ++++++++++++++++++
 .../java/org/apache/sis/filter/UnaryFunction.java  |  12 +-
 .../java/org/apache/sis/filter/package-info.java   |  10 +-
 .../java/org/apache/sis/image/PixelIterator.java   |   7 +
 .../apache/sis/image/WritablePixelIterator.java    |  11 +-
 .../sis/internal/coverage/GridCoverage2D.java      | 117 +++
 .../sis/internal/feature/AttributeConvention.java  |   2 +-
 .../java/org/apache/sis/internal/feature/ESRI.java |  30 +-
 .../sis/internal/feature/FeatureExpression.java    |  67 +-
 .../sis/internal/feature/FunctionRegister.java     |  42 +-
 .../apache/sis/internal/feature/Geometries.java    | 228 +++++-
 .../java/org/apache/sis/internal/feature/JTS.java  | 102 ++-
 .../org/apache/sis/internal/feature/Java2D.java    |  25 +-
 .../org/apache/sis/internal/feature/Resources.java |  15 +
 .../sis/internal/feature/Resources.properties      |   3 +
 .../sis/internal/feature/Resources_fr.properties   |   3 +
 .../org/apache/sis/internal/feature/jts/JTS.java   |  59 +-
 ...rg.apache.sis.internal.feature.FunctionRegister |   1 -
 .../apache/sis/coverage/SampleRangeFormatTest.java | 137 ++++
 .../apache/sis/filter/ArithmeticFunctionTest.java  |   4 +-
 .../org/apache/sis/filter/BetweenFunctionTest.java |  90 +++
 .../org/apache/sis/filter/CapabilitiesTest.java}   |  42 +-
 .../apache/sis/filter/ComparisonFunctionTest.java  | 151 ++++
 .../org/apache/sis/filter/DefaultObjectIdTest.java |   4 +-
 .../apache/sis/filter/FilterByIdentifierTest.java  |   4 +-
 .../org/apache/sis/filter/LeafExpressionTest.java  |   4 +-
 .../org/apache/sis/filter/LikeFunctionTest.java    |  42 +-
 .../org/apache/sis/filter/LogicalFunctionTest.java |   4 +-
 .../java/org/apache/sis/filter/PeriodLiteral.java  | 115 +++
 .../test/java/org/apache/sis/filter/SQLMMTest.java | 372 +++++++---
 .../org/apache/sis/filter/SpatialFunctionTest.java | 310 ++++++++
 .../apache/sis/filter/TemporalFunctionTest.java    | 341 +++++++++
 .../org/apache/sis/filter/UnaryFunctionTest.java   |   4 +-
 .../sis/internal/coverage/GridCoverage2DTest.java  | 126 ++++
 .../apache/sis/test/suite/FeatureTestSuite.java    |  12 +-
 core/sis-metadata/pom.xml                          |  13 +-
 .../java/org/apache/sis/internal/jaxb/Context.java |  21 +-
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |   8 +-
 .../sis/internal/jaxb/ModifiableIdentifierMap.java |   2 +-
 .../sis/internal/jaxb/PrimitiveTypeProperties.java |   6 +-
 .../apache/sis/internal/jaxb/gco/GO_DateTime.java  |   2 +-
 .../apache/sis/internal/jaxb/gco/GO_Decimal.java   |   2 +-
 .../org/apache/sis/internal/jaxb/gco/GO_Real.java  |   2 +-
 .../jaxb/gco/InternationalStringAdapter.java       |   2 +-
 .../apache/sis/internal/jaxb/gco/PropertyType.java |  12 +-
 .../sis/internal/jaxb/gco/StringAdapter.java       |   2 +-
 .../apache/sis/internal/jaxb/gco/package-info.java |   7 +-
 .../sis/internal/jaxb/geometry/package-info.java   |   2 +-
 .../sis/internal/jaxb/gmi/LE_ProcessStep.java      |   2 +-
 .../apache/sis/internal/jaxb/gmi/LE_Source.java    |   2 +-
 .../org/apache/sis/internal/jaxb/gmi/MI_Band.java  |   2 +-
 .../internal/jaxb/gmi/MI_CoverageDescription.java  |   2 +-
 .../sis/internal/jaxb/gmi/MI_Georectified.java     |   2 +-
 .../sis/internal/jaxb/gmi/MI_Georeferenceable.java |   2 +-
 .../sis/internal/jaxb/gmi/MI_ImageDescription.java |   2 +-
 .../apache/sis/internal/jaxb/gmi/MI_Metadata.java  |   2 +-
 .../apache/sis/internal/jaxb/gml/GMLAdapter.java   |   2 +-
 .../org/apache/sis/internal/jaxb/gml/Measure.java  |   2 +-
 .../jaxb/lan/LocalisedCharacterString.java         |  10 +-
 .../sis/internal/jaxb/metadata/CI_Address.java     |   2 +-
 .../sis/internal/jaxb/metadata/CI_Citation.java    |   2 +-
 .../sis/internal/jaxb/metadata/CI_Contact.java     |   2 +-
 .../apache/sis/internal/jaxb/metadata/CI_Date.java |   2 +-
 .../internal/jaxb/metadata/CI_OnlineResource.java  |   2 +-
 .../sis/internal/jaxb/metadata/CI_Party.java       |   2 +-
 .../internal/jaxb/metadata/CI_Responsibility.java  |   2 +-
 .../jaxb/metadata/CI_ResponsibleParty.java         |   2 +-
 .../sis/internal/jaxb/metadata/CI_Series.java      |   2 +-
 .../sis/internal/jaxb/metadata/CI_Telephone.java   |   2 +-
 .../sis/internal/jaxb/metadata/DQ_DataQuality.java |   2 +-
 .../sis/internal/jaxb/metadata/DQ_Element.java     |   2 +-
 .../jaxb/metadata/DQ_PositionalAccuracy.java       |   2 +-
 .../sis/internal/jaxb/metadata/DQ_Result.java      |   2 +-
 .../sis/internal/jaxb/metadata/EX_Extent.java      |   2 +-
 .../jaxb/metadata/EX_GeographicExtent.java         |   2 +-
 .../internal/jaxb/metadata/EX_TemporalExtent.java  |   2 +-
 .../internal/jaxb/metadata/EX_VerticalExtent.java  |   2 +-
 .../sis/internal/jaxb/metadata/LE_Algorithm.java   |   2 +-
 .../jaxb/metadata/LE_NominalResolution.java        |   2 +-
 .../jaxb/metadata/LE_ProcessStepReport.java        |   2 +-
 .../sis/internal/jaxb/metadata/LE_Processing.java  |   2 +-
 .../sis/internal/jaxb/metadata/LI_Lineage.java     |   2 +-
 .../sis/internal/jaxb/metadata/LI_ProcessStep.java |   2 +-
 .../sis/internal/jaxb/metadata/LI_Source.java      |   2 +-
 .../jaxb/metadata/MD_AggregateInformation.java     |   2 +-
 .../metadata/MD_ApplicationSchemaInformation.java  |   2 +-
 .../jaxb/metadata/MD_AssociatedResource.java       |   2 +-
 .../internal/jaxb/metadata/MD_AttributeGroup.java  |   2 +-
 .../internal/jaxb/metadata/MD_BrowseGraphic.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Constraints.java |   2 +-
 .../jaxb/metadata/MD_ContentInformation.java       |   2 +-
 .../jaxb/metadata/MD_DataIdentification.java       |   2 +-
 .../jaxb/metadata/MD_DigitalTransferOptions.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Dimension.java   |   2 +-
 .../internal/jaxb/metadata/MD_Distribution.java    |   2 +-
 .../sis/internal/jaxb/metadata/MD_Distributor.java |   2 +-
 .../metadata/MD_ExtendedElementInformation.java    |   2 +-
 .../internal/jaxb/metadata/MD_FeatureTypeInfo.java |   2 +-
 .../sis/internal/jaxb/metadata/MD_Format.java      |   2 +-
 .../jaxb/metadata/MD_GeometricObjects.java         |   2 +-
 .../internal/jaxb/metadata/MD_Identification.java  |   2 +-
 .../sis/internal/jaxb/metadata/MD_Identifier.java  |   2 +-
 .../internal/jaxb/metadata/MD_KeywordClass.java    |   2 +-
 .../sis/internal/jaxb/metadata/MD_Keywords.java    |   2 +-
 .../jaxb/metadata/MD_MaintenanceInformation.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Medium.java      |   2 +-
 .../sis/internal/jaxb/metadata/MD_Metadata.java    |   2 +-
 .../metadata/MD_MetadataExtensionInformation.java  |   2 +-
 .../internal/jaxb/metadata/MD_MetadataScope.java   |   2 +-
 .../metadata/MD_PortrayalCatalogueReference.java   |   2 +-
 .../internal/jaxb/metadata/MD_RangeDimension.java  |   2 +-
 .../internal/jaxb/metadata/MD_Releasability.java   |   2 +-
 .../jaxb/metadata/MD_RepresentativeFraction.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Resolution.java  |   2 +-
 .../sis/internal/jaxb/metadata/MD_Scope.java       |   2 +-
 .../jaxb/metadata/MD_ScopeDescription.java         |   2 +-
 .../jaxb/metadata/MD_SpatialRepresentation.java    |   2 +-
 .../jaxb/metadata/MD_StandardOrderProcess.java     |   2 +-
 .../sis/internal/jaxb/metadata/MD_Usage.java       |   2 +-
 .../jaxb/metadata/MI_AcquisitionInformation.java   |   2 +-
 .../jaxb/metadata/MI_EnvironmentalRecord.java      |   2 +-
 .../sis/internal/jaxb/metadata/MI_Event.java       |   2 +-
 .../apache/sis/internal/jaxb/metadata/MI_GCP.java  |   2 +-
 .../jaxb/metadata/MI_GeolocationInformation.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Instrument.java  |   2 +-
 .../sis/internal/jaxb/metadata/MI_Objective.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Operation.java   |   2 +-
 .../apache/sis/internal/jaxb/metadata/MI_Plan.java |   2 +-
 .../sis/internal/jaxb/metadata/MI_Platform.java    |   2 +-
 .../internal/jaxb/metadata/MI_PlatformPass.java    |   2 +-
 .../jaxb/metadata/MI_RangeElementDescription.java  |   2 +-
 .../internal/jaxb/metadata/MI_RequestedDate.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Requirement.java |   2 +-
 .../sis/internal/jaxb/metadata/MX_DataFile.java    |   2 +-
 .../internal/jaxb/metadata/RS_ReferenceSystem.java |  22 +-
 .../internal/jaxb/metadata/SV_CoupledResource.java |   2 +-
 .../jaxb/metadata/SV_OperationChainMetadata.java   |   2 +-
 .../jaxb/metadata/SV_OperationMetadata.java        |   2 +-
 .../sis/internal/jaxb/metadata/SV_Parameter.java   |   2 +-
 .../sis/internal/jaxb/metadata/package-info.java   |   2 +-
 .../metadata/replace/ReferenceSystemMetadata.java  |  12 +-
 .../jaxb/metadata/replace/ServiceParameter.java    |   2 +-
 .../org/apache/sis/internal/jaxb/package-info.java |   2 +-
 .../apache/sis/internal/metadata/Identifiers.java  |  20 +-
 .../apache/sis/internal/metadata/Resources.java    |  27 +
 .../sis/internal/metadata/Resources.properties     |   2 +
 .../sis/internal/metadata/Resources_fr.properties  |   2 +
 .../sis/internal/metadata/ServicesForUtility.java  |  28 +
 .../internal/metadata/TransformationAccuracy.java  |   2 +-
 .../sis/internal/metadata/sql/Initializer.java     |  22 +-
 .../sis/internal/metadata/sql/ScriptRunner.java    |  63 +-
 .../sis/internal/metadata/sql/package-info.java    |   2 +-
 .../java/org/apache/sis/internal/xml/Schemas.java  |   2 +-
 .../org/apache/sis/metadata/AbstractMetadata.java  |  19 +-
 .../org/apache/sis/metadata/MetadataCopier.java    |  41 +-
 .../org/apache/sis/metadata/MetadataFormat.java    |   2 +-
 .../org/apache/sis/metadata/MetadataStandard.java  |  18 +-
 .../org/apache/sis/metadata/MetadataVisitor.java   |   2 +-
 .../apache/sis/metadata/ModifiableMetadata.java    | 142 +---
 .../org/apache/sis/metadata/PropertyAccessor.java  |   4 +-
 .../apache/sis/metadata/PropertyInformation.java   |   2 +-
 .../java/org/apache/sis/metadata/StateChanger.java |   6 +-
 .../org/apache/sis/metadata/TreeNodeChildren.java  |   9 +-
 .../apache/sis/metadata/ValueExistencePolicy.java  |   2 +-
 .../apache/sis/metadata/iso/DefaultIdentifier.java |  13 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   |   4 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |   6 +-
 .../metadata/iso/acquisition/DefaultObjective.java |   2 +-
 .../sis/metadata/iso/acquisition/package-info.java |   4 +-
 .../sis/metadata/iso/citation/Citations.java       |  98 +--
 .../sis/metadata/iso/citation/DefaultCitation.java |   6 +-
 .../metadata/iso/citation/DefaultTelephone.java    |   8 +-
 .../sis/metadata/iso/citation/package-info.java    |   6 +-
 .../iso/constraint/DefaultLegalConstraints.java    |   2 +-
 .../sis/metadata/iso/constraint/package-info.java  |   4 +-
 .../sis/metadata/iso/content/package-info.java     |   4 +-
 .../distribution/DefaultStandardOrderProcess.java  |   4 +-
 .../metadata/iso/distribution/package-info.java    |   4 +-
 .../sis/metadata/iso/extent/DefaultExtent.java     |   2 +-
 .../iso/extent/DefaultGeographicBoundingBox.java   |   7 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |   2 +-
 .../metadata/iso/extent/DefaultVerticalExtent.java |   4 +-
 .../apache/sis/metadata/iso/extent/Extents.java    |   8 +-
 .../sis/metadata/iso/extent/package-info.java      |   4 +-
 .../DefaultAggregateInformation.java               |   2 +-
 .../identification/DefaultAssociatedResource.java  |   2 +-
 .../DefaultRepresentativeFraction.java             |   4 +-
 .../iso/identification/DefaultResolution.java      |  12 +-
 .../metadata/iso/identification/package-info.java  |   4 +-
 .../sis/metadata/iso/lineage/DefaultLineage.java   |   2 +-
 .../sis/metadata/iso/lineage/DefaultSource.java    |   2 +-
 .../sis/metadata/iso/lineage/package-info.java     |   4 +-
 .../iso/maintenance/DefaultScopeDescription.java   |  22 +-
 .../sis/metadata/iso/maintenance/package-info.java |   4 +-
 .../org/apache/sis/metadata/iso/package-info.java  |   6 +-
 .../metadata/iso/quality/DefaultDataQuality.java   |   2 +-
 .../iso/quality/DefaultQuantitativeResult.java     |   2 +-
 .../sis/metadata/iso/quality/package-info.java     |   4 +-
 .../metadata/iso/spatial/DefaultGeorectified.java  |   6 +-
 .../sis/metadata/iso/spatial/package-info.java     |   4 +-
 .../java/org/apache/sis/metadata/package-info.java |   8 +-
 .../apache/sis/metadata/sql/CachedStatement.java   |  33 +-
 .../org/apache/sis/metadata/sql/Dispatcher.java    |   2 +-
 .../sis/metadata/sql/IdentifierGenerator.java      |   2 +-
 .../apache/sis/metadata/sql/MetadataFallback.java  |  17 +-
 .../apache/sis/metadata/sql/MetadataSource.java    |  77 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |  28 +-
 .../org/apache/sis/metadata/sql/package-info.java  |   2 +-
 .../org/apache/sis/util/iso/AbstractFactory.java   |   2 +-
 .../java/org/apache/sis/util/iso/AbstractName.java |   4 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |   4 +-
 .../org/apache/sis/util/iso/DefaultMemberName.java |   2 +-
 .../apache/sis/util/iso/DefaultNameFactory.java    |   2 +-
 .../org/apache/sis/util/iso/DefaultNameSpace.java  |   4 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |   6 +-
 .../apache/sis/util/iso/DefaultRecordSchema.java   |   4 +-
 .../org/apache/sis/util/iso/DefaultRecordType.java |   6 +-
 .../org/apache/sis/util/iso/DefaultScopedName.java |   2 +-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |   4 +-
 .../org/apache/sis/util/iso/GlobalNameSpace.java   |   2 +-
 .../main/java/org/apache/sis/util/iso/Names.java   |  22 +-
 .../org/apache/sis/util/iso/RecordDefinition.java  |   4 +-
 .../main/java/org/apache/sis/util/iso/Types.java   |   2 +-
 .../java/org/apache/sis/util/iso/package-info.java |   5 +-
 .../java/org/apache/sis/xml/IdentifiedObject.java  |   2 +-
 .../java/org/apache/sis/xml/Implementation.java    |  32 +-
 .../java/org/apache/sis/xml/MarshalContext.java    |  10 +-
 .../java/org/apache/sis/xml/MarshallerPool.java    |  35 +-
 .../main/java/org/apache/sis/xml/Namespaces.java   |  24 +-
 .../main/java/org/apache/sis/xml/NilObject.java    |   2 +-
 .../main/java/org/apache/sis/xml/NilReason.java    |   4 +-
 .../apache/sis/xml/OGCNamespacePrefixMapper.java   |  79 --
 .../sis/xml/OGCNamespacePrefixMapper_Endorsed.java |  73 --
 .../src/main/java/org/apache/sis/xml/Pooled.java   |  16 +-
 .../java/org/apache/sis/xml/ReferenceResolver.java |   2 +-
 .../main/java/org/apache/sis/xml/Transformer.java  |   2 +-
 .../java/org/apache/sis/xml/ValueConverter.java    |   6 +-
 .../src/main/java/org/apache/sis/xml/XLink.java    |  20 +-
 .../src/main/java/org/apache/sis/xml/XML.java      |  42 +-
 .../main/java/org/apache/sis/xml/package-info.java |   4 +-
 .../sis/internal/jaxb/cat/EnumMarshallingTest.java |   2 +-
 .../apache/sis/metadata/MetadataCopierTest.java    |  48 +-
 .../apache/sis/metadata/MetadataStandardTest.java  |   4 +-
 .../sis/metadata/ModifiableMetadataTest.java       |  10 +-
 .../java/org/apache/sis/metadata/NameMapTest.java  |   2 +-
 .../apache/sis/metadata/TreeNodeChildrenTest.java  |   2 +-
 .../sis/metadata/iso/CustomMetadataTest.java       |   2 +-
 .../apache/sis/metadata/iso/MarshallingTest.java   |  24 +-
 .../metadata/iso/citation/DefaultCitationTest.java |  23 +-
 .../metadata/iso/citation/DefaultContactTest.java  |  20 +-
 .../metadata/iso/citation/HardCodedCitations.java  |   8 +-
 .../identification/DefaultBrowseGraphicTest.java   |  17 +-
 .../DefaultRepresentativeFractionTest.java         |   4 +-
 .../sis/metadata/xml/SchemaComplianceTest.java     |  24 +-
 .../java/org/apache/sis/test/MetadataAssert.java   |   2 +-
 .../java/org/apache/sis/test/sql/TestDatabase.java |  13 +-
 .../apache/sis/test/suite/MetadataTestSuite.java   |   1 -
 .../org/apache/sis/test/xml/PackageVerifier.java   |  10 +-
 .../org/apache/sis/test/xml/SchemaCompliance.java  |   2 +-
 .../org/apache/sis/xml/MarshallerPoolTest.java     |   2 -
 .../sis/xml/OGCNamespacePrefixMapperTest.java      | 134 ----
 core/sis-referencing-by-identifiers/pom.xml        |   4 +
 .../referencing/gazetteer/FinalLocationType.java   |  20 +-
 .../gazetteer/GeohashReferenceSystem.java          |   2 +-
 .../sis/referencing/gazetteer/LocationFormat.java  |   2 +-
 .../gazetteer/MilitaryGridReferenceSystem.java     |  12 +-
 .../gazetteer/ModifiableLocationType.java          |   4 +-
 .../gazetteer/ReferencingByIdentifiers.java        |   2 +-
 .../sis/referencing/gazetteer/package-info.java    |   2 +-
 .../referencing/gazetteer/LocationTypeTest.java    |   2 +-
 core/sis-referencing/pom.xml                       |   9 +
 .../org/apache/sis/distance/DistanceUtils.java     | 102 ---
 .../org/apache/sis/geometry/AbstractEnvelope.java  |  33 +-
 .../org/apache/sis/geometry/ArrayEnvelope.java     |   4 +-
 .../org/apache/sis/geometry/DirectPosition2D.java  |   2 +-
 .../java/org/apache/sis/geometry/Envelope2D.java   |  27 +-
 .../java/org/apache/sis/geometry/Envelopes.java    |  10 +-
 .../apache/sis/geometry/GeneralDirectPosition.java |  20 +-
 .../org/apache/sis/geometry/GeneralEnvelope.java   |  33 +-
 .../org/apache/sis/geometry/ImmutableEnvelope.java |   2 +-
 .../java/org/apache/sis/geometry/package-info.java |   8 +-
 .../internal/jaxb/referencing/CC_Conversion.java   |   2 +-
 .../jaxb/referencing/CC_CoordinateOperation.java   |   2 +-
 .../referencing/CC_GeneralOperationParameter.java  |   2 +-
 .../jaxb/referencing/CC_GeneralParameterValue.java |   2 +-
 .../jaxb/referencing/CC_OperationMethod.java       |   2 +-
 .../jaxb/referencing/CC_OperationParameter.java    |   2 +-
 .../referencing/CC_OperationParameterGroup.java    |   2 +-
 .../internal/jaxb/referencing/CD_Ellipsoid.java    |   2 +-
 .../jaxb/referencing/CD_EngineeringDatum.java      |   2 +-
 .../jaxb/referencing/CD_GeodeticDatum.java         |   2 +-
 .../internal/jaxb/referencing/CD_ImageDatum.java   |   2 +-
 .../jaxb/referencing/CD_ParametricDatum.java       |   2 +-
 .../jaxb/referencing/CD_PrimeMeridian.java         |   2 +-
 .../jaxb/referencing/CD_TemporalDatum.java         |   2 +-
 .../jaxb/referencing/CD_VerticalDatum.java         |   2 +-
 .../sis/internal/jaxb/referencing/CS_AffineCS.java |   2 +-
 .../internal/jaxb/referencing/CS_CartesianCS.java  |   2 +-
 .../jaxb/referencing/CS_CoordinateSystem.java      |   2 +-
 .../jaxb/referencing/CS_CoordinateSystemAxis.java  |   2 +-
 .../jaxb/referencing/CS_CylindricalCS.java         |   2 +-
 .../jaxb/referencing/CS_EllipsoidalCS.java         |   2 +-
 .../sis/internal/jaxb/referencing/CS_LinearCS.java |   2 +-
 .../internal/jaxb/referencing/CS_ParametricCS.java |   2 +-
 .../sis/internal/jaxb/referencing/CS_PolarCS.java  |   2 +-
 .../internal/jaxb/referencing/CS_SphericalCS.java  |   2 +-
 .../sis/internal/jaxb/referencing/CS_TimeCS.java   |   2 +-
 .../jaxb/referencing/CS_UserDefinedCS.java         |   2 +-
 .../internal/jaxb/referencing/CS_VerticalCS.java   |   2 +-
 .../apache/sis/internal/jaxb/referencing/Code.java |   4 +-
 .../internal/jaxb/referencing/RS_Identifier.java   |   4 +-
 .../sis/internal/jaxb/referencing/SC_CRS.java      |   2 +-
 .../internal/jaxb/referencing/SC_SingleCRS.java    |   4 +-
 .../internal/jaxb/referencing/SC_VerticalCRS.java  |   2 +-
 .../internal/jaxb/referencing/package-info.java    |   2 +-
 .../internal/referencing/DefinitionVerifier.java   |  10 +-
 .../sis/internal/referencing/DeprecatedCode.java   |   2 +-
 .../sis/internal/referencing/EPSGFactoryProxy.java |   7 +-
 .../apache/sis/internal/referencing/Formulas.java  |   5 +-
 .../referencing/GeodeticObjectBuilder.java         |   2 +-
 .../internal/referencing/PositionTransformer.java  |   2 +-
 .../referencing/PositionalAccuracyConstant.java    |   5 +-
 .../apache/sis/internal/referencing/Resources.java |   5 +
 .../sis/internal/referencing/Resources.properties  |   1 +
 .../internal/referencing/Resources_fr.properties   |   1 +
 .../internal/referencing/SignReversalComment.java  |   3 +
 .../sis/internal/referencing/WKTKeywords.java      |   2 +-
 .../referencing/j2d/ImmutableAffineTransform.java  |   2 +-
 .../referencing/j2d/IntervalRectangle.java         |   2 +-
 .../referencing/provider/AbstractLambert.java      |  22 +
 .../referencing/provider/AbstractMercator.java     |  22 +
 .../provider/AbstractStereographic.java            |  22 +
 .../referencing/provider/AlbersEqualArea.java      |  89 ++-
 .../internal/referencing/provider/EPSGName.java    |   2 +-
 .../sis/internal/referencing/provider/ESRI.java    | 107 ++-
 .../referencing/provider/Equirectangular.java      |  64 ++
 .../provider/FranceGeocentricInterpolation.java    |  10 +
 .../referencing/provider/GeocentricAffine.java     |  63 +-
 .../GeocentricAffineBetweenGeographic.java         |  56 ++
 .../referencing/provider/Geographic2Dto3D.java     |   6 +
 .../provider/GeographicAndVerticalOffsets.java     |   6 +
 .../referencing/provider/GeographicOffsets.java    |  18 +
 .../provider/GeographicToGeocentric.java           |  12 +
 .../referencing/provider/LambertConformal1SP.java  |  37 +
 .../referencing/provider/LambertConformal2SP.java  |  75 +-
 .../provider/LambertConformalMichigan.java         |  10 +
 .../referencing/provider/LambertConformalWest.java |  11 +
 .../provider/LambertCylindricalEqualArea.java      |  48 ++
 .../referencing/provider/MapProjection.java        | 149 ++--
 .../internal/referencing/provider/Mercator1SP.java |  37 +
 .../internal/referencing/provider/Mercator2SP.java |  29 +-
 .../referencing/provider/MercatorSpherical.java    |   2 +-
 .../referencing/provider/MillerCylindrical.java    |   2 +-
 .../internal/referencing/provider/Mollweide.java   |  24 +
 .../internal/referencing/provider/Molodensky.java  |  26 +-
 .../sis/internal/referencing/provider/NADCON.java  |  22 +-
 .../sis/internal/referencing/provider/NTv2.java    |  10 +
 .../referencing/provider/ObliqueMercator.java      |  93 ++-
 .../provider/ObliqueMercatorCenter.java            |  20 +
 .../referencing/provider/ObliqueStereographic.java |  33 +
 .../referencing/provider/Orthographic.java         | 196 +++++
 .../referencing/provider/PolarStereographicA.java  |  37 +
 .../referencing/provider/PolarStereographicB.java  |  43 +-
 .../referencing/provider/PolarStereographicC.java  |  22 +
 .../provider/PolarStereographicSouth.java          |   4 +-
 .../internal/referencing/provider/Polyconic.java   |  44 ++
 .../referencing/provider/RegionalMercator.java     |  37 +
 .../referencing/provider/SatelliteTracking.java    | 205 ++++++
 .../internal/referencing/provider/Sinusoidal.java  |  24 +
 .../referencing/provider/TransverseMercator.java   |  37 +-
 .../provider/ZonedTransverseMercator.java          |  21 +
 .../referencing/provider/package-info.java         |   3 +-
 .../java/org/apache/sis/io/wkt/Convention.java     |  13 +-
 .../java/org/apache/sis/io/wkt/ElementKind.java    |   2 +-
 .../org/apache/sis/io/wkt/FormattableObject.java   |   6 +-
 .../main/java/org/apache/sis/io/wkt/Formatter.java |   6 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   6 +-
 .../org/apache/sis/io/wkt/MathTransformParser.java |  23 +-
 .../main/java/org/apache/sis/io/wkt/Symbols.java   |  16 +-
 .../java/org/apache/sis/io/wkt/Transliterator.java |   6 +-
 .../sis/io/wkt/UnparsableObjectException.java      |   2 +-
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java |  49 +-
 .../java/org/apache/sis/io/wkt/package-info.java   |   8 +-
 .../sis/parameter/DefaultParameterDescriptor.java  |   4 +-
 .../parameter/DefaultParameterDescriptorGroup.java |   6 +-
 .../sis/parameter/DefaultParameterValue.java       |  18 +-
 .../sis/parameter/DefaultParameterValueGroup.java  |   8 +-
 .../sis/parameter/MapProjectionParameters.java     |   8 +-
 .../org/apache/sis/parameter/ParameterBuilder.java |   8 +-
 .../org/apache/sis/parameter/Parameterized.java    |   4 +-
 .../java/org/apache/sis/parameter/Parameters.java  |  14 +-
 .../org/apache/sis/parameter/TensorParameters.java |  16 +-
 .../sis/parameter/UninitializedParameter.java      |   4 +-
 .../sis/parameter/UnmodifiableParameterValue.java  |   2 +-
 .../org/apache/sis/parameter/package-info.java     |   6 +-
 .../sis/referencing/AbstractIdentifiedObject.java  |  90 ++-
 .../sis/referencing/AbstractReferenceSystem.java   |   4 +-
 .../java/org/apache/sis/referencing/Builder.java   |  67 +-
 .../main/java/org/apache/sis/referencing/CRS.java  | 102 +--
 .../java/org/apache/sis/referencing/CommonCRS.java |  41 +-
 .../sis/referencing/GeodesicsOnEllipsoid.java      | 337 +++++----
 .../apache/sis/referencing/GeodeticCalculator.java | 368 +++++++---
 ...odesicException.java => GeodeticException.java} |  44 +-
 .../apache/sis/referencing/IdentifiedObjects.java  | 228 +++---
 .../iso => referencing}/ImmutableIdentifier.java   |  46 +-
 .../apache/sis/referencing/NamedIdentifier.java    |   9 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |   4 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  24 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |   8 +-
 .../sis/referencing/crs/DefaultEngineeringCRS.java |   6 +-
 .../sis/referencing/crs/DefaultGeocentricCRS.java  |   8 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |  12 +-
 .../sis/referencing/crs/DefaultImageCRS.java       |   6 +-
 .../sis/referencing/crs/DefaultParametricCRS.java  |   6 +-
 .../sis/referencing/crs/DefaultProjectedCRS.java   |   6 +-
 .../sis/referencing/crs/DefaultTemporalCRS.java    |   6 +-
 .../sis/referencing/crs/DefaultVerticalCRS.java    |   6 +-
 .../sis/referencing/crs/SC_GeographicCRS.java      |   2 +-
 .../apache/sis/referencing/crs/package-info.java   |   2 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  |   8 +-
 .../apache/sis/referencing/cs/AxesConvention.java  |  15 +-
 .../org/apache/sis/referencing/cs/AxisFilter.java  |   6 +-
 .../sis/referencing/cs/CoordinateSystems.java      |  12 +-
 .../apache/sis/referencing/cs/DefaultAffineCS.java |   2 +-
 .../sis/referencing/cs/DefaultCartesianCS.java     |   6 +-
 .../sis/referencing/cs/DefaultCompoundCS.java      |   2 +-
 .../cs/DefaultCoordinateSystemAxis.java            |  14 +-
 .../sis/referencing/cs/DefaultCylindricalCS.java   |   6 +-
 .../sis/referencing/cs/DefaultEllipsoidalCS.java   |   6 +-
 .../apache/sis/referencing/cs/DefaultLinearCS.java |   6 +-
 .../sis/referencing/cs/DefaultParametricCS.java    |   6 +-
 .../apache/sis/referencing/cs/DefaultPolarCS.java  |   6 +-
 .../sis/referencing/cs/DefaultSphericalCS.java     |   6 +-
 .../apache/sis/referencing/cs/DefaultTimeCS.java   |   6 +-
 .../sis/referencing/cs/DefaultUserDefinedCS.java   |   6 +-
 .../sis/referencing/cs/DefaultVerticalCS.java      |   6 +-
 .../sis/referencing/cs/DirectionAlongMeridian.java |   4 +-
 .../sis/referencing/datum/AbstractDatum.java       |   6 +-
 .../sis/referencing/datum/BursaWolfParameters.java |  29 +-
 .../sis/referencing/datum/DatumShiftGrid.java      |  16 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    | 127 +---
 .../referencing/datum/DefaultEngineeringDatum.java |   6 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |  18 +-
 .../sis/referencing/datum/DefaultImageDatum.java   |   6 +-
 .../referencing/datum/DefaultParametricDatum.java  |   8 +-
 .../referencing/datum/DefaultPrimeMeridian.java    |  12 +-
 .../referencing/datum/DefaultTemporalDatum.java    |   8 +-
 .../referencing/datum/DefaultVerticalDatum.java    |   8 +-
 .../org/apache/sis/referencing/datum/Sphere.java   |  30 +-
 .../sis/referencing/datum/TimeDependentBWP.java    |   2 +-
 .../apache/sis/referencing/datum/package-info.java |   5 +-
 .../factory/CommonAuthorityFactory.java            |   4 +-
 .../factory/ConcurrentAuthorityFactory.java        |  10 +-
 .../factory/GeodeticAuthorityFactory.java          | 145 ++--
 .../referencing/factory/GeodeticObjectFactory.java |   6 +-
 .../factory/IdentifiedObjectFinder.java            |   4 +-
 .../referencing/factory/IdentifiedObjectSet.java   |   8 +-
 .../factory/MissingFactoryResourceException.java   |   2 +-
 .../factory/MultiAuthoritiesFactory.java           |  12 +-
 .../factory/UnavailableFactoryException.java       |   2 +-
 .../referencing/factory/sql/EPSGCodeFinder.java    |   2 +-
 .../referencing/factory/sql/EPSGDataAccess.java    |  75 +-
 .../sis/referencing/factory/sql/EPSGFactory.java   |   4 +-
 .../factory/sql/InstallationScriptProvider.java    |  10 +-
 .../sis/referencing/factory/sql/SQLTranslator.java |   2 +-
 .../sis/referencing/factory/sql/package-info.java  |   8 +-
 .../operation/AbstractCoordinateOperation.java     |  12 +-
 .../apache/sis/referencing/operation/CRSPair.java  |   2 +-
 .../operation/CoordinateOperationFinder.java       |   6 +-
 .../operation/CoordinateOperationRegistry.java     |   2 +-
 .../operation/DefaultConcatenatedOperation.java    |   6 +-
 .../referencing/operation/DefaultConversion.java   |   8 +-
 .../operation/DefaultOperationMethod.java          |  10 +-
 .../operation/DefaultPassThroughOperation.java     |   4 +-
 .../operation/DefaultTransformation.java           |   6 +-
 .../operation/InverseOperationMethod.java          |   2 +-
 .../operation/builder/LinearTransformBuilder.java  |   2 +-
 .../operation/builder/LocalizationGridBuilder.java |   2 +-
 .../operation/builder/ResidualGrid.java            |   2 +-
 .../operation/matrix/GeneralMatrix.java            |   2 +-
 .../sis/referencing/operation/matrix/Matrices.java |  15 +-
 .../sis/referencing/operation/matrix/Matrix1.java  |  15 +-
 .../sis/referencing/operation/matrix/Matrix2.java  |  15 +-
 .../sis/referencing/operation/matrix/Matrix3.java  |  13 +-
 .../sis/referencing/operation/matrix/Matrix4.java  |  13 +-
 .../referencing/operation/matrix/MatrixSIS.java    |   9 +-
 .../sis/referencing/operation/matrix/Solver.java   |   4 +-
 .../referencing/operation/matrix/package-info.java |  10 +-
 .../sis/referencing/operation/package-info.java    |   6 +-
 .../operation/projection/AlbersEqualArea.java      |   7 +-
 .../operation/projection/ConformalProjection.java  |   6 +-
 .../operation/projection/CylindricalEqualArea.java |   2 +-
 .../operation/projection/Initializer.java          |  16 +-
 .../referencing/operation/projection/Inverter.java | 105 +++
 .../projection/LambertConicConformal.java          |   9 +-
 .../referencing/operation/projection/Mercator.java |  10 +-
 .../operation/projection/Mollweide.java            |   8 +-
 .../operation/projection/NormalizedProjection.java |  36 +-
 .../operation/projection/ObliqueMercator.java      |   6 +-
 .../operation/projection/ObliqueStereographic.java |   9 +-
 .../operation/projection/Orthographic.java         | 261 +++++++
 .../operation/projection/Polyconic.java            |   2 +-
 .../operation/projection/ProjectionException.java  |   2 +-
 .../operation/projection/SatelliteTracking.java    | 377 ++++++++++
 .../operation/projection/Sinusoidal.java           |   7 +-
 .../operation/projection/TransverseMercator.java   |   2 +-
 .../operation/projection/ZonedGridSystem.java      |   2 +-
 .../operation/projection/package-info.java         |  26 +-
 .../transform/AbstractLinearTransform.java         |   6 +-
 .../operation/transform/AbstractMathTransform.java |  12 +-
 .../transform/AbstractMathTransform1D.java         |   6 +-
 .../transform/AbstractMathTransform2D.java         |   6 +-
 .../operation/transform/ConcatenatedTransform.java |   7 +-
 .../operation/transform/ContextualParameter.java   |   2 +-
 .../operation/transform/ContextualParameters.java  |  34 +-
 .../transform/CoordinateSystemTransform.java       |   2 +-
 .../operation/transform/DatumShiftTransform.java   |  35 +-
 .../transform/DefaultMathTransformFactory.java     |  12 +-
 .../transform/EllipsoidToCentricTransform.java     |   4 +-
 .../transform/ExponentialTransform1D.java          |   2 +-
 .../transform/InterpolatedGeocentricTransform.java |   4 +-
 .../transform/InterpolatedMolodenskyTransform.java |   2 +-
 .../operation/transform/InterpolatedTransform.java |  10 +-
 .../operation/transform/IterationStrategy.java     |  17 +-
 .../operation/transform/LinearInterpolator1D.java  |   2 +-
 .../operation/transform/LinearTransform.java       |  12 +-
 .../transform/LogarithmicTransform1D.java          |   2 +-
 .../operation/transform/MathTransformProvider.java |   4 +-
 .../operation/transform/MathTransforms.java        |   2 +-
 .../operation/transform/MolodenskyFormula.java     |   2 +-
 .../operation/transform/MolodenskyTransform.java   |   2 +-
 .../operation/transform/OperationMethodSet.java    |   4 +-
 .../operation/transform/PassThroughTransform.java  |  17 +-
 .../operation/transform/PowerTransform1D.java      |   2 +-
 .../transform/SpecializableTransform.java          |   2 +-
 .../operation/transform/TransferFunction.java      |   4 +-
 .../referencing/operation/transform/formulas.html  |  12 +-
 .../operation/transform/package-info.java          |   4 +-
 .../org/apache/sis/referencing/package-info.java   |   8 +-
 ...g.opengis.referencing.operation.OperationMethod |   2 +
 .../referencing/provider/Descriptions.properties   |   5 +
 .../apache/sis/distance/LatLonPointRadiusTest.java |  89 ---
 .../apache/sis/geometry/CoordinateFormatTest.java  |   2 +-
 .../sis/internal/jaxb/referencing/CodeTest.java    |   2 +-
 .../internal/referencing/provider/NTv2Test.java    |   2 +-
 .../provider/ParameterNameTableGenerator.java      | 325 +++++++++
 .../referencing/provider/ProvidersTest.java        |  16 +-
 .../apache/sis/io/wkt/MathTransformParserTest.java |  21 +-
 .../parameter/DefaultParameterDescriptorTest.java  |   2 +-
 .../sis/parameter/DefaultParameterValueTest.java   |   2 +-
 .../sis/parameter/ParameterValueGroupWrapper.java  |   3 +-
 .../referencing/AbstractIdentifiedObjectTest.java  |   1 -
 .../referencing/AbstractReferenceSystemTest.java   |   1 -
 .../org/apache/sis/referencing/BuilderTest.java    |   1 -
 .../java/org/apache/sis/referencing/CRSTest.java   |  16 +-
 .../apache/sis/referencing/ClenshawSummation.java  | 460 ++++++++++++
 .../org/apache/sis/referencing/CommonCRSTest.java  |  14 +-
 .../sis/referencing/GeodesicsOnEllipsoidTest.java  |  97 ++-
 .../sis/referencing/GeodeticCalculatorTest.java    | 105 +--
 .../ImmutableIdentifierTest.java                   |   2 +-
 .../referencing/crs/DefaultGeocentricCRSTest.java  |   2 +-
 .../apache/sis/referencing/cs/NormalizerTest.java  |   2 +-
 .../referencing/datum/DefaultEllipsoidTest.java    |  85 +--
 .../datum/DefaultTemporalDatumTest.java            |   2 +-
 .../referencing/factory/sql/EPSGInstallerTest.java |  13 +-
 .../factory/sql/epsg/DataScriptFormatter.java      |  10 +-
 .../epsg/{MethodDimensions.sql => DebugTools.sql}  |   8 +-
 .../sis/referencing/factory/sql/epsg/package.html  | 138 ++--
 .../operation/DefaultOperationMethodTest.java      |   2 +-
 .../operation/matrix/MatrixTestCase.java           |   2 +-
 .../referencing/operation/matrix/SolverTest.java   |   2 +-
 .../projection/LambertConicConformalTest.java      |   2 +-
 .../operation/projection/OrthographicTest.java     | 162 +++++
 .../projection/SatelliteTrackingTest.java          | 407 +++++++++++
 .../transform/DefaultMathTransformFactoryTest.java |   9 +-
 .../report/CoordinateReferenceSystems.java         | 487 +++++--------
 .../sis/referencing/report/package-info.java       |   2 +-
 .../sis/test/integration/ConsistencyTest.java      |   2 +-
 .../test/integration/CoordinateOperationTest.java  |  79 +-
 .../apache/sis/test/integration/MetadataTest.java  | 247 ++-----
 .../sis/test/integration/MetadataVerticalTest.java | 214 ++++++
 .../sis/test/suite/ReferencingTestSuite.java       |  10 +-
 .../org/apache/sis/test/widget/package-info.java   |   2 +-
 .../org/apache/sis/test/integration/Metadata.xml   |  63 +-
 .../sis/internal/converter/AngleConverter.java     |   4 +-
 .../sis/internal/converter/ArrayConverter.java     |   2 +-
 .../internal/converter/CharSequenceConverter.java  |   2 +-
 .../apache/sis/internal/converter/ClassPair.java   |   2 +-
 .../internal/converter/CollectionConverter.java    |   2 +-
 .../sis/internal/converter/ConverterRegistry.java  |  17 +-
 .../sis/internal/converter/DateConverter.java      |   6 +-
 .../sis/internal/converter/FallbackConverter.java  |   2 +-
 .../sis/internal/converter/IdentityConverter.java  |   2 +-
 .../sis/internal/converter/NumberConverter.java    |   4 +-
 .../sis/internal/converter/ObjectToString.java     |   2 +-
 .../sis/internal/converter/PathConverter.java      |   2 +-
 .../sis/internal/converter/StringConverter.java    |   6 +-
 .../sis/internal/converter/SystemConverter.java    |   7 +-
 .../sis/internal/converter/SystemRegistry.java     |   2 +-
 .../sis/internal/converter/package-info.java       |   2 +-
 .../java/org/apache/sis/internal/jdk9/JDK9.java    |  19 +-
 .../org/apache/sis/internal/jdk9/package-info.java |   2 +-
 .../apache/sis/internal/system/DaemonThread.java   |   4 +-
 .../sis/internal/system/DelayedExecutor.java       |   2 +-
 .../sis/internal/system/DelayedRunnable.java       |   8 +-
 .../org/apache/sis/internal/system/Modules.java    |  12 +-
 .../org/apache/sis/internal/system/Supervisor.java |   2 -
 .../org/apache/sis/internal/system/Threads.java    |   8 +-
 .../sis/internal/util/AutoMessageFormat.java       |   2 +-
 .../apache/sis/internal/util/CheckedArrayList.java |   2 +-
 .../apache/sis/internal/util/CollectionsExt.java   |  24 +-
 .../org/apache/sis/internal/util/Constants.java    |   2 +-
 .../apache/sis/internal/util/DefinitionURI.java    |   4 +-
 .../org/apache/sis/internal/util/DoubleDouble.java |  12 +-
 .../apache/sis/internal/util/MetadataServices.java |  25 +
 .../org/apache/sis/internal/util/Numerics.java     |   2 +-
 .../java/org/apache/sis/internal/util/Strings.java |  55 +-
 .../sis/internal/util/TemporalUtilities.java       |   2 -
 .../sis/internal/util/UnmodifiableArrayList.java   |   8 +-
 .../org/apache/sis/internal/util/package-info.java |   4 +-
 .../src/main/java/org/apache/sis/io/Appender.java  |   2 +-
 .../main/java/org/apache/sis/io/ClassFormat.java   |   4 +-
 .../java/org/apache/sis/io/CompoundFormat.java     |   6 +-
 .../main/java/org/apache/sis/io/DefaultFormat.java |   2 +-
 .../org/apache/sis/io/IdentifiedObjectFormat.java  |   2 +-
 .../main/java/org/apache/sis/io/LineAppender.java  |   2 +-
 .../main/java/org/apache/sis/io/TableAppender.java |   9 +-
 .../main/java/org/apache/sis/io/TabularFormat.java |   4 +-
 .../main/java/org/apache/sis/io/package-info.java  |   4 +-
 .../apache/sis/math/CompoundDirectPositions.java   |   2 +-
 .../java/org/apache/sis/math/DecimalFunctions.java |   6 +-
 .../java/org/apache/sis/math/MathFunctions.java    |   6 +-
 .../src/main/java/org/apache/sis/math/Plane.java   |   3 +-
 .../main/java/org/apache/sis/math/Statistics.java  |   5 +-
 .../src/main/java/org/apache/sis/math/Vector.java  |  10 +-
 .../org/apache/sis/measure/AbstractConverter.java  |   2 +-
 .../main/java/org/apache/sis/measure/Angle.java    |   6 +-
 .../java/org/apache/sis/measure/AngleFormat.java   |   1 +
 .../apache/sis/measure/ConcatenatedConverter.java  |   2 +-
 .../org/apache/sis/measure/ConventionalUnit.java   |   4 +-
 .../org/apache/sis/measure/ElevationAngle.java     |   2 +-
 .../sis/measure/FormattedCharacterIterator.java    |   4 +-
 .../org/apache/sis/measure/IdentityConverter.java  | 109 +++
 .../main/java/org/apache/sis/measure/Latitude.java |   2 +-
 .../org/apache/sis/measure/LinearConverter.java    |  49 +-
 .../java/org/apache/sis/measure/Longitude.java     |   2 +-
 .../org/apache/sis/measure/MeasurementRange.java   |   6 +-
 .../java/org/apache/sis/measure/NumberRange.java   |   8 +-
 .../main/java/org/apache/sis/measure/Range.java    |  12 +-
 .../java/org/apache/sis/measure/RangeFormat.java   |   4 +-
 .../apache/sis/measure/SexagesimalConverter.java   |   2 +-
 .../java/org/apache/sis/measure/SystemUnit.java    |   4 +-
 .../java/org/apache/sis/measure/UnitFormat.java    |  10 +-
 .../main/java/org/apache/sis/measure/Units.java    | 293 +++++---
 .../src/main/java/org/apache/sis/setup/About.java  |  21 +-
 .../java/org/apache/sis/setup/Configuration.java   | 142 ++++
 .../main/java/org/apache/sis/setup/OptionKey.java  |  10 +-
 .../java/org/apache/sis/util/ArgumentChecks.java   |  27 +-
 .../main/java/org/apache/sis/util/ArraysExt.java   |   6 +-
 .../java/org/apache/sis/util/CharSequences.java    |  29 +-
 .../main/java/org/apache/sis/util/Characters.java  |   2 +-
 .../src/main/java/org/apache/sis/util/Classes.java |   2 +-
 .../java/org/apache/sis/util/ComparisonMode.java   |  28 +-
 .../java/org/apache/sis/util/Configuration.java    |   8 +-
 .../apache/sis/util/CorruptedObjectException.java  |   2 +-
 .../main/java/org/apache/sis/util/Disposable.java  |   2 +-
 .../org/apache/sis/util/LenientComparable.java     |   9 +-
 .../java/org/apache/sis/util/ObjectConverter.java  |   2 +-
 .../java/org/apache/sis/util/StringBuilders.java   |  35 +-
 .../main/java/org/apache/sis/util/Utilities.java   |  14 +-
 .../src/main/java/org/apache/sis/util/Version.java |   6 +-
 .../sis/util/collection/BackingStoreException.java |  24 +-
 .../java/org/apache/sis/util/collection/Cache.java |   6 +-
 .../apache/sis/util/collection/CacheEntries.java   |   2 +-
 .../apache/sis/util/collection/CodeListSet.java    |   4 +-
 .../sis/util/collection/DefaultTreeTable.java      |   2 +-
 .../org/apache/sis/util/collection/DerivedMap.java |   4 +-
 .../org/apache/sis/util/collection/DerivedSet.java |   4 +-
 .../org/apache/sis/util/collection/RangeSet.java   |   6 +-
 .../apache/sis/util/collection/TableColumn.java    |   2 +-
 .../apache/sis/util/collection/TreeNodeList.java   |   2 +-
 .../org/apache/sis/util/collection/TreeTable.java  |   9 +-
 .../sis/util/collection/TreeTableFormat.java       |   8 +-
 .../org/apache/sis/util/collection/TreeTables.java |   2 +-
 .../org/apache/sis/util/collection/WeakEntry.java  |  13 +-
 .../apache/sis/util/collection/WeakHashSet.java    |  11 +-
 .../sis/util/collection/WeakValueHashMap.java      |   9 +-
 .../sis/util/iso/AbstractInternationalString.java  |  10 +-
 .../sis/util/iso/DefaultInternationalString.java   |   6 +-
 .../sis/util/iso/ResourceInternationalString.java  |  12 +-
 .../sis/util/iso/SimpleInternationalString.java    |   6 +-
 .../org/apache/sis/util/logging/LoggerAdapter.java |   8 +-
 .../org/apache/sis/util/logging/LoggerFactory.java |   2 +-
 .../java/org/apache/sis/util/logging/Logging.java  |  53 +-
 .../apache/sis/util/logging/MonolineFormatter.java |  11 +-
 .../apache/sis/util/logging/PerformanceLevel.java  |   2 +-
 .../apache/sis/util/logging/WarningListener.java   |  78 --
 .../apache/sis/util/logging/WarningListeners.java  | 382 ----------
 .../org/apache/sis/util/logging/package-info.java  |   6 +-
 .../java/org/apache/sis/util/resources/Errors.java |   2 +-
 .../sis/util/resources/IndexedResourceBundle.java  |  14 +-
 .../resources/ResourceInternationalString.java     |   2 +-
 .../org/apache/sis/util/resources/Vocabulary.java  | 369 +++++-----
 .../sis/util/resources/Vocabulary.properties       |   5 +-
 .../sis/util/resources/Vocabulary_fr.properties    |   5 +-
 .../apache/sis/util/resources/package-info.java    |   2 +-
 .../measure/FormattedCharacterIteratorTest.java    |   2 +-
 .../apache/sis/measure/LinearConverterTest.java    |  14 +-
 .../org/apache/sis/measure/QuantitiesTest.java     |  17 +
 .../org/apache/sis/test/ProjectDirectories.java    | 164 +++++
 .../test/java/org/apache/sis/test/TestCase.java    |   4 +
 .../org/apache/sis/test/TestConfiguration.java     |   9 +-
 .../test/java/org/apache/sis/test/TestSuite.java   |  35 +-
 .../java/org/apache/sis/test/package-info.java     |   4 +-
 .../apache/sis/test/suite/UtilityTestSuite.java    |   1 -
 .../sis/util/logging/EmptyWarningListeners.java    |  71 --
 .../sis/util/logging/WarningListenersTest.java     | 117 ---
 ide-project/NetBeans/build.xml                     |   1 +
 ide-project/NetBeans/nbproject/build-impl.xml      |  52 +-
 ide-project/NetBeans/nbproject/genfiles.properties |   6 +-
 ide-project/NetBeans/nbproject/project.properties  |  71 +-
 ide-project/NetBeans/nbproject/project.xml         |   5 +-
 pom.xml                                            |  84 ++-
 profiles/sis-french-profile/pom.xml                |   5 +
 .../apache/sis/profile/france/package-info.java    |   2 +-
 .../apache/sis/internal/earth/netcdf/GCOM_C.java   |   2 +-
 .../sis/internal/earth/netcdf/package-info.java    |   2 +-
 .../apache/sis/profile/japan/JapaneseProfile.java  |  25 +-
 src/main/config/logging.properties                 |   2 +-
 src/main/javadoc/overview.html                     |   4 +-
 src/main/javadoc/sis.css                           |  58 +-
 .../storage/earthobservation/LandsatReader.java    |  15 +-
 .../sis/storage/earthobservation/LandsatStore.java |  57 +-
 .../earthobservation/LandsatStoreProvider.java     |   2 +-
 .../earthobservation/LandsatReaderTest.java        |   7 +-
 .../sis/storage/earthobservation/LandsatTest.txt   |   2 +-
 .../org/apache/sis/storage/gdal/Proj4Factory.java  |   6 +-
 .../org/apache/sis/storage/gdal/package-info.java  |   4 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |  52 +-
 .../sis/storage/geotiff/GeoTiffStoreProvider.java  |   2 +-
 .../sis/storage/geotiff/GridGeometryBuilder.java   |   2 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    |   8 +-
 .../org/apache/sis/internal/netcdf/Convention.java |  40 +-
 .../org/apache/sis/internal/netcdf/Decoder.java    |   7 +-
 .../sis/internal/netcdf/DiscreteSampling.java      |   7 +-
 .../apache/sis/internal/netcdf/NamedElement.java   |   4 +-
 .../java/org/apache/sis/internal/netcdf/Node.java  |   7 +-
 .../apache/sis/internal/netcdf/RasterResource.java |  79 +-
 .../org/apache/sis/internal/netcdf/Variable.java   |  14 +-
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |  13 +-
 .../sis/internal/netcdf/impl/FeaturesInfo.java     |  10 +-
 .../sis/internal/netcdf/impl/VariableInfo.java     |  10 +-
 .../apache/sis/internal/netcdf/package-info.java   |   2 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |  15 +-
 .../sis/internal/netcdf/ucar/FeaturesWrapper.java  |   5 +-
 .../sis/internal/netcdf/ucar/LogAdapter.java       |  11 +-
 .../sis/internal/netcdf/ucar/VariableWrapper.java  |   4 +-
 .../apache/sis/storage/netcdf/AttributeNames.java  |   3 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  |  34 +-
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |  40 +-
 .../sis/storage/netcdf/NetcdfStoreProvider.java    |  22 +-
 .../apache/sis/storage/netcdf/package-info.java    |   2 +-
 .../org/apache/sis/internal/netcdf/TestCase.java   |  11 +-
 .../internal/netcdf/impl/ChannelDecoderTest.java   |   3 +-
 .../storage/netcdf/NetcdfStoreProviderTest.java    |   9 +-
 .../apache/sis/internal/shapefile/AutoChecker.java |   4 +-
 .../internal/shapefile/ShapefileByteReader.java    |  64 +-
 .../internal/shapefile/ShapefileDescriptor.java    |   6 +-
 .../sis/storage/shapefile/InputFeatureStream.java  |   2 +-
 .../jdbc/AbstractTestBaseForInternalJDBC.java      |   2 +-
 .../sis/storage/shapefile/ShapeFileTest.java       |   4 +-
 .../apache/sis/internal/sql/feature/Analyzer.java  |   7 +-
 .../apache/sis/internal/sql/feature/Database.java  |   5 +-
 .../sis/internal/sql/feature/DialectMapping.java   |   7 +-
 .../apache/sis/internal/sql/feature/Features.java  |   6 +-
 .../sis/internal/sql/feature/OGC06104r4.java       |   9 +-
 .../sis/internal/sql/feature/PostGISMapping.java   |  12 +-
 .../sis/internal/sql/feature/QueryFeatureSet.java  |   4 +-
 .../sis/internal/sql/feature/SpatialFunctions.java |   8 +-
 .../sis/internal/sql/feature/TableReference.java   |  11 +-
 .../sis/internal/sql/feature/TableSubset.java      |  12 +-
 .../java/org/apache/sis/storage/sql/SQLStore.java  |  41 +-
 .../apache/sis/storage/sql/SQLStoreProvider.java   |  11 +-
 .../org/apache/sis/storage/sql/package-info.java   |   2 +-
 storage/sis-storage/pom.xml                        |   5 +
 .../apache/sis/index/tree}/LatLonPointRadius.java  |  94 +--
 .../java/org/apache/sis/index/tree/QuadTree.java   |   8 +-
 .../org/apache/sis/index/tree/QuadTreeWriter.java  |   1 +
 .../sis/internal/storage/AbstractFeatureSet.java   |  22 +-
 .../sis/internal/storage/AbstractGridResource.java |  43 +-
 .../sis/internal/storage/AbstractResource.java     |  95 +--
 .../sis/internal/storage/AggregatedFeatureSet.java |  32 +-
 .../apache/sis/internal/storage/Capability.java    |  10 +-
 .../internal/storage/ConcatenatedFeatureSet.java   |  23 +-
 .../internal/storage/DocumentedStoreProvider.java  |   7 +-
 .../sis/internal/storage/JoinFeatureSet.java       |  11 +-
 .../sis/internal/storage/MemoryFeatureSet.java     |  11 +-
 .../sis/internal/storage/MetadataBuilder.java      |  30 +-
 .../sis/internal/storage/ResourceOnFileSystem.java |   2 +-
 .../org/apache/sis/internal/storage/Resources.java |  20 +
 .../sis/internal/storage/Resources.properties      |   4 +
 .../sis/internal/storage/Resources_fr.properties   |   4 +
 .../apache/sis/internal/storage/StoreMetadata.java |  15 +-
 .../apache/sis/internal/storage/URIDataStore.java  |  38 +-
 .../org/apache/sis/internal/storage/csv/Store.java |   6 +-
 .../sis/internal/storage/csv/StoreProvider.java    |  12 +-
 .../sis/internal/storage/csv/package-info.java     |   2 +-
 .../storage/folder/FolderStoreProvider.java        |   9 +-
 .../apache/sis/internal/storage/folder/Store.java  |  36 +-
 .../sis/internal/storage/io/ChannelData.java       |   2 +-
 .../sis/internal/storage/io/ChannelDataInput.java  |   4 +-
 .../sis/internal/storage/io/ChannelDataOutput.java |   4 +-
 .../sis/internal/storage/io/ChannelFactory.java    |  43 +-
 .../storage/io/ChannelImageInputStream.java        |   2 +-
 .../internal/storage/io/HyperRectangleReader.java  |  13 +-
 .../sis/internal/storage/io/IOUtilities.java       |   2 +-
 .../internal/storage/io/InputStreamAdapter.java    |   2 +-
 .../org/apache/sis/internal/storage/io/Region.java |  78 +-
 .../sis/internal/storage/io/package-info.java      |   2 +-
 .../apache/sis/internal/storage/package-info.java  |   2 +-
 .../sis/internal/storage/query/CoverageQuery.java  | 259 +++++++
 .../sis/internal/storage/query/CoverageSubset.java | 181 +++++
 .../sis/internal/storage/query/FeatureSubset.java  |  24 +-
 .../sis/internal/storage/query/SimpleQuery.java    | 156 ++--
 .../internal/storage/query/SortByComparator.java   |   4 +-
 .../sis/internal/storage/query/package-info.java   |   2 +-
 .../org/apache/sis/internal/storage/wkt/Store.java |   2 +-
 .../sis/internal/storage/wkt/StoreFormat.java      |  16 +-
 .../sis/internal/storage/xml/MimeTypeDetector.java |   2 +-
 .../org/apache/sis/internal/storage/xml/Store.java |  39 +-
 .../java/org/apache/sis/storage/Aggregate.java     |   4 +-
 .../main/java/org/apache/sis/storage/DataSet.java  |   2 +-
 .../java/org/apache/sis/storage/DataStore.java     | 135 ++--
 .../org/apache/sis/storage/DataStoreException.java |   4 +-
 .../org/apache/sis/storage/DataStoreProvider.java  |  59 +-
 .../org/apache/sis/storage/DataStoreRegistry.java  |   6 +-
 .../java/org/apache/sis/storage/DataStores.java    |   2 +-
 .../java/org/apache/sis/storage/FeatureNaming.java |   4 +-
 .../apache/sis/storage/GridCoverageResource.java   |  38 +-
 .../apache/sis/storage/IllegalNameException.java   |   2 +-
 ...NameException.java => NoSuchDataException.java} |  44 +-
 .../java/org/apache/sis/storage/ProbeResult.java   |   6 +-
 .../main/java/org/apache/sis/storage/Query.java    |   4 +-
 .../main/java/org/apache/sis/storage/Resource.java |  62 +-
 .../org/apache/sis/storage/StorageConnector.java   |  13 +-
 .../org/apache/sis/storage/WritableAggregate.java  |   2 +-
 .../sis/storage/WritableGridCoverageResource.java  |   4 +-
 .../org/apache/sis/storage/event/ChangeEvent.java  |  60 --
 .../apache/sis/storage/event/ChangeListener.java   |  54 --
 .../apache/sis/storage/event}/QuietLogRecord.java  |  14 +-
 .../org/apache/sis/storage/event/StoreEvent.java   |  91 +++
 .../apache/sis/storage/event/StoreListener.java    |  56 ++
 .../apache/sis/storage/event/StoreListeners.java   | 613 ++++++++++++++++
 .../org/apache/sis/storage/event/WarningEvent.java |  90 +++
 .../org/apache/sis/storage/event/package-info.java |  20 +-
 .../java/org/apache/sis/storage/package-info.java  |   2 +-
 .../internal/storage/AbstractGridResourceTest.java |   3 -
 .../java/org/apache/sis/storage/DataStoreMock.java |  45 +-
 .../sis/storage/event/StoreListenersTest.java      | 109 +++
 .../apache/sis/test/suite/StorageTestSuite.java    |   1 +
 storage/sis-xmlstore/pom.xml                       |   5 +
 .../storage/gpx/GroupAsPolylineOperation.java      |   3 +
 .../sis/internal/storage/gpx/StoreProvider.java    |  10 +-
 .../internal/storage/xml/stream/StaxDataStore.java |  31 +-
 .../internal/storage/xml/stream/StaxStreamIO.java  |   2 +-
 .../storage/xml/stream/StaxStreamReader.java       |  12 +-
 .../storage/xml/stream/StaxStreamWriter.java       |   4 +-
 1001 files changed, 27996 insertions(+), 9785 deletions(-)
 create mode 100644 application/sis-javafx/doc/readme.txt
 rename application/sis-javafx/src/main/java/org/apache/sis/gui/{Main.java => DataViewer.java} (71%)
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ExpandableList.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ExpandedFeature.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureList.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureLoader.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
 copy {storage/sis-storage/src/main/java/org/apache/sis/internal/storage => application/sis-javafx/src/main/java/org/apache/sis/gui/dataset}/package-info.java (68%)
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataNode.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataOverview.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/RepresentationInfo.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/ResourceView.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/Section.java
 copy {storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query => application/sis-javafx/src/main/java/org/apache/sis/gui/metadata}/package-info.java (74%)
 copy {storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query => application/sis-javafx/src/main/java/org/apache/sis/gui}/package-info.java (74%)
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/AuthorityCodes.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/CRSButton.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/CRSTable.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/CodeFilter.java
 copy {storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query => application/sis-javafx/src/main/java/org/apache/sis/gui/referencing}/package-info.java (74%)
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/BackgroundThreads.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ExceptionReporter.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/FXUtilities.java
 delete mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/FontGlyphs.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/IdentityValueFactory.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/RecentChoices.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ResourceLoader.java
 create mode 100644 application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Styles.java
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/CRSChooser.fxml
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/proj_conic.png
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/proj_geo.png
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/proj_square.png
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/proj_stereo.png
 delete mode 100644 application/sis-javafx/src/main/resources/org/apache/sis/gui/referencing/proj_utm.png
 copy {storage/sis-xmlstore => core/sis-cql}/pom.xml (73%)
 create mode 100644 core/sis-cql/src/main/antlr4/org/apache/sis/internal/cql/CQL.g4
 create mode 100644 core/sis-cql/src/main/java/org/apache/sis/cql/CQL.java
 copy storage/sis-storage/src/main/java/org/apache/sis/storage/event/package-info.java => core/sis-cql/src/main/java/org/apache/sis/cql/CQLException.java (53%)
 create mode 100644 core/sis-cql/src/main/java/org/apache/sis/cql/FilterToCQLVisitor.java
 create mode 100644 core/sis-cql/src/main/java/org/apache/sis/internal/cql/AntlrCQL.java
 create mode 100644 core/sis-cql/src/test/java/org/apache/sis/cql/CQLTestCase.java
 copy storage/sis-storage/src/main/java/org/apache/sis/storage/event/package-info.java => core/sis-cql/src/test/java/org/apache/sis/cql/CQLTestSuite.java (53%)
 create mode 100644 core/sis-cql/src/test/java/org/apache/sis/cql/ExpressionReadingTest.java
 create mode 100644 core/sis-cql/src/test/java/org/apache/sis/cql/ExpressionWritingTest.java
 create mode 100644 core/sis-cql/src/test/java/org/apache/sis/cql/FilterReadingTest.java
 create mode 100644 core/sis-cql/src/test/java/org/apache/sis/cql/FilterWritingTest.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/coverage/IllegalSampleDimensionException.java
 delete mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/AbstractFunction.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/Capabilities.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/DefaultLike.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/InvalidExpressionException.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/NamedFunction.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/ST_Buffer.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/ST_Centroid.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/ST_Simplify.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/ST_SimplifyPreserveTopology.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/filter/TemporalFunction.java
 create mode 100644 core/sis-feature/src/main/java/org/apache/sis/internal/coverage/GridCoverage2D.java
 delete mode 100644 core/sis-feature/src/main/resources/META-INF/services/org.apache.sis.internal.feature.FunctionRegister
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/coverage/SampleRangeFormatTest.java
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/filter/BetweenFunctionTest.java
 copy core/{sis-utility/src/main/java/org/apache/sis/util/Configuration.java => sis-feature/src/test/java/org/apache/sis/filter/CapabilitiesTest.java} (57%)
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/filter/ComparisonFunctionTest.java
 copy storage/sis-storage/src/main/java/org/apache/sis/storage/event/package-info.java => core/sis-feature/src/test/java/org/apache/sis/filter/LikeFunctionTest.java (54%)
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/filter/PeriodLiteral.java
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/filter/SpatialFunctionTest.java
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/filter/TemporalFunctionTest.java
 create mode 100644 core/sis-feature/src/test/java/org/apache/sis/internal/coverage/GridCoverage2DTest.java
 delete mode 100644 core/sis-metadata/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper.java
 delete mode 100644 core/sis-metadata/src/main/java/org/apache/sis/xml/OGCNamespacePrefixMapper_Endorsed.java
 delete mode 100644 core/sis-metadata/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java
 delete mode 100644 core/sis-referencing/src/main/java/org/apache/sis/distance/DistanceUtils.java
 create mode 100644 core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Orthographic.java
 create mode 100644 core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/SatelliteTracking.java
 rename core/sis-referencing/src/main/java/org/apache/sis/referencing/{operation/GeodesicException.java => GeodeticException.java} (53%)
 rename core/sis-referencing/src/main/java/org/apache/sis/{metadata/iso => referencing}/ImmutableIdentifier.java (93%)
 create mode 100644 core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Inverter.java
 create mode 100644 core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Orthographic.java
 create mode 100644 core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/SatelliteTracking.java
 create mode 100644 core/sis-referencing/src/main/resources/org/apache/sis/internal/referencing/provider/Descriptions.properties
 delete mode 100644 core/sis-referencing/src/test/java/org/apache/sis/distance/LatLonPointRadiusTest.java
 create mode 100644 core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ParameterNameTableGenerator.java
 create mode 100644 core/sis-referencing/src/test/java/org/apache/sis/referencing/ClenshawSummation.java
 rename core/sis-referencing/src/test/java/org/apache/sis/{metadata/iso => referencing}/ImmutableIdentifierTest.java (99%)
 rename core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/epsg/{MethodDimensions.sql => DebugTools.sql} (90%)
 create mode 100644 core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/OrthographicTest.java
 create mode 100644 core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/SatelliteTrackingTest.java
 create mode 100644 core/sis-referencing/src/test/java/org/apache/sis/test/integration/MetadataVerticalTest.java
 create mode 100644 core/sis-utility/src/main/java/org/apache/sis/measure/IdentityConverter.java
 create mode 100644 core/sis-utility/src/main/java/org/apache/sis/setup/Configuration.java
 delete mode 100644 core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListener.java
 delete mode 100644 core/sis-utility/src/main/java/org/apache/sis/util/logging/WarningListeners.java
 create mode 100644 core/sis-utility/src/test/java/org/apache/sis/test/ProjectDirectories.java
 delete mode 100644 core/sis-utility/src/test/java/org/apache/sis/util/logging/EmptyWarningListeners.java
 delete mode 100644 core/sis-utility/src/test/java/org/apache/sis/util/logging/WarningListenersTest.java
 copy storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/package-info.java => profiles/sis-japan-profile/src/main/java/org/apache/sis/profile/japan/JapaneseProfile.java (58%)
 rename {core/sis-referencing/src/main/java/org/apache/sis/distance => storage/sis-storage/src/main/java/org/apache/sis/index/tree}/LatLonPointRadius.java (59%)
 create mode 100644 storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/CoverageQuery.java
 create mode 100644 storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/CoverageSubset.java
 copy storage/sis-storage/src/main/java/org/apache/sis/storage/{IllegalNameException.java => NoSuchDataException.java} (53%)
 delete mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/event/ChangeEvent.java
 delete mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/event/ChangeListener.java
 rename {core/sis-utility/src/main/java/org/apache/sis/util/logging => storage/sis-storage/src/main/java/org/apache/sis/storage/event}/QuietLogRecord.java (84%)
 create mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreEvent.java
 create mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListener.java
 create mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
 create mode 100644 storage/sis-storage/src/main/java/org/apache/sis/storage/event/WarningEvent.java
 create mode 100644 storage/sis-storage/src/test/java/org/apache/sis/storage/event/StoreListenersTest.java


[sis] 02/04: fix(*): fix merge

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

amanin pushed a commit to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git

commit c49061857c3d9dedb839ed47ada4535e0eb7528a
Author: Alexis Manin <am...@apache.org>
AuthorDate: Thu Nov 14 17:15:38 2019 +0100

    fix(*): fix merge
---
 .../java/org/apache/sis/filter/DefaultBBOX.java    | 75 ++++++++++++++++++----
 .../apache/sis/filter/DefaultFilterFactory.java    |  2 +-
 .../java/org/apache/sis/filter/ST_Envelope.java    | 17 +++--
 .../java/org/apache/sis/filter/ST_Intersects.java  | 37 +++++++++--
 .../test/java/org/apache/sis/filter/SQLMMTest.java | 13 +---
 .../org/apache/sis/filter/SpatialFunctionTest.java | 24 ++++---
 .../sis/internal/sql/feature/DialectMapping.java   |  7 +-
 .../sis/internal/sql/feature/OGC06104r4.java       |  9 +--
 .../sis/internal/sql/feature/PostGISMapping.java   | 12 ++--
 .../sis/internal/sql/feature/QueryFeatureSet.java  |  4 +-
 .../sis/internal/sql/feature/SpatialFunctions.java |  8 +--
 .../sis/internal/sql/feature/TableSubset.java      | 12 ++--
 .../sis/internal/storage/query/SimpleQuery.java    | 19 +++---
 13 files changed, 168 insertions(+), 71 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java
index 688e39d..450d563 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java
@@ -16,6 +16,9 @@
  */
 package org.apache.sis.filter;
 
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Objects;
 import java.util.function.Predicate;
 
 import org.opengis.feature.AttributeType;
@@ -27,13 +30,17 @@ import org.opengis.filter.expression.Literal;
 import org.opengis.filter.spatial.BBOX;
 import org.opengis.geometry.Envelope;
 import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.TransformException;
 
 import org.apache.sis.feature.Features;
 import org.apache.sis.geometry.AbstractEnvelope;
+import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.geometry.ImmutableEnvelope;
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.util.NullArgumentException;
+import org.apache.sis.util.collection.BackingStoreException;
 
 /**
  * @implNote AMBIGUITY : Description of BBOX operator from <a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html#60">
@@ -48,14 +55,25 @@ import org.apache.sis.util.NullArgumentException;
  *
  *     TODO: CRS check.
  */
-final class DefaultBBOX implements BBOX {
+final class DefaultBBOX implements BBOX, Serializable {
+
+    private static final long serialVersionUID = 3068335120981348484L;
 
     final Expression left;
     final Expression right;
 
-    private final Predicate intersects;
+    private transient Predicate intersects;
 
     DefaultBBOX(Expression left, Expression right) {
+        this.left = left;
+        this.right = right;
+        init();
+    }
+
+    /**
+     * Initialize this filter state. It is necessary because of serialization compliance.
+     */
+    private void init() {
         if (left == null && right == null) {
             throw new NullArgumentException(
                     "Both arguments are null, but at least one must be given " +
@@ -63,9 +81,6 @@ final class DefaultBBOX implements BBOX {
             );
         }
 
-        this.left = left;
-        this.right = right;
-
         if (left instanceof Literal) {
             intersects = asOptimizedTest((Literal) left, right);
         } else if (right instanceof Literal) {
@@ -106,13 +121,13 @@ final class DefaultBBOX implements BBOX {
          * operand is null. It does not state what to do if both are null, but we'll follow the same behavior.
          */
         if (leftEval == null || rightEval == null) return false;
-        return GeneralEnvelope.castOrCopy(leftEval).intersects(rightEval);
+        return intersect(AbstractEnvelope.castOrCopy(leftEval), rightEval);
     }
 
     private static boolean intersect(final Object candidate, final Expression valueExtractor, final AbstractEnvelope constEnvelope) {
         final Envelope candidateEnv = asEnvelope(valueExtractor, candidate);
         if (candidateEnv == null) return false;
-        return constEnvelope.intersects(candidateEnv, true);
+        return intersect(constEnvelope, candidateEnv);
     }
 
     /**
@@ -126,7 +141,7 @@ final class DefaultBBOX implements BBOX {
      */
     private static boolean multiIntersect(Object candidate, Envelope fixed) {
         // TODO: We could optimize by caching feature-type properties. The best way would be an initialisation
-        // procedure freezing target data type, but I'm no sure such a mechanism would be possible.
+        // procedure freezing target data type, but I'm not sure such a mechanism would be possible.
         final GeneralEnvelope constEnv = GeneralEnvelope.castOrCopy(fixed);
         if (candidate instanceof Feature) {
             final Feature f = (Feature) candidate;
@@ -147,15 +162,15 @@ final class DefaultBBOX implements BBOX {
                     .map(p -> p.getName().toString())
                     .map(f::getPropertyValue)
                     .map(Geometries::getEnvelope)
-                    .allMatch(fEnv -> fEnv != null && constEnv.intersects(fEnv, true));
+                    .allMatch(fEnv -> fEnv != null && intersect(constEnv, fEnv));
         } else if (candidate instanceof Envelope) {
-            return constEnv.intersects((Envelope) candidate);
+            return intersect(constEnv, (Envelope) candidate);
         } else {
             final Envelope env = Geometries.getEnvelope(candidate);
             if (env == null) throw new UnsupportedOperationException(
                     "Candidate type unsupported: "+candidate == null ? "null" : candidate.getClass().getCanonicalName()
             );
-            return constEnv.intersects(env);
+            return intersect(constEnv, env);
         }
     }
 
@@ -180,6 +195,44 @@ final class DefaultBBOX implements BBOX {
         return other == null ? it -> multiIntersect(it, constEnv) : it -> intersect(it, other, constEnv);
     }
 
+    /**
+     * Ensure that given envelopes intersect, transforming them in a common suitable system if needed.
+     */
+    private static boolean intersect(AbstractEnvelope left, Envelope right) {
+        final CRSMatching.Match bridge = CRSMatching
+                .left(left.getCoordinateReferenceSystem())
+                .right(right.getCoordinateReferenceSystem());
+        final CoordinateOperation left2CommonOp = bridge.fromLeft().orElse(null);
+        final CoordinateOperation right2CommonOp = bridge.fromRight().orElse(null);
+        try {
+            if (left2CommonOp != null) left = Envelopes.transform(left2CommonOp, left);
+            if (right2CommonOp != null) right = Envelopes.transform(right2CommonOp, right);
+        } catch (TransformException e) {
+            throw new BackingStoreException(e);
+        }
+
+        return left.intersects(right, true); // See class doc for why true here.
+    }
+
+    private void readObject(java.io.ObjectInputStream stream)
+            throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        init();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DefaultBBOX that = (DefaultBBOX) o;
+        return Objects.equals(left, that.left) &&
+                Objects.equals(right, that.right);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(left, right);
+    }
     /*
      * DEPRECATED OPERATIONS: NOT IMPLEMENTED
      */
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
index 3dbf6bf..291f3d9 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
@@ -322,7 +322,7 @@ public class DefaultFilterFactory implements FilterFactory2 {
      */
     @Override
     public Intersects intersects(final Expression left, final Expression right) {
-        return new SpatialFunction.Intersects(left, right);
+        return new ST_Intersects(new Expression[]{left, right});
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Envelope.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Envelope.java
index b8f89a5..c383721 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Envelope.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Envelope.java
@@ -31,6 +31,8 @@ import org.opengis.metadata.extent.GeographicBoundingBox;
 
 import org.apache.sis.feature.DefaultAttributeType;
 import org.apache.sis.feature.Features;
+import org.apache.sis.feature.builder.FeatureTypeBuilder;
+import org.apache.sis.feature.builder.PropertyTypeBuilder;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.geometry.ImmutableEnvelope;
 import org.apache.sis.internal.feature.AttributeConvention;
@@ -45,13 +47,13 @@ import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
  *
  * @author Alexis Manin (Geomatys)
  */
-public class ST_Envelope extends AbstractFunction implements FeatureExpression {
+public class ST_Envelope extends NamedFunction implements FeatureExpression {
 
     public static final String NAME = "ST_Envelope";
 
     private final Worker worker;
     public ST_Envelope(Expression[] parameters) {
-        super(NAME, parameters, null);
+        super(parameters);
         if (parameters == null || parameters.length != 1) throw new MismatchedDimensionException(
                 String.format(
                     "Single parameter expected for %s operation: source Geometry. However, %d arguments were provided",
@@ -66,13 +68,18 @@ public class ST_Envelope extends AbstractFunction implements FeatureExpression {
     }
 
     @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
     public Object evaluate(Object object) {
         return worker.evaluate(object);
     }
 
     @Override
-    public PropertyType expectedType(FeatureType type) {
-        return worker.type(type);
+    public PropertyTypeBuilder expectedType(FeatureType valueType, FeatureTypeBuilder addTo) {
+        return addTo.addProperty(worker.type(valueType));
     }
 
     /**
@@ -126,7 +133,7 @@ public class ST_Envelope extends AbstractFunction implements FeatureExpression {
 
         @Override
         public PropertyType type(FeatureType target) {
-            final PropertyType expressionType = source.expectedType(target);
+            final PropertyType expressionType = source.expectedType(target, new FeatureTypeBuilder()).build();
             final AttributeType<?> attr = Features.castOrUnwrap(expressionType)
                     .orElseThrow(() -> new UnsupportedOperationException("Cannot evaluate given expression because it does not create attribute values"));
             // If given expression evaluates directly to a bbox, there's no need for a conversion step.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java
index de9fa37..63ce1e6 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java
@@ -16,8 +16,11 @@
  */
 package org.apache.sis.filter;
 
+import java.io.IOException;
+import java.io.Serializable;
 import java.util.AbstractMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Predicate;
 
 import org.opengis.filter.FilterVisitor;
@@ -41,17 +44,16 @@ import static org.apache.sis.util.ArgumentChecks.ensureNonEmpty;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
 /**
- * TODO: check CRS
  * TODO: refine once Geometry API is stable.
  */
-public class ST_Intersects implements Intersects {
+public final class ST_Intersects implements Intersects, Serializable {
 
     public static final String NAME = "ST_Intersect";
 
     final Expression left;
     final Expression right;
 
-    private final Predicate intersects;
+    private transient Predicate intersects;
 
     public ST_Intersects(Expression[] parameters) {
         ensureNonEmpty("Parameters", parameters);
@@ -59,6 +61,10 @@ public class ST_Intersects implements Intersects {
 
         left = parameters[0];
         right = parameters[1];
+        init();
+    }
+
+    private void init() {
         ensureNonNull("Left operand", left);
         ensureNonNull("Right operand", right);
         if (left instanceof Literal && right instanceof Literal) {
@@ -93,7 +99,7 @@ public class ST_Intersects implements Intersects {
     private static org.locationtech.jts.geom.Geometry transformSilently(org.locationtech.jts.geom.Geometry target, CoordinateOperation op) {
         try {
             return JTS.transform(target, op);
-        } catch (TransformException e) {
+        } catch (TransformException | FactoryException e) {
             throw new BackingStoreException(e);
         }
     }
@@ -173,4 +179,27 @@ public class ST_Intersects implements Intersects {
     public Object accept(FilterVisitor visitor, Object extraData) {
         return visitor.visit(this, extraData);
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ST_Intersects that = (ST_Intersects) o;
+        return left.equals(that.left) &&
+                right.equals(that.right);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(left, right);
+    }
+
+    /**
+     * Initialize this filter state. It is necessary because of serialization compliance.
+     */
+    private void readObject(java.io.ObjectInputStream stream)
+            throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        init();
+    }
 }
diff --git a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
index 1350a92..2d6d724 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
@@ -25,7 +25,6 @@ import org.opengis.filter.expression.Literal;
 import org.opengis.filter.expression.PropertyName;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.crs.ProjectedCRS;
 
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.geometry.GeneralEnvelope;
@@ -315,17 +314,10 @@ public final strictfp class SQLMMTest extends TestCase {
         final Literal lPoint = factory.literal(point);
         expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 
-        // Disjoint
+        // utm domain contained in CRS:84
+        /* TODO: this is broken. We have to reproject geometries each time we change CRS.
         final ProjectedCRS nadUtm = CommonCRS.NAD27.universal(32, 37);
-        final ProjectedCRS wgsUtm = CommonCRS.WGS84.universal(-2, 4);
-
         point.setUserData(nadUtm);
-        ring.setUserData(wgsUtm);
-        expectFailFast(() -> intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
-        expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
-
-        // TODO: activate back after fixing CRS.suggestCommonTarget
-        // utm domain contained in CRS:84
         ring.setUserData(CommonCRS.defaultGeographic());
         assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
         assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
@@ -335,6 +327,7 @@ public final strictfp class SQLMMTest extends TestCase {
         point.setUserData(CommonCRS.WGS84.universal(7, 8));
         assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
         assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
+        */
     }
 
     private static ST_Intersects intersects(final Expression left, Expression right) {
diff --git a/core/sis-feature/src/test/java/org/apache/sis/filter/SpatialFunctionTest.java b/core/sis-feature/src/test/java/org/apache/sis/filter/SpatialFunctionTest.java
index 5a3011c..2921b66 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SpatialFunctionTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SpatialFunctionTest.java
@@ -16,14 +16,6 @@
  */
 package org.apache.sis.filter;
 
-import org.apache.sis.test.TestCase;
-import org.junit.Test;
-
-import static org.apache.sis.test.Assert.*;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LinearRing;
 import org.opengis.filter.FilterFactory2;
 import org.opengis.filter.spatial.BBOX;
 import org.opengis.filter.spatial.Beyond;
@@ -37,6 +29,18 @@ import org.opengis.filter.spatial.Overlaps;
 import org.opengis.filter.spatial.Touches;
 import org.opengis.filter.spatial.Within;
 
+import org.apache.sis.test.TestCase;
+
+import org.junit.Test;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
+import org.locationtech.jts.geom.LinearRing;
+
+import static org.apache.sis.test.Assert.assertFalse;
+import static org.apache.sis.test.Assert.assertSerializedEquals;
+import static org.apache.sis.test.Assert.assertTrue;
+
 
 /**
  * Tests {@link SpatialFunction} implementations.
@@ -129,11 +133,11 @@ public final strictfp class SpatialFunctionTest extends TestCase {
 
     @Test
     public void testBBOX() {
-        BBOX bbox = FF.bbox(FF.literal(RIGHT_GEOMETRY), 1, 1, 6, 6, "EPSG:4326");
+        BBOX bbox = FF.bbox(FF.literal(RIGHT_GEOMETRY), 1, 1, 6, 6, null);
         assertTrue(bbox.evaluate(null));
         assertSerializedEquals(bbox);
 
-        bbox = FF.bbox(FF.literal(RIGHT_GEOMETRY), -3, -2, 4, 1, "EPSG:4326");
+        bbox = FF.bbox(FF.literal(RIGHT_GEOMETRY), -3, -2, 4, 1, null);
         assertFalse(bbox.evaluate(null));
         assertSerializedEquals(bbox);
     }
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/DialectMapping.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/DialectMapping.java
index 017b834..49d3385 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/DialectMapping.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/DialectMapping.java
@@ -20,7 +20,9 @@ import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Optional;
 
+import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.metadata.sql.Dialect;
+import org.apache.sis.setup.GeometryLibrary;
 
 /**
  * Specifies mapping between values stored in database and Java. It is particularly useful for geo-related information,
@@ -54,12 +56,15 @@ public interface DialectMapping extends SQLCloseable {
     interface Spi {
         /**
          * Checks if database is compliant with this service specification, and create a mapper in such case.
+         *
+         * @param geometryDriver The library to use if the given mapping needs to create geometries. It mainly serves
+         *                       to obtain a geometry factory through {@link Geometries#implementation(GeometryLibrary)}.
          * @param c The connection to use to connect to the database. It will be read-only.
          * @return A component compatible with database of given connection, or nothing if the database is not supported
          * by this component.
          * @throws SQLException If an error occurs while fetching information from database.
          */
-        Optional<DialectMapping> create(final Connection c) throws SQLException;
+        Optional<DialectMapping> create(final GeometryLibrary geometryDriver, final Connection c) throws SQLException;
 
         /**
          *
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/OGC06104r4.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/OGC06104r4.java
index ab18bd0..c9b1d19 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/OGC06104r4.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/OGC06104r4.java
@@ -26,6 +26,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.metadata.sql.Dialect;
+import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.collection.Cache;
 
@@ -53,12 +54,12 @@ final class OGC06104r4 implements DialectMapping {
      */
     final Cache<Integer, CoordinateReferenceSystem> sessionCache;
 
-    private OGC06104r4(final OGC06104r4.Spi spi, Connection c) throws SQLException {
+    private OGC06104r4(final OGC06104r4.Spi spi, GeometryLibrary geometryDriver, Connection c) throws SQLException {
         this.spi = spi;
         sessionCache = new Cache<>(7, 0, true);
         this.identifyGeometries = new GeometryIdentification(c, sessionCache);
 
-        this.library = Geometries.implementation(null);
+        this.library = Geometries.implementation(geometryDriver);
     }
 
     @Override
@@ -163,8 +164,8 @@ final class OGC06104r4 implements DialectMapping {
     public static final class Spi implements DialectMapping.Spi {
 
         @Override
-        public Optional<DialectMapping> create(Connection c) throws SQLException {
-            return Optional.of(new OGC06104r4(this, c));
+        public Optional<DialectMapping> create(GeometryLibrary geometryDriver, Connection c) throws SQLException {
+            return Optional.of(new OGC06104r4(this, geometryDriver, c));
         }
 
         @Override
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PostGISMapping.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PostGISMapping.java
index 3c45b8a..6927e42 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PostGISMapping.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/PostGISMapping.java
@@ -29,11 +29,13 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
 import org.apache.sis.internal.feature.Geometries;
 import org.apache.sis.internal.metadata.sql.Dialect;
+import org.apache.sis.setup.GeometryLibrary;
 import org.apache.sis.util.collection.BackingStoreException;
 import org.apache.sis.util.collection.Cache;
 import org.apache.sis.util.logging.Logging;
 
-import static org.apache.sis.internal.sql.feature.OGC06104r4.*;
+import static org.apache.sis.internal.sql.feature.OGC06104r4.Reader;
+import static org.apache.sis.internal.sql.feature.OGC06104r4.getGeometricClass;
 
 /**
  * Maps geometric values between PostGIS natural representation (Hexadecimal EWKT) and SIS.
@@ -60,13 +62,13 @@ public final class PostGISMapping implements DialectMapping {
      */
     final Cache<Integer, CoordinateReferenceSystem> sessionCache;
 
-    private PostGISMapping(final PostGISMapping.Spi spi, Connection c) throws SQLException {
+    private PostGISMapping(final PostGISMapping.Spi spi, GeometryLibrary geometryDriver, Connection c) throws SQLException {
         this.spi = spi;
         sessionCache = new Cache<>(7, 0, true);
         this.identifyGeometries = new GeometryIdentification(c, "geometry_columns", "f_geometry_column", "type", sessionCache);
         this.identifyGeographies = new GeometryIdentification(c, "geography_columns", "f_geography_column", "type", sessionCache);
 
-        this.library = Geometries.implementation(null);
+        this.library = Geometries.implementation(geometryDriver);
     }
 
     @Override
@@ -118,7 +120,7 @@ public final class PostGISMapping implements DialectMapping {
     public static final class Spi implements DialectMapping.Spi {
 
         @Override
-        public Optional<DialectMapping> create(Connection c) throws SQLException {
+        public Optional<DialectMapping> create(GeometryLibrary geometryDriver, Connection c) throws SQLException {
             try {
                 checkPostGISVersion(c);
             } catch (SQLException e) {
@@ -127,7 +129,7 @@ public final class PostGISMapping implements DialectMapping {
                 logger.log(Level.FINE, "Cannot determine PostGIS version", e);
                 return Optional.empty();
             }
-            return Optional.of(new PostGISMapping(this, c));
+            return Optional.of(new PostGISMapping(this, geometryDriver, c));
         }
 
         private void checkPostGISVersion(final Connection c) throws SQLException {
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/QueryFeatureSet.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/QueryFeatureSet.java
index 68ff1e0..83aa9eb 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/QueryFeatureSet.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/QueryFeatureSet.java
@@ -40,8 +40,8 @@ import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.FeatureSet;
 import org.apache.sis.storage.Query;
 import org.apache.sis.storage.UnsupportedQueryException;
+import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.util.collection.BackingStoreException;
-import org.apache.sis.util.logging.WarningListeners;
 
 /**
  * Stores SQL query given at built time, and execute it when calling {@link #features(boolean) data stream}. Note that
@@ -153,7 +153,7 @@ public class QueryFeatureSet extends AbstractFeatureSet {
         this(queryBuilder, createAdapter(queryBuilder, analyzer, conn), analyzer.listeners, source);
     }
 
-    QueryFeatureSet(SQLBuilder queryBuilder, FeatureAdapter adapter, WarningListeners listeners, DataSource source) {
+    QueryFeatureSet(SQLBuilder queryBuilder, FeatureAdapter adapter, StoreListeners listeners, DataSource source) {
         super(listeners);
         this.source = source;
         this.adapter = adapter;
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SpatialFunctions.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SpatialFunctions.java
index bf95272..182e206 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SpatialFunctions.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/SpatialFunctions.java
@@ -87,7 +87,7 @@ class SpatialFunctions {
         library = null;
 
         final Dialect dialect = Dialect.guess(metadata);
-        specificMapping = forDialect(dialect, c);
+        specificMapping = forDialect(dialect, library, c);
         defaultMapping = new ANSIMapping(isByteUnsigned);
     }
 
@@ -131,12 +131,12 @@ class SpatialFunctions {
      * @return
      * @throws SQLException
      */
-    static Optional<DialectMapping> forDialect(final Dialect dialect, Connection c) throws SQLException {
+    static Optional<DialectMapping> forDialect(final Dialect dialect, final GeometryLibrary geomDriver, Connection c) throws SQLException {
         switch (dialect) {
-            case POSTGRESQL: return new PostGISMapping.Spi().create(c);
+            case POSTGRESQL: return new PostGISMapping.Spi().create(geomDriver, c);
             default: {
                 try {
-                    return new OGC06104r4.Spi().create(c);
+                    return new OGC06104r4.Spi().create(geomDriver, c);
                 } catch (SQLException e) {
                     final Logger logger = Logging.getLogger("org.apache.sis.internal.sql");
                     logger.warning("No supported geometric binding. For more information, activate debug logs.");
diff --git a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableSubset.java b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableSubset.java
index 74ce400..d202b21 100644
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableSubset.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/TableSubset.java
@@ -29,8 +29,8 @@ import org.opengis.util.GenericName;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.FeatureSet;
 import org.apache.sis.storage.Query;
-import org.apache.sis.storage.event.ChangeEvent;
-import org.apache.sis.storage.event.ChangeListener;
+import org.apache.sis.storage.event.StoreEvent;
+import org.apache.sis.storage.event.StoreListener;
 
 /**
  * A {@link Table} feature set on which a query has been applied.
@@ -77,12 +77,12 @@ public class TableSubset implements FeatureSet {
     }
 
     @Override
-    public <T extends ChangeEvent> void addListener(ChangeListener<? super T> listener, Class<T> eventType) {
-        parent.addListener(listener, eventType);
+    public <T extends StoreEvent> void addListener(Class<T> eventType, StoreListener<? super T> listener) {
+        parent.addListener(eventType, listener);
     }
 
     @Override
-    public <T extends ChangeEvent> void removeListener(ChangeListener<? super T> listener, Class<T> eventType) {
-        parent.removeListener(listener, eventType);
+    public <T extends StoreEvent> void removeListener(Class<T> eventType, StoreListener<? super T> listener) {
+        parent.removeListener(eventType, listener);
     }
 }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
index 5d50a6c..b1af455 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
@@ -17,17 +17,23 @@
 package org.apache.sis.internal.storage.query;
 
 import java.util.Arrays;
-import java.util.Map;
-import java.util.List;
 import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+
+import org.opengis.feature.FeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.sort.SortBy;
 import org.opengis.util.GenericName;
-import org.apache.sis.filter.InvalidExpressionException;
+
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.feature.builder.PropertyTypeBuilder;
+import org.apache.sis.filter.InvalidExpressionException;
 import org.apache.sis.internal.feature.FeatureExpression;
-import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.storage.Resources;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.storage.FeatureSet;
 import org.apache.sis.storage.Query;
 import org.apache.sis.util.ArgumentChecks;
@@ -36,10 +42,6 @@ import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.iso.Names;
 
 // Branch-dependent imports
-import org.opengis.feature.FeatureType;
-import org.opengis.filter.Filter;
-import org.opengis.filter.expression.Expression;
-import org.opengis.filter.sort.SortBy;
 
 
 /**
@@ -137,6 +139,7 @@ public class SimpleQuery extends Query implements Cloneable {
                     throw new IllegalArgumentException(Resources.format(Resources.Keys.DuplicatedQueryProperty_3, key, p, i));
                 }
             }
+            this.columns = columns;
         }
     }
 


[sis] 04/04: chore(Feature): add cross-CRS test for intersection operator.

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

amanin pushed a commit to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 716f0b73a10fc0a39e3736dc5f1f71fb40a43570
Author: Alexis Manin <am...@apache.org>
AuthorDate: Fri Nov 15 16:44:32 2019 +0100

    chore(Feature): add cross-CRS test for intersection operator.
---
 .../test/java/org/apache/sis/filter/SQLMMTest.java | 38 +++++++++++++---------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
index feba114..bbc13e6 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
@@ -25,9 +25,13 @@ import org.opengis.filter.expression.Literal;
 import org.opengis.filter.expression.PropertyName;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
 
 import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.internal.feature.jts.JTS;
+import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.test.TestCase;
@@ -38,7 +42,6 @@ import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.Geometry;
 import org.locationtech.jts.geom.GeometryFactory;
 import org.locationtech.jts.geom.LineString;
-import org.locationtech.jts.geom.LinearRing;
 import org.locationtech.jts.geom.Point;
 import org.locationtech.jts.geom.Polygon;
 
@@ -269,7 +272,7 @@ public final strictfp class SQLMMTest extends TestCase {
     }
 
     @Test
-    public void ST_Intersects() {
+    public void ST_Intersects() throws Exception {
         try {
             new ST_Intersects(null, null);
             fail("ST_Intersects operator should not accept null parameters");
@@ -286,7 +289,7 @@ public final strictfp class SQLMMTest extends TestCase {
 
         final Coordinate start = new Coordinate(0, 0.1);
         final Coordinate second = new Coordinate(1.2, 0.2);
-        final LinearRing ring = geometryFactory.createLinearRing(new Coordinate[]{
+        final Polygon ring = geometryFactory.createPolygon(new Coordinate[]{
                 start, second, new Coordinate(0.7, 0.8), start
         });
 
@@ -298,7 +301,7 @@ public final strictfp class SQLMMTest extends TestCase {
 
         // Border should intersect
         final Feature f = mock();
-        final Point point = geometryFactory.createPoint(second);
+        Point point = geometryFactory.createPoint(second);
         f.setPropertyValue(P_NAME, point);
         final PropertyName geomName = factory.property(P_NAME);
         st = new ST_Intersects(geomName, lring);
@@ -309,25 +312,30 @@ public final strictfp class SQLMMTest extends TestCase {
 
         // Ensure CRS conversion works as expected (see package-info).
         // Missing
-        point.setUserData(CommonCRS.defaultGeographic());
+        final GeographicCRS crs84 = CommonCRS.defaultGeographic();
+        point.setUserData(crs84);
         expectFailFast(() -> new ST_Intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
         final Literal lPoint = factory.literal(point);
         expectFailFast(() -> new ST_Intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 
         // utm domain contained in CRS:84
-        /* TODO: this is broken. We have to reproject geometries each time we change CRS.
         final ProjectedCRS nadUtm = CommonCRS.NAD27.universal(32, 37);
-        point.setUserData(nadUtm);
-        ring.setUserData(CommonCRS.defaultGeographic());
-        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
-        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
+        // slightly move point, because edge test is likely to fail due to transform roundings.
+        point = geometryFactory.createPoint(new Coordinate(0.8, 0.3));
+        final Geometry nadPoint = JTS.transform(point, CRS.findOperation(crs84, nadUtm, null));
+        f.setPropertyValue(P_NAME, nadPoint);
+        ring.setUserData(crs84);
+        assertTrue("Intersection should be found when CRS are compatible", new ST_Intersects(geomName, lring).evaluate(f));
+        assertTrue("Intersection should be found when CRS are compatible", new ST_Intersects(factory.literal(nadPoint), lring).evaluate(null));
 
         // Common base CRS
-        ring.setUserData(CommonCRS.WGS84.universal(0, 0));
-        point.setUserData(CommonCRS.WGS84.universal(7, 8));
-        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
-        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
-        */
+        final ProjectedCRS utm00 = CommonCRS.WGS84.universal(0, 0);
+        final Geometry ringUtm00 = JTS.transform(ring, CRS.findOperation(crs84, utm00, null));
+        final ProjectedCRS utm78 = CommonCRS.WGS84.universal(7, 8);
+        final Geometry pointUtm78 = JTS.transform(ring, CRS.findOperation(crs84, utm78, null));
+        f.setPropertyValue(P_NAME, pointUtm78);
+        assertTrue("Intersection should be found when CRS are compatible", new ST_Intersects(geomName, factory.literal(ringUtm00)).evaluate(f));
+        assertTrue("Intersection should be found when CRS are compatible", new ST_Intersects(factory.literal(pointUtm78), factory.literal(ringUtm00)).evaluate(null));
     }
 
     @Test


[sis] 01/04: Merge branch 'geoapi-4.0' into refactor/sql-store

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

amanin pushed a commit to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 15e88bbbdcc3d54977828d798f41e0e6c415065a
Merge: 71a39a3 adafeb6
Author: Alexis Manin <am...@apache.org>
AuthorDate: Thu Nov 14 15:19:41 2019 +0100

    Merge branch 'geoapi-4.0' into refactor/sql-store

 NOTICE                                             |  13 +-
 README                                             |  30 +-
 application/pom.xml                                |  17 +-
 application/sis-console/pom.xml                    |   9 +
 application/sis-console/src/main/artifact/README   |   6 +-
 application/sis-console/src/main/artifact/bin/sis  |   5 +-
 .../sis-console/src/main/artifact/lib/README       |   1 +
 .../java/org/apache/sis/console/AboutCommand.java  |   2 +-
 .../main/java/org/apache/sis/console/Command.java  |   8 +-
 .../apache/sis/console/ResourcesDownloader.java    |   2 +-
 .../org/apache/sis/console/TransformCommand.java   |   3 +-
 .../java/org/apache/sis/console/package-info.java  |   4 +-
 application/sis-javafx/doc/readme.txt              |  19 +
 application/sis-javafx/pom.xml                     |  45 +-
 .../apache/sis/gui/{Main.java => DataViewer.java}  |  89 +-
 .../org/apache/sis/gui/dataset/ExpandableList.java | 425 +++++++++
 .../apache/sis/gui/dataset/ExpandedFeature.java    | 214 +++++
 .../org/apache/sis/gui/dataset/FeatureList.java    | 340 ++++++++
 .../org/apache/sis/gui/dataset/FeatureLoader.java  | 346 ++++++++
 .../org/apache/sis/gui/dataset/FeatureTable.java   | 479 +++++++---
 .../apache/sis/gui/dataset/ResourceExplorer.java   | 135 +++
 .../org/apache/sis/gui/dataset/ResourceTree.java   | 783 +++++++++++++----
 .../org/apache/sis/gui/dataset}/package-info.java  |  19 +-
 .../sis/gui/metadata/IdentificationInfo.java       | 346 ++++++++
 .../org/apache/sis/gui/metadata/MetadataNode.java  | 228 -----
 .../apache/sis/gui/metadata/MetadataOverview.java  | 430 ---------
 .../apache/sis/gui/metadata/MetadataSummary.java   | 339 ++++++++
 .../org/apache/sis/gui/metadata/MetadataTree.java  | 332 +++++++
 .../sis/gui/metadata/RepresentationInfo.java       | 123 +++
 .../org/apache/sis/gui/metadata/ResourceView.java  | 399 ---------
 .../java/org/apache/sis/gui/metadata/Section.java  | 289 ++++++
 .../org/apache/sis/gui/metadata}/package-info.java |  16 +-
 .../java/org/apache/sis/gui}/package-info.java     |  14 +-
 .../apache/sis/gui/referencing/AuthorityCodes.java | 459 ++++++++++
 .../org/apache/sis/gui/referencing/CRSButton.java  |  79 --
 .../org/apache/sis/gui/referencing/CRSChooser.java | 249 ++++--
 .../org/apache/sis/gui/referencing/CRSTable.java   | 349 --------
 .../java/org/apache/sis/gui/referencing/Code.java  |  94 +-
 .../org/apache/sis/gui/referencing/CodeFilter.java | 110 +++
 .../org/apache/sis/gui/referencing/WKTPane.java    | 188 +++-
 .../apache/sis/gui/referencing}/package-info.java  |  13 +-
 .../apache/sis/internal/gui/BackgroundThreads.java |  94 ++
 .../apache/sis/internal/gui/ExceptionReporter.java | 198 +++++
 .../org/apache/sis/internal/gui/FXUtilities.java   |  91 --
 .../org/apache/sis/internal/gui/FontGlyphs.java    | 143 ---
 .../sis/internal/gui/IdentityValueFactory.java     |  74 ++
 .../org/apache/sis/internal/gui/RecentChoices.java |  95 ++
 .../apache/sis/internal/gui/ResourceLoader.java    | 262 ++++++
 .../org/apache/sis/internal/gui/Resources.java     | 204 ++++-
 .../apache/sis/internal/gui/Resources.properties   |  42 +-
 .../sis/internal/gui/Resources_fr.properties       |  42 +-
 .../java/org/apache/sis/internal/gui/Styles.java   |  98 +++
 .../org/apache/sis/internal/gui/package-info.java  |   5 +-
 .../org/apache/sis/gui/referencing/CRSChooser.fxml |  30 -
 .../org/apache/sis/gui/referencing/proj_conic.png  | Bin 591 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_geo.png    | Bin 834 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_square.png | Bin 519 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_stereo.png | Bin 959 -> 0 bytes
 .../org/apache/sis/gui/referencing/proj_utm.png    | Bin 681 -> 0 bytes
 .../org/apache/sis/services/LocationServlet.java   |  13 +-
 core/pom.xml                                       |   1 +
 .../src/main/ant/prepare-release.xml               |  26 +-
 .../org/apache/sis/internal/doclet/Doclet.java     |  45 +-
 .../org/apache/sis/internal/doclet/Include.java    |   2 +-
 .../org/apache/sis/internal/doclet/Taglet.java     |  23 +-
 .../apache/sis/internal/unopkg/package-info.java   |   4 +-
 {storage/sis-xmlstore => core/sis-cql}/pom.xml     |  75 +-
 .../main/antlr4/org/apache/sis/internal/cql/CQL.g4 | 280 ++++++
 .../src/main/java/org/apache/sis/cql/CQL.java      | 752 ++++++++++++++++
 .../main/java/org/apache/sis/cql/CQLException.java |  37 +-
 .../org/apache/sis/cql/FilterToCQLVisitor.java     | 660 ++++++++++++++
 .../java/org/apache/sis/internal/cql/AntlrCQL.java |  98 +++
 .../test/java/org/apache/sis/cql/CQLTestCase.java  |  60 ++
 .../test/java/org/apache/sis/cql/CQLTestSuite.java |  33 +-
 .../org/apache/sis/cql/ExpressionReadingTest.java  | 613 +++++++++++++
 .../org/apache/sis/cql/ExpressionWritingTest.java  | 339 ++++++++
 .../java/org/apache/sis/cql/FilterReadingTest.java | 808 +++++++++++++++++
 .../java/org/apache/sis/cql/FilterWritingTest.java | 401 +++++++++
 .../java/org/apache/sis/coverage/Category.java     |   8 +-
 .../java/org/apache/sis/coverage/CategoryList.java |   8 +-
 .../coverage/IllegalSampleDimensionException.java  |  62 ++
 .../org/apache/sis/coverage/SampleDimension.java   |  13 +-
 .../org/apache/sis/coverage/SampleRangeFormat.java | 148 ++--
 .../main/java/org/apache/sis/coverage/ToNaN.java   |   6 +-
 .../org/apache/sis/coverage/grid/GridCoverage.java |   2 +-
 .../apache/sis/coverage/grid/GridDerivation.java   |  26 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   2 +-
 .../apache/sis/coverage/grid/ImageRenderer.java    |   2 +-
 .../java/org/apache/sis/coverage/package-info.java |   2 +-
 .../apache/sis/feature/AbstractAssociation.java    |   4 +-
 .../org/apache/sis/feature/AbstractAttribute.java  |  11 +-
 .../org/apache/sis/feature/AbstractFeature.java    |  16 +-
 .../apache/sis/feature/AbstractIdentifiedType.java |   4 +-
 .../apache/sis/feature/CharacteristicTypeMap.java  |   2 +-
 .../apache/sis/feature/DefaultAssociationRole.java |   2 +-
 .../apache/sis/feature/DefaultAttributeType.java   |   8 +-
 .../org/apache/sis/feature/DefaultFeatureType.java |  10 +-
 .../org/apache/sis/feature/EnvelopeOperation.java  |   2 +-
 .../java/org/apache/sis/feature/FeatureFormat.java |   6 +-
 .../org/apache/sis/feature/FeatureOperations.java  |  10 +-
 .../main/java/org/apache/sis/feature/Features.java |  35 +
 .../apache/sis/feature/MultiValuedAssociation.java |   2 +-
 .../apache/sis/feature/MultiValuedAttribute.java   |   2 +-
 .../apache/sis/feature/SingletonAssociation.java   |   4 +-
 .../org/apache/sis/feature/SingletonAttribute.java |   4 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |   9 -
 .../apache/sis/feature/builder/TypeBuilder.java    |   2 +-
 .../java/org/apache/sis/feature/package-info.java  |   6 +-
 .../org/apache/sis/filter/AbstractFunction.java    | 141 ---
 .../org/apache/sis/filter/ArithmeticFunction.java  |  61 +-
 .../java/org/apache/sis/filter/BinaryFunction.java |  18 +-
 .../java/org/apache/sis/filter/Capabilities.java   | 437 ++++++++++
 .../org/apache/sis/filter/ComparisonFunction.java  | 503 ++++++++---
 .../apache/sis/filter/DefaultFilterFactory.java    | 317 ++++---
 .../java/org/apache/sis/filter/DefaultLike.java    | 101 +++
 .../org/apache/sis/filter/DefaultObjectId.java     |   4 +-
 .../java/org/apache/sis/filter/DefaultSortBy.java  |   4 +-
 .../org/apache/sis/filter/FilterByIdentifier.java  |   6 +-
 .../sis/filter/InvalidExpressionException.java     |  92 ++
 .../java/org/apache/sis/filter/LeafExpression.java |  59 +-
 .../org/apache/sis/filter/LogicalFunction.java     |  12 +-
 .../java/org/apache/sis/filter/NamedFunction.java  | 210 +++++
 .../src/main/java/org/apache/sis/filter/Node.java  |  20 +-
 .../src/main/java/org/apache/sis/filter/SQLMM.java |  76 +-
 .../main/java/org/apache/sis/filter/ST_Buffer.java |  99 +++
 .../java/org/apache/sis/filter/ST_Centroid.java    |  96 ++
 .../java/org/apache/sis/filter/ST_Simplify.java    | 112 +++
 .../sis/filter/ST_SimplifyPreserveTopology.java    | 112 +++
 .../java/org/apache/sis/filter/ST_Transform.java   | 217 +++--
 .../org/apache/sis/filter/SpatialFunction.java     | 968 +++++++++++++++++++++
 .../org/apache/sis/filter/TemporalFunction.java    | 722 +++++++++++++++
 .../java/org/apache/sis/filter/UnaryFunction.java  |  12 +-
 .../java/org/apache/sis/filter/package-info.java   |  10 +-
 .../java/org/apache/sis/image/PixelIterator.java   |   7 +
 .../apache/sis/image/WritablePixelIterator.java    |  11 +-
 .../sis/internal/coverage/GridCoverage2D.java      | 117 +++
 .../sis/internal/feature/AttributeConvention.java  |   2 +-
 .../java/org/apache/sis/internal/feature/ESRI.java |  30 +-
 .../sis/internal/feature/FeatureExpression.java    |  67 +-
 .../sis/internal/feature/FunctionRegister.java     |  42 +-
 .../apache/sis/internal/feature/Geometries.java    | 226 ++++-
 .../java/org/apache/sis/internal/feature/JTS.java  | 102 ++-
 .../org/apache/sis/internal/feature/Java2D.java    |  25 +-
 .../org/apache/sis/internal/feature/Resources.java |  15 +
 .../sis/internal/feature/Resources.properties      |   3 +
 .../sis/internal/feature/Resources_fr.properties   |   3 +
 .../org/apache/sis/internal/feature/jts/JTS.java   |  59 +-
 ...rg.apache.sis.internal.feature.FunctionRegister |   1 -
 .../apache/sis/coverage/SampleRangeFormatTest.java | 137 +++
 .../apache/sis/filter/ArithmeticFunctionTest.java  |   4 +-
 .../org/apache/sis/filter/BetweenFunctionTest.java |  90 ++
 .../org/apache/sis/filter/CapabilitiesTest.java}   |  42 +-
 .../apache/sis/filter/ComparisonFunctionTest.java  | 151 ++++
 .../org/apache/sis/filter/DefaultObjectIdTest.java |   4 +-
 .../apache/sis/filter/FilterByIdentifierTest.java  |   4 +-
 .../org/apache/sis/filter/LeafExpressionTest.java  |   4 +-
 .../org/apache/sis/filter/LikeFunctionTest.java    |  42 +-
 .../org/apache/sis/filter/LogicalFunctionTest.java |   4 +-
 .../java/org/apache/sis/filter/PeriodLiteral.java  | 115 +++
 .../test/java/org/apache/sis/filter/SQLMMTest.java | 327 +++++--
 .../org/apache/sis/filter/SpatialFunctionTest.java | 306 +++++++
 .../apache/sis/filter/TemporalFunctionTest.java    | 341 ++++++++
 .../org/apache/sis/filter/UnaryFunctionTest.java   |   4 +-
 .../sis/internal/coverage/GridCoverage2DTest.java  | 126 +++
 .../apache/sis/test/suite/FeatureTestSuite.java    |  12 +-
 core/sis-metadata/pom.xml                          |  13 +-
 .../java/org/apache/sis/internal/jaxb/Context.java |  21 +-
 .../sis/internal/jaxb/IdentifierMapAdapter.java    |   8 +-
 .../sis/internal/jaxb/ModifiableIdentifierMap.java |   2 +-
 .../sis/internal/jaxb/PrimitiveTypeProperties.java |   6 +-
 .../apache/sis/internal/jaxb/gco/GO_DateTime.java  |   2 +-
 .../apache/sis/internal/jaxb/gco/GO_Decimal.java   |   2 +-
 .../org/apache/sis/internal/jaxb/gco/GO_Real.java  |   2 +-
 .../jaxb/gco/InternationalStringAdapter.java       |   2 +-
 .../apache/sis/internal/jaxb/gco/PropertyType.java |  12 +-
 .../sis/internal/jaxb/gco/StringAdapter.java       |   2 +-
 .../apache/sis/internal/jaxb/gco/package-info.java |   7 +-
 .../sis/internal/jaxb/geometry/package-info.java   |   2 +-
 .../sis/internal/jaxb/gmi/LE_ProcessStep.java      |   2 +-
 .../apache/sis/internal/jaxb/gmi/LE_Source.java    |   2 +-
 .../org/apache/sis/internal/jaxb/gmi/MI_Band.java  |   2 +-
 .../internal/jaxb/gmi/MI_CoverageDescription.java  |   2 +-
 .../sis/internal/jaxb/gmi/MI_Georectified.java     |   2 +-
 .../sis/internal/jaxb/gmi/MI_Georeferenceable.java |   2 +-
 .../sis/internal/jaxb/gmi/MI_ImageDescription.java |   2 +-
 .../apache/sis/internal/jaxb/gmi/MI_Metadata.java  |   2 +-
 .../apache/sis/internal/jaxb/gml/GMLAdapter.java   |   2 +-
 .../org/apache/sis/internal/jaxb/gml/Measure.java  |   2 +-
 .../jaxb/lan/LocalisedCharacterString.java         |  10 +-
 .../sis/internal/jaxb/metadata/CI_Address.java     |   2 +-
 .../sis/internal/jaxb/metadata/CI_Citation.java    |   2 +-
 .../sis/internal/jaxb/metadata/CI_Contact.java     |   2 +-
 .../apache/sis/internal/jaxb/metadata/CI_Date.java |   2 +-
 .../internal/jaxb/metadata/CI_OnlineResource.java  |   2 +-
 .../sis/internal/jaxb/metadata/CI_Party.java       |   2 +-
 .../internal/jaxb/metadata/CI_Responsibility.java  |   2 +-
 .../jaxb/metadata/CI_ResponsibleParty.java         |   2 +-
 .../sis/internal/jaxb/metadata/CI_Series.java      |   2 +-
 .../sis/internal/jaxb/metadata/CI_Telephone.java   |   2 +-
 .../sis/internal/jaxb/metadata/DQ_DataQuality.java |   2 +-
 .../sis/internal/jaxb/metadata/DQ_Element.java     |   2 +-
 .../jaxb/metadata/DQ_PositionalAccuracy.java       |   2 +-
 .../sis/internal/jaxb/metadata/DQ_Result.java      |   2 +-
 .../sis/internal/jaxb/metadata/EX_Extent.java      |   2 +-
 .../jaxb/metadata/EX_GeographicExtent.java         |   2 +-
 .../internal/jaxb/metadata/EX_TemporalExtent.java  |   2 +-
 .../internal/jaxb/metadata/EX_VerticalExtent.java  |   2 +-
 .../sis/internal/jaxb/metadata/LE_Algorithm.java   |   2 +-
 .../jaxb/metadata/LE_NominalResolution.java        |   2 +-
 .../jaxb/metadata/LE_ProcessStepReport.java        |   2 +-
 .../sis/internal/jaxb/metadata/LE_Processing.java  |   2 +-
 .../sis/internal/jaxb/metadata/LI_Lineage.java     |   2 +-
 .../sis/internal/jaxb/metadata/LI_ProcessStep.java |   2 +-
 .../sis/internal/jaxb/metadata/LI_Source.java      |   2 +-
 .../jaxb/metadata/MD_AggregateInformation.java     |   2 +-
 .../metadata/MD_ApplicationSchemaInformation.java  |   2 +-
 .../jaxb/metadata/MD_AssociatedResource.java       |   2 +-
 .../internal/jaxb/metadata/MD_AttributeGroup.java  |   2 +-
 .../internal/jaxb/metadata/MD_BrowseGraphic.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Constraints.java |   2 +-
 .../jaxb/metadata/MD_ContentInformation.java       |   2 +-
 .../jaxb/metadata/MD_DataIdentification.java       |   2 +-
 .../jaxb/metadata/MD_DigitalTransferOptions.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Dimension.java   |   2 +-
 .../internal/jaxb/metadata/MD_Distribution.java    |   2 +-
 .../sis/internal/jaxb/metadata/MD_Distributor.java |   2 +-
 .../metadata/MD_ExtendedElementInformation.java    |   2 +-
 .../internal/jaxb/metadata/MD_FeatureTypeInfo.java |   2 +-
 .../sis/internal/jaxb/metadata/MD_Format.java      |   2 +-
 .../jaxb/metadata/MD_GeometricObjects.java         |   2 +-
 .../internal/jaxb/metadata/MD_Identification.java  |   2 +-
 .../sis/internal/jaxb/metadata/MD_Identifier.java  |   2 +-
 .../internal/jaxb/metadata/MD_KeywordClass.java    |   2 +-
 .../sis/internal/jaxb/metadata/MD_Keywords.java    |   2 +-
 .../jaxb/metadata/MD_MaintenanceInformation.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Medium.java      |   2 +-
 .../sis/internal/jaxb/metadata/MD_Metadata.java    |   2 +-
 .../metadata/MD_MetadataExtensionInformation.java  |   2 +-
 .../internal/jaxb/metadata/MD_MetadataScope.java   |   2 +-
 .../metadata/MD_PortrayalCatalogueReference.java   |   2 +-
 .../internal/jaxb/metadata/MD_RangeDimension.java  |   2 +-
 .../internal/jaxb/metadata/MD_Releasability.java   |   2 +-
 .../jaxb/metadata/MD_RepresentativeFraction.java   |   2 +-
 .../sis/internal/jaxb/metadata/MD_Resolution.java  |   2 +-
 .../sis/internal/jaxb/metadata/MD_Scope.java       |   2 +-
 .../jaxb/metadata/MD_ScopeDescription.java         |   2 +-
 .../jaxb/metadata/MD_SpatialRepresentation.java    |   2 +-
 .../jaxb/metadata/MD_StandardOrderProcess.java     |   2 +-
 .../sis/internal/jaxb/metadata/MD_Usage.java       |   2 +-
 .../jaxb/metadata/MI_AcquisitionInformation.java   |   2 +-
 .../jaxb/metadata/MI_EnvironmentalRecord.java      |   2 +-
 .../sis/internal/jaxb/metadata/MI_Event.java       |   2 +-
 .../apache/sis/internal/jaxb/metadata/MI_GCP.java  |   2 +-
 .../jaxb/metadata/MI_GeolocationInformation.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Instrument.java  |   2 +-
 .../sis/internal/jaxb/metadata/MI_Objective.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Operation.java   |   2 +-
 .../apache/sis/internal/jaxb/metadata/MI_Plan.java |   2 +-
 .../sis/internal/jaxb/metadata/MI_Platform.java    |   2 +-
 .../internal/jaxb/metadata/MI_PlatformPass.java    |   2 +-
 .../jaxb/metadata/MI_RangeElementDescription.java  |   2 +-
 .../internal/jaxb/metadata/MI_RequestedDate.java   |   2 +-
 .../sis/internal/jaxb/metadata/MI_Requirement.java |   2 +-
 .../sis/internal/jaxb/metadata/MX_DataFile.java    |   2 +-
 .../internal/jaxb/metadata/RS_ReferenceSystem.java |  22 +-
 .../internal/jaxb/metadata/SV_CoupledResource.java |   2 +-
 .../jaxb/metadata/SV_OperationChainMetadata.java   |   2 +-
 .../jaxb/metadata/SV_OperationMetadata.java        |   2 +-
 .../sis/internal/jaxb/metadata/SV_Parameter.java   |   2 +-
 .../sis/internal/jaxb/metadata/package-info.java   |   2 +-
 .../metadata/replace/ReferenceSystemMetadata.java  |  12 +-
 .../jaxb/metadata/replace/ServiceParameter.java    |   2 +-
 .../org/apache/sis/internal/jaxb/package-info.java |   2 +-
 .../apache/sis/internal/metadata/Identifiers.java  |  20 +-
 .../apache/sis/internal/metadata/Resources.java    |  27 +
 .../sis/internal/metadata/Resources.properties     |   2 +
 .../sis/internal/metadata/Resources_fr.properties  |   2 +
 .../sis/internal/metadata/ServicesForUtility.java  |  28 +
 .../internal/metadata/TransformationAccuracy.java  |   2 +-
 .../sis/internal/metadata/sql/Initializer.java     |  22 +-
 .../sis/internal/metadata/sql/ScriptRunner.java    |  63 +-
 .../sis/internal/metadata/sql/package-info.java    |   2 +-
 .../java/org/apache/sis/internal/xml/Schemas.java  |   2 +-
 .../org/apache/sis/metadata/AbstractMetadata.java  |  19 +-
 .../org/apache/sis/metadata/MetadataCopier.java    |  41 +-
 .../org/apache/sis/metadata/MetadataFormat.java    |   2 +-
 .../org/apache/sis/metadata/MetadataStandard.java  |  18 +-
 .../org/apache/sis/metadata/MetadataVisitor.java   |   2 +-
 .../apache/sis/metadata/ModifiableMetadata.java    | 142 +--
 .../org/apache/sis/metadata/PropertyAccessor.java  |   4 +-
 .../apache/sis/metadata/PropertyInformation.java   |   2 +-
 .../java/org/apache/sis/metadata/StateChanger.java |   6 +-
 .../org/apache/sis/metadata/TreeNodeChildren.java  |   9 +-
 .../apache/sis/metadata/ValueExistencePolicy.java  |   2 +-
 .../apache/sis/metadata/iso/DefaultIdentifier.java |  13 +-
 .../apache/sis/metadata/iso/DefaultMetadata.java   |   4 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |   6 +-
 .../metadata/iso/acquisition/DefaultObjective.java |   2 +-
 .../sis/metadata/iso/acquisition/package-info.java |   4 +-
 .../sis/metadata/iso/citation/Citations.java       |  98 +--
 .../sis/metadata/iso/citation/DefaultCitation.java |   6 +-
 .../metadata/iso/citation/DefaultTelephone.java    |   8 +-
 .../sis/metadata/iso/citation/package-info.java    |   6 +-
 .../iso/constraint/DefaultLegalConstraints.java    |   2 +-
 .../sis/metadata/iso/constraint/package-info.java  |   4 +-
 .../sis/metadata/iso/content/package-info.java     |   4 +-
 .../distribution/DefaultStandardOrderProcess.java  |   4 +-
 .../metadata/iso/distribution/package-info.java    |   4 +-
 .../sis/metadata/iso/extent/DefaultExtent.java     |   2 +-
 .../iso/extent/DefaultGeographicBoundingBox.java   |   7 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |   2 +-
 .../metadata/iso/extent/DefaultVerticalExtent.java |   4 +-
 .../apache/sis/metadata/iso/extent/Extents.java    |   8 +-
 .../sis/metadata/iso/extent/package-info.java      |   4 +-
 .../DefaultAggregateInformation.java               |   2 +-
 .../identification/DefaultAssociatedResource.java  |   2 +-
 .../DefaultRepresentativeFraction.java             |   4 +-
 .../iso/identification/DefaultResolution.java      |  12 +-
 .../metadata/iso/identification/package-info.java  |   4 +-
 .../sis/metadata/iso/lineage/DefaultLineage.java   |   2 +-
 .../sis/metadata/iso/lineage/DefaultSource.java    |   2 +-
 .../sis/metadata/iso/lineage/package-info.java     |   4 +-
 .../iso/maintenance/DefaultScopeDescription.java   |  22 +-
 .../sis/metadata/iso/maintenance/package-info.java |   4 +-
 .../org/apache/sis/metadata/iso/package-info.java  |   6 +-
 .../metadata/iso/quality/DefaultDataQuality.java   |   2 +-
 .../iso/quality/DefaultQuantitativeResult.java     |   2 +-
 .../sis/metadata/iso/quality/package-info.java     |   4 +-
 .../metadata/iso/spatial/DefaultGeorectified.java  |   6 +-
 .../sis/metadata/iso/spatial/package-info.java     |   4 +-
 .../java/org/apache/sis/metadata/package-info.java |   8 +-
 .../apache/sis/metadata/sql/CachedStatement.java   |  33 +-
 .../org/apache/sis/metadata/sql/Dispatcher.java    |   2 +-
 .../sis/metadata/sql/IdentifierGenerator.java      |   2 +-
 .../apache/sis/metadata/sql/MetadataFallback.java  |  17 +-
 .../apache/sis/metadata/sql/MetadataSource.java    |  77 +-
 .../apache/sis/metadata/sql/MetadataWriter.java    |  28 +-
 .../org/apache/sis/metadata/sql/package-info.java  |   2 +-
 .../org/apache/sis/util/iso/AbstractFactory.java   |   2 +-
 .../java/org/apache/sis/util/iso/AbstractName.java |   4 +-
 .../org/apache/sis/util/iso/DefaultLocalName.java  |   4 +-
 .../org/apache/sis/util/iso/DefaultMemberName.java |   2 +-
 .../apache/sis/util/iso/DefaultNameFactory.java    |   2 +-
 .../org/apache/sis/util/iso/DefaultNameSpace.java  |   4 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |   6 +-
 .../apache/sis/util/iso/DefaultRecordSchema.java   |   4 +-
 .../org/apache/sis/util/iso/DefaultRecordType.java |   6 +-
 .../org/apache/sis/util/iso/DefaultScopedName.java |   2 +-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |   4 +-
 .../org/apache/sis/util/iso/GlobalNameSpace.java   |   2 +-
 .../main/java/org/apache/sis/util/iso/Names.java   |  22 +-
 .../org/apache/sis/util/iso/RecordDefinition.java  |   4 +-
 .../main/java/org/apache/sis/util/iso/Types.java   |   2 +-
 .../java/org/apache/sis/util/iso/package-info.java |   5 +-
 .../java/org/apache/sis/xml/IdentifiedObject.java  |   2 +-
 .../java/org/apache/sis/xml/Implementation.java    |  32 +-
 .../java/org/apache/sis/xml/MarshalContext.java    |  10 +-
 .../java/org/apache/sis/xml/MarshallerPool.java    |  35 +-
 .../main/java/org/apache/sis/xml/Namespaces.java   |  24 +-
 .../main/java/org/apache/sis/xml/NilObject.java    |   2 +-
 .../main/java/org/apache/sis/xml/NilReason.java    |   4 +-
 .../apache/sis/xml/OGCNamespacePrefixMapper.java   |  79 --
 .../sis/xml/OGCNamespacePrefixMapper_Endorsed.java |  73 --
 .../src/main/java/org/apache/sis/xml/Pooled.java   |  16 +-
 .../java/org/apache/sis/xml/ReferenceResolver.java |   2 +-
 .../main/java/org/apache/sis/xml/Transformer.java  |   2 +-
 .../java/org/apache/sis/xml/ValueConverter.java    |   6 +-
 .../src/main/java/org/apache/sis/xml/XLink.java    |  20 +-
 .../src/main/java/org/apache/sis/xml/XML.java      |  42 +-
 .../main/java/org/apache/sis/xml/package-info.java |   4 +-
 .../sis/internal/jaxb/cat/EnumMarshallingTest.java |   2 +-
 .../apache/sis/metadata/MetadataCopierTest.java    |  48 +-
 .../apache/sis/metadata/MetadataStandardTest.java  |   4 +-
 .../sis/metadata/ModifiableMetadataTest.java       |  10 +-
 .../java/org/apache/sis/metadata/NameMapTest.java  |   2 +-
 .../apache/sis/metadata/TreeNodeChildrenTest.java  |   2 +-
 .../sis/metadata/iso/CustomMetadataTest.java       |   2 +-
 .../apache/sis/metadata/iso/MarshallingTest.java   |  24 +-
 .../metadata/iso/citation/DefaultCitationTest.java |  23 +-
 .../metadata/iso/citation/DefaultContactTest.java  |  20 +-
 .../metadata/iso/citation/HardCodedCitations.java  |   8 +-
 .../identification/DefaultBrowseGraphicTest.java   |  17 +-
 .../DefaultRepresentativeFractionTest.java         |   4 +-
 .../sis/metadata/xml/SchemaComplianceTest.java     |  24 +-
 .../java/org/apache/sis/test/MetadataAssert.java   |   2 +-
 .../java/org/apache/sis/test/sql/TestDatabase.java |  13 +-
 .../apache/sis/test/suite/MetadataTestSuite.java   |   1 -
 .../org/apache/sis/test/xml/PackageVerifier.java   |  10 +-
 .../org/apache/sis/test/xml/SchemaCompliance.java  |   2 +-
 .../org/apache/sis/xml/MarshallerPoolTest.java     |   2 -
 .../sis/xml/OGCNamespacePrefixMapperTest.java      | 134 ---
 core/sis-referencing-by-identifiers/pom.xml        |   4 +
 .../referencing/gazetteer/FinalLocationType.java   |  20 +-
 .../gazetteer/GeohashReferenceSystem.java          |   2 +-
 .../sis/referencing/gazetteer/LocationFormat.java  |   2 +-
 .../gazetteer/MilitaryGridReferenceSystem.java     |  12 +-
 .../gazetteer/ModifiableLocationType.java          |   4 +-
 .../gazetteer/ReferencingByIdentifiers.java        |   2 +-
 .../sis/referencing/gazetteer/package-info.java    |   2 +-
 .../referencing/gazetteer/LocationTypeTest.java    |   2 +-
 core/sis-referencing/pom.xml                       |   9 +
 .../org/apache/sis/distance/DistanceUtils.java     | 102 ---
 .../org/apache/sis/geometry/AbstractEnvelope.java  |  33 +-
 .../org/apache/sis/geometry/ArrayEnvelope.java     |   4 +-
 .../org/apache/sis/geometry/DirectPosition2D.java  |   2 +-
 .../java/org/apache/sis/geometry/Envelope2D.java   |  27 +-
 .../java/org/apache/sis/geometry/Envelopes.java    |  10 +-
 .../apache/sis/geometry/GeneralDirectPosition.java |  20 +-
 .../org/apache/sis/geometry/GeneralEnvelope.java   |  33 +-
 .../org/apache/sis/geometry/ImmutableEnvelope.java |   2 +-
 .../java/org/apache/sis/geometry/package-info.java |   8 +-
 .../internal/jaxb/referencing/CC_Conversion.java   |   2 +-
 .../jaxb/referencing/CC_CoordinateOperation.java   |   2 +-
 .../referencing/CC_GeneralOperationParameter.java  |   2 +-
 .../jaxb/referencing/CC_GeneralParameterValue.java |   2 +-
 .../jaxb/referencing/CC_OperationMethod.java       |   2 +-
 .../jaxb/referencing/CC_OperationParameter.java    |   2 +-
 .../referencing/CC_OperationParameterGroup.java    |   2 +-
 .../internal/jaxb/referencing/CD_Ellipsoid.java    |   2 +-
 .../jaxb/referencing/CD_EngineeringDatum.java      |   2 +-
 .../jaxb/referencing/CD_GeodeticDatum.java         |   2 +-
 .../internal/jaxb/referencing/CD_ImageDatum.java   |   2 +-
 .../jaxb/referencing/CD_ParametricDatum.java       |   2 +-
 .../jaxb/referencing/CD_PrimeMeridian.java         |   2 +-
 .../jaxb/referencing/CD_TemporalDatum.java         |   2 +-
 .../jaxb/referencing/CD_VerticalDatum.java         |   2 +-
 .../sis/internal/jaxb/referencing/CS_AffineCS.java |   2 +-
 .../internal/jaxb/referencing/CS_CartesianCS.java  |   2 +-
 .../jaxb/referencing/CS_CoordinateSystem.java      |   2 +-
 .../jaxb/referencing/CS_CoordinateSystemAxis.java  |   2 +-
 .../jaxb/referencing/CS_CylindricalCS.java         |   2 +-
 .../jaxb/referencing/CS_EllipsoidalCS.java         |   2 +-
 .../sis/internal/jaxb/referencing/CS_LinearCS.java |   2 +-
 .../internal/jaxb/referencing/CS_ParametricCS.java |   2 +-
 .../sis/internal/jaxb/referencing/CS_PolarCS.java  |   2 +-
 .../internal/jaxb/referencing/CS_SphericalCS.java  |   2 +-
 .../sis/internal/jaxb/referencing/CS_TimeCS.java   |   2 +-
 .../jaxb/referencing/CS_UserDefinedCS.java         |   2 +-
 .../internal/jaxb/referencing/CS_VerticalCS.java   |   2 +-
 .../apache/sis/internal/jaxb/referencing/Code.java |   4 +-
 .../internal/jaxb/referencing/RS_Identifier.java   |   4 +-
 .../sis/internal/jaxb/referencing/SC_CRS.java      |   2 +-
 .../internal/jaxb/referencing/SC_SingleCRS.java    |   4 +-
 .../internal/jaxb/referencing/SC_VerticalCRS.java  |   2 +-
 .../internal/jaxb/referencing/package-info.java    |   2 +-
 .../internal/referencing/DefinitionVerifier.java   |  10 +-
 .../sis/internal/referencing/DeprecatedCode.java   |   2 +-
 .../sis/internal/referencing/EPSGFactoryProxy.java |   7 +-
 .../apache/sis/internal/referencing/Formulas.java  |   5 +-
 .../referencing/GeodeticObjectBuilder.java         |   2 +-
 .../internal/referencing/PositionTransformer.java  |   2 +-
 .../referencing/PositionalAccuracyConstant.java    |   5 +-
 .../apache/sis/internal/referencing/Resources.java |   5 +
 .../sis/internal/referencing/Resources.properties  |   1 +
 .../internal/referencing/Resources_fr.properties   |   1 +
 .../internal/referencing/SignReversalComment.java  |   3 +
 .../sis/internal/referencing/WKTKeywords.java      |   2 +-
 .../referencing/j2d/ImmutableAffineTransform.java  |   2 +-
 .../referencing/j2d/IntervalRectangle.java         |   2 +-
 .../referencing/provider/AbstractLambert.java      |  22 +
 .../referencing/provider/AbstractMercator.java     |  22 +
 .../provider/AbstractStereographic.java            |  22 +
 .../referencing/provider/AlbersEqualArea.java      |  89 +-
 .../internal/referencing/provider/EPSGName.java    |   2 +-
 .../sis/internal/referencing/provider/ESRI.java    | 107 ++-
 .../referencing/provider/Equirectangular.java      |  64 ++
 .../provider/FranceGeocentricInterpolation.java    |  10 +
 .../referencing/provider/GeocentricAffine.java     |  63 +-
 .../GeocentricAffineBetweenGeographic.java         |  56 ++
 .../referencing/provider/Geographic2Dto3D.java     |   6 +
 .../provider/GeographicAndVerticalOffsets.java     |   6 +
 .../referencing/provider/GeographicOffsets.java    |  18 +
 .../provider/GeographicToGeocentric.java           |  12 +
 .../referencing/provider/LambertConformal1SP.java  |  37 +
 .../referencing/provider/LambertConformal2SP.java  |  75 +-
 .../provider/LambertConformalMichigan.java         |  10 +
 .../referencing/provider/LambertConformalWest.java |  11 +
 .../provider/LambertCylindricalEqualArea.java      |  48 +
 .../referencing/provider/MapProjection.java        | 149 ++--
 .../internal/referencing/provider/Mercator1SP.java |  37 +
 .../internal/referencing/provider/Mercator2SP.java |  29 +-
 .../referencing/provider/MercatorSpherical.java    |   2 +-
 .../referencing/provider/MillerCylindrical.java    |   2 +-
 .../internal/referencing/provider/Mollweide.java   |  24 +
 .../internal/referencing/provider/Molodensky.java  |  26 +-
 .../sis/internal/referencing/provider/NADCON.java  |  22 +-
 .../sis/internal/referencing/provider/NTv2.java    |  10 +
 .../referencing/provider/ObliqueMercator.java      |  93 +-
 .../provider/ObliqueMercatorCenter.java            |  20 +
 .../referencing/provider/ObliqueStereographic.java |  33 +
 .../referencing/provider/Orthographic.java         | 196 +++++
 .../referencing/provider/PolarStereographicA.java  |  37 +
 .../referencing/provider/PolarStereographicB.java  |  43 +-
 .../referencing/provider/PolarStereographicC.java  |  22 +
 .../provider/PolarStereographicSouth.java          |   4 +-
 .../internal/referencing/provider/Polyconic.java   |  44 +
 .../referencing/provider/RegionalMercator.java     |  37 +
 .../referencing/provider/SatelliteTracking.java    | 205 +++++
 .../internal/referencing/provider/Sinusoidal.java  |  24 +
 .../referencing/provider/TransverseMercator.java   |  37 +-
 .../provider/ZonedTransverseMercator.java          |  21 +
 .../referencing/provider/package-info.java         |   3 +-
 .../java/org/apache/sis/io/wkt/Convention.java     |  13 +-
 .../java/org/apache/sis/io/wkt/ElementKind.java    |   2 +-
 .../org/apache/sis/io/wkt/FormattableObject.java   |   6 +-
 .../main/java/org/apache/sis/io/wkt/Formatter.java |   6 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |   6 +-
 .../org/apache/sis/io/wkt/MathTransformParser.java |  23 +-
 .../main/java/org/apache/sis/io/wkt/Symbols.java   |  16 +-
 .../java/org/apache/sis/io/wkt/Transliterator.java |   6 +-
 .../sis/io/wkt/UnparsableObjectException.java      |   2 +-
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java |  49 +-
 .../java/org/apache/sis/io/wkt/package-info.java   |   8 +-
 .../sis/parameter/DefaultParameterDescriptor.java  |   4 +-
 .../parameter/DefaultParameterDescriptorGroup.java |   6 +-
 .../sis/parameter/DefaultParameterValue.java       |  18 +-
 .../sis/parameter/DefaultParameterValueGroup.java  |   8 +-
 .../sis/parameter/MapProjectionParameters.java     |   8 +-
 .../org/apache/sis/parameter/ParameterBuilder.java |   8 +-
 .../org/apache/sis/parameter/Parameterized.java    |   4 +-
 .../java/org/apache/sis/parameter/Parameters.java  |  14 +-
 .../org/apache/sis/parameter/TensorParameters.java |  16 +-
 .../sis/parameter/UninitializedParameter.java      |   4 +-
 .../sis/parameter/UnmodifiableParameterValue.java  |   2 +-
 .../org/apache/sis/parameter/package-info.java     |   6 +-
 .../sis/referencing/AbstractIdentifiedObject.java  |  90 +-
 .../sis/referencing/AbstractReferenceSystem.java   |   4 +-
 .../java/org/apache/sis/referencing/Builder.java   |  67 +-
 .../main/java/org/apache/sis/referencing/CRS.java  | 102 +--
 .../java/org/apache/sis/referencing/CommonCRS.java |  41 +-
 .../sis/referencing/GeodesicsOnEllipsoid.java      | 337 ++++---
 .../apache/sis/referencing/GeodeticCalculator.java | 368 +++++---
 ...odesicException.java => GeodeticException.java} |  44 +-
 .../apache/sis/referencing/IdentifiedObjects.java  | 228 +++--
 .../iso => referencing}/ImmutableIdentifier.java   |  46 +-
 .../apache/sis/referencing/NamedIdentifier.java    |   9 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |   4 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  24 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |   8 +-
 .../sis/referencing/crs/DefaultEngineeringCRS.java |   6 +-
 .../sis/referencing/crs/DefaultGeocentricCRS.java  |   8 +-
 .../sis/referencing/crs/DefaultGeographicCRS.java  |  12 +-
 .../sis/referencing/crs/DefaultImageCRS.java       |   6 +-
 .../sis/referencing/crs/DefaultParametricCRS.java  |   6 +-
 .../sis/referencing/crs/DefaultProjectedCRS.java   |   6 +-
 .../sis/referencing/crs/DefaultTemporalCRS.java    |   6 +-
 .../sis/referencing/crs/DefaultVerticalCRS.java    |   6 +-
 .../sis/referencing/crs/SC_GeographicCRS.java      |   2 +-
 .../apache/sis/referencing/crs/package-info.java   |   2 +-
 .../org/apache/sis/referencing/cs/AbstractCS.java  |   8 +-
 .../apache/sis/referencing/cs/AxesConvention.java  |  15 +-
 .../org/apache/sis/referencing/cs/AxisFilter.java  |   6 +-
 .../sis/referencing/cs/CoordinateSystems.java      |  12 +-
 .../apache/sis/referencing/cs/DefaultAffineCS.java |   2 +-
 .../sis/referencing/cs/DefaultCartesianCS.java     |   6 +-
 .../sis/referencing/cs/DefaultCompoundCS.java      |   2 +-
 .../cs/DefaultCoordinateSystemAxis.java            |  14 +-
 .../sis/referencing/cs/DefaultCylindricalCS.java   |   6 +-
 .../sis/referencing/cs/DefaultEllipsoidalCS.java   |   6 +-
 .../apache/sis/referencing/cs/DefaultLinearCS.java |   6 +-
 .../sis/referencing/cs/DefaultParametricCS.java    |   6 +-
 .../apache/sis/referencing/cs/DefaultPolarCS.java  |   6 +-
 .../sis/referencing/cs/DefaultSphericalCS.java     |   6 +-
 .../apache/sis/referencing/cs/DefaultTimeCS.java   |   6 +-
 .../sis/referencing/cs/DefaultUserDefinedCS.java   |   6 +-
 .../sis/referencing/cs/DefaultVerticalCS.java      |   6 +-
 .../sis/referencing/cs/DirectionAlongMeridian.java |   4 +-
 .../sis/referencing/datum/AbstractDatum.java       |   6 +-
 .../sis/referencing/datum/BursaWolfParameters.java |  29 +-
 .../sis/referencing/datum/DatumShiftGrid.java      |  16 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    | 127 +--
 .../referencing/datum/DefaultEngineeringDatum.java |   6 +-
 .../referencing/datum/DefaultGeodeticDatum.java    |  18 +-
 .../sis/referencing/datum/DefaultImageDatum.java   |   6 +-
 .../referencing/datum/DefaultParametricDatum.java  |   8 +-
 .../referencing/datum/DefaultPrimeMeridian.java    |  12 +-
 .../referencing/datum/DefaultTemporalDatum.java    |   8 +-
 .../referencing/datum/DefaultVerticalDatum.java    |   8 +-
 .../org/apache/sis/referencing/datum/Sphere.java   |  30 +-
 .../sis/referencing/datum/TimeDependentBWP.java    |   2 +-
 .../apache/sis/referencing/datum/package-info.java |   5 +-
 .../factory/CommonAuthorityFactory.java            |   4 +-
 .../factory/ConcurrentAuthorityFactory.java        |  10 +-
 .../factory/GeodeticAuthorityFactory.java          | 145 +--
 .../referencing/factory/GeodeticObjectFactory.java |   6 +-
 .../factory/IdentifiedObjectFinder.java            |   4 +-
 .../referencing/factory/IdentifiedObjectSet.java   |   8 +-
 .../factory/MissingFactoryResourceException.java   |   2 +-
 .../factory/MultiAuthoritiesFactory.java           |  12 +-
 .../factory/UnavailableFactoryException.java       |   2 +-
 .../referencing/factory/sql/EPSGCodeFinder.java    |   2 +-
 .../referencing/factory/sql/EPSGDataAccess.java    |  75 +-
 .../sis/referencing/factory/sql/EPSGFactory.java   |   4 +-
 .../factory/sql/InstallationScriptProvider.java    |  10 +-
 .../sis/referencing/factory/sql/SQLTranslator.java |   2 +-
 .../sis/referencing/factory/sql/package-info.java  |   8 +-
 .../operation/AbstractCoordinateOperation.java     |  12 +-
 .../apache/sis/referencing/operation/CRSPair.java  |   2 +-
 .../operation/CoordinateOperationFinder.java       |   6 +-
 .../operation/CoordinateOperationRegistry.java     |   2 +-
 .../operation/DefaultConcatenatedOperation.java    |   6 +-
 .../referencing/operation/DefaultConversion.java   |   8 +-
 .../operation/DefaultOperationMethod.java          |  10 +-
 .../operation/DefaultPassThroughOperation.java     |   4 +-
 .../operation/DefaultTransformation.java           |   6 +-
 .../operation/InverseOperationMethod.java          |   2 +-
 .../operation/builder/LinearTransformBuilder.java  |   2 +-
 .../operation/builder/LocalizationGridBuilder.java |   2 +-
 .../operation/builder/ResidualGrid.java            |   2 +-
 .../operation/matrix/GeneralMatrix.java            |   2 +-
 .../sis/referencing/operation/matrix/Matrices.java |  15 +-
 .../sis/referencing/operation/matrix/Matrix1.java  |  15 +-
 .../sis/referencing/operation/matrix/Matrix2.java  |  15 +-
 .../sis/referencing/operation/matrix/Matrix3.java  |  13 +-
 .../sis/referencing/operation/matrix/Matrix4.java  |  13 +-
 .../referencing/operation/matrix/MatrixSIS.java    |   9 +-
 .../sis/referencing/operation/matrix/Solver.java   |   4 +-
 .../referencing/operation/matrix/package-info.java |  10 +-
 .../sis/referencing/operation/package-info.java    |   6 +-
 .../operation/projection/AlbersEqualArea.java      |   7 +-
 .../operation/projection/ConformalProjection.java  |   6 +-
 .../operation/projection/CylindricalEqualArea.java |   2 +-
 .../operation/projection/Initializer.java          |  16 +-
 .../referencing/operation/projection/Inverter.java | 105 +++
 .../projection/LambertConicConformal.java          |   9 +-
 .../referencing/operation/projection/Mercator.java |  10 +-
 .../operation/projection/Mollweide.java            |   8 +-
 .../operation/projection/NormalizedProjection.java |  36 +-
 .../operation/projection/ObliqueMercator.java      |   6 +-
 .../operation/projection/ObliqueStereographic.java |   9 +-
 .../operation/projection/Orthographic.java         | 261 ++++++
 .../operation/projection/Polyconic.java            |   2 +-
 .../operation/projection/ProjectionException.java  |   2 +-
 .../operation/projection/SatelliteTracking.java    | 377 ++++++++
 .../operation/projection/Sinusoidal.java           |   7 +-
 .../operation/projection/TransverseMercator.java   |   2 +-
 .../operation/projection/ZonedGridSystem.java      |   2 +-
 .../operation/projection/package-info.java         |  26 +-
 .../transform/AbstractLinearTransform.java         |   6 +-
 .../operation/transform/AbstractMathTransform.java |  12 +-
 .../transform/AbstractMathTransform1D.java         |   6 +-
 .../transform/AbstractMathTransform2D.java         |   6 +-
 .../operation/transform/ConcatenatedTransform.java |   7 +-
 .../operation/transform/ContextualParameter.java   |   2 +-
 .../operation/transform/ContextualParameters.java  |  34 +-
 .../transform/CoordinateSystemTransform.java       |   2 +-
 .../operation/transform/DatumShiftTransform.java   |  35 +-
 .../transform/DefaultMathTransformFactory.java     |  12 +-
 .../transform/EllipsoidToCentricTransform.java     |   4 +-
 .../transform/ExponentialTransform1D.java          |   2 +-
 .../transform/InterpolatedGeocentricTransform.java |   4 +-
 .../transform/InterpolatedMolodenskyTransform.java |   2 +-
 .../operation/transform/InterpolatedTransform.java |  10 +-
 .../operation/transform/IterationStrategy.java     |  17 +-
 .../operation/transform/LinearInterpolator1D.java  |   2 +-
 .../operation/transform/LinearTransform.java       |  12 +-
 .../transform/LogarithmicTransform1D.java          |   2 +-
 .../operation/transform/MathTransformProvider.java |   4 +-
 .../operation/transform/MathTransforms.java        |   2 +-
 .../operation/transform/MolodenskyFormula.java     |   2 +-
 .../operation/transform/MolodenskyTransform.java   |   2 +-
 .../operation/transform/OperationMethodSet.java    |   4 +-
 .../operation/transform/PassThroughTransform.java  |  17 +-
 .../operation/transform/PowerTransform1D.java      |   2 +-
 .../transform/SpecializableTransform.java          |   2 +-
 .../operation/transform/TransferFunction.java      |   4 +-
 .../referencing/operation/transform/formulas.html  |  12 +-
 .../operation/transform/package-info.java          |   4 +-
 .../org/apache/sis/referencing/package-info.java   |   8 +-
 ...g.opengis.referencing.operation.OperationMethod |   2 +
 .../referencing/provider/Descriptions.properties   |   5 +
 .../apache/sis/distance/LatLonPointRadiusTest.java |  89 --
 .../apache/sis/geometry/CoordinateFormatTest.java  |   2 +-
 .../sis/internal/jaxb/referencing/CodeTest.java    |   2 +-
 .../internal/referencing/provider/NTv2Test.java    |   2 +-
 .../provider/ParameterNameTableGenerator.java      | 325 +++++++
 .../referencing/provider/ProvidersTest.java        |  16 +-
 .../apache/sis/io/wkt/MathTransformParserTest.java |  21 +-
 .../parameter/DefaultParameterDescriptorTest.java  |   2 +-
 .../sis/parameter/DefaultParameterValueTest.java   |   2 +-
 .../sis/parameter/ParameterValueGroupWrapper.java  |   3 +-
 .../referencing/AbstractIdentifiedObjectTest.java  |   1 -
 .../referencing/AbstractReferenceSystemTest.java   |   1 -
 .../org/apache/sis/referencing/BuilderTest.java    |   1 -
 .../java/org/apache/sis/referencing/CRSTest.java   |  16 +-
 .../apache/sis/referencing/ClenshawSummation.java  | 460 ++++++++++
 .../org/apache/sis/referencing/CommonCRSTest.java  |  14 +-
 .../sis/referencing/GeodesicsOnEllipsoidTest.java  |  97 ++-
 .../sis/referencing/GeodeticCalculatorTest.java    | 105 ++-
 .../ImmutableIdentifierTest.java                   |   2 +-
 .../referencing/crs/DefaultGeocentricCRSTest.java  |   2 +-
 .../apache/sis/referencing/cs/NormalizerTest.java  |   2 +-
 .../referencing/datum/DefaultEllipsoidTest.java    |  85 +-
 .../datum/DefaultTemporalDatumTest.java            |   2 +-
 .../referencing/factory/sql/EPSGInstallerTest.java |  13 +-
 .../factory/sql/epsg/DataScriptFormatter.java      |  10 +-
 .../epsg/{MethodDimensions.sql => DebugTools.sql}  |   8 +-
 .../sis/referencing/factory/sql/epsg/package.html  | 138 +--
 .../operation/DefaultOperationMethodTest.java      |   2 +-
 .../operation/matrix/MatrixTestCase.java           |   2 +-
 .../referencing/operation/matrix/SolverTest.java   |   2 +-
 .../projection/LambertConicConformalTest.java      |   2 +-
 .../operation/projection/OrthographicTest.java     | 162 ++++
 .../projection/SatelliteTrackingTest.java          | 407 +++++++++
 .../transform/DefaultMathTransformFactoryTest.java |   9 +-
 .../report/CoordinateReferenceSystems.java         | 487 ++++-------
 .../sis/referencing/report/package-info.java       |   2 +-
 .../sis/test/integration/ConsistencyTest.java      |   2 +-
 .../test/integration/CoordinateOperationTest.java  |  79 +-
 .../apache/sis/test/integration/MetadataTest.java  | 247 ++----
 .../sis/test/integration/MetadataVerticalTest.java | 214 +++++
 .../sis/test/suite/ReferencingTestSuite.java       |  10 +-
 .../org/apache/sis/test/widget/package-info.java   |   2 +-
 .../org/apache/sis/test/integration/Metadata.xml   |  63 +-
 .../sis/internal/converter/AngleConverter.java     |   4 +-
 .../sis/internal/converter/ArrayConverter.java     |   2 +-
 .../internal/converter/CharSequenceConverter.java  |   2 +-
 .../apache/sis/internal/converter/ClassPair.java   |   2 +-
 .../internal/converter/CollectionConverter.java    |   2 +-
 .../sis/internal/converter/ConverterRegistry.java  |  17 +-
 .../sis/internal/converter/DateConverter.java      |   6 +-
 .../sis/internal/converter/FallbackConverter.java  |   2 +-
 .../sis/internal/converter/IdentityConverter.java  |   2 +-
 .../sis/internal/converter/NumberConverter.java    |   4 +-
 .../sis/internal/converter/ObjectToString.java     |   2 +-
 .../sis/internal/converter/PathConverter.java      |   2 +-
 .../sis/internal/converter/StringConverter.java    |   6 +-
 .../sis/internal/converter/SystemConverter.java    |   7 +-
 .../sis/internal/converter/SystemRegistry.java     |   2 +-
 .../sis/internal/converter/package-info.java       |   2 +-
 .../java/org/apache/sis/internal/jdk9/JDK9.java    |  19 +-
 .../org/apache/sis/internal/jdk9/package-info.java |   2 +-
 .../apache/sis/internal/system/DaemonThread.java   |   4 +-
 .../sis/internal/system/DelayedExecutor.java       |   2 +-
 .../sis/internal/system/DelayedRunnable.java       |   8 +-
 .../org/apache/sis/internal/system/Modules.java    |  12 +-
 .../org/apache/sis/internal/system/Supervisor.java |   2 -
 .../org/apache/sis/internal/system/Threads.java    |   8 +-
 .../sis/internal/util/AutoMessageFormat.java       |   2 +-
 .../apache/sis/internal/util/CheckedArrayList.java |   2 +-
 .../apache/sis/internal/util/CollectionsExt.java   |  24 +-
 .../org/apache/sis/internal/util/Constants.java    |   2 +-
 .../apache/sis/internal/util/DefinitionURI.java    |   4 +-
 .../org/apache/sis/internal/util/DoubleDouble.java |  12 +-
 .../apache/sis/internal/util/MetadataServices.java |  25 +
 .../org/apache/sis/internal/util/Numerics.java     |   2 +-
 .../java/org/apache/sis/internal/util/Strings.java |  55 +-
 .../sis/internal/util/TemporalUtilities.java       |   2 -
 .../sis/internal/util/UnmodifiableArrayList.java   |   8 +-
 .../org/apache/sis/internal/util/package-info.java |   4 +-
 .../src/main/java/org/apache/sis/io/Appender.java  |   2 +-
 .../main/java/org/apache/sis/io/ClassFormat.java   |   4 +-
 .../java/org/apache/sis/io/CompoundFormat.java     |   6 +-
 .../main/java/org/apache/sis/io/DefaultFormat.java |   2 +-
 .../org/apache/sis/io/IdentifiedObjectFormat.java  |   2 +-
 .../main/java/org/apache/sis/io/LineAppender.java  |   2 +-
 .../main/java/org/apache/sis/io/TableAppender.java |   9 +-
 .../main/java/org/apache/sis/io/TabularFormat.java |   4 +-
 .../main/java/org/apache/sis/io/package-info.java  |   4 +-
 .../apache/sis/math/CompoundDirectPositions.java   |   2 +-
 .../java/org/apache/sis/math/DecimalFunctions.java |   6 +-
 .../java/org/apache/sis/math/MathFunctions.java    |   6 +-
 .../src/main/java/org/apache/sis/math/Plane.java   |   3 +-
 .../main/java/org/apache/sis/math/Statistics.java  |   5 +-
 .../src/main/java/org/apache/sis/math/Vector.java  |  10 +-
 .../org/apache/sis/measure/AbstractConverter.java  |   2 +-
 .../main/java/org/apache/sis/measure/Angle.java    |   6 +-
 .../java/org/apache/sis/measure/AngleFormat.java   |   1 +
 .../apache/sis/measure/ConcatenatedConverter.java  |   2 +-
 .../org/apache/sis/measure/ConventionalUnit.java   |   4 +-
 .../org/apache/sis/measure/ElevationAngle.java     |   2 +-
 .../sis/measure/FormattedCharacterIterator.java    |   4 +-
 .../org/apache/sis/measure/IdentityConverter.java  | 109 +++
 .../main/java/org/apache/sis/measure/Latitude.java |   2 +-
 .../org/apache/sis/measure/LinearConverter.java    |  49 +-
 .../java/org/apache/sis/measure/Longitude.java     |   2 +-
 .../org/apache/sis/measure/MeasurementRange.java   |   6 +-
 .../java/org/apache/sis/measure/NumberRange.java   |   8 +-
 .../main/java/org/apache/sis/measure/Range.java    |  12 +-
 .../java/org/apache/sis/measure/RangeFormat.java   |   4 +-
 .../apache/sis/measure/SexagesimalConverter.java   |   2 +-
 .../java/org/apache/sis/measure/SystemUnit.java    |   4 +-
 .../java/org/apache/sis/measure/UnitFormat.java    |  10 +-
 .../main/java/org/apache/sis/measure/Units.java    | 293 ++++---
 .../src/main/java/org/apache/sis/setup/About.java  |  21 +-
 .../java/org/apache/sis/setup/Configuration.java   | 142 +++
 .../main/java/org/apache/sis/setup/OptionKey.java  |  10 +-
 .../java/org/apache/sis/util/ArgumentChecks.java   |  27 +-
 .../main/java/org/apache/sis/util/ArraysExt.java   |   6 +-
 .../java/org/apache/sis/util/CharSequences.java    |  29 +-
 .../main/java/org/apache/sis/util/Characters.java  |   2 +-
 .../src/main/java/org/apache/sis/util/Classes.java |   2 +-
 .../java/org/apache/sis/util/ComparisonMode.java   |  28 +-
 .../java/org/apache/sis/util/Configuration.java    |   8 +-
 .../apache/sis/util/CorruptedObjectException.java  |   2 +-
 .../main/java/org/apache/sis/util/Disposable.java  |   2 +-
 .../org/apache/sis/util/LenientComparable.java     |   9 +-
 .../java/org/apache/sis/util/ObjectConverter.java  |   2 +-
 .../java/org/apache/sis/util/StringBuilders.java   |  35 +-
 .../main/java/org/apache/sis/util/Utilities.java   |  14 +-
 .../src/main/java/org/apache/sis/util/Version.java |   6 +-
 .../sis/util/collection/BackingStoreException.java |  24 +-
 .../java/org/apache/sis/util/collection/Cache.java |   6 +-
 .../apache/sis/util/collection/CacheEntries.java   |   2 +-
 .../apache/sis/util/collection/CodeListSet.java    |   4 +-
 .../sis/util/collection/DefaultTreeTable.java      |   2 +-
 .../org/apache/sis/util/collection/DerivedMap.java |   4 +-
 .../org/apache/sis/util/collection/DerivedSet.java |   4 +-
 .../org/apache/sis/util/collection/RangeSet.java   |   6 +-
 .../apache/sis/util/collection/TableColumn.java    |   2 +-
 .../apache/sis/util/collection/TreeNodeList.java   |   2 +-
 .../org/apache/sis/util/collection/TreeTable.java  |   9 +-
 .../sis/util/collection/TreeTableFormat.java       |   8 +-
 .../org/apache/sis/util/collection/TreeTables.java |   2 +-
 .../org/apache/sis/util/collection/WeakEntry.java  |  13 +-
 .../apache/sis/util/collection/WeakHashSet.java    |  11 +-
 .../sis/util/collection/WeakValueHashMap.java      |   9 +-
 .../sis/util/iso/AbstractInternationalString.java  |  10 +-
 .../sis/util/iso/DefaultInternationalString.java   |   6 +-
 .../sis/util/iso/ResourceInternationalString.java  |  12 +-
 .../sis/util/iso/SimpleInternationalString.java    |   6 +-
 .../org/apache/sis/util/logging/LoggerAdapter.java |   8 +-
 .../org/apache/sis/util/logging/LoggerFactory.java |   2 +-
 .../java/org/apache/sis/util/logging/Logging.java  |  53 +-
 .../apache/sis/util/logging/MonolineFormatter.java |  11 +-
 .../apache/sis/util/logging/PerformanceLevel.java  |   2 +-
 .../apache/sis/util/logging/WarningListener.java   |  78 --
 .../apache/sis/util/logging/WarningListeners.java  | 382 --------
 .../org/apache/sis/util/logging/package-info.java  |   6 +-
 .../java/org/apache/sis/util/resources/Errors.java |   2 +-
 .../sis/util/resources/IndexedResourceBundle.java  |  14 +-
 .../resources/ResourceInternationalString.java     |   2 +-
 .../org/apache/sis/util/resources/Vocabulary.java  | 369 ++++----
 .../sis/util/resources/Vocabulary.properties       |   5 +-
 .../sis/util/resources/Vocabulary_fr.properties    |   5 +-
 .../apache/sis/util/resources/package-info.java    |   2 +-
 .../measure/FormattedCharacterIteratorTest.java    |   2 +-
 .../apache/sis/measure/LinearConverterTest.java    |  14 +-
 .../org/apache/sis/measure/QuantitiesTest.java     |  17 +
 .../org/apache/sis/test/ProjectDirectories.java    | 164 ++++
 .../test/java/org/apache/sis/test/TestCase.java    |   4 +
 .../org/apache/sis/test/TestConfiguration.java     |   9 +-
 .../test/java/org/apache/sis/test/TestSuite.java   |  35 +-
 .../java/org/apache/sis/test/package-info.java     |   4 +-
 .../apache/sis/test/suite/UtilityTestSuite.java    |   1 -
 .../sis/util/logging/EmptyWarningListeners.java    |  71 --
 .../sis/util/logging/WarningListenersTest.java     | 117 ---
 ide-project/NetBeans/build.xml                     |   1 +
 ide-project/NetBeans/nbproject/build-impl.xml      |  52 +-
 ide-project/NetBeans/nbproject/genfiles.properties |   6 +-
 ide-project/NetBeans/nbproject/project.properties  |  71 +-
 ide-project/NetBeans/nbproject/project.xml         |   5 +-
 pom.xml                                            |  84 +-
 profiles/sis-french-profile/pom.xml                |   5 +
 .../apache/sis/profile/france/package-info.java    |   2 +-
 .../apache/sis/internal/earth/netcdf/GCOM_C.java   |   2 +-
 .../sis/internal/earth/netcdf/package-info.java    |   2 +-
 .../apache/sis/profile/japan/JapaneseProfile.java  |  25 +-
 src/main/config/logging.properties                 |   2 +-
 src/main/javadoc/overview.html                     |   4 +-
 src/main/javadoc/sis.css                           |  58 +-
 .../storage/earthobservation/LandsatReader.java    |  15 +-
 .../sis/storage/earthobservation/LandsatStore.java |  57 +-
 .../earthobservation/LandsatStoreProvider.java     |   2 +-
 .../earthobservation/LandsatReaderTest.java        |   7 +-
 .../sis/storage/earthobservation/LandsatTest.txt   |   2 +-
 .../org/apache/sis/storage/gdal/Proj4Factory.java  |   6 +-
 .../org/apache/sis/storage/gdal/package-info.java  |   4 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |  52 +-
 .../sis/storage/geotiff/GeoTiffStoreProvider.java  |   2 +-
 .../sis/storage/geotiff/GridGeometryBuilder.java   |   2 +-
 .../sis/storage/geotiff/ImageFileDirectory.java    |   8 +-
 .../org/apache/sis/internal/netcdf/Convention.java |  40 +-
 .../org/apache/sis/internal/netcdf/Decoder.java    |   7 +-
 .../sis/internal/netcdf/DiscreteSampling.java      |   7 +-
 .../apache/sis/internal/netcdf/NamedElement.java   |   4 +-
 .../java/org/apache/sis/internal/netcdf/Node.java  |   7 +-
 .../apache/sis/internal/netcdf/RasterResource.java |  79 +-
 .../org/apache/sis/internal/netcdf/Variable.java   |  14 +-
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |  13 +-
 .../sis/internal/netcdf/impl/FeaturesInfo.java     |  10 +-
 .../sis/internal/netcdf/impl/VariableInfo.java     |  10 +-
 .../apache/sis/internal/netcdf/package-info.java   |   2 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |  15 +-
 .../sis/internal/netcdf/ucar/FeaturesWrapper.java  |   5 +-
 .../sis/internal/netcdf/ucar/LogAdapter.java       |  11 +-
 .../sis/internal/netcdf/ucar/VariableWrapper.java  |   4 +-
 .../apache/sis/storage/netcdf/AttributeNames.java  |   3 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  |  34 +-
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |  40 +-
 .../sis/storage/netcdf/NetcdfStoreProvider.java    |  22 +-
 .../apache/sis/storage/netcdf/package-info.java    |   2 +-
 .../org/apache/sis/internal/netcdf/TestCase.java   |  11 +-
 .../internal/netcdf/impl/ChannelDecoderTest.java   |   3 +-
 .../storage/netcdf/NetcdfStoreProviderTest.java    |   9 +-
 .../apache/sis/internal/shapefile/AutoChecker.java |   4 +-
 .../internal/shapefile/ShapefileByteReader.java    |  64 +-
 .../internal/shapefile/ShapefileDescriptor.java    |   6 +-
 .../sis/storage/shapefile/InputFeatureStream.java  |   2 +-
 .../jdbc/AbstractTestBaseForInternalJDBC.java      |   2 +-
 .../sis/storage/shapefile/ShapeFileTest.java       |   4 +-
 .../apache/sis/internal/sql/feature/Analyzer.java  |   7 +-
 .../apache/sis/internal/sql/feature/Database.java  |   5 +-
 .../apache/sis/internal/sql/feature/Features.java  |   6 +-
 .../sis/internal/sql/feature/TableReference.java   |  11 +-
 .../java/org/apache/sis/storage/sql/SQLStore.java  |  41 +-
 .../apache/sis/storage/sql/SQLStoreProvider.java   |  11 +-
 .../org/apache/sis/storage/sql/package-info.java   |   2 +-
 storage/sis-storage/pom.xml                        |   5 +
 .../apache/sis/index/tree}/LatLonPointRadius.java  |  94 +-
 .../java/org/apache/sis/index/tree/QuadTree.java   |   8 +-
 .../org/apache/sis/index/tree/QuadTreeWriter.java  |   1 +
 .../sis/internal/storage/AbstractFeatureSet.java   |  22 +-
 .../sis/internal/storage/AbstractGridResource.java |  43 +-
 .../sis/internal/storage/AbstractResource.java     |  95 +-
 .../sis/internal/storage/AggregatedFeatureSet.java |  32 +-
 .../apache/sis/internal/storage/Capability.java    |  10 +-
 .../internal/storage/ConcatenatedFeatureSet.java   |  23 +-
 .../internal/storage/DocumentedStoreProvider.java  |   7 +-
 .../sis/internal/storage/JoinFeatureSet.java       |  11 +-
 .../sis/internal/storage/MemoryFeatureSet.java     |  11 +-
 .../sis/internal/storage/MetadataBuilder.java      |  30 +-
 .../sis/internal/storage/ResourceOnFileSystem.java |   2 +-
 .../org/apache/sis/internal/storage/Resources.java |  20 +
 .../sis/internal/storage/Resources.properties      |   4 +
 .../sis/internal/storage/Resources_fr.properties   |   4 +
 .../apache/sis/internal/storage/StoreMetadata.java |  15 +-
 .../apache/sis/internal/storage/URIDataStore.java  |  38 +-
 .../org/apache/sis/internal/storage/csv/Store.java |   6 +-
 .../sis/internal/storage/csv/StoreProvider.java    |  12 +-
 .../sis/internal/storage/csv/package-info.java     |   2 +-
 .../storage/folder/FolderStoreProvider.java        |   9 +-
 .../apache/sis/internal/storage/folder/Store.java  |  36 +-
 .../sis/internal/storage/io/ChannelData.java       |   2 +-
 .../sis/internal/storage/io/ChannelDataInput.java  |   4 +-
 .../sis/internal/storage/io/ChannelDataOutput.java |   4 +-
 .../sis/internal/storage/io/ChannelFactory.java    |  43 +-
 .../storage/io/ChannelImageInputStream.java        |   2 +-
 .../internal/storage/io/HyperRectangleReader.java  |  13 +-
 .../sis/internal/storage/io/IOUtilities.java       |   2 +-
 .../internal/storage/io/InputStreamAdapter.java    |   2 +-
 .../org/apache/sis/internal/storage/io/Region.java |  78 +-
 .../sis/internal/storage/io/package-info.java      |   2 +-
 .../apache/sis/internal/storage/package-info.java  |   2 +-
 .../sis/internal/storage/query/CoverageQuery.java  | 259 ++++++
 .../sis/internal/storage/query/CoverageSubset.java | 181 ++++
 .../sis/internal/storage/query/FeatureSubset.java  |  24 +-
 .../sis/internal/storage/query/SimpleQuery.java    | 167 ++--
 .../internal/storage/query/SortByComparator.java   |   4 +-
 .../sis/internal/storage/query/package-info.java   |   2 +-
 .../org/apache/sis/internal/storage/wkt/Store.java |   2 +-
 .../sis/internal/storage/wkt/StoreFormat.java      |  16 +-
 .../sis/internal/storage/xml/MimeTypeDetector.java |   2 +-
 .../org/apache/sis/internal/storage/xml/Store.java |  39 +-
 .../java/org/apache/sis/storage/Aggregate.java     |   4 +-
 .../main/java/org/apache/sis/storage/DataSet.java  |   2 +-
 .../java/org/apache/sis/storage/DataStore.java     | 135 +--
 .../org/apache/sis/storage/DataStoreException.java |   4 +-
 .../org/apache/sis/storage/DataStoreProvider.java  |  59 +-
 .../org/apache/sis/storage/DataStoreRegistry.java  |   6 +-
 .../java/org/apache/sis/storage/DataStores.java    |   2 +-
 .../java/org/apache/sis/storage/FeatureNaming.java |   4 +-
 .../apache/sis/storage/GridCoverageResource.java   |  38 +-
 .../apache/sis/storage/IllegalNameException.java   |   2 +-
 ...NameException.java => NoSuchDataException.java} |  44 +-
 .../java/org/apache/sis/storage/ProbeResult.java   |   6 +-
 .../main/java/org/apache/sis/storage/Query.java    |   4 +-
 .../main/java/org/apache/sis/storage/Resource.java |  62 +-
 .../org/apache/sis/storage/StorageConnector.java   |  13 +-
 .../org/apache/sis/storage/WritableAggregate.java  |   2 +-
 .../sis/storage/WritableGridCoverageResource.java  |   4 +-
 .../org/apache/sis/storage/event/ChangeEvent.java  |  60 --
 .../apache/sis/storage/event/ChangeListener.java   |  54 --
 .../apache/sis/storage/event}/QuietLogRecord.java  |  14 +-
 .../org/apache/sis/storage/event/StoreEvent.java   |  91 ++
 .../apache/sis/storage/event/StoreListener.java    |  56 ++
 .../apache/sis/storage/event/StoreListeners.java   | 613 +++++++++++++
 .../org/apache/sis/storage/event/WarningEvent.java |  90 ++
 .../org/apache/sis/storage/event/package-info.java |  20 +-
 .../java/org/apache/sis/storage/package-info.java  |   2 +-
 .../internal/storage/AbstractGridResourceTest.java |   3 -
 .../java/org/apache/sis/storage/DataStoreMock.java |  45 +-
 .../sis/storage/event/StoreListenersTest.java      | 109 +++
 .../apache/sis/test/suite/StorageTestSuite.java    |   1 +
 storage/sis-xmlstore/pom.xml                       |   5 +
 .../storage/gpx/GroupAsPolylineOperation.java      |   3 +
 .../sis/internal/storage/gpx/StoreProvider.java    |  10 +-
 .../internal/storage/xml/stream/StaxDataStore.java |  31 +-
 .../internal/storage/xml/stream/StaxStreamIO.java  |   2 +-
 .../storage/xml/stream/StaxStreamReader.java       |  12 +-
 .../storage/xml/stream/StaxStreamWriter.java       |   4 +-
 991 files changed, 27940 insertions(+), 9684 deletions(-)

diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
index b8c90a3,8d27c54..3dbf6bf
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
@@@ -53,17 -33,15 +52,20 @@@ import org.opengis.filter.spatial.Withi
  import org.opengis.filter.temporal.*;
  import org.opengis.geometry.Envelope;
  import org.opengis.geometry.Geometry;
 +import org.opengis.referencing.NoSuchAuthorityCodeException;
 +import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.util.FactoryException;
  import org.opengis.util.GenericName;
- 
- import org.apache.sis.geometry.GeneralEnvelope;
- import org.apache.sis.geometry.ImmutableEnvelope;
+ import org.apache.sis.internal.system.Modules;
+ import org.apache.sis.internal.system.SystemListener;
  import org.apache.sis.internal.feature.FunctionRegister;
+ import org.apache.sis.internal.feature.Resources;
  import org.apache.sis.referencing.CRS;
  import org.apache.sis.util.collection.BackingStoreException;
 -import org.opengis.util.FactoryException;
 +
++import org.apache.sis.geometry.GeneralEnvelope;
++import org.apache.sis.geometry.ImmutableEnvelope;
+ 
  
  /**
   * Default implementation of GeoAPI filter factory for creation of {@link Filter} and {@link Expression} instances.
diff --cc core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
index cc40a87,22783ba..1846bc2
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/package-info.java
@@@ -19,54 -19,17 +19,58 @@@
   * Filters features according their properties.
   * A <cite>filter expression</cite> is a construct used to constraint a feature set to a subset.
   *
 + * All operations in this package try to follow rules of both following standards:
 + * <ul>
 + *     <li><a href="https://www.iso.org/fr/standard/53698.html">ISO/IEC 13249-3:2011 - SQLMM</a></li>
 + *     <li><a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC® Filter Encoding 2.0 Encoding Standard</a></li>
 + * </ul>
 + *
 + * <div class="section">General considerations:</div>
 + * <div class="section">Coordinate reference system handling:</div>
 + * As stated by Filter encoding 2.0.2, section 7.8.4, heterogeneous coordinate reference systems must be handled by
 + * libraries, one way or another. The standard does not define any strategy. As Apache-SIS contains a powerful
 + * transform system, we'll try to handle differences in the following way:
 + * <ul>
 + *     <li>
 + *         If all evaluated geometries define a srid, but their not the same, we'll try to project them in a common
 + *         space. The strategy will be guided by {@link org.apache.sis.referencing.CRS#suggestCommonTarget(org.opengis.metadata.extent.GeographicBoundingBox, org.opengis.referencing.crs.CoordinateReferenceSystem...) Referencing utility method}.
 + *         If it cannot provide a common space, we will fail any ongoing operation.
 + *     </li>
 + *     <li>
 + *         Missing information:
 + *         <ul>
 + *              <li>If no geometry contains any srid, consider they're defined in the same space, and proceed</li>
 + *              <li>If one geometry define a CRS but the other do not, consider that an ambiguity resides: fail.</li>
 + *         </ul>
 + *     </li>
 + * </ul>
 + *
 + * <div class="section">Optimisations</div>
 + * For now, few to no optimisation is done in the operators. Most of important ones would require one of the two
 + * following things:
 + * <ul>
 + *     <li>
 + *         Context information: Filters does not know in advance the feature type they're operating upon, which is
 + *         vital to define some calculus parameters, as property value conversion strategy, spatial system changes, etc.
 + *         Such information would allow operators to prepare data at initialisation time.
 + *     </li>
 + *     <li>
 + *         User hints: some operations could be set faster at the cost of precision. To activate such things, it would
 + *         require user consent. Most naïve example is spatial reference system conversion, which could be de-activated
 + *         for systems with nearly equal parameters (see {@link org.apache.sis.util.Utilities#equalsApproximately(java.lang.Object, java.lang.Object)}.
 + *     </li>
 + * </ul>
-  * extra-information for
-  * the operator, as well as hints from the user to allow sac
++ *
++ * <div class="section">Thread-safety</div>
+  * <p>All filter and expression implementations provided by Apache SIS are thread-safe.
+  * They are not necessarily stateless however; for example a filter may remember which
+  * warnings have been reported in order to avoid to report the same warning twice.</p>
+  *
   * @author  Johann Sorel (Geomatys)
   * @author  Martin Desruisseaux (Geomatys)
-  * @version 1.0
+  * @version 1.1
   *
 - * @see <a href="http://docs.opengeospatial.org/is/09-026r2/09-026r2.html">OGC® Filter Encoding 2.0 Encoding Standard</a>
 - *
 - * @since 1.1
 + * @since 1.0
   * @module
   */
  package org.apache.sis.filter;
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
index cca1b26,f32b4f9..47486eb
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/ESRI.java
@@@ -16,19 -16,25 +16,33 @@@
   */
  package org.apache.sis.internal.feature;
  
 +import java.nio.ByteBuffer;
  import java.util.Iterator;
 +import java.util.stream.Stream;
 +
+ import com.esri.core.geometry.Geometry;
+ import com.esri.core.geometry.Envelope2D;
+ import com.esri.core.geometry.MultiPath;
+ import com.esri.core.geometry.Polyline;
+ import com.esri.core.geometry.Polygon;
+ import com.esri.core.geometry.Point;
+ import com.esri.core.geometry.Point2D;
+ import com.esri.core.geometry.Point3D;
+ import com.esri.core.geometry.WktImportFlags;
+ import com.esri.core.geometry.WktExportFlags;
+ import com.esri.core.geometry.OperatorImportFromWkt;
+ import com.esri.core.geometry.OperatorExportToWkt;
+ import com.esri.core.geometry.OperatorCentroid2D;
++
  import org.apache.sis.geometry.GeneralEnvelope;
 -import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.math.Vector;
 +import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.util.Classes;
  
 +import com.esri.core.geometry.*;
 +
 +import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 +
  
  /**
   * Centralizes some usages of ESRI geometry API by Apache SIS.
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
index 46881bf,f92634a..fa6856d
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
@@@ -17,27 -17,20 +17,33 @@@
  package org.apache.sis.internal.feature;
  
  import java.util.Iterator;
 +import java.util.Optional;
 +import java.util.function.Function;
  import java.util.logging.Level;
  import java.util.logging.LogRecord;
 +import java.util.stream.Stream;
 +
 +import org.opengis.geometry.DirectPosition;
 +import org.opengis.geometry.Envelope;
 +import org.opengis.geometry.Geometry;
 +import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.referencing.crs.SingleCRS;
 +import org.opengis.referencing.cs.CoordinateSystemAxis;
+ import org.opengis.util.FactoryException;
+ import org.opengis.referencing.operation.TransformException;
+ import org.opengis.referencing.operation.CoordinateOperation;
 -import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +
 +import org.apache.sis.geometry.GeneralEnvelope;
 +import org.apache.sis.internal.referencing.AxisDirections;
  import org.apache.sis.internal.system.Loggers;
 +import org.apache.sis.math.Vector;
 +import org.apache.sis.referencing.CRS;
 +import org.apache.sis.setup.GeometryLibrary;
 +import org.apache.sis.util.collection.BackingStoreException;
  import org.apache.sis.util.logging.Logging;
+ import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.UnsupportedImplementationException;
+ import org.apache.sis.util.Classes;
 -import org.apache.sis.geometry.GeneralEnvelope;
 -import org.apache.sis.setup.GeometryLibrary;
 -import org.apache.sis.math.Vector;
  
  
  /**
@@@ -159,19 -166,35 +179,48 @@@ public abstract class Geometries<G> 
      }
  
      /**
 +     * Transforms an envelope to a polygon whose start point is lower corner, and points composing result are the
 +     * envelope corners in clockwise order.
 +     * @param env The envelope to convert.
 +     * @param wraparound How to resolve wrap-around ambiguities on the envelope.
 +     * @return If any geometric implementation is installed, return a polygon (or two polygons in case of
 +     * {@link WrapResolution#SPLIT split handling of wrap-around}.
 +     */
 +    public static Optional<Geometry> toGeometry(final Envelope env, WrapResolution wraparound) {
 +        return findStrategy(g -> g.tryConvertToGeometry(env, wraparound))
 +                .map(result -> new GeometryWrapper(result, env));
 +    }
 +
 +    /**
+      * If the given geometry is an implementation of this library, returns its coordinate reference system.
+      * Otherwise returns {@code null}. The default implementation returns {@code null} because only a few
+      * geometry implementations can store CRS information.
+      *
+      * @see #tryTransform(Object, CoordinateOperation, CoordinateReferenceSystem)
+      */
+     CoordinateReferenceSystem tryGetCoordinateReferenceSystem(Object point) throws FactoryException {
+         return null;
+     }
+ 
+     /**
+      * Gets the Coordinate Reference System (CRS) from the given geometry. If no CRS information is found or
+      * if the geometry implementation can not store this information, then this method returns {@code null}.
+      *
+      * @param  geometry the geometry from which to get the CRS, or {@code null}.
+      * @return the coordinate reference system, or {@code null}.
+      * @throws FactoryException if the CRS is defined by a SRID code and that code can not be used.
+      *
+      * @see #transform(Object, CoordinateReferenceSystem)
+      */
+     public static CoordinateReferenceSystem getCoordinateReferenceSystem(final Object geometry) throws FactoryException {
+         for (Geometries<?> g = implementation; g != null; g = g.fallback) {
+             CoordinateReferenceSystem crs = g.tryGetCoordinateReferenceSystem(geometry);
+             if (crs != null) return crs;
+         }
+         return null;
+     }
+ 
+     /**
       * If the given point is an implementation of this library, returns its coordinate.
       * Otherwise returns {@code null}.
       */
@@@ -351,8 -379,18 +425,8 @@@
          while (paths.hasNext()) {
              final Object first = paths.next();
              if (first != null) {
 -                for (Geometries<?> g = implementation; g != null; g = g.fallback) {
 -                    final Object merged = g.tryMergePolylines(first, paths);
 -                    if (merged != null) {
 -                        return merged;
 -                    }
 -                }
 -                /*
 -                 * Use the same exception type than `tryMergePolylines(…)` implementations.
 -                 * Also the same type than exception occurring elsewhere in the code of the
 -                 * caller (GroupAsPolylineOperation).
 -                 */
 -                throw new ClassCastException(unsupportedImplementation(first));
 +                return findStrategy(g -> g.tryMergePolylines(first, paths))
-                         .orElseThrow(() -> unsupported(2));
++                        .orElseThrow(() -> new ClassCastException(unsupportedImplementation(first)));
              }
          }
          return null;
@@@ -363,156 -534,16 +570,165 @@@
       *
       * @param  dimension  number of dimensions (2 or 3) requested for the geometry object.
       */
-     static UnsupportedOperationException unsupported(final int dimension) {
-         return new UnsupportedOperationException(Resources.format(Resources.Keys.UnsupportedGeometryObject_1, dimension));
+     static String unsupported(final int dimension) {
+         return Resources.format(Resources.Keys.UnsupportedGeometryObject_1, dimension);
+     }
+ 
+     /**
+      * Returns an error message for an unsupported geometry object implementation.
+      *
+      * @param  geometry  the unsupported object.
+      */
+     private static String unsupportedImplementation(final Object geometry) {
+         return Errors.format(Errors.Keys.UnsupportedType_1, Classes.getClass(geometry));
      }
 +
 +    private static <T> Optional<T> findStrategy(final Function<Geometries<?>, T> op) {
 +        for (Geometries<?> g = implementation; g != null; g = g.fallback) {
 +            final T result = op.apply(g);
 +            if (result != null) return Optional.of(result);
 +        }
 +
 +        return Optional.empty();
 +    }
 +
 +    /**
 +     * See {@link Geometries#toGeometry(Envelope, WrapResolution)}.
 +     */
 +    Object tryConvertToGeometry(final Envelope env, WrapResolution resolution) {
 +        // Ensure that we can isolate an horizontal part in the given envelope.
 +        final int x;
 +        if (env.getDimension() == 2) {
 +            x = 0;
 +        } else {
 +            final CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
 +            if (crs == null) throw new IllegalArgumentException("Envelope with more than 2 dimensions, but without CRS: cannot isolate horizontal part.");
 +            final SingleCRS hCrs = CRS.getHorizontalComponent(crs);
 +            if (hCrs == null) throw new IllegalArgumentException("Cannot find an horizontal part in given CRS");
 +            x = AxisDirections.indexOfColinear(crs.getCoordinateSystem(), hCrs.getCoordinateSystem());
 +        }
 +
 +        final int y = x+1;
 +
 +        final DirectPosition lc = env.getLowerCorner();
 +        final DirectPosition uc = env.getUpperCorner();
 +        double minX = lc.getOrdinate(x);
 +        double minY = lc.getOrdinate(y);
 +        double maxX = uc.getOrdinate(x);
 +        double maxY = uc.getOrdinate(y);
 +        double[] splittedLeft = null;
 +        // We start by short-circuiting simplest case for minor simplicity/performance reason.
 +        if (!WrapResolution.NONE.equals(resolution)) {
 +            // ensure the envelope is correctly defined, by forcing non-authorized wrapped axes to take entire crs span.
 +            final GeneralEnvelope fixedEnv = new GeneralEnvelope(env);
 +            fixedEnv.normalize();
 +            int wrapAxis = -1;
 +            for (int i = x ; i <= y && wrapAxis < x ; i++) {
 +                if (fixedEnv.getLower(i) > fixedEnv.getUpper(i)) wrapAxis = i;
 +            }
 +            if (wrapAxis >= x) {
 +                final CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
 +                if (crs == null) throw new IllegalArgumentException("Cannot resolve wrap-around for an envelope without any system defined");
 +                final CoordinateSystemAxis axis = crs.getCoordinateSystem().getAxis(wrapAxis);
 +                final double wrapRange = axis.getMaximumValue() - axis.getMinimumValue();
 +                switch (resolution) {
 +                    case EXPAND:
 +                        // simpler and more performant than a call to GeneralEnvelope.simplify()
 +                        if (wrapAxis == x) {
 +                            minX = axis.getMinimumValue();
 +                            maxX = axis.getMaximumValue();
 +                        } else {
 +                            minY = axis.getMinimumValue();
 +                            maxY = axis.getMaximumValue();
 +                        }
 +                        break;
 +                    case SPLIT:
 +                        if (wrapAxis == x) {
 +                            splittedLeft = new double[]{axis.getMinimumValue(), minY, maxX, maxY};
 +                            maxX = axis.getMaximumValue();
 +                        }
 +                        else {
 +                            splittedLeft = new double[] {minX, axis.getMinimumValue(), maxX, maxY};
 +                            maxY = axis.getMaximumValue();
 +                        }
 +                        break;
 +                    case CONTIGUOUS:
 +                        if (wrapAxis == x) maxX += wrapRange;
 +                        else maxY += wrapRange;
 +                        break;
 +                    default:
 +                        throw new IllegalArgumentException("Unknown or unset wrap resolution: " + resolution);
 +                }
 +            }
 +        }
 +
 +        Vector[] points = clockwiseRing(minX, minY, maxX, maxY);
 +
 +        final G mainRect = createPolyline(2, points);
 +        if (splittedLeft != null) {
 +            minX = splittedLeft[0];
 +            minY = splittedLeft[1];
 +            maxX = splittedLeft[2];
 +            maxY = splittedLeft[3];
 +            Vector[] points2 = clockwiseRing(minX, minY, maxX, maxY);
 +            final G secondRect = createPolyline(2, points2);
 +            return createMultiPolygon(Stream.of(mainRect, secondRect));
 +        }
 +
 +        /* Geotk original method had an option to insert a median point on wrappped around axis, but we have not ported
 +         * it, because in an orthonormal space, I don't see any case where it could be useful. However, in case it
 +         * have to be added, we can do it here by amending created ring(s).
 +         */
 +        return toPolygon(mainRect);
 +    }
 +
 +    /**
 +     * Create a sequence of points describing a rectangle whose start point is the lower left one. The sequence of
 +     * points describe each corner, going in clockwise order and repeating starting point to properly close the ring.
 +     *
 +     * @param minX Lower coordinate of first axis.
 +     * @param minY Lower coordinate of second axis.
 +     * @param maxX Upper coordinate of first axis.
 +     * @param maxY Upper coordinate of second axis.
 +     *
 +     * @return A set of 5 points describing given rectangle.
 +     */
 +    private static Vector[] clockwiseRing(final double minX, final double minY, final double maxX, final double maxY) {
 +        return new Vector[]{
 +                Vector.create(new double[]{minX, minY}),
 +                Vector.create(new double[]{minX, maxY}),
 +                Vector.create(new double[]{maxX, maxY}),
 +                Vector.create(new double[]{maxX, minY}),
 +                Vector.create(new double[]{minX, minY})
 +        };
 +    }
 +
 +    /**
 +     * Extract all points from input geometry, and return them as a contiguous set of ordinates.
 +     * For rings, point order (clockwise/counter-clockwise) is implementation dependant.
 +     *
 +     * @param geometry The geometry to extract point from.
 +     */
 +    public static Optional<double[]> getOrdinates(Geometry geometry) {
 +        return findStrategy(g -> g.getPoints(geometry));
 +    }
 +
 +    public abstract double[] getPoints(Object geometry);
 +
 +    public abstract G createMultiPolygon(final Stream<?> polygonsOrLinearRings);
 +
 +    public static Object createMultiPolygon_(final Stream polygonsOrLinearRings) {
 +        return findStrategy(g -> g.createMultiPolygon(polygonsOrLinearRings));
 +    }
 +
 +    /**
 +     * Try and associate given coordinate reference system to the specified geometry. It should replace any previously
 +     * set referencing information.
 +     *
 +     * @param target The geometry to embed referencing information into.
 +     * @param toApply Referencing information to add.
 +     */
 +    public void setCRS(G target, CoordinateReferenceSystem toApply) {
 +        throw new UnsupportedOperationException("Not supported yet");
 +    }
  }
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
index ea6d1f9,b5ded9f..17f826c
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
@@@ -16,22 -16,20 +16,25 @@@
   */
  package org.apache.sis.internal.feature;
  
- import java.util.ArrayList;
+ import java.util.Map;
+ import java.util.List;
  import java.util.Arrays;
+ import java.util.ArrayList;
  import java.util.Iterator;
- import java.util.List;
 -import org.opengis.util.FactoryException;
 +import java.util.stream.Stream;
 +
+ import org.opengis.referencing.operation.TransformException;
+ import org.opengis.referencing.operation.CoordinateOperation;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.util.FactoryException;
 +
 +import org.apache.sis.geometry.GeneralEnvelope;
 +import org.apache.sis.math.Vector;
 +import org.apache.sis.setup.GeometryLibrary;
 +import org.apache.sis.util.Classes;
 +import org.apache.sis.util.collection.BackingStoreException;
 +
  import org.locationtech.jts.geom.Coordinate;
 -import org.locationtech.jts.geom.Point;
 -import org.locationtech.jts.geom.Polygon;
 -import org.locationtech.jts.geom.LineString;
 -import org.locationtech.jts.geom.MultiLineString;
  import org.locationtech.jts.geom.Envelope;
  import org.locationtech.jts.geom.Geometry;
  import org.locationtech.jts.geom.GeometryFactory;
@@@ -310,45 -321,43 +364,85 @@@ add:    for (;;) 
          return toGeometry(lines);
      }
  
 +    @Override
 +    public double[] getPoints(Object geometry) {
 +        if (geometry instanceof GeometryWrapper) {
 +            geometry = ((GeometryWrapper) geometry).geometry;
 +        }
 +
 +        if (geometry instanceof Geometry) {
 +            Geometry geom = (Geometry) geometry;
 +            final int nbPts = geom.getNumPoints();
 +            final Coordinate[] coords = geom.getCoordinates();
 +            double[] ordinates = new double[nbPts * 2];
 +            for (int i = 0, j=0; i < nbPts ; i++) {
 +                final Coordinate coord = coords[i];
 +                ordinates[j++] = coord.x;
 +                ordinates[j++] = coord.y;
 +            }
 +            return ordinates;
 +        }
 +
 +        return null;
 +    }
 +
 +    @Override
 +    public MultiPolygon createMultiPolygon(Stream<?> polygonsOrLinearRings) {
 +        final Polygon[] polys = polygonsOrLinearRings
 +                .map(this::castToPolygon)
 +                .toArray(size -> new Polygon[size]);
 +        return factory.createMultiPolygon(polys);
 +    }
 +
 +    private Polygon castToPolygon(Object input) {
 +        if (input instanceof GeometryWrapper) input = ((GeometryWrapper) input).geometry;
 +
 +        if (input instanceof Geometry) return toPolygon((Geometry) input);
 +        else throw new IllegalArgumentException("Given argument cannot be cast to polygon");
 +    }
 +
 +    @Override
 +    public void setCRS(Geometry target, CoordinateReferenceSystem toApply) {
 +        org.apache.sis.internal.feature.jts.JTS.setCoordinateReferenceSystem(target, toApply);
 +    }
++
+     /**
+      * If the given geometry is a JTS geometry, computes its buffer. Otherwise returns {@code null}.
+      */
+     @Override
+     Object tryBuffer(final Object geometry, final double distance) {
+         if (geometry instanceof Geometry) {
+             final Geometry jts = (Geometry) geometry;
+             final Geometry buffer = jts.buffer(distance);
+             copyMetadata(jts, buffer);
+             return buffer;
+         }
+         return null;
+     }
+ 
+     /**
+      * Tries to transforms the given geometry to the specified Coordinate Reference System (CRS),
+      * or returns {@code null} if this method can not perform this operation on the given object.
+      * Exactly one of {@code operation} and {@code targetCRS} shall be non-null.
+      *
+      * @param  geometry   the geometry to transform.
+      * @param  operation  the coordinate operation to apply, or {@code null}.
+      * @param  targetCRS  the target coordinate reference system, or {@code null}.
+      * @return the transformed geometry, or the same geometry if it is already in target CRS.
+      *
+      * @see #tryGetCoordinateReferenceSystem(Object)
+      */
+     @Override
+     Geometry tryTransform(final Object geometry, final CoordinateOperation operation, final CoordinateReferenceSystem targetCRS)
+             throws FactoryException, TransformException
+     {
+         if (geometry instanceof Geometry) {
+             if (operation != null) {
+                 return org.apache.sis.internal.feature.jts.JTS.transform((Geometry) geometry, operation);
+             } else {
+                 return org.apache.sis.internal.feature.jts.JTS.transform((Geometry) geometry, targetCRS);
+             }
+         }
+         return null;
+     }
  }
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
index 50a492b,19a019a..5f1fcc5
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Java2D.java
@@@ -19,27 -19,19 +19,30 @@@ package org.apache.sis.internal.feature
  import java.awt.Shape;
  import java.awt.geom.Line2D;
  import java.awt.geom.Path2D;
 +import java.awt.geom.PathIterator;
  import java.awt.geom.Point2D;
  import java.awt.geom.Rectangle2D;
 +import java.util.Arrays;
 +import java.util.Iterator;
 +import java.util.Spliterator;
 +import java.util.function.Consumer;
 +import java.util.stream.DoubleStream;
 +import java.util.stream.Stream;
 +import java.util.stream.StreamSupport;
 +
+ import java.awt.geom.RectangularShape;
++
  import org.apache.sis.geometry.GeneralEnvelope;
 -import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.internal.feature.j2d.ShapeProperties;
  import org.apache.sis.internal.referencing.j2d.ShapeUtilities;
  import org.apache.sis.math.Vector;
 +import org.apache.sis.setup.GeometryLibrary;
  import org.apache.sis.util.Classes;
  import org.apache.sis.util.Numbers;
+ import org.apache.sis.util.UnsupportedImplementationException;
  
 +import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 +
  
  /**
   * Centralizes usages of some (not all) Java2D geometry API by Apache SIS.
@@@ -285,86 -253,7 +304,86 @@@ add:    for (;;) 
       * Parses the given WKT.
       */
      @Override
 -    public Object parseWKT(final String wkt) {
 +    public Shape parseWKT(final String wkt) {
-         throw unsupported(2);
+         throw new UnsupportedImplementationException(unsupported("parseWKT"));
      }
 +
 +    @Override
 +    public Shape parseWKB(byte[] source) {
-         throw unsupported(2);
++        throw new UnsupportedImplementationException(unsupported("parseWKB"));
 +    }
 +
 +    /**
 +     * An abstraction over {@link PathIterator} to use it in a streaming context.
 +     */
 +    private static final class PathSpliterator implements Spliterator<Segment> {
 +
 +        private final PathIterator source;
 +
 +        private PathSpliterator(PathIterator source) {
 +            this.source = source;
 +        }
 +
 +        @Override
 +        public boolean tryAdvance(Consumer<? super Segment> action) {
 +            if (source.isDone()) return false;
 +            final double[] coords = new double[6];
 +            final int segmentType = source.currentSegment(coords);
 +            action.accept(new Segment(segmentType, coords));
 +            source.next();
 +            return true;
 +        }
 +
 +        @Override
 +        public Spliterator<Segment> trySplit() {
 +            return null;
 +        }
 +
 +        @Override
 +        public long estimateSize() {
 +            return Long.MAX_VALUE;
 +        }
 +
 +        @Override
 +        public int characteristics() {
 +            return Spliterator.NONNULL | Spliterator.ORDERED | Spliterator.IMMUTABLE;
 +        }
 +    }
 +
 +    /**
 +     * Describe a path segment as described by {@link PathIterator#currentSegment(double[]) AWT path iteration API}.
 +     * Basically, the awt abstraction is really poor, so we made a wrapper around it to describe segments.
 +     */
 +    private static class Segment {
 +        /**
 +         * This segment type ({@link PathIterator#SEG_CLOSE}, etc.).
 +         */
 +        final int type;
 +        /**
 +         * Brut points composing the segment, as returned by {@link PathIterator#currentSegment(double[])}.
 +         */
 +        private final double[] points;
 +
 +        Segment(int type, double[] points) {
 +            this.type = type;
 +            this.points = points;
 +        }
 +
 +        /**
 +         *
 +         * @return points composing this segment, as a contiguous set of ordinates. Points are all 2D, so every two
 +         * elements in backed stream describe a point. Can be empty in case of {@link PathIterator#SEG_CLOSE closing segment}.
 +         */
 +        DoubleStream ordinates() {
 +            switch (type) {
 +                case PathIterator.SEG_CLOSE: return DoubleStream.empty();
 +                case PathIterator.SEG_QUADTO: return Arrays.stream(points, 0, 4);
 +                case PathIterator.SEG_CUBICTO: return Arrays.stream(points);
 +                case PathIterator.SEG_LINETO:
 +                case PathIterator.SEG_MOVETO:
 +                        return Arrays.stream(points, 0, 2);
 +                default: throw new IllegalStateException("Unknown segment type: "+type);
 +            }
 +        }
 +    }
  }
diff --cc core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
index 39a9ffc,b766a06..ada49fb
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/jts/JTS.java
@@@ -107,31 -101,33 +107,57 @@@ public final class JTS extends Static 
          return null;
      }
  
 +    public static Optional<CoordinateReferenceSystem> setCoordinateReferenceSystem(final Geometry target, final CoordinateReferenceSystem toSet) {
 +        ensureNonNull("Target geometry", target);
 +        final Object ud = target.getUserData();
 +        if (ud == null) {
 +            // By security, we reset SRID in case old CRS was defined this way.
 +            target.setSRID(0);
 +            target.setUserData(toSet);
 +            return Optional.empty();
 +        } else if (ud instanceof CoordinateReferenceSystem) {
 +            target.setUserData(toSet);
 +            return Optional.of((CoordinateReferenceSystem) ud);
 +        } else if (ud instanceof Map) {
 +            final Map asMap = (Map) ud;
 +            // In case user-data contains other useful data, we don't switch from map to CRS. We also reset SRID.
 +            final Object oldVal = asMap.put(CRS_KEY, toSet);
 +            // By security, we reset SRID in case old CRS was defined this way.
 +            if (oldVal == null) {
 +                target.setSRID(0);
 +            }
 +        }
 +
 +        throw new IllegalArgumentException("Cannot modify input geometry, because user-data does not comply with SIS convention (should be a map or null, but was "+ud.getClass().getCanonicalName()+").");
 +    }
 +
      /**
+      * Finds an operation between the given CRS valid in the given area of interest.
+      * This method does not verify the CRS of the given geometry.
+      *
+      * @param  sourceCRS       the CRS of source coordinates.
+      * @param  targetCRS       the CRS of target coordinates.
+      * @param  areaOfInterest  the area of interest.
+      * @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}.
+      * @throws FactoryException if the operation can not be created.
+      */
+     private static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS,
+                                                      final CoordinateReferenceSystem targetCRS,
+                                                      final Geometry areaOfInterest)
+             throws FactoryException
+     {
+         DefaultGeographicBoundingBox bbox = new DefaultGeographicBoundingBox();
+         try {
+             final Envelope e = areaOfInterest.getEnvelopeInternal();
+             bbox.setBounds(new Envelope2D(sourceCRS, e.getMinX(), e.getMinY(), e.getWidth(), e.getHeight()));
+         } catch (TransformException ex) {
+             bbox = null;
+             Logging.ignorableException(Logging.getLogger(Loggers.GEOMETRY), JTS.class, "transform", ex);
+         }
+         return CRS.findOperation(sourceCRS, targetCRS, bbox);
+     }
+ 
+     /**
       * Transforms the given geometry to the specified Coordinate Reference System (CRS).
       * If the given CRS or the given geometry is null, the geometry is returned unchanged.
       * If the geometry has no Coordinate Reference System, a {@link TransformException} is thrown.
diff --cc core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
index 8b2cda5,0ed8ba5..1350a92
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
@@@ -16,219 -16,239 +16,376 @@@
   */
  package org.apache.sis.filter;
  
 -import org.locationtech.jts.geom.Coordinate;
 -import org.locationtech.jts.geom.Envelope;
 -import org.locationtech.jts.geom.Geometry;
 -import org.locationtech.jts.geom.GeometryFactory;
 -import org.locationtech.jts.geom.LineString;
 -import org.locationtech.jts.geom.Point;
 -import org.locationtech.jts.geom.Polygon;
  import org.opengis.feature.Feature;
  import org.opengis.feature.FeatureType;
- import org.opengis.filter.FilterFactory2;
+ import org.opengis.filter.FilterFactory;
 +import org.opengis.filter.expression.Expression;
  import org.opengis.filter.expression.Function;
 +import org.opengis.filter.expression.Literal;
 +import org.opengis.filter.expression.PropertyName;
 +import org.opengis.geometry.Envelope;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
 +import org.opengis.referencing.crs.ProjectedCRS;
 +
  import org.apache.sis.feature.builder.FeatureTypeBuilder;
 -import org.apache.sis.referencing.crs.HardCodedCRS;
 +import org.apache.sis.geometry.GeneralEnvelope;
  import org.apache.sis.referencing.CommonCRS;
++import org.apache.sis.referencing.crs.HardCodedCRS;
  import org.apache.sis.test.TestCase;
 +import org.apache.sis.util.NullArgumentException;
 +
- import org.junit.Assert;
  import org.junit.Test;
 +import org.locationtech.jts.geom.Coordinate;
++import org.locationtech.jts.geom.Geometry;
 +import org.locationtech.jts.geom.GeometryFactory;
 +import org.locationtech.jts.geom.LineString;
 +import org.locationtech.jts.geom.LinearRing;
 +import org.locationtech.jts.geom.Point;
++import org.locationtech.jts.geom.Polygon;
  
 -import static org.opengis.test.Assert.*;
 +import static org.apache.sis.internal.feature.GeometriesTestCase.expectFailFast;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
++import static org.opengis.test.Assert.assertEquals;
++import static org.opengis.test.Assert.assertInstanceOf;
+ 
  
  /**
+  * Tests {@link SQLMM} functions implementations.
+  * Current implementation tests Java Topology Suite (JTS) implementation only.
   *
-  * @author Johann Sorel (Geomatys)
+  * @author  Johann Sorel (Geomatys)
+  * @version 1.1
+  * @since   1.1
+  * @module
   */
- public class SQLMMTest extends TestCase {
+ public final strictfp class SQLMMTest extends TestCase {
 +
 +    private static final String P_NAME = "geom";
- 
++    
      /**
       * The factory to use for creating the objects to test.
       */
-     private final FilterFactory2 factory = new DefaultFilterFactory();
-     private final GeometryFactory gf = new GeometryFactory();
+     private final FilterFactory factory;
  
      /**
-      * Test SQL/MM ST_Transform function.
+      * The factory to use for creating Java Topology Suite (JTS) objects.
       */
-     @Test
-     public void ST_TransformTest() {
+     private final GeometryFactory geometryFactory;
  
-         CoordinateReferenceSystem inCrs = CommonCRS.WGS84.normalizedGeographic();
-         CoordinateReferenceSystem outCrs = CommonCRS.WGS84.geographic();
+     /**
+      * Creates a new test case.
+      */
+     public SQLMMTest() {
+         factory = new DefaultFilterFactory();
+         geometryFactory = new GeometryFactory();
+     }
  
-         //test invalid
+     /**
+      * Verifies that attempts to create a function of the given name fail if no argument is provided.
+      */
+     private void assertRequireArguments(final String functionName) {
          try {
-             factory.function("ST_Transform");
-             Assert.fail("Creation with no argument should fail");
+             factory.function(functionName);
+             fail("Creation with no argument should fail");
          } catch (IllegalArgumentException ex) {
-             //ok
+             final String message = ex.getMessage();
+             assertTrue(message, message.contains("parameters"));
          }
+     }
  
-         //create a test feature
-         final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
-         ftb.setName("test");
-         ftb.addAttribute(Point.class).setName("geom").setCRS(inCrs);
+     /**
+      * Wraps the given geometry in a feature object. The geometry will be stored in a property named {@code "geom"}.
+      *
+      * @param  geometry  the geometry to wrap in a feature.
+      * @param  crs       the coordinate reference system to assign to the geometry.
+      */
+     private static Feature wrapInFeature(final Geometry geometry, final CoordinateReferenceSystem crs) {
+         final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName("test");
+         ftb.addAttribute(Point.class).setName("geom").setCRS(crs);
          final FeatureType type = ftb.build();
-         final Point geometry = gf.createPoint(new Coordinate(10, 30));
-         geometry.setUserData(inCrs);
+         geometry.setUserData(crs);
          final Feature feature = type.newInstance();
          feature.setPropertyValue("geom", geometry);
+         return feature;
+     }
  
-         { //test transform function using epsg code
-             final Function fct = factory.function("ST_Transform", factory.property("geom"), factory.literal("EPSG:4326"));
- 
-             //check result
-             final Object newGeom = fct.evaluate(feature);
-             assertTrue(newGeom instanceof Point);
-             final Point trs = (Point) newGeom;
-             Assert.assertEquals(outCrs, trs.getUserData());
-             Assert.assertEquals(30.0, trs.getX(), 0.0);
-             Assert.assertEquals(10.0, trs.getY(), 0.0);
-         }
+     /**
+      * Evaluates the given function and returns its result as an object of the given type.
+      *
+      * @param  expectedType  the expected type of the result.
+      * @param  feature       the feature to use as input value. May be {@code null}.
+      * @param  testing       the function to test.
+      * @return evaluation result.
+      */
+     private static <G extends Geometry> G evaluate(final Class<G> expectedType, final Feature feature, final Function testing) {
+         final Object result = testing.evaluate(feature);
+         assertInstanceOf("Expected JTS geometry.", expectedType, result);
+         return expectedType.cast(result);
+     }
  
-         { //test transform function using crs object
-             final Function fct = factory.function("ST_Transform", factory.property("geom"), factory.literal(outCrs));
+     /**
+      * Test SQL/MM {@link ST_Transform} function.
+      */
+     @Test
+     public void testTransform() {
+         /*
+          * Verify that creation of a function without arguments is not allowed.
+          */
+         assertRequireArguments("ST_Transform");
+         /*
+          * Create a feature to be used for testing purpose. For this test, the CRS transformation
+          * will be simply a change of axis order from (λ,φ) to (φ,λ).
+          */
+         final Point geometry = geometryFactory.createPoint(new Coordinate(10, 30));
+         final Feature feature = wrapInFeature(geometry, HardCodedCRS.WGS84);
+         /*
+          * Test transform function using the full CRS object, then using only EPSG code.
+          */
+         testTransform(feature, HardCodedCRS.WGS84_φλ, HardCodedCRS.WGS84_φλ);
+         testTransform(feature, "EPSG:4326", CommonCRS.WGS84.geographic());
+     }
  
-             //check result
-             final Object newGeom = fct.evaluate(feature);
-             assertTrue(newGeom instanceof Point);
-             final Point trs = (Point) newGeom;
-             Assert.assertEquals(outCrs, trs.getUserData());
-             Assert.assertEquals(30.0, trs.getX(), 0.0);
-             Assert.assertEquals(10.0, trs.getY(), 0.0);
-         }
+     /**
+      * Tests {@link ST_Transform} on the given feature. The feature must have a property named {@code "geom"}.
+      * The result is expected to be a geometry using WGS84 datum with (φ,λ) axis order.
+      *
+      * @param  feature       the feature to use for testing the function.
+      * @param  specifiedCRS  the argument to give to the {@code "ST_Transform"} function.
+      * @param  expectedCRS   the CRS expected as a result of the transform function.
+      */
+     private void testTransform(final Feature feature, final Object specifiedCRS, final CoordinateReferenceSystem expectedCRS) {
+         final Point result = evaluate(Point.class, feature, factory.function("ST_Transform",
+                 factory.property("geom"), factory.literal(specifiedCRS)));
+         assertEquals("userData", expectedCRS, result.getUserData());
+         assertEquals(30, result.getX(), STRICT);
+         assertEquals(10, result.getY(), STRICT);
      }
  
+     /**
+      * Test SQL/MM {@link ST_Centroid} function.
+      */
      @Test
-     public void ST_Envelope() {
-         try {
-             new ST_Envelope(new Expression[2]);
-             fail("ST_Envelope operator should accept a single parameter");
-         } catch (IllegalArgumentException e) {
-             // expected behavior
-         }
+     public void testCentroid() {
+         assertRequireArguments("ST_Centroid");
+         /*
+          * Creates a single linestring for testing the centroid function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final LineString geometry = geometryFactory.createLineString(new Coordinate[] {
+             new Coordinate(10, 20),
+             new Coordinate(30, 20)
+         });
+         geometry.setSRID(4326);
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         /*
+          * Execute the function and check the result.
+          */
+         final Point result = evaluate(Point.class, null, factory.function("ST_Centroid", factory.literal(geometry)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
+         assertEquals(20, result.getX(), STRICT);
+         assertEquals(20, result.getY(), STRICT);
+     }
  
-         try {
-             new ST_Envelope(null);
-             fail("ST_Envelope operator should accept a single parameter");
-         } catch (IllegalArgumentException e) {
-             // expected behavior
-         }
+     /**
+      * Test SQL/MM {@link ST_Buffer} function.
+      */
+     @Test
+     public void ST_BufferTest() {
+         assertRequireArguments("ST_Buffer");
+         /*
+          * Creates a single point for testing the buffer function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final Point geometry = geometryFactory.createPoint(new Coordinate(10, 20));
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         geometry.setSRID(4326);
+         /*
+          * Execute the function and check the result.
+          */
+         final Polygon result = evaluate(Polygon.class, null, factory.function("ST_Buffer", factory.literal(geometry), factory.literal(1)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
 -        final Envelope env = result.getEnvelopeInternal();
++        final org.locationtech.jts.geom.Envelope env = result.getEnvelopeInternal();
+         assertEquals( 9, env.getMinX(), STRICT);
+         assertEquals(11, env.getMaxX(), STRICT);
+         assertEquals(19, env.getMinY(), STRICT);
+         assertEquals(21, env.getMaxY(), STRICT);
+     }
  
-         final LineString pt = gf.createLineString(new Coordinate[]{
-                 new Coordinate(12, 3.3),
-                 new Coordinate(13.1, 4.4),
-                 new Coordinate(12.02, 5.7)
-         });
-         ST_Envelope operator = new ST_Envelope(new Expression[]{factory.literal(pt)});
-         final GeneralEnvelope expectedEnv = new GeneralEnvelope(2);
-         expectedEnv.setEnvelope(12, 3.3, 13.1, 5.7);
-         Envelope evaluated = (Envelope) operator.evaluate(null);
-         assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
-         evaluated = (Envelope) operator.evaluate(null);
-         assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
+     /**
+      * Test SQL/MM {@link ST_Simplify} function.
+      */
+     @Test
+     public void ST_SimplifyTest() {
+         assertRequireArguments("ST_Simplify");
+         /*
+          * Creates a single line for testing the simplify function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final LineString geometry = geometryFactory.createLineString(new Coordinate[]{new Coordinate(10, 20), new Coordinate(15, 20), new Coordinate(20, 20)});
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         geometry.setSRID(4326);
+         /*
+          * Execute the function and check the result.
+          */
+         final LineString result = evaluate(LineString.class, null, factory.function("ST_Simplify", factory.literal(geometry), factory.literal(10)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
+         Coordinate[] coordinates = result.getCoordinates();
+         assertEquals(2, coordinates.length);
+         assertEquals(10, coordinates[0].x, STRICT);
+         assertEquals(20, coordinates[0].y, STRICT);
+         assertEquals(20, coordinates[1].x, STRICT);
+         assertEquals(20, coordinates[1].y, STRICT);
+     }
  
-         // After testing literal data, we'll now try to extract data from a feature.
-         final Feature f = mock();
-         f.setPropertyValue(P_NAME, pt);
-         operator = new ST_Envelope(new Expression[]{factory.property(P_NAME)});
-         evaluated = (Envelope) operator.evaluate(f);
-         assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
+     /**
+      * Test SQL/MM {@link ST_SimplifyPreserveTopology} function.
+      */
+     @Test
+     public void ST_SimplifyPreserveTopologyTest() {
+         assertRequireArguments("ST_SimplifyPreserveTopology");
+         /*
+          * Creates a single line for testing the simplify function. The CRS is not used by this computation,
+          * but we declare it in order to verify that the information is propagated to the result.
+          */
+         final LineString geometry = geometryFactory.createLineString(new Coordinate[]{new Coordinate(10, 20), new Coordinate(15, 20), new Coordinate(20, 20)});
+         geometry.setUserData(HardCodedCRS.WGS84_φλ);
+         geometry.setSRID(4326);
+         /*
+          * Execute the function and check the result.
+          */
+         final LineString result = evaluate(LineString.class, null, factory.function("ST_SimplifyPreserveTopology", factory.literal(geometry), factory.literal(10)));
+         assertEquals("userData", HardCodedCRS.WGS84_φλ, result.getUserData());
+         assertEquals("SRID", 4326, result.getSRID());
+         Coordinate[] coordinates = result.getCoordinates();
+         assertEquals(2, coordinates.length);
+         assertEquals(10, coordinates[0].x, STRICT);
+         assertEquals(20, coordinates[0].y, STRICT);
+         assertEquals(20, coordinates[1].x, STRICT);
+         assertEquals(20, coordinates[1].y, STRICT);
      }
 +
 +    @Test
 +    public void ST_Intersects() {
 +        try {
 +            new ST_Intersects(null);
 +            fail("ST_Intersects operator should accept exactly 2 parameters");
 +        } catch (NullArgumentException e) {
 +            // expected behavior
 +        }
 +
 +        try {
 +            new ST_Intersects(new Expression[3]);
 +            fail("ST_Intersects operator should accept exactly 2 parameters");
 +        } catch (IllegalArgumentException e) {
 +            // expected behavior
 +        }
 +
 +        final Coordinate start = new Coordinate(0, 0.1);
 +        final Coordinate second = new Coordinate(1.2, 0.2);
-         final LinearRing ring = gf.createLinearRing(new Coordinate[]{
++        final LinearRing ring = geometryFactory.createLinearRing(new Coordinate[]{
 +                start, second, new Coordinate(0.7, 0.8), start
 +        });
 +
 +        final Literal lring = factory.literal(ring);
-         ST_Intersects st = intersects(factory.literal(gf.createPoint(new Coordinate(2, 4))), lring);
++        ST_Intersects st = intersects(factory.literal(geometryFactory.createPoint(new Coordinate(2, 4))), lring);
 +        // Ensure argument nullity does not modify behavior
 +        assertFalse("Unexpected intersection", st.evaluate(null));
 +        assertFalse("Unexpected intersection", st.evaluate(new Object()));
 +
 +        // Border should intersect
 +        final Feature f = mock();
-         final Point point = gf.createPoint(second);
++        final Point point = geometryFactory.createPoint(second);
 +        f.setPropertyValue(P_NAME, point);
 +        final PropertyName geomName = factory.property(P_NAME);
 +        st = intersects(geomName, lring);
 +        assertTrue("Border point should intersect triangle", st.evaluate(f));
 +        // Ensure inverting expression does not modify behavior.
 +        st = intersects(lring, geomName);
 +        assertTrue("Border point should intersect triangle", st.evaluate(f));
 +
 +        // Ensure CRS conversion works as expected (see package-info).
 +        // Missing
 +        point.setUserData(CommonCRS.defaultGeographic());
 +        expectFailFast(() -> intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
 +        final Literal lPoint = factory.literal(point);
 +        expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 +
 +        // Disjoint
 +        final ProjectedCRS nadUtm = CommonCRS.NAD27.universal(32, 37);
 +        final ProjectedCRS wgsUtm = CommonCRS.WGS84.universal(-2, 4);
 +
 +        point.setUserData(nadUtm);
 +        ring.setUserData(wgsUtm);
 +        expectFailFast(() -> intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
 +        expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 +
 +        // TODO: activate back after fixing CRS.suggestCommonTarget
 +        // utm domain contained in CRS:84
- //        ring.setUserData(CommonCRS.defaultGeographic());
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
++        ring.setUserData(CommonCRS.defaultGeographic());
++        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
++        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
 +
 +        // Common base CRS
- //        ring.setUserData(CommonCRS.WGS84.universal(0, 0));
- //        point.setUserData(CommonCRS.WGS84.universal(7, 8));
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
- //        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
++        ring.setUserData(CommonCRS.WGS84.universal(0, 0));
++        point.setUserData(CommonCRS.WGS84.universal(7, 8));
++        assertTrue("Intersection should be found when CRS are compatible", intersects(geomName, lring).evaluate(f));
++        assertTrue("Intersection should be found when CRS are compatible", intersects(lPoint, lring).evaluate(null));
 +    }
 +
 +    private static ST_Intersects intersects(final Expression left, Expression right) {
 +        return new ST_Intersects(new Expression[]{left, right});
 +    }
 +
++    @Test
++    public void ST_Envelope() {
++        try {
++            new ST_Envelope(new Expression[2]);
++            fail("ST_Envelope operator should accept a single parameter");
++        } catch (IllegalArgumentException e) {
++            // expected behavior
++        }
++
++        try {
++            new ST_Envelope(null);
++            fail("ST_Envelope operator should accept a single parameter");
++        } catch (IllegalArgumentException e) {
++            // expected behavior
++        }
++
++        final LineString pt = geometryFactory.createLineString(new Coordinate[]{
++                new Coordinate(12, 3.3),
++                new Coordinate(13.1, 4.4),
++                new Coordinate(12.02, 5.7)
++        });
++        ST_Envelope operator = new ST_Envelope(new Expression[]{factory.literal(pt)});
++        final GeneralEnvelope expectedEnv = new GeneralEnvelope(2);
++        expectedEnv.setEnvelope(12, 3.3, 13.1, 5.7);
++        Envelope evaluated = (Envelope) operator.evaluate(null);
++        assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
++        evaluated = (Envelope) operator.evaluate(null);
++        assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
++
++        // After testing literal data, we'll now try to extract data from a feature.
++        final Feature f = mock();
++        f.setPropertyValue(P_NAME, pt);
++        operator = new ST_Envelope(new Expression[]{factory.property(P_NAME)});
++        evaluated = (Envelope) operator.evaluate(f);
++        assertTrue(String.format("Bad result:%nExpected: %s%nBut got: %s", expectedEnv.toString(), evaluated.toString()), expectedEnv.equals(evaluated, 1e-10, false));
++    }
++
 +    /**
 +     *
-      * @return A feature with a single property of {@link Object any} type named after
++     * @return A feature with a single property of {@link Object any} type named after {@link #P_NAME this constant}.
 +     */
 +    private static Feature mock() {
 +        final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName("mock");
 +        ftb.addAttribute(Object.class).setName(P_NAME);
 +        final FeatureType mockType = ftb.build();
 +        return mockType.newInstance();
 +    }
  }
diff --cc core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index a8912d4,b139c7a..fe67a0e
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@@ -16,38 -16,33 +16,39 @@@
   */
  package org.apache.sis.referencing;
  
 -import java.util.Map;
 -import java.util.List;
  import java.util.ArrayList;
  import java.util.Collections;
 +import java.util.List;
 +import java.util.Map;
+ import java.util.logging.Filter;
  import java.util.logging.LogRecord;
 -import org.opengis.util.FactoryException;
 +
  import org.opengis.geometry.Envelope;
 -import org.opengis.referencing.NoSuchAuthorityCodeException;
 +import org.opengis.geometry.Geometry;
 +import org.opengis.metadata.citation.Citation;
 +import org.opengis.metadata.extent.BoundingPolygon;
 +import org.opengis.metadata.extent.Extent;
 +import org.opengis.metadata.extent.GeographicBoundingBox;
 +import org.opengis.metadata.extent.GeographicExtent;
  import org.opengis.referencing.IdentifiedObject;
 -import org.opengis.referencing.cs.CartesianCS;
 -import org.opengis.referencing.cs.EllipsoidalCS;
 -import org.opengis.referencing.cs.AxisDirection;
 -import org.opengis.referencing.cs.CoordinateSystem;
 -import org.opengis.referencing.cs.CoordinateSystemAxis;
 +import org.opengis.referencing.NoSuchAuthorityCodeException;
 +import org.opengis.referencing.crs.CRSAuthorityFactory;
  import org.opengis.referencing.crs.CRSFactory;
 -import org.opengis.referencing.crs.SingleCRS;
  import org.opengis.referencing.crs.CompoundCRS;
  import org.opengis.referencing.crs.CoordinateReferenceSystem;
 -import org.opengis.referencing.crs.CRSAuthorityFactory;
 +import org.opengis.referencing.crs.EngineeringCRS;
 +import org.opengis.referencing.crs.GeneralDerivedCRS;
  import org.opengis.referencing.crs.GeodeticCRS;
  import org.opengis.referencing.crs.GeographicCRS;
 -import org.opengis.referencing.crs.GeneralDerivedCRS;
  import org.opengis.referencing.crs.ProjectedCRS;
 +import org.opengis.referencing.crs.SingleCRS;
  import org.opengis.referencing.crs.TemporalCRS;
  import org.opengis.referencing.crs.VerticalCRS;
 -import org.opengis.referencing.crs.EngineeringCRS;
 +import org.opengis.referencing.cs.AxisDirection;
 +import org.opengis.referencing.cs.CartesianCS;
 +import org.opengis.referencing.cs.CoordinateSystem;
 +import org.opengis.referencing.cs.CoordinateSystemAxis;
 +import org.opengis.referencing.cs.EllipsoidalCS;
  import org.opengis.referencing.datum.Datum;
  import org.opengis.referencing.datum.GeodeticDatum;
  import org.opengis.referencing.operation.Conversion;
@@@ -77,23 -74,24 +78,22 @@@ import org.apache.sis.referencing.crs.D
  import org.apache.sis.referencing.crs.DefaultGeographicCRS;
  import org.apache.sis.referencing.crs.DefaultProjectedCRS;
  import org.apache.sis.referencing.crs.DefaultVerticalCRS;
 -import org.apache.sis.referencing.crs.DefaultCompoundCRS;
 -import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
 +import org.apache.sis.referencing.cs.AxisFilter;
 +import org.apache.sis.referencing.cs.CoordinateSystems;
 +import org.apache.sis.referencing.cs.DefaultVerticalCS;
 +import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 +import org.apache.sis.referencing.factory.UnavailableFactoryException;
  import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
  import org.apache.sis.referencing.operation.CoordinateOperationContext;
 -import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
  import org.apache.sis.referencing.operation.DefaultConversion;
 -import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 -import org.apache.sis.referencing.factory.UnavailableFactoryException;
 -import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 -import org.apache.sis.metadata.iso.extent.Extents;
 +import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
+ import org.apache.sis.util.resources.Errors;
+ import org.apache.sis.util.logging.Logging;
  import org.apache.sis.util.ArgumentChecks;
 -import org.apache.sis.util.Utilities;
  import org.apache.sis.util.Static;
 +import org.apache.sis.util.Utilities;
- import org.apache.sis.util.logging.Logging;
- import org.apache.sis.util.logging.WarningListener;
- import org.apache.sis.util.resources.Errors;
  
  // Branch-dependent imports
 -import org.opengis.geometry.Geometry;
  
  
  /**
diff --cc pom.xml
index eb9792a,fb79bb9..4bf193f
--- a/pom.xml
+++ b/pom.xml
@@@ -529,22 -532,16 +538,27 @@@
             Dependencies to be inherited by all modules.
         =========================================================== -->
    <dependencies>
 +    <!-- 
 +      Unit test declaration. Embed aggregator dependency + retrocompatibility artifact ('vintage'). 
 +      The later won't be needed anymore once all JUnit tests have been upgraded to new JUnit version.
 +    -->
      <dependency>
 -      <groupId>junit</groupId>
 -      <artifactId>junit</artifactId>
 -      <scope>test</scope>
 -    </dependency>
 +			<groupId>org.junit.jupiter</groupId>
 +			<artifactId>junit-jupiter</artifactId>
 +			<version>${junit.jupiter.version}</version>
 +			<scope>test</scope>
 +		</dependency>
 +    <dependency>
 +			<groupId>org.junit.vintage</groupId>
 +			<artifactId>junit-vintage-engine</artifactId>
 +			<version>${junit.jupiter.version}</version>
 +			<scope>test</scope>
 +		</dependency>
+     <dependency>   <!-- To be removed after https://issues.apache.org/jira/browse/SIS-469 is done. -->
+       <groupId>jakarta.xml.bind</groupId>
+       <artifactId>jakarta.xml.bind-api</artifactId>
+       <scope>test</scope>
+     </dependency>
    </dependencies>
  
  
@@@ -563,9 -560,9 +577,10 @@@
      <maven.compiler.source>8</maven.compiler.source>
      <maven.compiler.target>8</maven.compiler.target>
      <sis.plugin.version>${project.version}</sis.plugin.version>
-     <sis.non-free.version>1.0-M1</sis.non-free.version>                 <!-- Used only if "non-free" profile is enabled. -->
-     <geoapi.version>4.0-M11</geoapi.version>
+     <sis.non-free.version>1.0</sis.non-free.version>                 <!-- Used only if "non-free" profile is enabled. -->
+     <geoapi.version>4.0-SNAPSHOT</geoapi.version>
+     <jaxb.version>2.3.2</jaxb.version>
 +		<junit.jupiter.version>5.5.2</junit.jupiter.version>
    </properties>
  
    <profiles>
@@@ -678,13 -675,9 +693,12 @@@
            <includes>
              <include>**/*TestSuite.java</include>
            </includes>
 -          <systemPropertyVariables>
 -            <derby.stream.error.file>${project.build.directory}/derby.log</derby.stream.error.file>
 -          </systemPropertyVariables>
 +          <systemProperties>
 +            <property>
 +              <name>derby.stream.error.file</name>
 +              <value>${project.build.directory}/derby.log</value>
 +            </property>
 +          </systemProperties>
-           <argLine>--add-modules java.xml.bind,java.xml.ws.annotation,javafx.graphics</argLine>
          </configuration>
        </plugin>
  
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
index 063a17f,bb973e8..861822f
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Analyzer.java
@@@ -27,32 -28,21 +27,31 @@@ import java.util.function.Supplier
  import java.util.logging.Level;
  import java.util.logging.LogRecord;
  import javax.sql.DataSource;
 -import java.sql.SQLException;
 -import java.sql.DatabaseMetaData;
 -import java.sql.ResultSet;
 -import org.opengis.util.NameSpace;
 -import org.opengis.util.NameFactory;
 +
  import org.opengis.util.GenericName;
 +import org.opengis.util.NameFactory;
 +import org.opengis.util.NameSpace;
 +
 +import org.apache.sis.feature.builder.AssociationRoleBuilder;
 +import org.apache.sis.feature.builder.AttributeRole;
 +import org.apache.sis.feature.builder.AttributeTypeBuilder;
 +import org.apache.sis.feature.builder.FeatureTypeBuilder;
  import org.apache.sis.internal.metadata.sql.Dialect;
 +import org.apache.sis.internal.metadata.sql.Reflection;
  import org.apache.sis.internal.metadata.sql.SQLUtilities;
 +import org.apache.sis.internal.sql.feature.FeatureAdapter.PropertyMapper;
  import org.apache.sis.internal.system.DefaultFactories;
- import org.apache.sis.storage.DataStore;
 -import org.apache.sis.storage.sql.SQLStore;
 +import org.apache.sis.storage.DataStoreContentException;
  import org.apache.sis.storage.DataStoreException;
  import org.apache.sis.storage.InternalDataStoreException;
+ import org.apache.sis.storage.event.StoreListeners;
 +import org.apache.sis.storage.sql.SQLStore;
 +import org.apache.sis.util.collection.BackingStoreException;
 +import org.apache.sis.util.iso.Names;
- import org.apache.sis.util.logging.WarningListeners;
  import org.apache.sis.util.resources.ResourceInternationalString;
  
 +import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 +
  
  /**
   * Helper methods for creating {@code FeatureType}s from database structure.
@@@ -159,14 -141,11 +158,14 @@@ final class Analyzer 
       * @param  listeners  Value of {@code SQLStore.listeners}.
       * @param  locale     Value of {@code SQLStore.getLocale()}.
       */
-     Analyzer(final DataSource source, final Connection databaseConnection, final WarningListeners<DataStore> listeners,
 -    Analyzer(final DataSource source, final DatabaseMetaData metadata, final StoreListeners listeners,
++    Analyzer(final DataSource source, final Connection databaseConnection, final StoreListeners listeners,
               final Locale locale) throws SQLException
      {
 +        ensureNonNull("Database connection provider", source);
 +        ensureNonNull("Database connection", databaseConnection);
          this.source      = source;
 -        this.metadata    = metadata;
 +        this.connection  = databaseConnection;
 +        this.metadata    = databaseConnection.getMetaData();
          this.listeners   = listeners;
          this.locale      = locale;
          this.strings     = new HashMap<>();
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Database.java
index 0985cfb,66ba910..f908a74
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Database.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Database.java
@@@ -109,10 -108,10 +108,10 @@@ public final class Database 
       * @throws DataStoreException if a logical error occurred while analyzing the database structure.
       */
      public Database(final SQLStore store, final Connection connection, final DataSource source,
-             final GenericName[] tableNames, final WarningListeners<DataStore> listeners)
+             final GenericName[] tableNames, final StoreListeners listeners)
              throws SQLException, DataStoreException
      {
 -        final Analyzer analyzer = new Analyzer(source, connection.getMetaData(), listeners, store.getLocale());
 +        final Analyzer analyzer = new Analyzer(source, connection, listeners, store.getLocale());
          final String[] tableTypes = getTableTypes(analyzer.metadata);
          final Set<TableReference> declared = new LinkedHashSet<>();
          for (final GenericName tableName : tableNames) {
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Features.java
index 7e700a7,fd04b4b..dcd0269
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Features.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Features.java
@@@ -147,12 -135,10 +147,12 @@@ final class Features implements Spliter
      private final Class<?> keyComponentClass;
  
      /**
-      * Estimated number of rows, or {@literal <= 0} if unknown.
+      * Estimated number of remaining rows, or {@literal <= 0} if unknown.
       */
-     private final long estimatedSize;
+     private long estimatedSize;
  
 +    private final FeatureAdapter.ResultSetAdapter adapter;
 +
      /**
       * Creates a new iterator over the feature instances.
       *
diff --cc storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
index f4c20ca,7ca22ad..440988d
--- a/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
+++ b/storage/sis-sqlstore/src/main/java/org/apache/sis/storage/sql/SQLStore.java
@@@ -35,10 -31,14 +35,12 @@@ import org.apache.sis.storage.Aggregate
  import org.apache.sis.storage.DataStore;
  import org.apache.sis.storage.DataStoreException;
  import org.apache.sis.storage.IllegalNameException;
 +import org.apache.sis.storage.Resource;
  import org.apache.sis.storage.StorageConnector;
- import org.apache.sis.storage.event.ChangeEvent;
- import org.apache.sis.storage.event.ChangeListener;
+ import org.apache.sis.storage.event.StoreEvent;
+ import org.apache.sis.storage.event.StoreListener;
+ import org.apache.sis.storage.event.WarningEvent;
 -import org.apache.sis.internal.sql.feature.Database;
 -import org.apache.sis.internal.sql.feature.Resources;
 -import org.apache.sis.internal.storage.MetadataBuilder;
+ import org.apache.sis.internal.util.Strings;
  import org.apache.sis.util.ArgumentChecks;
  import org.apache.sis.util.Exceptions;
  
diff --cc storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
index 598a338,cb75e22..5d50a6c
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/SimpleQuery.java
@@@ -119,15 -123,20 +123,21 @@@ public class SimpleQuery extends Query 
       */
      @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter")
      public void setColumns(Column... columns) {
 -        if (columns != null) {
 +        if (columns == null || columns.length < 1) {
 +            this.columns = null;
 +        } else {
              columns = columns.clone();
-             for (int i = 0; i < columns.length; i++) {
-                 ArgumentChecks.ensureNonNullElement("columns", i, columns[i]);
+             final Map<Object,Integer> uniques = new LinkedHashMap<>(Containers.hashMapCapacity(columns.length));
+             for (int i=0; i<columns.length; i++) {
+                 final Column c = columns[i];
+                 ArgumentChecks.ensureNonNullElement("columns", i, c);
+                 final Object key = c.alias != null ? c.alias : c.expression;
+                 final Integer p = uniques.putIfAbsent(key, i);
+                 if (p != null) {
+                     throw new IllegalArgumentException(Resources.format(Resources.Keys.DuplicatedQueryProperty_3, key, p, i));
+                 }
              }
-             this.columns = columns;
          }
 -        this.columns = columns;
      }
  
      /**


[sis] 03/04: refactor(Feature): Merge duplicate bbox and intersection operators (SQLMM and Filter encoding)

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

amanin pushed a commit to branch refactor/sql-store
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 65e7ddd0f361d1255cccf934aec9aef7442b5cd7
Author: Alexis Manin <am...@apache.org>
AuthorDate: Fri Nov 15 15:34:37 2019 +0100

    refactor(Feature): Merge duplicate bbox and intersection operators (SQLMM and Filter encoding)
    
    Chosen bbox  and intersect filters are more strict in terms of common space definition. They are less dependant of JTS also. and efforts of optimisation at built are done (though more powerful ones would be possible if more context information were given to them)
---
 .../java/org/apache/sis/filter/BinaryFunction.java |  12 +-
 .../java/org/apache/sis/filter/CRSMatching.java    |  81 ++++++-
 .../java/org/apache/sis/filter/DefaultBBOX.java    |  22 +-
 .../apache/sis/filter/DefaultFilterFactory.java    |   2 +-
 .../java/org/apache/sis/filter/ST_Intersects.java  |  39 +---
 .../org/apache/sis/filter/SpatialFunction.java     | 242 +++------------------
 .../apache/sis/internal/feature/Geometries.java    |   4 +-
 .../java/org/apache/sis/internal/feature/JTS.java  |   2 +-
 .../test/java/org/apache/sis/filter/SQLMMTest.java |  24 +-
 9 files changed, 139 insertions(+), 289 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java b/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java
index e7ddda1..341b9e1 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/BinaryFunction.java
@@ -16,17 +16,19 @@
  */
 package org.apache.sis.filter;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.Collection;
-import java.math.BigInteger;
-import java.math.BigDecimal;
-import org.apache.sis.util.Numbers;
-import org.apache.sis.math.Fraction;
+
+import org.opengis.filter.expression.Expression;
+
 import org.apache.sis.math.DecimalFunctions;
+import org.apache.sis.math.Fraction;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.Numbers;
 
 // Branch-dependent imports
-import org.opengis.filter.expression.Expression;
 
 
 /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java b/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java
index 23dfdf2..c85b512 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/CRSMatching.java
@@ -2,8 +2,10 @@ package org.apache.sis.filter;
 
 import java.util.Optional;
 
+import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
 
 import org.apache.sis.referencing.CRS;
@@ -13,6 +15,10 @@ import org.apache.sis.util.collection.BackingStoreException;
 import static org.apache.sis.referencing.IdentifiedObjects.getIdentifierOrName;
 
 /**
+ * Tries to find a common space for two given CRS operands. The common space is defined using {@link CRS#suggestCommonTarget(GeographicBoundingBox, CoordinateReferenceSystem...)}.
+ * Usage: initialize through {@link #left(CoordinateReferenceSystem)}, giving your first (left) operand as argument.
+ * Then use {@link #right(CoordinateReferenceSystem)} to specify the other (right) operand.
+ *
  * TODO: improve CRS conversion/suggestion by allowing user to input a geographic region of interest.
  */
 @FunctionalInterface
@@ -37,15 +43,45 @@ public interface CRSMatching {
         }
     }
 
-    Match right(final CoordinateReferenceSystem other);
+    Match right(final CoordinateReferenceSystem rightCrs);
+
+    /**
+     * Defines that a common space has been found for both input operands.
+     */
+    abstract class Match {
+
+        /**
+         *
+         * @return If both input CRS were null, an empty shell. Otherwise, the common space defined by {@link CRS#suggestCommonTarget(GeographicBoundingBox, CoordinateReferenceSystem...)}.
+         * Note that it can be one of the original systems (in which cas one of the operations provided will be empty),
+         * or a third-party one (common geographic base, for example).
+         */
+        abstract Optional<CoordinateReferenceSystem> getCommonCRS();
+
+        /**
+         *
+         * @return Coordinate operation to use for going from left operand system to common space. Can be empty if the
+         * common space is equal to left operand system.
+         */
+        abstract Optional<CoordinateOperation> fromLeft();
+
+        /**
+         *
+         * @return Coordinate operation to use for going from right operand system to common space. Can be empty if the
+         *         common space is equal to right operand system.
+         */
+        abstract Optional<CoordinateOperation> fromRight();
+
+        public final <L> L transformLeftToCommon(L leftValue, Transformer<L> operator) throws TransformException {
+            return transform(leftValue, fromLeft(), operator);
+        }
 
-    interface Match {
-        Optional<CoordinateReferenceSystem> getCommonCRS();
-        Optional<CoordinateOperation> fromLeft();
-        Optional<CoordinateOperation> fromRight();
+        public final <R> R transformRightToCommon(R rightValue, Transformer<R> operator) throws TransformException {
+            return transform(rightValue, fromRight(), operator);
+        }
     }
 
-    final class NullMatch implements Match {
+    final class NullMatch extends Match {
 
         @Override
         public Optional<CoordinateReferenceSystem> getCommonCRS() {
@@ -63,17 +99,17 @@ public interface CRSMatching {
         }
     }
 
-    final class DefaultMatch implements Match {
+    final class DefaultMatch extends Match {
 
         final CoordinateReferenceSystem commonCRS;
         final Optional<CoordinateOperation> fromLeft;
         final Optional<CoordinateOperation> fromRight;
 
-        public DefaultMatch(CoordinateReferenceSystem commonCRS, CoordinateReferenceSystem left, CoordinateReferenceSystem right) {
+        public DefaultMatch(CoordinateReferenceSystem commonCRS, CoordinateReferenceSystem leftCrs, CoordinateReferenceSystem rightCrs) {
             this.commonCRS = commonCRS;
             try {
-                fromLeft = createOp(left, commonCRS);
-                fromRight = createOp(right, commonCRS);
+                fromLeft = createOp(leftCrs, commonCRS);
+                fromRight = createOp(rightCrs, commonCRS);
             } catch (FactoryException e) {
                 throw new BackingStoreException(e);
             }
@@ -103,4 +139,29 @@ public interface CRSMatching {
             return Optional.of(op);
         }
     }
+
+    /**
+     * TODO: We should NOT accept factory exception here. The transform uses an already built coordinate operation, no
+     * CRS factory should be needed in the process.
+     * @param <T> Type of object to transform (envelope, geometry, etc.).
+     */
+    @FunctionalInterface
+    interface Transformer<T> {
+        T apply(T operand, CoordinateOperation op) throws TransformException, FactoryException;
+    }
+
+    static <T> T transform(T in, Optional<CoordinateOperation> coordOp, Transformer<T> transformer) throws TransformException {
+        try {
+            return coordOp.map(op -> {
+                try {
+                    return transformer.apply(in, op);
+                } catch (TransformException | FactoryException e) {
+                    throw new BackingStoreException(e);
+                }
+            })
+                    .orElse(in);
+        } catch (BackingStoreException e) {
+            throw e.unwrapOrRethrow(TransformException.class);
+        }
+    }
 }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java
index 450d563..85ff6b2 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultBBOX.java
@@ -55,7 +55,7 @@ import org.apache.sis.util.collection.BackingStoreException;
  *
  *     TODO: CRS check.
  */
-final class DefaultBBOX implements BBOX, Serializable {
+final class DefaultBBOX extends SpatialFunction implements BBOX, Serializable {
 
     private static final long serialVersionUID = 3068335120981348484L;
 
@@ -65,8 +65,9 @@ final class DefaultBBOX implements BBOX, Serializable {
     private transient Predicate intersects;
 
     DefaultBBOX(Expression left, Expression right) {
-        this.left = left;
-        this.right = right;
+        super(left == null ? Expression.NIL : left, right == null ? Expression.NIL : right);
+        this.left = left == Expression.NIL ? null : left;
+        this.right = right == Expression.NIL ? null : right;
         init();
     }
 
@@ -89,16 +90,6 @@ final class DefaultBBOX implements BBOX, Serializable {
     }
 
     @Override
-    public Expression getExpression1() {
-        return left;
-    }
-
-    @Override
-    public Expression getExpression2() {
-        return right;
-    }
-
-    @Override
     public boolean evaluate(Object object) {
         return intersects.test(object);
     }
@@ -230,6 +221,11 @@ final class DefaultBBOX implements BBOX, Serializable {
     }
 
     @Override
+    protected String getName() {
+        return BBOX.NAME;
+    }
+
+    @Override
     public int hashCode() {
         return Objects.hash(left, right);
     }
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
index 291f3d9..6c2c9dc 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/DefaultFilterFactory.java
@@ -322,7 +322,7 @@ public class DefaultFilterFactory implements FilterFactory2 {
      */
     @Override
     public Intersects intersects(final Expression left, final Expression right) {
-        return new ST_Intersects(new Expression[]{left, right});
+        return new ST_Intersects(left, right);
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java
index 63ce1e6..a77f21c 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/ST_Intersects.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.io.Serializable;
 import java.util.AbstractMap;
 import java.util.Map;
-import java.util.Objects;
 import java.util.function.Predicate;
 
 import org.opengis.filter.FilterVisitor;
@@ -40,27 +39,24 @@ import org.apache.sis.util.collection.BackingStoreException;
 import org.locationtech.jts.geom.prep.PreparedGeometry;
 import org.locationtech.jts.geom.prep.PreparedGeometryFactory;
 
-import static org.apache.sis.util.ArgumentChecks.ensureNonEmpty;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
 /**
  * TODO: refine once Geometry API is stable.
  */
-public final class ST_Intersects implements Intersects, Serializable {
+public final class ST_Intersects extends SpatialFunction implements Intersects, Serializable {
 
-    public static final String NAME = "ST_Intersect";
+    public static final String NAME = "ST_Intersects";
 
     final Expression left;
     final Expression right;
 
     private transient Predicate intersects;
 
-    public ST_Intersects(Expression[] parameters) {
-        ensureNonEmpty("Parameters", parameters);
-        if (parameters.length != 2) throw new IllegalArgumentException("2 parameters are expected for intersection, but "+parameters.length+" are provided");
-
-        left = parameters[0];
-        right = parameters[1];
+    public ST_Intersects(Expression left, Expression right) {
+        super(left, right);
+        this.left = left;
+        this.right = right;
         init();
     }
 
@@ -161,16 +157,6 @@ public final class ST_Intersects implements Intersects, Serializable {
     }
 
     @Override
-    public Expression getExpression1() {
-        return left;
-    }
-
-    @Override
-    public Expression getExpression2() {
-        return right;
-    }
-
-    @Override
     public boolean evaluate(Object object) {
         return intersects.test(object);
     }
@@ -181,17 +167,8 @@ public final class ST_Intersects implements Intersects, Serializable {
     }
 
     @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        ST_Intersects that = (ST_Intersects) o;
-        return left.equals(that.left) &&
-                right.equals(that.right);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(left, right);
+    protected String getName() {
+        return org.opengis.filter.spatial.Intersects.NAME;
     }
 
     /**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java b/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java
index 32794fa..205764b 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/SpatialFunction.java
@@ -18,43 +18,35 @@ package org.apache.sis.filter;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import javax.measure.Unit;
 import javax.measure.UnitConverter;
-import org.apache.sis.coverage.grid.GridCoverage;
-import org.apache.sis.internal.feature.AttributeConvention;
-import org.apache.sis.internal.feature.Geometries;
-import org.apache.sis.math.Fraction;
-import org.apache.sis.measure.Units;
-import org.apache.sis.referencing.CRS;
-import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.util.ObjectConverters;
-import org.apache.sis.util.UnconvertibleObjectException;
-import org.apache.sis.util.Utilities;
-import org.apache.sis.util.collection.BackingStoreException;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LinearRing;
-import org.locationtech.jts.geom.Polygon;
-import org.locationtech.jts.geom.prep.PreparedGeometry;
-import org.locationtech.jts.geom.prep.PreparedGeometryFactory;
+
 import org.opengis.feature.Feature;
 import org.opengis.feature.PropertyNotFoundException;
 import org.opengis.filter.FilterVisitor;
 import org.opengis.filter.expression.Expression;
 import org.opengis.filter.expression.PropertyName;
 import org.opengis.filter.spatial.BinarySpatialOperator;
-import org.opengis.geometry.Envelope;
-import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
 
+import org.apache.sis.coverage.grid.GridCoverage;
+import org.apache.sis.internal.feature.AttributeConvention;
+import org.apache.sis.internal.feature.Geometries;
+import org.apache.sis.internal.feature.WrapResolution;
+import org.apache.sis.math.Fraction;
+import org.apache.sis.measure.Units;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.setup.GeometryLibrary;
+import org.apache.sis.util.ObjectConverters;
+import org.apache.sis.util.UnconvertibleObjectException;
+import org.apache.sis.util.Utilities;
+
+import org.locationtech.jts.geom.Geometry;
+
 /**
  *
  * @author  Johann Sorel (Geomatys)
@@ -64,12 +56,13 @@ import org.opengis.util.FactoryException;
  */
 abstract class SpatialFunction extends BinaryFunction implements BinarySpatialOperator {
 
-    private static final LinearRing[] EMPTY_RINGS = new LinearRing[0];
-    private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
-    private static final PreparedGeometryFactory PREPARED_FACTORY = new PreparedGeometryFactory();
-
     private static CoordinateReferenceSystem MERCATOR;
 
+    /**
+     * TODO: We should generify this. But too much code already depends on JTS, so for now I hack this
+     */
+    private static final Geometries<Geometry> SIS_GEOMETRY_FACTORY = (Geometries<Geometry>) Geometries.implementation(GeometryLibrary.JTS);
+
     private static CoordinateReferenceSystem getMercator() throws FactoryException {
         if (MERCATOR == null) {
             MERCATOR = CRS.forCode("EPSG:3395");
@@ -121,11 +114,9 @@ abstract class SpatialFunction extends BinaryFunction implements BinarySpatialOp
 
         Geometry candidate;
         if (value instanceof GridCoverage) {
-            candidate = (Geometry) value;
-        } else if (value instanceof GridCoverage) {
             //use the coverage envelope
             final GridCoverage coverage = (GridCoverage) value;
-            candidate = toGeometry(coverage.getGridGeometry().getEnvelope());
+            candidate = SIS_GEOMETRY_FACTORY.tryConvertToGeometry(coverage.getGridGeometry().getEnvelope(), WrapResolution.SPLIT);
         } else {
             try {
                 candidate = ObjectConverters.convert(value, Geometry.class);
@@ -138,69 +129,23 @@ abstract class SpatialFunction extends BinaryFunction implements BinarySpatialOp
     }
 
     /**
-     * Envelope to geometry.
-     */
-    private static Polygon toGeometry(final Envelope env) {
-        final Coordinate[] coordinates = new Coordinate[]{
-            new Coordinate(env.getMinimum(0), env.getMinimum(1)),
-            new Coordinate(env.getMinimum(0), env.getMaximum(1)),
-            new Coordinate(env.getMaximum(0), env.getMaximum(1)),
-            new Coordinate(env.getMaximum(0), env.getMinimum(1)),
-            new Coordinate(env.getMinimum(0), env.getMinimum(1))};
-        final LinearRing ring = GEOMETRY_FACTORY.createLinearRing(coordinates);
-        Polygon polygon = GEOMETRY_FACTORY.createPolygon(ring, new LinearRing[0]);
-        polygon.setUserData(env.getCoordinateReferenceSystem());
-        return polygon;
-    }
-
-    /**
-     * Envelope to prepared geometry.
-     */
-    private static PreparedGeometry toPreparedGeometry(final Envelope env){
-        double minX = env.getMinimum(0);
-        double minY = env.getMinimum(1);
-        double maxX = env.getMaximum(0);
-        double maxY = env.getMaximum(1);
-        if (Double.isNaN(minX) || Double.isInfinite(minX)) minX = Double.MIN_VALUE;
-        if (Double.isNaN(minY) || Double.isInfinite(minY)) minY = Double.MIN_VALUE;
-        if (Double.isNaN(maxX) || Double.isInfinite(maxX)) maxX = Double.MAX_VALUE;
-        if (Double.isNaN(maxY) || Double.isInfinite(maxY)) maxY = Double.MAX_VALUE;
-
-        final Coordinate[] coords = new Coordinate[5];
-        coords[0] = new Coordinate(minX, minY);
-        coords[1] = new Coordinate(minX, maxY);
-        coords[2] = new Coordinate(maxX, maxY);
-        coords[3] = new Coordinate(maxX, minY);
-        coords[4] = new Coordinate(minX, minY);
-        final LinearRing ring = GEOMETRY_FACTORY.createLinearRing(coords);
-        Geometry geom = GEOMETRY_FACTORY.createPolygon(ring, EMPTY_RINGS);
-        return PREPARED_FACTORY.create(geom);
-    }
-
-    /**
      * Reproject geometries to the same CRS if needed and if possible.
      */
     private static Geometry[] toSameCRS(final Geometry leftGeom, final Geometry rightGeom)
-            throws NoSuchAuthorityCodeException, FactoryException, TransformException {
+            throws FactoryException, TransformException {
 
         final CoordinateReferenceSystem leftCRS = Geometries.getCoordinateReferenceSystem(leftGeom);
         final CoordinateReferenceSystem rightCRS = Geometries.getCoordinateReferenceSystem(rightGeom);
 
-        if (leftCRS == null || rightCRS == null) {
-            //one or both geometries doesn't have a defined CRS, we assume that both
-            //are in the same CRS
-            return new Geometry[]{leftGeom, rightGeom};
-        } else if (Utilities.equalsIgnoreMetadata(leftCRS, rightCRS)) {
-            //both are in the same CRS, nothing to reproject
-            return new Geometry[]{leftGeom, rightGeom};
-        }
-
-        //we choose to reproject the right operand.
-        //there is no special reason to make this choice but we must make one.
-        //perhaps there could be a way to determine a best crs ?
-        final CoordinateOperation trs = CRS.findOperation(rightCRS, leftCRS, null);
+        final CRSMatching.Match match = CRSMatching
+                .left(leftCRS)
+                .right(rightCRS);
 
-        return new Geometry[]{leftGeom, (Geometry) Geometries.transform(rightGeom, trs)};
+        final CRSMatching.Transformer<Geometry> projectGeom = (g, op) -> SIS_GEOMETRY_FACTORY.tryTransform(g, op, null);
+        return new Geometry[]{
+                match.transformLeftToCommon(leftGeom, projectGeom),
+                match.transformRightToCommon(rightGeom, projectGeom)
+        };
     }
 
     /**
@@ -282,133 +227,6 @@ abstract class SpatialFunction extends BinaryFunction implements BinarySpatialOp
         }
     }
 
-
-    /**
-     * The {@value #NAME} filter.
-     */
-    static final class BBOX extends SpatialFunction implements org.opengis.filter.spatial.BBOX {
-
-        /**
-         * For cross-version compatibility.
-         */
-        private static final long serialVersionUID = -4806881904891000892L;
-
-        //cache the bbox geometry
-        private transient PreparedGeometry boundingGeometry;
-        private final org.locationtech.jts.geom.Envelope boundingEnv;
-        private final CoordinateReferenceSystem crs;
-
-        private final Envelope env;
-
-        BBOX(Expression expression, Envelope env) {
-            super(expression, new LeafExpression.Literal(env));
-            this.env = env;
-            boundingGeometry = toPreparedGeometry(env);
-            boundingEnv = boundingGeometry.getGeometry().getEnvelopeInternal();
-            final CoordinateReferenceSystem crsFilter = env.getCoordinateReferenceSystem();
-            if (crsFilter != null) {
-                this.crs = crsFilter;
-            } else {
-                // In CQL if crs is not specified, it is EPSG:4326
-                this.crs = CommonCRS.WGS84.normalizedGeographic();
-            }
-        }
-
-        private PreparedGeometry getPreparedGeometry(){
-            if (boundingGeometry == null) {
-                boundingGeometry = toPreparedGeometry(env);
-            }
-            return boundingGeometry;
-        }
-
-        @Override
-        protected String getName() {
-            return NAME;
-        }
-
-        @Override
-        public String getPropertyName() {
-            if (expression1 instanceof PropertyName) {
-                return ((PropertyName) expression1).getPropertyName();
-            }
-            return null;
-        }
-
-        @Override
-        public String getSRS() {
-            try {
-                return IdentifiedObjects.lookupURN(env.getCoordinateReferenceSystem(), null);
-            } catch (FactoryException ex) {
-                throw new BackingStoreException(ex.getMessage(), ex);
-            }
-        }
-
-        @Override
-        public double getMinX() {
-            return env.getMinimum(0);
-        }
-
-        @Override
-        public double getMinY() {
-            return env.getMinimum(1);
-        }
-
-        @Override
-        public double getMaxX() {
-            return env.getMaximum(0);
-        }
-
-        @Override
-        public double getMaxY() {
-            return env.getMaximum(1);
-        }
-
-        @Override
-        public boolean evaluate(Object object) {
-            Geometry candidate = toGeometry(object, expression1);
-
-            if (candidate == null) {
-                return false;
-            }
-
-            //we don't know in which crs it is, try to find it
-            CoordinateReferenceSystem candidateCrs = null;
-            try {
-                candidateCrs = Geometries.getCoordinateReferenceSystem(candidate);
-            } catch (FactoryException ex) {
-                warning(ex);
-            }
-
-            //if we don't know the crs, we will assume it's the objective crs already
-            if (candidateCrs != null) {
-                //reproject in objective crs if needed
-                if (!Utilities.equalsIgnoreMetadata(this.crs, candidateCrs)) {
-                    try {
-                        candidate = (Geometry) Geometries.transform(candidate, CRS.findOperation(candidateCrs, this.crs, null));
-                    } catch (MismatchedDimensionException | TransformException | FactoryException ex) {
-                        warning(ex);
-                        return false;
-                    }
-                }
-            }
-
-            final org.locationtech.jts.geom.Envelope candidateEnv = candidate.getEnvelopeInternal();
-
-            if (boundingEnv.contains(candidateEnv) || candidateEnv.contains(boundingEnv)) {
-                return true;
-            } else if (boundingEnv.intersects(candidateEnv)) {
-                return getPreparedGeometry().intersects(candidate);
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public Object accept(FilterVisitor visitor, Object extraData) {
-            return visitor.visit(this, extraData);
-        }
-    }
-
     /**
      * The {@value #NAME} filter.
      */
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
index fa6856d..4849071 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
@@ -475,7 +475,7 @@ public abstract class Geometries<G> {
      *
      * @see #tryGetCoordinateReferenceSystem(Object)
      */
-    Object tryTransform(Object geometry, CoordinateOperation operation, CoordinateReferenceSystem targetCRS)
+    public G tryTransform(Object geometry, CoordinateOperation operation, CoordinateReferenceSystem targetCRS)
             throws FactoryException, TransformException
     {
         if (rootClass.isInstance(geometry)) {
@@ -595,7 +595,7 @@ public abstract class Geometries<G> {
     /**
      * See {@link Geometries#toGeometry(Envelope, WrapResolution)}.
      */
-    Object tryConvertToGeometry(final Envelope env, WrapResolution resolution) {
+    public G tryConvertToGeometry(final Envelope env, WrapResolution resolution) {
         // Ensure that we can isolate an horizontal part in the given envelope.
         final int x;
         if (env.getDimension() == 2) {
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
index 17f826c..0c9920b 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/JTS.java
@@ -433,7 +433,7 @@ add:    for (;;) {
      * @see #tryGetCoordinateReferenceSystem(Object)
      */
     @Override
-    Geometry tryTransform(final Object geometry, final CoordinateOperation operation, final CoordinateReferenceSystem targetCRS)
+    public Geometry tryTransform(final Object geometry, final CoordinateOperation operation, final CoordinateReferenceSystem targetCRS)
             throws FactoryException, TransformException
     {
         if (geometry instanceof Geometry) {
diff --git a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
index 2d6d724..feba114 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/filter/SQLMMTest.java
@@ -271,16 +271,16 @@ public final strictfp class SQLMMTest extends TestCase {
     @Test
     public void ST_Intersects() {
         try {
-            new ST_Intersects(null);
-            fail("ST_Intersects operator should accept exactly 2 parameters");
+            new ST_Intersects(null, null);
+            fail("ST_Intersects operator should not accept null parameters");
         } catch (NullArgumentException e) {
             // expected behavior
         }
 
         try {
-            new ST_Intersects(new Expression[3]);
-            fail("ST_Intersects operator should accept exactly 2 parameters");
-        } catch (IllegalArgumentException e) {
+            new ST_Intersects(null, factory.literal(new GeneralEnvelope(2)));
+            fail("ST_Intersects operator should not accept null parameters");
+        } catch (NullArgumentException e) {
             // expected behavior
         }
 
@@ -291,7 +291,7 @@ public final strictfp class SQLMMTest extends TestCase {
         });
 
         final Literal lring = factory.literal(ring);
-        ST_Intersects st = intersects(factory.literal(geometryFactory.createPoint(new Coordinate(2, 4))), lring);
+        ST_Intersects st = new ST_Intersects(factory.literal(geometryFactory.createPoint(new Coordinate(2, 4))), lring);
         // Ensure argument nullity does not modify behavior
         assertFalse("Unexpected intersection", st.evaluate(null));
         assertFalse("Unexpected intersection", st.evaluate(new Object()));
@@ -301,18 +301,18 @@ public final strictfp class SQLMMTest extends TestCase {
         final Point point = geometryFactory.createPoint(second);
         f.setPropertyValue(P_NAME, point);
         final PropertyName geomName = factory.property(P_NAME);
-        st = intersects(geomName, lring);
+        st = new ST_Intersects(geomName, lring);
         assertTrue("Border point should intersect triangle", st.evaluate(f));
         // Ensure inverting expression does not modify behavior.
-        st = intersects(lring, geomName);
+        st = new ST_Intersects(lring, geomName);
         assertTrue("Border point should intersect triangle", st.evaluate(f));
 
         // Ensure CRS conversion works as expected (see package-info).
         // Missing
         point.setUserData(CommonCRS.defaultGeographic());
-        expectFailFast(() -> intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
+        expectFailFast(() -> new ST_Intersects(geomName, lring).evaluate(f), IllegalArgumentException.class);
         final Literal lPoint = factory.literal(point);
-        expectFailFast(() -> intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
+        expectFailFast(() -> new ST_Intersects(lPoint, lring).evaluate(null), IllegalArgumentException.class);
 
         // utm domain contained in CRS:84
         /* TODO: this is broken. We have to reproject geometries each time we change CRS.
@@ -330,10 +330,6 @@ public final strictfp class SQLMMTest extends TestCase {
         */
     }
 
-    private static ST_Intersects intersects(final Expression left, Expression right) {
-        return new ST_Intersects(new Expression[]{left, right});
-    }
-
     @Test
     public void ST_Envelope() {
         try {