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