Hello, I started using the org.apache.sis.storage.sis-geotiff module (version 1.1) for my application.
I tested it with various public domain GeoTIFF files ( https://download.osgeo.org/geotiff/samples/), and got this exception a few times: org.opengis.util.NoSuchIdentifierException: No operation method found for name or identifier “GeoTIFF:XX”, where XX varies from 1 to 27. Each one of these values is an entry in the 6.3.3.3 section of this document: http://geotiff.maptools.org/spec/geotiff6.html#6.3.3.3 This exception comes from the CRSBuilder class: https://github.com/apache/sis/blob/master/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java After initially sharing my findings with Martin, I understand that the support for the ProjCoordTransGeoKey values from 1 to 27 is not complete yet. For full support, I also understand that Apache SIS would need to support the following projection methods: case "2": // CT_TransvMercator_Modified_Alaska case "5": // CT_ObliqueMercator_Rosenmund case "6": //CT_ObliqueMercator_Spherical case "9": // CT_LambertConfConic_Helmert case "13": // CT_EquidistantConic case "14": // CT_Stereographic case "19": // CT_Gnomonic case "21": // CT_Orthographic case "23": // CT_Robinson case "25": // CT_VanDerGrinten I am proposing to implement partial support of the following projection methods: case "1": // CT_TransverseMercator case "3": // CT_ObliqueMercator case "4": // CT_ObliqueMercator_Laborde case "7": // CT_Mercator case "8": // CT_LambertConfConic_2SP case "10": // CT_LambertAzimEqualArea case "11": // CT_AlbersEqualArea case "12": // CT_AzimuthalEquidistant, using Modified Azimuthal Equidistant case "15": // CT_PolarStereographic case "16": // CT_ObliqueStereographic case "17": // CT_Equirectangular case "18": // CT_CassiniSoldner case "26": // CT_NewZealandMapGrid case "27": // CT_TransvMercator_SouthOriented case "20": // CT_MillerCylindrical case "22": // CT_Polyconic case "24": // CT_Sinusoidal Using http://geotiff.maptools.org/proj_list/ as a resource, I came up with this code as part of the CRSBuilder.createConversion method: switch (type) { // based on http://geotiff.maptools.org/proj_list/ case "1": // CT_TransverseMercator method = getCoordinateOperationFactory().getOperationMethod("EPSG:9807"); break; case "3": // CT_ObliqueMercator method = getCoordinateOperationFactory().getOperationMethod("EPSG:9815"); break; case "4": // CT_ObliqueMercator_Laborde method = getCoordinateOperationFactory().getOperationMethod("EPSG:9813"); break; case "7": // CT_Mercator method = getCoordinateOperationFactory().getOperationMethod("EPSG:9804"); break; case "8": // CT_LambertConfConic_2SP method = getCoordinateOperationFactory().getOperationMethod("EPSG:9802"); break; case "10": // CT_LambertAzimEqualArea method = getCoordinateOperationFactory().getOperationMethod("EPSG:9820"); break; case "11": // CT_AlbersEqualArea method = getCoordinateOperationFactory().getOperationMethod("EPSG:9822"); break; case "12": // CT_AzimuthalEquidistant, using Modified Azimuthal Equidistant method = getCoordinateOperationFactory().getOperationMethod("EPSG:9832"); break; case "15": // CT_PolarStereographic method = getCoordinateOperationFactory().getOperationMethod("EPSG:9810"); break; case "16": // CT_ObliqueStereographic method = getCoordinateOperationFactory().getOperationMethod("EPSG:9809"); break; case "17": // CT_Equirectangular method = getCoordinateOperationFactory().getOperationMethod("EPSG:9823"); break; case "18": // CT_CassiniSoldner method = getCoordinateOperationFactory().getOperationMethod("EPSG:9806"); break; case "26": // CT_NewZealandMapGrid method = getCoordinateOperationFactory().getOperationMethod("EPSG:9811"); break; case "27": // CT_TransvMercator_SouthOriented method = getCoordinateOperationFactory().getOperationMethod("EPSG:9808"); break; case "20": // CT_MillerCylindrical method = new MillerCylindrical(); break; case "22": // CT_Polyconic method = new Polyconic(); break; case "24": // CT_Sinusoidal method = new Sinusoidal(); break; case "2": // CT_TransvMercator_Modified_Alaska (not supported by Apache SIS) case "5": // CT_ObliqueMercator_Rosenmund (not supported by Apache SIS) case "6": //CT_ObliqueMercator_Spherical (not supported by Apache SIS) case "9": // CT_LambertConfConic_Helmert (not supported by Apache SIS) case "13": // CT_EquidistantConic (not supported by Apache SIS) case "14": // CT_Stereographic (not supported by Apache SIS) case "19": // CT_Gnomonic (not supported by Apache SIS) case "21": // CT_Orthographic (not supported by Apache SIS) case "23": // CT_Robinson (not supported by Apache SIS) case "25": // CT_VanDerGrinten (not supported by Apache SIS) default: method = getCoordinateOperationFactory().getOperationMethod(Constants.GEOTIFF + ':' + type); break; } Martin proposed that I share my findings on this forum. He also suggested that there are potential issues with this approach, that I will summarize here: 1/ http://geotiff.maptools.org/proj_list/ is not authoritative 2/ it's not certain whether Azimuthal Equidistant and Modified Azimuthal Equidistant are a match in case #12 3/ having a hard-coded mapping might not be the best way of doing things. External third parties might want to customize this to add their own mapping. Or these mappings could be discovered from the classpath at runtime. I am opening this discussion to see what you guys think. I am volunteering to submit this patch to the CRSBuilder class if there is a consensus that this is the right change. -Thierry
