Hello Thierry

Thanks for your tests and sharing the results. Regarding the support of map projections in GeoTIFF reader, the ones listed below should be already supported by current reader. Unless there is a bug (in which case I would be interested to have more information), it should not be necessary to add a switch statement for them.

    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 "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


However this mapping is not obvious when reading the source code. This mapping exists, but is defined outside the GeoTIFF reader. The trick is that the following code:

    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");
         etc...
    }


Can also be written as below:

   switch (type) { // based on http://geotiff.maptools.org/proj_list/
        case "1": // CT_TransverseMercator
            method = 
getCoordinateOperationFactory().getOperationMethod("GeoTIFF:1");
            break;
        case "3": // CT_ObliqueMercator
            method = 
getCoordinateOperationFactory().getOperationMethod("GeoTIFF:3");
            break;
        case "4": // CT_ObliqueMercator_Laborde
            method = 
getCoordinateOperationFactory().getOperationMethod("GeoTIFF:4");
            break;
        case "7": // CT_Mercator
            method = 
getCoordinateOperationFactory().getOperationMethod("GeoTIFF:7");
        etc...
   }


EPSG is one authority, but not the only one. ESRI, GeoTIFF, NetCDF and S57 are other authorities known to the SIS referencing module. So "GeoTIFF:3" is already considered by SIS as synonymous of "EPSG:9815". When using "GeoTIFF" instead of "EPSG" as the authority, the codes in the getOperationMethod(…) argument are identical to the switch argument. This is why the whole switch statement can be simplified by this single line:

   method = getCoordinateOperationFactory().getOperationMethod("GeoTIFF:" + 
type);

The advantage of this approach is to make possible to plugin new map projections defined by external projects. For example the Geotk project defines the "New Zealand Map Grid" projection (that code can not be ported to Apache SIS as-is for licensing reason). If Geotk is on the classpath, the "GeoTIFF:26" code become automatically recognized. This extension capability would be lost if we replaced the current mechanism by a switch statement.

An inconvenient of current approach is that it make more difficult to see what are the currently supported map projections, as the list does not appear explicitly in the code. However it is possible to write a small program that automatically generates this list, for example in HTML. That generated page could be included in the documentation of GeoTIFF module. Is it something you would like to contribute?

Another consequence of this approach is that code like below will not really help. It will just replace the "No operation method found for name or identifier GeoTIFF:26" message by "No operation method found for name or identifier EPSG:9811".

    case "26": // CT_NewZealandMapGrid
         method = 
getCoordinateOperationFactory().getOperationMethod("EPSG:9811");
         break;


About the following projection:

case "12": // CT_AzimuthalEquidistant, using Modified Azimuthal Equidistant
I do not have a clear answer about whether it would be correct or not. However when looking at the Snyder's book "Map Projection — a working manual", the section about Azimuthal Equidistant does not give formulas for the general case. Instead the most general formula that I saw was the approximation used for Micronesia, which is named "Modified Azimuthal Equidistant" by EPSG. My assumption is that a truly generic formula for "Azimuthal Equidistant" is not provided by Snyder's book because too complex. I also assume that most map projection libraries implemented that formula, and because it was given in a section named "Azimuthal Equidistant", the libraries used that name.


About the non-supported projections:

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)

A problem with Apache SIS as currently designed is that the support of a map projection is a "all or nothing" behavior. We have not really explored mechanisms for partially implemented map projections, for example when only the projection and parameter names are known but the actual formula is not yet implemented. If we want to add this mechanism, it would actually be a work outside the GeoTIFF module (it would be in the referencing module instead). Is it something you would like to contribute?

    Regards,

        Martin


Reply via email to