|
44 | 44 | import java.awt.color.*; |
45 | 45 | import java.awt.image.*; |
46 | 46 | import java.io.*; |
| 47 | +import java.lang.reflect.Field; |
47 | 48 | import java.lang.reflect.Method; |
48 | 49 | import java.nio.*; |
49 | 50 | import java.util.*; |
@@ -84,6 +85,9 @@ public class GDALUtils |
84 | 85 | protected static final String GDAL_DATA_PATH = "GDAL_DATA"; |
85 | 86 |
|
86 | 87 | protected static final AtomicBoolean gdalIsAvailable = new AtomicBoolean(false); |
| 88 | + |
| 89 | + public enum LatLonOrder { latLonCRSauthority, longitudeLatitude }; |
| 90 | + private static LatLonOrder latLonOrder = LatLonOrder.latLonCRSauthority; |
87 | 91 |
|
88 | 92 | static |
89 | 93 | { |
@@ -199,6 +203,25 @@ public class GDALUtils |
199 | 203 | } |
200 | 204 | } |
201 | 205 | } |
| 206 | + |
| 207 | + // For GDAL 3.0, set the transformation axis order. Coordinate transformations |
| 208 | + // for vesion 2.x and 3.x have lat/lon reversed |
| 209 | + // See https://gdal.org/tutorials/osr_api_tut.html#crs-and-axis-order |
| 210 | + public static void setGDAL3axis(SpatialReference srs) |
| 211 | + { |
| 212 | + // Force all transformations to return longitude, latitude |
| 213 | + try { |
| 214 | + Class<?>[] a = { int.class }; |
| 215 | + Method setAxis = srs.getClass().getMethod("SetAxisMappingStrategy", a); |
| 216 | + Field v = org.gdal.osr.osrConstants.class.getField("OAMS_TRADITIONAL_GIS_ORDER"); |
| 217 | + setAxis.invoke(srs, v.getInt(v)); |
| 218 | + latLonOrder = LatLonOrder.longitudeLatitude; |
| 219 | + } catch (Exception e) { |
| 220 | + e.printStackTrace(); |
| 221 | + } |
| 222 | + } |
| 223 | + |
| 224 | + public static LatLonOrder getLatLonOrder() { return latLonOrder; } |
202 | 225 |
|
203 | 226 | protected static String getCurrentDirectory() |
204 | 227 | { |
@@ -1164,6 +1187,7 @@ public static SpatialReference createGeographicSRS() throws WWRuntimeException |
1164 | 1187 | } |
1165 | 1188 |
|
1166 | 1189 | SpatialReference srs = new SpatialReference(); |
| 1190 | + GDALUtils.setGDAL3axis(srs); |
1167 | 1191 | srs.ImportFromProj4("+proj=latlong +datum=WGS84 +no_defs"); |
1168 | 1192 | return srs; |
1169 | 1193 | } |
@@ -1468,6 +1492,7 @@ else if (dataType == gdalconst.GDT_UInt32) |
1468 | 1492 | { |
1469 | 1493 | params.setValue(AVKey.SPATIAL_REFERENCE_WKT, proj_wkt); |
1470 | 1494 | srs = new SpatialReference(proj_wkt); |
| 1495 | + GDALUtils.setGDAL3axis(srs); |
1471 | 1496 | } |
1472 | 1497 |
|
1473 | 1498 | double[] gt = new double[6]; |
@@ -1504,6 +1529,12 @@ else if (Angle.isValidLongitude(minX) && Angle.isValidLatitude(maxY) |
1504 | 1529 | if (null == srs) |
1505 | 1530 | { |
1506 | 1531 | srs = createGeographicSRS(); |
| 1532 | + // For GDAL 3.0, set the transformation axis order |
| 1533 | + try { |
| 1534 | + Method setAxis = srs.getClass().getMethod("SetAxisMappingStrategy", Integer.class); |
| 1535 | + Field v = org.gdal.osr.osrConstants.class.getField("OAMS_TRADITIONAL_GIS_ORDER"); |
| 1536 | + setAxis.invoke(srs, v); |
| 1537 | + } catch (Exception e) {} |
1507 | 1538 | } |
1508 | 1539 | else if (srs.IsGeographic() == 0) |
1509 | 1540 | { |
|
0 commit comments