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

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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 49bda1dfe2 Use WKT 2 format when writting PRJ files. This is not the 
common practice (which is to use WKT 1), but that practice was using an 
ambiguous WKT 1 variant. The WKT 2 aims to avoid those ambiguities, and 
hopefully is starting to be supported widely enough.
49bda1dfe2 is described below

commit 49bda1dfe2f0abbb855b3592b7d6cf20453294e2
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Apr 21 22:36:11 2022 +0200

    Use WKT 2 format when writting PRJ files. This is not the common practice 
(which is to use WKT 1),
    but that practice was using an ambiguous WKT 1 variant. The WKT 2 aims to 
avoid those ambiguities,
    and hopefully is starting to be supported widely enough.
---
 .../src/main/java/org/apache/sis/io/wkt/Formatter.java    | 10 +++++-----
 .../org/apache/sis/io/wkt/GeodeticObjectParserTest.java   | 10 +++++-----
 .../org/apache/sis/internal/storage/PRJDataStore.java     | 11 +++++++++--
 .../sis/internal/storage/esri/WritableStoreTest.java      | 15 +++++++++------
 4 files changed, 28 insertions(+), 18 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java 
b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
index ae773a901c..044b16632d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
@@ -1472,7 +1472,7 @@ public class Formatter implements Localized {
             closeElement(false);
             /*
              * ISO 19162 requires the conversion factor to be positive.
-             * In addition, keywords other than "Unit" are not valid in WKt 1.
+             * In addition, keywords other than "Unit" are not valid in WKT 1.
              */
             if (!(conversion > 0) || (keyword != WKTKeywords.Unit && isWKT1)) {
                 setInvalidWKT(Unit.class, null);
@@ -1696,8 +1696,8 @@ public class Formatter implements Localized {
             if (unit != null && units.remove(unit.getSystemUnit()) != unit) {
                 /*
                  * The unit that we removed was not the expected one. Probably 
the user has invoked
-                 * addContextualUnit(…) again without a matching call to 
restoreContextualUnit(…).
-                 * However this check does not work in 
Convention.WKT1_COMMON_UNITS mode, since the
+                 * addContextualUnit(…) again without a matching call to 
`restoreContextualUnit(…)`.
+                 * However this check does not work in 
`Convention.WKT1_COMMON_UNITS` mode, since the
                  * map is always empty in that mode.
                  */
                 if (!convention.usesCommonUnits) {
@@ -1708,8 +1708,8 @@ public class Formatter implements Localized {
         } else if (units.put(previous.getSystemUnit(), previous) != unit) {
             /*
              * The unit that we replaced was not the expected one. Probably 
the user has invoked
-             * addContextualUnit(…) again without a matching call to 
restoreContextualUnit(…).
-             * Note that this case should never happen in 
Convention.WKT1_COMMON_UNITS mode,
+             * addContextualUnit(…) again without a matching call to 
`restoreContextualUnit(…)`.
+             * Note that this case should never happen in 
`Convention.WKT1_COMMON_UNITS` mode,
              * since `previous` should never be non-null in that mode (if the 
user followed
              * the documented pattern).
              */
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
index 822a0f0afb..4a106b9519 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
@@ -436,7 +436,7 @@ public final strictfp class GeodeticObjectParserTest 
extends TestCase {
          * those units are ignored).
          *
          * This is a violation of both OGC 01-009 and ISO 19162 standards, but 
this is what GDAL does.
-         * So we allow this interpretation in Convention.WKT1_COMMON_UNITS for 
compatibility reasons.
+         * So we allow this interpretation in `Convention.WKT1_COMMON_UNITS` 
for compatibility reasons.
          */
         wkt = wkt.replace("2.5969213", "2.33722917");   // Convert unit in 
prime meridian.
         newParser(Convention.WKT1_IGNORE_AXES);
@@ -695,8 +695,8 @@ public final strictfp class GeodeticObjectParserTest 
extends TestCase {
 
         validateParisFranceII(parse(ProjectedCRS.class, wkt), 0, true);
         /*
-         * Parse again using Convention.WKT1_COMMON_UNITS and ignoring AXIS[…] 
elements.
-         * See the comment in 'testGeographicWithParisMeridian' method for a 
discussion.
+         * Parse again using `Convention.WKT1_COMMON_UNITS` and ignoring 
AXIS[…] elements.
+         * See the comment in `testGeographicWithParisMeridian` method for a 
discussion.
          * The new aspect tested by this method is that the unit should be 
ignored
          * for the parameters in addition to the prime meridian.
          */
@@ -933,11 +933,11 @@ public final strictfp class GeodeticObjectParserTest 
extends TestCase {
     public void testMathTransform() throws ParseException, 
NoninvertibleTransformException {
         /*
          * Test "Transverse Mercator" (not south-oriented) with an axis 
oriented toward south.
-         * The 'south' transform is actually the usual Transverse Mercator 
projection, despite
+         * The `south` transform is actually the usual Transverse Mercator 
projection, despite
          * having axis oriented toward South.  Consequently the "False 
Northing" parameter has
          * the same meaning for those two CRS. Since we assigned the same 
False Northing value,
          * those two CRS have their "False origin" at the same location. This 
is why conversion
-         * from 'south' to 'north' introduce no translation, only a reversal 
of y axis.
+         * from `south` to `north` introduce no translation, only a reversal 
of y axis.
          */
         ProjectedCRS north = parseTransverseMercator(false, false, 1000);
         assertEquals(AxisDirection.WEST,  
north.getCoordinateSystem().getAxis(0).getDirection());
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java
index da82d2fa69..fb29f70e0b 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java
@@ -146,7 +146,7 @@ public abstract class PRJDataStore extends URIDataStore {
             final String wkt = readAuxiliaryFile(PRJ, encoding).toString();
             if (wkt != null) {
                 final StoreFormat format = new StoreFormat(locale, timezone, 
null, listeners);
-                format.setConvention(Convention.WKT1_COMMON_UNITS);
+                format.setConvention(Convention.WKT1_COMMON_UNITS);         // 
Ignored if the format is WKT 2.
                 crs = (CoordinateReferenceSystem) format.parseObject(wkt);
                 format.validate(crs);
             }
@@ -298,6 +298,13 @@ public abstract class PRJDataStore extends URIDataStore {
      * Writes the {@code "*.prj"} auxiliary file if {@link #crs} is non-null.
      * If {@link #crs} is null and the auxiliary file exists, it is deleted.
      *
+     * <h4>WKT version used</h4>
+     * Current version writes the CRS in WKT 2 format. This is not the common 
practice, which uses WKT 1.
+     * But the WKT 1 variant used by the common practice is not the standard 
format defined by OGC 01-009.
+     * It is more like  {@link Convention#WKT1_IGNORE_AXES}, which has many 
ambiguity problems. The WKT 2
+     * format fixes those ambiguities. We hope that major software have 
updated their referencing engine
+     * and can now parse WKT 2 as well as WKT 1.
+     *
      * @throws DataStoreException if an error occurred while writing the file.
      */
     protected final void writePRJ() throws DataStoreException {
@@ -306,7 +313,7 @@ public abstract class PRJDataStore extends URIDataStore {
                 deleteAuxiliaryFile(PRJ);
             } else try (BufferedWriter out = writeAuxiliaryFile(PRJ, 
encoding)) {
                 final StoreFormat format = new StoreFormat(locale, timezone, 
null, listeners);
-                format.setConvention(Convention.WKT1_COMMON_UNITS);
+                // Keep the default "WKT 2" format (see method javadoc).
                 format.format(crs, out);
                 out.newLine();
             }
diff --git 
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/esri/WritableStoreTest.java
 
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/esri/WritableStoreTest.java
index a589191d3d..490aff7266 100644
--- 
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/esri/WritableStoreTest.java
+++ 
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/esri/WritableStoreTest.java
@@ -90,13 +90,16 @@ public final strictfp class WritableStoreTest extends 
TestCase {
     private static void verifyContent(final Path file) throws IOException {
         assertArrayEquals(getExpectedLines(), 
Files.readAllLines(file).toArray());
         assertArrayEquals(new String[] {
-            "GEOGCS[\"WGS 84\",",
+            "GEODCRS[\"WGS 84\",",
             "  DATUM[\"World Geodetic System 1984\",",
-            "    SPHEROID[\"WGS84\", 6378137.0, 298.257223563]],",
-            "    PRIMEM[\"Greenwich\", 0.0],",
-            "  UNIT[\"degree\", 0.017453292519943295],",
-            "  AXIS[\"Longitude\", EAST],",
-            "  AXIS[\"Latitude\", NORTH]]",
+            "    ELLIPSOID[\"WGS84\", 6378137.0, 298.257223563, 
LENGTHUNIT[\"metre\", 1]]],",
+            "    PRIMEM[\"Greenwich\", 0.0, ANGLEUNIT[\"degree\", 
0.017453292519943295]],",
+            "  CS[ellipsoidal, 2],",
+            "    AXIS[\"Longitude (L)\", east, ORDER[1]],",
+            "    AXIS[\"Latitude (B)\", north, ORDER[2]],",
+            "    ANGLEUNIT[\"degree\", 0.017453292519943295],",
+            "  AREA[\"World\"],",
+            "  BBOX[-90.00, -180.00, 90.00, 180.00]]",
         }, Files.readAllLines(toPRJ(file)).toArray());
     }
 

Reply via email to