You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@sis.apache.org by Florian Micklich <mi...@apache.org> on 2022/11/16 00:27:13 UTC

Re: manually setup an EPSG database base information

Hi Martin,

thanks again for all the information.
Now another question came to my mind.

Is it possible to recall the setDatabase method? For example the db settings are set via variables and can be updated by the user during runtime.
So I want / have to update  the Configuration.current() as well.



``` 
Configuration.current().setDatabase(ProjTransformation::createDataSource);
``` 

If I call this again with new settings I get:
```
Connection to a SpatialMetadata database is already initialized
``` 

Greetings
Florian



Am Sonntag, dem 30.10.2022 um 21:18 +0100 schrieb Martin Desruisseaux:
> 
>       Hello Florian<br>
>       
> My pleasure if I can be of any help :-)<br>
>       <br>
>       
> Le 30/10/2022 à 13:32, Florian Micklich via user a écrit :<br>
>     <br>
> > 
> >         
> >         What happens (for some reason) the db is not available anymore.
> >         Is there an exception I can catch to handle something like this?<br>
> If SIS needs to use the EPSG database and an error occurred, an org.opengis.util.FactoryException will
>       be thrown (this is a checked exception). The cause of that
>       exception should be the SQLException.<br>
> <br>
>     <br>
> > Is there a method in SIS that I can use to verify that the
> >         DataSource has been set up correctly?<br>
> The easiest way is to request an EPSG code, for example System.out.println(CRS.forCode("EPSG::3395")).
>       This is not fully reliable however for two reasons:<br>
> - If that EPSG code was requested before, SIS may return a
>         cached value, in which case database problem that may have
>         occurred in the meantime will be unnoticed.
> - If the EPSG database is not available at all, SIS fallback on
>         hard-coded values for a few commonly used CRS. The EPSG::3395
>         code is not in current list [1], but it may be in a future
>         version.<br>
>       
> 
> A good way to know the status of Apache SIS is to execute the
>       following code:<br>
> ```
> System.out.println(org.apache.setup.About.configuration());
> > ```
> 
> It should prints a tree. Among the first lines, there is
>       information about the EPSG database used. It should show something
>       like "EPSG database 9.1 on PostgreSQL". If it shows something like
>       "EPSG database subset", then it is not using the database.<br>
>     <br><br>
> > Also thanks for the hint with the index. I see there is also a
> >         prepare.sql script.
> >         Is this also necessary or what is its purpose?<br>
> Not if you create the EPSG tables yourself from the SQL scripts
>       published by EPSG. But SIS has another way to create the EPSG
>       database. You can just give a connection to an initially empty
>       database, i.e. same as what you currently do but without executing
>       any SQL script. If the org.apache.sis.non-free:sis-epsg
>       (instead of sis-embedded) JAR is on
>       the classpath ([2] but without Derby), SIS will automatically
>       execute installation scripts when first needed, including the
>       index creation. However during the installation process, SIS
>       perform a few changes on-the-fly:<br>
> - It creates an "epsg" schema.
> - The "epsg_" prefix is table names is replaced by "epsg.", i.e.
>         the tables are written in "epsg" schema.
> - A few VARCHAR columns which
>         were used as enumerations are replaced by real enumeration (this
>         is slightly more efficient). This is where the "Prepare.sql" script come into play: it
>         creates the enumerations before to run the EPSG scripts.<br>
>       
> 
> All those steps are automatic if sis-epsg
>       is on the classpath and you let SIS creates the "epsg" schema
>       itself when first needed. A message is logged at the INFO level when this creation is
>       running.<br>
>     Martin<br>
>     <br>```
> [1] [https://sis.apache.org/apidocs/org/apache/sis/referencing/CRS.html#forCode(java.lang.String)](https://sis.apache.org/apidocs/org/apache/sis/referencing/CRS.html#forCode(java.lang.String))
> [2] [https://sis.apache.org/epsg.html#maven-epsg](https://sis.apache.org/epsg.html#maven-epsg)
> ```
> 
> <br>
>     <br>

Re: manually setup an EPSG database base information

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello Florian

Le 17/11/2022 à 17:39, Florian Micklich a écrit :

> Clearing the cache would be a good feature, I think. Or something like 
> a forced option to not use the cache. We can create a Jira ticket if 
> you want so that this idea doesn't get lost. Just let me know where to 
> do that.
>
I suggest to create a JIRA issue there: 
https://issues.apache.org/jira/projects/SIS/


> Another question has come up for me. You mentioned that I can use it 
> to check the status of Apache SIS (…snip…) Is there an easy way to get 
> the column entry for a geodesic dataset as string to compare the 
> result to a pattern?
>
You can use the following code for starting:

    CRSAuthorityFactory factory = CRS.getAuthorityFactory("EPSG");
    Citation authority = factory.getAuthority();
    System.out.println(authority);

The Citation class is derived from ISO 19115, an international standard 
about metadata. That class and its properties are standardized. This 
standard is used extensively by Apache SIS for many kinds of resources: 
data (including GeoTIFF, netCDF, etc.), services, etc. In this 
particular case we get the following output on my machine (the language 
depends on the locale; only English and French supported at this time):

    Citation…………………………………………………… EPSG Geodetic Parameter Dataset
       ├─Edition…………………………………………… 9.9.1
       ├─Edition date……………………………… 12 sept. 2020, 00:00:00
       ├─Identifier…………………………………… EPSG
       ├─Online resource (1 de 3)
       │   ├─Linkage…………………………………https://epsg.org/
       │   └─Function……………………………… Moteur de recherche
       ├─Online resource (2 de 3)
       │   ├─Linkage…………………………………https://epsg.org/
       │   └─Function……………………………… Téléchargement
       └─Online resource (3 de 3)
           ├─Linkage………………………………… jdbc:derby:/home/desruisseaux/Projets/SIS/Data/Databases/SpatialMetadata
           ├─Description……………………… Base de données géodésique EPSG version 9.9.1 sur « Apache Derby » version 10.14.
           └─Function……………………………… CONNECTION

If you are interested specifically the the EPSG database version, the 
following code will give "9.9.1" directly:

    String edition = authority.getEdition().toString();

All information shown in above tree are accessible by a getter of the 
same name (authority.getIdentifier(), authority.getOnlineResource(), etc.).

     Martin


Re: manually setup an EPSG database base information

Posted by Florian Micklich <mi...@apache.org>.
Hi Martin,

thanks a lot for the explanation.

On the topic of data source. The use case of updating credentials is not really needed at this time. 
It was just a nice thought. I will try your workaround.

Clearing the cache would be a good feature, I think. Or something like a forced option to not use the cache.
We can create a Jira ticket if you want so that this idea doesn't get lost. Just let me know where to do that.

There is a difference in the WKT string between cached and requested EPSG code. So it is clear which "source" was used.

```
Request
Id["EPSG", 32634, "9.9.1", URI["urn:ogc:def:crs:EPSG:9.9.1:32634"]]]

Cache
Id["EPSG", 32634, URI["urn:ogc:def:crs:EPSG::32634"]]]
```


Another question has come up for me.
You mentioned that I can use it to check the status of Apache SIS


```
System.out.println(org.apache.sis.setup.About.configuration());
```

Is there an easy way to get the column entry for a geodesic dataset as string to compare the result to a pattern?  I am stuck with the getRoot() and getColumns() methods.
I have 3 possible situations that I want to check. 

1.  Correct Version and everything is fine.

``` 
Local configuration 
  ├─Versions                                                                                        
  │   ├─Apache SIS………………………………………………………………………………………………………………………………………………………………………………………………………………………… 1.2
  │   ├─Java………………………………………………………………………………………………………………………………………………………………………………………………………………………………………… 11.0.17 (Azul Systems, Inc.)
  │   ├─Operating system………………………………………………………………………………………………………………………………………………………………………………………………………… Linux 5.15.0-53-generic (amd64)
  │   └─Geodetic dataset………………………………………………………………………………………………………………………………………………………………………………………………………… EPSG geodetic dataset version 9.9.1 on “PostgreSQL” version 14.4.
```
2. Not supported Version because user imported wrong version.
```
Local configuration                                                                                 
  ├─Versions                                                                                        
  │   ├─Apache SIS………………………………………………………………………………………………………………………………………………………………………………………………………………………… 1.2
  │   ├─Java………………………………………………………………………………………………………………………………………………………………………………………………………………………………………… 11.0.17 (Azul Systems, Inc.)
  │   ├─Operating system………………………………………………………………………………………………………………………………………………………………………………………………………… Linux 5.15.0-53-generic (amd64)
  │   └─Geodetic dataset………………………………………………………………………………………………………………………………………………………………………………………………………… EPSG geodetic dataset version 10.076 on “PostgreSQL” version 14.4.
``` 

3. No imported Database so I have to give a totally other feedback.
```
Local configuration                                                                                 
  ├─Versions                                                                                        
  │   ├─Apache SIS………………………………………………………………………………………………………………………………………………………………………………………………………………………… 1.2
  │   ├─Java………………………………………………………………………………………………………………………………………………………………………………………………………………………………………… 11.0.17 (Azul Systems, Inc.)
  │   ├─Operating system………………………………………………………………………………………………………………………………………………………………………………………………………… Linux 5.15.0-53-generic (amd64)
  │   └─Geodetic dataset………………………………………………………………………………………………………………………………………………………………………………………………………… Untitled

``` 

Greetings
Florian


Am Mittwoch, dem 16.11.2022 um 11:49 +0100 schrieb Martin Desruisseaux:
> 
>       Hello Florian<br>
>       <br>
>       
> Le 16/11/2022 à 01:27, Florian Micklich a écrit :<br>
>     <br>
> > 
> >         
> >         Is it possible to recall the setDatabase method? For example the
> >         db settings are set via variables and can be updated by the user
> >         during runtime.
> >         So I want / have to update the Configuration.current() as well.<br>
> Currently setDatabase(…)
>       does not allow allow to change the data source after it has been
>       initialized, for reason given in next paragraph. As a workaround,
>       it is possible to achieve a similar effect by providing a custom
>       implementation of DataSource
>       interface, with a field which is the real PGDataSource
>       (if using PostgreSQL) and with all methods doing redirection to
>       that PGDataSource. That way, the
>       value of that field can be changed and it will be taken in account
>       the next time that DataSource.getConnection()
>       is invoked.<br>
> An issue is that the new data source will not be
>       taken in account immediately. SIS keeps JDBC connection open a
>       little bit (in case there is many consecutive uses of EPSG
>       factory, which is often the case at least in SIS internal) and
>       closes it only after 1 minute of inactivity. So the new data
>       source would be taken in account only after the user stay one
>       minute without requesting any EPSG codes. For avoiding this delay,
>       we need to force an immediate release of JDBC resources after the
>       data source changed:<br>
> ```
> ConcurrentAuthorityFactory<?> factory = (ConcurrentAuthorityFactory<?>) CRS.getAuthorityFactory("EPSG");
> > factory.close();
> > ```
> 
> Note: there is also a factory.setTimeout(…)
>       method if you want to change the 1 minute timeout to something
>       else.<br>
> Above workaround is not perfect. If there is any
>       CRS cached in memory, they will not be updated by above change. It
>       is technically possible to improve setDatabase(…)
>       for allowing cleaner change, which would include flushing the
>       caches. If there is a need for that, I suggest that we create a
>       JIRA issue.<br>
>     Martin<br>
> <br>
>     <br>

Re: manually setup an EPSG database base information

Posted by Martin Desruisseaux <ma...@geomatys.com>.
Hello Florian

Le 16/11/2022 à 01:27, Florian Micklich a écrit :

> Is it possible to recall the setDatabase method? For example the db 
> settings are set via variables and can be updated by the user during 
> runtime. So I want / have to update the Configuration.current() as well.
>
Currently setDatabase(…) does not allow allow to change the data source 
after it has been initialized, for reason given in next paragraph. As a 
workaround, it is possible to achieve a similar effect by providing a 
custom implementation of DataSource interface, with a field which is the 
real PGDataSource (if using PostgreSQL) and with all methods doing 
redirection to that PGDataSource. That way, the value of that field can 
be changed and it will be taken in account the next time that 
DataSource.getConnection() is invoked.

An issue is that the new data source will not be taken in account 
immediately. SIS keeps JDBC connection open a little bit (in case there 
is many consecutive uses of EPSG factory, which is often the case at 
least in SIS internal) and closes it only after 1 minute of inactivity. 
So the new data source would be taken in account only after the user 
stay one minute without requesting any EPSG codes. For avoiding this 
delay, we need to force an immediate release of JDBC resources after the 
data source changed:

    ConcurrentAuthorityFactory<?> factory = (ConcurrentAuthorityFactory<?>) CRS.getAuthorityFactory("EPSG");
    factory.close();

Note: there is also a factory.setTimeout(…) method if you want to change 
the 1 minute timeout to something else.

Above workaround is not perfect. If there is any CRS cached in memory, 
they will not be updated by above change. It is technically possible to 
improve setDatabase(…) for allowing cleaner change, which would include 
flushing the caches. If there is a need for that, I suggest that we 
create a JIRA issue.

     Martin