You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@sis.apache.org by César Martínez Izquierdo <ce...@gmail.com> on 2018/01/29 18:25:17 UTC

API for CRS transformation

Hi,

I am evaluating using SIS as the basis for our CRS management libraries on
gvSIG project (a desktop, Java-based GIS application).

I am checking we can implement all our use-cases, but I am finding some
limitations regarding selection of CRS transform operations.

Currently, we offer the user the opportunity to choose the transformation
method when transforming coordinates from a source CRS to a target CRS
involving different datums (for instance from EPSG:23030 to EPSG:4326).

However, I don't find a clear way to get this information from SIS API.
Ideally, I would expect a method like:
Set<CoordinateOperation> ops = CRS.findOperations(source, target, context);
but it obviously doesn't exist at the moment.

I have achieved a similar goal by diving a bit in the implementation and
subclassing CoordinateOperationFinder and DefaultCoordinateOperationFactory
:

[...]
Set<CoordinateOperation> operations =
((CoordinateOperationAuthorityFactory)
registry).createFromCoordinateReferenceSystemCodes("4230", "4326");
Set<CoordinateOperation> operations =
((CoordinateOperationAuthorityFactory) CustomCoordinateOperationFinder
finder = new
CustomCoordinateOperationFinder((CoordinateOperationAuthorityFactory)
registry,
                (CoordinateOperationFactory) auxFactory, null);
CoordinateOperation concatenatedOps = finder.createOperationStep(source,
(SingleCRS)target, selectedOp);

This approach is clearly a bad idea, since:
- those classes have been designed to not being subclassed (declaring a lot
of private or "friendly" methods) and I assume my implementation would be
very sensitive to SIS version updates
- we loose the heuristics internally used by SIS to use the right
concatenation pipeline (in the example: EPSG:23030 to EPSG:4230, then
EPSG:4326). Which means that we would need to replicate those heuristics in
our library to take into account all the different scenarios, as it is
currently done by SIS internally.
- it seems to fail if CRS.findOperation has been previously called (I
assume that caused by transformation caching for those CRS pairs)

However, I believe that CRS.findOperations would not be extremely hard to
implement if done within Apache SIS library (instead of doing it
externally). Do you think it would be feasible? Would you be keen on
accepting such contribution?

Thanks in advance,

César Martínez Izquierdo




-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   César Martínez Izquierdo
   GIS developer
   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
   SCOLAB: http://www.scolab.es
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: API for CRS transformation

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Le 06/02/2018 à 11:38, César Martínez Izquierdo a écrit :

> I think there are two different requirements being mixed here (…snip…):
>
> 1- defining the database to be used (embedded or external, database
> directory, database name, etc)
> 2- getting a connection to the defined database
>
> For the second one, I think it would be enough to place a
> getDataSource() method somewhere in the API.
>
Yes, it may be the most pragmatic approach.


> If I correctly understand the code, at the moment you try to get a
> JNDI context if available. Otherwise, you try to use Derby
> EmbeddedDataSource to open (and potentially create) a database named
> "SpatialMetadata" on SIS_DATA (if available) or on "derby.system.home"
> otherwise.
>
Right.


> I think it is fine to delegate on the SIS user the decision to provide
> a JNDI context or to set SIS_DATA or derby.system.home. When an
> external database should be used and JNDI is absent, I think the most
> standard way would be to provide a JDBC connection string. It would
> also be nice to be able to provide SIS_DATA as a Java property in
> addition to the environment variable.
>
Since JNDI is standard and "derby.system.home" is defined outside SIS,
the SIS_DATA environment variable is currently the only SIS-specific
configuration alternative. We avoided adding other SIS-specific
alternatives for now (e.g. a SIS_DATA property) because having too many
ways to configure the system makes client support more difficult. In our
experience with Geotk, when a user reports a problem related to EPSG
dataset, in most cases the cause is SIS selecting a different database
than the one the user thought. So I agree that we may need to provide
different way to configure SIS, but I think we should be careful to not
add too many ways and wait to identify the most useful ones in practice.
I agree that a JDBC connection string is one of those.


> Finally, I wonder if it makes sense to have several configured
> databases (for instance for providing CRS definitions from a different
> authority), although I understand that in this case I would just
> register the authority factory and SIS doesn't need to know about the
> database internally used by the authority.
>
Yes. In addition of different authorities, it can also be different
versions of the same authority. For example you can have many versions
of EPSG databases. SIS automatically detects version numbers and takes
than in account when users ask for codes like "EPSG:8.2:4326". But the
current approach is that SIS manages by default only one database -
SpatialMetadata - with many schemas in it, and let the definition of
other databases to users.

    Martin



Re: API for CRS transformation

Posted by César Martínez Izquierdo <ce...@gmail.com>.
Hi again,

I think there are two different requirements being mixed here (or maybe I
don't fully understand the point):
1- defining the database to be used (embedded or external, database
directory, database name, etc)
2- getting a connection to the defined database

For the second one, I think it would be enough to place a getDataSource()
method somewhere in the API. As SIS is suppose to be already configured, it
will be able to return the DataSource.

For the first one, I don't know the full SIS picture to figure out the best
option. If I correctly understand the code, at the moment you try to get a
JNDI context if available.
Otherwise, you try to use Derby EmbeddedDataSource to open (and potentially
create) a database named "SpatialMetadata" on SIS_DATA (if available) or on
"derby.system.home" otherwise.

I think it is fine to delegate on the SIS user the decision to provide a
JNDI context or to set SIS_DATA or derby.system.home. When an external
database should be used and JNDI is absent, I think the most standard way
would be to provide a JDBC connection string. It would also be nice to be
able to provide SIS_DATA as a Java property in addition to the environment
variable. Finally, I wonder if it makes sense to have several configured
databases (for instance for providing CRS definitions from a different
authority), although I understand that in this case I would just register
the authority factory and SIS doesn't need to know about the database
internally used by the authority.

Best regards,

César


On 6 February 2018 at 10:19, Martin Desruisseaux <
martin.desruisseaux@geomatys.com> wrote:

> Hello César
>
> Le 05/02/2018 à 18:57, César Martínez Izquierdo a écrit :
>
> I think that JNDI may be relevant to specify the database used by a
> specific SIS deployment.
>
> Yes, but an issue is that there is no JNDI environment by default in a
> standard Java installation. JNDI environments come with container like
> Tomcat. We could provide our own micro-JNDI environment when none is
> present (it is not difficult to do), but wasn't sure we want to go that
> path.
>
>
> For the user case I was describing, I think the method you cited
> (Initializer.getDataSource()) is more than enough (and also generic), as I
> just want to launch queries against the configured database (whichever it
> is). However, it will be useless if it is not visible on Java 9.
>
> In Java 9, it it still possible to bypass the restriction with an option
> given to Java on command-line. Even with restriction enabled, that
> functionality can still be available in next SIS version; we just need to
> decide how (JNDI or otherwise). A possible approach may be to use
> Initializer.getDataSource() for now, and switch to the public API later
> after we provided one.
>
>
> In any case, now I realise that for a particular deployment, if I know I
> will be using epsg with derby, I can just create a new data source to
> "SpatialMetadata" database, using Java standard procedures.
>
> The difficulty is to determine in which directory is located the database
> (unless using the embedded database, or the default Derby location). I
> would suggest to use Initializer.getDataSource() instead, and try to
> agree on a public API for next SIS release. I opened a JIRA issue if anyone
> want to comment on that:
>
> https://issues.apache.org/jira/browse/SIS-395
>
> Martin
>
>
>


-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   César Martínez Izquierdo
   GIS developer
   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
   SCOLAB: http://www.scolab.es
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: API for CRS transformation

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello César

Le 05/02/2018 à 18:57, César Martínez Izquierdo a écrit :

> I think that JNDI may be relevant to specify the database used by a
> specific SIS deployment.
>
Yes, but an issue is that there is no JNDI environment by default in a
standard Java installation. JNDI environments come with container like
Tomcat. We could provide our own micro-JNDI environment when none is
present (it is not difficult to do), but wasn't sure we want to go that
path.


> For the user case I was describing, I think the method you cited
> (Initializer.getDataSource()) is more than enough (and also generic),
> as I just want to launch queries against the configured database
> (whichever it is). However, it will be useless if it is not visible on
> Java 9.
>
In Java 9, it it still possible to bypass the restriction with an option
given to Java on command-line. Even with restriction enabled, that
functionality can still be available in next SIS version; we just need
to decide how (JNDI or otherwise). A possible approach may be to use
Initializer.getDataSource() for now, and switch to the public API later
after we provided one.


> In any case, now I realise that for a particular deployment, if I know
> I will be using epsg with derby, I can just create a new data source
> to "SpatialMetadata" database, using Java standard procedures.
>
The difficulty is to determine in which directory is located the
database (unless using the embedded database, or the default Derby
location). I would suggest to use Initializer.getDataSource() instead,
and try to agree on a public API for next SIS release. I opened a JIRA
issue if anyone want to comment on that:

    https://issues.apache.org/jira/browse/SIS-395

Martin



Re: API for CRS transformation

Posted by César Martínez Izquierdo <ce...@gmail.com>.
Dear Martin,

On 3 February 2018 at 12:20, Martin Desruisseaux <
martin.desruisseaux@geomatys.com> wrote:

>
> No public API yet, but there is an internal class in
> org.apache.sis.internal.metadata.sql:
>
> DataSource ds = Initializer.getDataSource();
>
> Everything under "org.apache.sis.internal" packages is non-committed API
> (excluded from Javadoc); in Java 9, they would be inaccessible from other
> modules. We have not yet determined what could be a public API for fetching
> this DataSource, mostly because I'm not sure what would be the most
> standard approach. A common answer is "use JNDI" (this is the way to do in
> a container like Tomcat), but I'm not aware of a standard JNDI
> implementation in standalone Java. Suggestions are welcome!
>
I think that JNDI may be relevant to specify the database used by a
specific SIS deployment.

For the user case I was describing, I think the method you cited
(Initializer.getDataSource()) is more than enough (and also generic), as I
just want to launch queries against the configured database (whichever it
is).

However, it will be useless if it is not visible on Java 9. In any case,
now I realise that for a particular deployment, if I know I will be using
epsg with derby, I can just create a new data source to "SpatialMetadata"
database, using Java standard procedures.
        final Class<?> c =
Class.forName("org.apache.derby.jdbc.EmbeddedDataSource", true,
AppSis.class.getClassLoader());
        final DataSource ds = (DataSource) c.newInstance();
        final Class<?>[] args = {String.class};
        c.getMethod("setDatabaseName", args).invoke(ds, "SpatialMetadata");
        c.getMethod("setDataSourceName", args).invoke(ds, "Apache SIS
spatial metadata");
        Connection c = ds.getConnection();
        c.createStatement().executeQuery("SELECT * FROM ...");

Do you know if this approach has any harmful side effects (besides the
weakness of hard-coding the database name)?

Thanks for your help,

César

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   César Martínez Izquierdo
   GIS developer
   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
   SCOLAB: http://www.scolab.es
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: API for CRS transformation

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello César

Le 02/02/2018 à 21:08, César Martínez Izquierdo a écrit :

> Thanks Martin, the proposed workaround for
> CoordinateOperationAuthorityFactory works as expected.
>
Good, thanks for letting us know.


> One last question, I don't find a way to query/search the existing
> CRSs by name (for instance retrieving a list of CRSs having ETRS89 in
> the name).
>
This is an undocumented feature, but CRS.forCode(String) accepts names.
For example CRS.forCode("EPSG::WGS 84 / World Mercator") will work.
However this method intentionally fails if there is ambiguity. For
example CRS.forCode("EPSG::WGS 84") fails because it could apply to more
than one CRS.


> Of course I could get the full list of available CRSs on the
> authority, try to instantiate each of them and apply the filter then,
> but seems a suboptimal approach.
>
A less suboptimal approach is to get the list of available code with
CRSAuthorityFactory.getAuthorityCodes(CoordinateReferenceSystem.class),
then get the name of each of them by calls to
CRSAuthorityFactory.getDescriptionText(code). That later method is
lightweight; is returns the name without instantiating the object.
However it stay less efficient than a SQL query.


> As an alternative, is there a way to get the connection to the
> underlying EPSG database to directly launch queries?
>
No public API yet, but there is an internal class in
org.apache.sis.internal.metadata.sql:

    DataSource ds = Initializer.getDataSource();

Everything under "org.apache.sis.internal" packages is non-committed API
(excluded from Javadoc); in Java 9, they would be inaccessible from
other modules. We have not yet determined what could be a public API for
fetching this DataSource, mostly because I'm not sure what would be the
most standard approach. A common answer is "use JNDI" (this is the way
to do in a container like Tomcat), but I'm not aware of a standard JNDI
implementation in standalone Java. Suggestions are welcome!

    Martin



Re: API for CRS transformation

Posted by César Martínez Izquierdo <ce...@gmail.com>.
Thanks Martin, the proposed workaround for
CoordinateOperationAuthorityFactory works as expected.

One last question, I don't find a way to query/search the existing CRSs by
name (for instance retrieving a list of CRSs having ETRS89 in the name).
Of course I could get the full list of available CRSs on the authority, try
to instantiate each of them and apply the filter then, but seems a
suboptimal approach.

As an alternative, is there a way to get the connection to the underlying
EPSG database to directly launch queries? This would allow very different
user cases to be implemented without requiring exposing everything on SIS
API. I understand that probably you don't want to assume that there is an
underlying database at all (in the general API), but maybe it is something
that could be available on a lower level API.

Regards,

César


On 31 January 2018 at 20:01, Martin Desruisseaux <
martin.desruisseaux@geomatys.com> wrote:

> Hello César
>
> Le 31/01/2018 à 16:35, César Martínez Izquierdo a écrit :
>
> Thank you Martin for the pointer to CoordinateOperationAuthorityFactory.
> However, I've failed to instantiate it: (...snip...) java.util.
> NoSuchElementException
>
> Indeed, my mistake. After verification I saw that
> CoordinateOperationAuthorityFactory is not registered in META-INF/services.
> I filled a JIRA task on this issue:
>
> https://issues.apache.org/jira/browse/SIS-393
>
> In the meantime, the following trick should work. It is fragile because of
> the cast, but this is a temporary solution (more on it below):
>
> CoordinateOperationAuthorityFactory factory = (CoordinateOperationAuthorityFactory) CRS.getAuthorityFactory("EPSG");
>
> A more permanent solution will be to rely on the upcoming ISO 19111
> revision. All those FooFactory interfaces where not derived from ISO
> 19111; they are GeoAPI additions. But latest ISO 19111 draft defines a
> RegisterOperations interface with a findCoordinateOperations(…) method.
> Once this standard is officially adopted, we plan to align on it.
>
>
> The documentation states that Java 7 is required, but I've seen that you
> are adapting the code now to Java 8 (in trunk), and removing Java 7 support
> (if I correctly understood the changes). What are your plans for the
> future? Will you move to Java 9 and drop Java 8 support? Have you
> considered keeping compatibility with several versions (e.g. 7 to 9)?
>
> We try to keep compatibility with several versions. Despite having
> branches for different JDK versions, Apache SIS should be runnable on all
> Java versions above the target version except Java 9 (actually not yet
> tested). The purpose of those branches is only to be ready when we decide
> to upgrade the Java requirement, by allowing immediate use of new Java
> features.
>
> The reason for upgrading to Java 8 is for allowing the use of following
> packages in public API. If it was not for this need (or if we needed those
> packages only in non-public API), we could have stayed on Java 7 longer:
>
>    - java.time
>    - java.util.stream
>
> Regarding Java 9, I'm not aware of any new classes or interfaces that we
> would need to leverage in public API. Consequently we have no reason to
> force the use of Java 9 at runtime any time soon (we may require Java 9 for
> building SIS, but not for using in other projects). My proposal is to
> deploy either Java 8 files, or maybe multi-version JAR files for Java 8 and
> 9.
>
>
> I've seen that some projections are defined on EPSG but they are not
> currently supported on SIS (for instance Lambert azimuthal equal-area
> projection). Do you have a list of them?
>
> The coordinate operation methods published in EPSG guidance notes are
> listed there, together with an indication of whether it is implemented in
> SIS or remain to be done:
>
> https://issues.apache.org/jira/browse/SIS-212
>
> In a few cases we have code pending in the Geotk project, but we need to
> continue the intellectual property review (http://svn.apache.org/repos/
> asf/sis/ip-review/) before to port them to Apache SIS.
>
>
> Do you have plans to implement (some of) them?
>
> At least the easy ones (a few coordinate operations there are merely
> affine transforms with parameters expressed in a different way) and the
> projections we can port from Geotk. When I will be able to do that however
> is uncertain.
>
> Regards,
>
>     Martin
>
>
>


-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   César Martínez Izquierdo
   GIS developer
   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
   SCOLAB: http://www.scolab.es
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: API for CRS transformation

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello César

Le 31/01/2018 à 16:35, César Martínez Izquierdo a écrit :

> Thank you Martin for the pointer to
> CoordinateOperationAuthorityFactory. However, I've failed to
> instantiate it: (...snip...) java.util.NoSuchElementException
>
Indeed, my mistake. After verification I saw that
CoordinateOperationAuthorityFactory is not registered in
META-INF/services. I filled a JIRA task on this issue:

    https://issues.apache.org/jira/browse/SIS-393

In the meantime, the following trick should work. It is fragile because
of the cast, but this is a temporary solution (more on it below):

    CoordinateOperationAuthorityFactory factory = (CoordinateOperationAuthorityFactory) CRS.getAuthorityFactory("EPSG");

A more permanent solution will be to rely on the upcoming ISO 19111
revision. All those FooFactory interfaces where not derived from ISO
19111; they are GeoAPI additions. But latest ISO 19111 draft defines a
RegisterOperations interface with a findCoordinateOperations(…) method.
Once this standard is officially adopted, we plan to align on it.


> The documentation states that Java 7 is required, but I've seen that
> you are adapting the code now to Java 8 (in trunk), and removing Java
> 7 support (if I correctly understood the changes). What are your plans
> for the future? Will you move to Java 9 and drop Java 8 support? Have
> you considered keeping compatibility with several versions (e.g. 7 to 9)?
>
We try to keep compatibility with several versions. Despite having
branches for different JDK versions, Apache SIS should be runnable on
all Java versions above the target version except Java 9 (actually not
yet tested). The purpose of those branches is only to be ready when we
decide to upgrade the Java requirement, by allowing immediate use of new
Java features.

The reason for upgrading to Java 8 is for allowing the use of following
packages in public API. If it was not for this need (or if we needed
those packages only in non-public API), we could have stayed on Java 7
longer:

  * java.time
  * java.util.stream

Regarding Java 9, I'm not aware of any new classes or interfaces that we
would need to leverage in public API. Consequently we have no reason to
force the use of Java 9 at runtime any time soon (we may require Java 9
for building SIS, but not for using in other projects). My proposal is
to deploy either Java 8 files, or maybe multi-version JAR files for Java
8 and 9.


> I've seen that some projections are defined on EPSG but they are not
> currently supported on SIS (for instance Lambert azimuthal equal-area
> projection). Do you have a list of them?

The coordinate operation methods published in EPSG guidance notes are
listed there, together with an indication of whether it is implemented
in SIS or remain to be done:

    https://issues.apache.org/jira/browse/SIS-212

In a few cases we have code pending in the Geotk project, but we need to
continue the intellectual property review
(http://svn.apache.org/repos/asf/sis/ip-review/) before to port them to
Apache SIS.


> Do you have plans to implement (some of) them?

At least the easy ones (a few coordinate operations there are merely
affine transforms with parameters expressed in a different way) and the
projections we can port from Geotk. When I will be able to do that
however is uncertain.

Regards,

    Martin



Re: API for CRS transformation

Posted by César Martínez Izquierdo <ce...@gmail.com>.
Thank you Martin for the pointer to CoordinateOperationAuthorityFactory.
However, I've failed to instantiate it:

    ServiceLoader<CoordinateOperationAuthorityFactory> loader =
(ServiceLoader<CoordinateOperationAuthorityFactory>)
ServiceLoader.load(CoordinateOperationAuthorityFactory.class);
    CoordinateOperationAuthorityFactory factory = loader.iterator().next();

Then I get:
Exception in thread "main" java.util.NoSuchElementException
    at
java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:365)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.gvsig.sis_proj.AppSis.listOperations(AppSis.java:140)
    at org.gvsig.sis_proj.AppSis.main(AppSis.java:99)

So the factory is not properly loaded.

I've successfully instantiated CRSAuthorityFactory using similar code:

    ServiceLoader<CoordinateOperationAuthorityFactory> loader =
(ServiceLoader<CoordinateOperationAuthorityFactory>)
ServiceLoader.load(CoordinateOperationAuthorityFactory.class);
    CoordinateOperationAuthorityFactory factory = loader.iterator().next();

Some more questions:
- The documentation states that Java 7 is required, but I've seen that you
are adapting the code now to Java 8 (in trunk), and removing Java 7 support
(if I correctly understood the changes). What are your plans for the
future? Will you move to Java 9 and drop Java 8 support? Have you
considered keeping compatibility with several versions (e.g. 7 to 9)? We
are currently using Java 8, so Java 7 is not a concern for us, but we would
not like to be rushed to migrate our code to Java 9 (or future versions)
because SIS enforces it.

-I've seen that some projections are defined on EPSG but they are not
currently supported on SIS (for instance Lambert azimuthal equal-area
projection). Do you have a list of them? Do you have plans to implement
(some of) them?

Thanks for the support.

César




On 29 January 2018 at 20:13, Martin Desruisseaux <
martin.desruisseaux@geomatys.com> wrote:

> Hello César
>
> Le 29/01/2018 à 19:25, César Martínez Izquierdo a écrit :
>
> I am evaluating using SIS as the basis for our CRS management libraries on
> gvSIG project (a desktop, Java-based GIS application).
>
> Yes, we know gvSIG :-)
>
>
> Currently, we offer the user the opportunity to choose the transformation
> method when transforming coordinates from a source CRS to a target CRS
> involving different datums (for instance from EPSG:23030 to EPSG:4326).
> However, I don't find a clear way to get this information from SIS API.
> Ideally, I would expect a method like:
>
> Set<CoordinateOperation> ops = CRS.findOperations(source, target, context);
>
> but it obviously doesn't exist at the moment.
>
> Actually something like that exists somewhere else.
> 'org.apache.sis.crs.CRS' is a convenience class targeting what look like
> the most commonly used operations. For getting more flexibility, we need to
> instantiate some more specific classes. The functionality you are looking
> for is provided by the CoordinateOperationAuthorityFactory interface:
>
> http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/operation/
> CoordinateOperationAuthorityFactory.html
>
> To get an instance of this interface, you can use the following code:
>
> ServiceLoader.load(CoordinateOperationAuthorityFactory.class).findFirst():
>
>
> I have achieved a similar goal by diving a bit in the implementation and
> subclassing CoordinateOperationFinder and DefaultCoordinateOperationFactory
> (...snip...)
>
> - those classes have been designed to not being subclassed (declaring a
> lot of private or "friendly" methods) and I assume my implementation would
> be very sensitive to SIS version updates
>
> The method declared public or protected should be okay; we try to keep
> them stable. At the very least, they will not be removed without a
> deprecation cycle. The fact that lot of methods are private is a
> consequence of being careful about what we commit to keep stable.
>
>
> - we loose the heuristics internally used by SIS to use the right
> concatenation pipeline (in the example: EPSG:23030 to EPSG:4230, then
> EPSG:4326). Which means that we would need to replicate those heuristics in
> our library to take into account all the different scenarios, as it is
> currently done by SIS internally.
>
> Indeed, the proposed approach would list only operations explicitly
> defined by EPSG, which usually include only transformation between two
> GeographicCRS (not between ProjectedCRS). I presume that you need the later
> too?
>
>
> However, I believe that CRS.findOperations would not be extremely hard to
> implement if done within Apache SIS library (instead of doing it
> externally). Do you think it would be feasible?
>
> You mean in a way that list all transformations defined by EPSG even if
> some CRS are ProjectedCRS? It would be possible. Current implementation
> already iterates over all possibilities and apply some user-configurable
> rules for selecting the "best" operation. Those rules are based on the
> region of interest and desired accuracy.
>
>
> Would you be keen on accepting such contribution?
>
> Of course :-) The work would basically be to replace the above-cited
> filtering by a code storing visited operations in a list.
>
>     Regards,
>
>         Martin
>
>
>


-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   César Martínez Izquierdo
   GIS developer
   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
   SCOLAB: http://www.scolab.es
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: API for CRS transformation

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello César

Le 29/01/2018 à 19:25, César Martínez Izquierdo a écrit :

> I am evaluating using SIS as the basis for our CRS management
> libraries on gvSIG project (a desktop, Java-based GIS application).
>
Yes, we know gvSIG :-)


> Currently, we offer the user the opportunity to choose the
> transformation method when transforming coordinates from a source CRS
> to a target CRS involving different datums (for instance from
> EPSG:23030 to EPSG:4326). However, I don't find a clear way to get
> this information from SIS API. Ideally, I would expect a method like:
>
> Set<CoordinateOperation> ops = CRS.findOperations(source, target,
> context);
>
> but it obviously doesn't exist at the moment.
>
Actually something like that exists somewhere else.
'org.apache.sis.crs.CRS' is a convenience class targeting what look like
the most commonly used operations. For getting more flexibility, we need
to instantiate some more specific classes. The functionality you are
looking for is provided by the CoordinateOperationAuthorityFactory
interface:

http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/operation/CoordinateOperationAuthorityFactory.html

To get an instance of this interface, you can use the following code:

    ServiceLoader.load(CoordinateOperationAuthorityFactory.class).findFirst():


> I have achieved a similar goal by diving a bit in the implementation
> and subclassing CoordinateOperationFinder and
> DefaultCoordinateOperationFactory (...snip...)
>
> - those classes have been designed to not being subclassed (declaring
> a lot of private or "friendly" methods) and I assume my implementation
> would be very sensitive to SIS version updates
>
The method declared public or protected should be okay; we try to keep
them stable. At the very least, they will not be removed without a
deprecation cycle. The fact that lot of methods are private is a
consequence of being careful about what we commit to keep stable.


> - we loose the heuristics internally used by SIS to use the right
> concatenation pipeline (in the example: EPSG:23030 to EPSG:4230, then
> EPSG:4326). Which means that we would need to replicate those
> heuristics in our library to take into account all the different
> scenarios, as it is currently done by SIS internally.
>
Indeed, the proposed approach would list only operations explicitly
defined by EPSG, which usually include only transformation between two
GeographicCRS (not between ProjectedCRS). I presume that you need the
later too?


> However, I believe that CRS.findOperations would not be extremely hard
> to implement if done within Apache SIS library (instead of doing it
> externally). Do you think it would be feasible?
>
You mean in a way that list all transformations defined by EPSG even if
some CRS are ProjectedCRS? It would be possible. Current implementation
already iterates over all possibilities and apply some user-configurable
rules for selecting the "best" operation. Those rules are based on the
region of interest and desired accuracy.


> Would you be keen on accepting such contribution?
>
Of course :-) The work would basically be to replace the above-cited
filtering by a code storing visited operations in a list.

    Regards,

        Martin