sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ferenc Hechler (JIRA)" <>
Subject [jira] [Created] (SIS-432) Using BETA2007.gsb grid throws IllegalArgumentException
Date Tue, 09 Oct 2018 21:44:00 GMT
Ferenc Hechler created SIS-432:

             Summary: Using BETA2007.gsb grid throws IllegalArgumentException
                 Key: SIS-432
             Project: Spatial Information Systems
          Issue Type: Bug
    Affects Versions: 0.8
            Reporter: Ferenc Hechler
         Attachments: patch_BETA2007_gsb.png

The following program transforms Gauß-Krüger coordinates (used in Germany) to the WGS84

public static void main(String[] args) throws Exception {
  double hochwert = 5500000.0;
  double rechtswert = 3500000.0;
  CoordinateReferenceSystem sourceCRS = CRS.forCode("EPSG:31467");
  CoordinateReferenceSystem targetCRS = CRS.forCode("EPSG:4326");
  CoordinateOperation operation = CRS.findOperation(sourceCRS, targetCRS, null);
  DirectPosition ptSrc = new DirectPosition2D(hochwert, rechtswert);
  DirectPosition ptDst = operation.getMathTransform().transform(ptSrc, null);

  System.out.println("Source:   " + ptSrc);
  System.out.println("Target:   " + ptDst);  
  System.out.println("Expected: POINT(49.63670826166641 8.99895896840875)");
Running the program gives the following output:

Okt 09, 2018 10:45:00 PM org.apache.sis.referencing.operation.CoordinateOperationFinder createOperation
WARNUNG: Can not parse “BETA2007.gsb” as a file in the NTv2 format.
Source:   POINT(5500000 3500000)
Target:   POINT(49.636710642245184 8.99896356404719)
Expected: POINT(49.63670826166641 8.99895896840875)

As you can see, the result is not as expected.
The reason is, that the grid shift file BETA2007.gsb was not found, as the warning before
already stated: *WARNUNG: Can not parse “BETA2007.gsb” as a file in the NTv2 format.*

The grid shift file "BETA2007.gsb" can be downloaded from the following website:

There is a link to the ASCII version [BETA2007.gsa|]
and the binary format, which is needed for Apache SIS [BETA2007.gsb|]

I downloaded the BETA2007.gsb file and copied it into the current working directory (or into
the project folder in Eclipse).
Then I started the same main program again and got the follwoing exception:

Exception in thread "main" org.apache.sis.referencing.factory.InvalidGeodeticParameterException:
Value ‘grid.cellPrecision’ = ? is invalid. Expected a number greater than 0.
	at org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.createParameterizedTransform(
	at org.apache.sis.referencing.factory.sql.EPSGDataAccess.createCoordinateOperation(
	at org.apache.sis.referencing.factory.AuthorityFactoryProxy$34.create(
	at org.apache.sis.referencing.factory.AuthorityFactoryProxy$34.create(
	at org.apache.sis.referencing.factory.ConcurrentAuthorityFactory.create(
	at org.apache.sis.referencing.factory.ConcurrentAuthorityFactory.createCoordinateOperation(
	at org.apache.sis.internal.referencing.DeferredCoordinateOperation.create(
	at org.apache.sis.referencing.operation.CoordinateOperationRegistry.createOperation(
	at org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperation(
	at org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperationStep(
	at org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperation(
	at org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory.createOperation(
	at org.apache.sis.referencing.CRS.findOperation(
	at de.hechler.apsistest.GK3toWGS84.main(
Caused by: java.lang.IllegalArgumentException: Value ‘grid.cellPrecision’ = ? is invalid.
Expected a number greater than 0.
	at org.apache.sis.referencing.operation.transform.InterpolatedTransform$Inverse.<init>(
	at org.apache.sis.referencing.operation.transform.InterpolatedTransform2D$Inverse.<init>(
	at org.apache.sis.referencing.operation.transform.InterpolatedTransform2D.createInverse(
	at org.apache.sis.referencing.operation.transform.InterpolatedTransform.<init>(
	at org.apache.sis.referencing.operation.transform.InterpolatedTransform2D.<init>(
	at org.apache.sis.referencing.operation.transform.InterpolatedTransform.createGeodeticTransformation(
	at org.apache.sis.internal.referencing.provider.NTv2.createMathTransform(
	at org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.createParameterizedTransform(
	... 14 more

I debugged into the code and found the following.

In InterpolatedTransform the DataShiftGrid is checked for its accuracy (getCellPrecision()
returns accuracy/10):
tolerance = grid.getCellPrecision();
if (!(tolerance > 0)) {         // Use ! for catching NaN.
    throw new IllegalArgumentException(Errors.format(
        Errors.Keys.ValueNotGreaterThanZero_2, "grid.cellPrecision", tolerance));

In a DatumShiftGridFile.Float instance is created to read in the BETA2007.gsb file.
In DatumShiftGridFile.Float the accuracy member variable is initialized with NaN:

     * The best translation accuracy that we can expect from this file.
     * <p>This field is initialized to Double#NaN. It is loader responsibility
     * to assign a value to this field after DatumShiftGridFile construction.</p>
    protected double accuracy;

The loader, in this case, is and so it is responsible to set the accuracy field.
And there is code to set the accuracy based on the data in the BETA2007.gsb file:

for (int i=0; i<count; i++) {
  ensureBufferContains(4 * (Float.SIZE / Byte.SIZE));
  ty[i] = (float) (buffer.getFloat() / dy);   // Division by dx and dy because isCellValueRatio
= true.
  tx[i] = (float) (buffer.getFloat() / dx);
  final double accuracy = Math.min(buffer.getFloat() / dy, buffer.getFloat() / dx);
  if (accuracy > 0 && !(accuracy >= grid.accuracy)) {   // Use '!' for replacing
the initial NaN.
    grid.accuracy = accuracy;

So, the grid.accuracy is set to the minimum accuracy from longitude and latitude.
But as to see in the ASCII file, all precision fields (third and fourth column) are set to
GS_COUNT  5208
 -2.749746  7.165792  0.000000  0.000000
 -2.750032  7.067153  0.000000  0.000000
 -2.750411  6.968641  0.000000  0.000000
 -6.330753  2.260298  0.000000  0.000000
 -6.338144  2.193162  0.000000  0.000000
 -6.345754  2.126569  0.000000  0.000000

(the .gsb file is the binary created from the .gsa file)

And because of this, the grid.accuracy is never set and remains *NaN*.
And then the validation in InterpolatedTransform throws the IllegalArgumentException.

I patched the BETA2007.gsb file at position 0x168:

The change would be in ASCII:
GS_COUNT  5208
 -2.749746  7.165792  0.000001  0.000001
 -2.750032  7.067153  0.000000  0.000000
 -2.750411  6.968641  0.000000  0.000000
 -6.330753  2.260298  0.000000  0.000000
 -6.338144  2.193162  0.000000  0.000000
 -6.345754  2.126569  0.000000  0.000000

So the first shift gets an accuracy value greater then 0.0.
With this patched BETA2007.gsb file the program runs as expected:
Source:   POINT(5500000 3500000)
Target:   POINT(49.63670826166641 8.99895896840875)
Expected: POINT(49.63670826166641 8.99895896840875)

So may be, that this is in real an issue for the BETA2007 file, because it does not provide
an accuracy for any shift value.
But the BETA2007.gsb file from above is the official file and I did not find any other source
providing accuracy values.
On the website it is stated, that the accuracy is less than one meter.

I think the issue could be fixed In, so that it initializes the grid.accuracy to
some default value if it is NaN after checking all shifts.

LocalizationGridBuilder has some similiair intialization:
(gridPrecision > 0) ? gridPrecision : DEFAULT_PRECISION);

Maybe this can be done in NTv2 for NaN values.

This message was sent by Atlassian JIRA

View raw message