I guess that's the part where I am confused.
When I call new
MyCRSBuilder(....).getCoordinateOperationFactory().getOperationMethod("GeoTIFF:4");
I get
Exception in thread "main" org.opengis.util.NoSuchIdentifierException: No
operation method found for name or identifier “GeoTIFF:4”.
at
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.getOperationMethod(DefaultMathTransformFactory.java:474)
at
org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory.getOperationMethod(DefaultCoordinateOperationFactory.java:287)
I am unsure how the GeoTIFF:xxx operations get plugged in/recognized by the
code. I am probably doing something wrong, maybe some initializer I should
be calling first? Or a configuration file I am missing?
I created my own MyCRSBuilder class for this test, based on the CRSBuilder
code, but taking only a map of <Integer, Object> in it's constructor .
I don't mind the hard-coded logic so much. I'd rather contribute a
standalone version of the CRSBuilder that essentially takes a map of
<Short, Object> or <Integer, Object> in its constructor. This would make
it easier to unit test, and directly reusable in my own use case. My use
case doesn't need the TIFF file parsing part of the Apache SIS storage
module, just the interpretation of the GeoTIFF meta data itself.
On Mon, Feb 14, 2022 at 5:44 AM Martin Desruisseaux <
[email protected]> wrote:
> 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
>
>
>