sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Martin Desruisseaux (JIRA)" <j...@apache.org>
Subject [jira] [Assigned] (SIS-432) Using BETA2007.gsb grid throws IllegalArgumentException
Date Wed, 10 Oct 2018 08:49:00 GMT

     [ https://issues.apache.org/jira/browse/SIS-432?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Martin Desruisseaux reassigned SIS-432:
---------------------------------------

    Assignee: Martin Desruisseaux

> Using BETA2007.gsb grid throws IllegalArgumentException
> -------------------------------------------------------
>
>                 Key: SIS-432
>                 URL: https://issues.apache.org/jira/browse/SIS-432
>             Project: Spatial Information Systems
>          Issue Type: Bug
>    Affects Versions: 0.8
>            Reporter: Ferenc Hechler
>            Assignee: Martin Desruisseaux
>            Priority: Major
>         Attachments: patch_BETA2007_gsb.png
>
>
> The following program transforms Gauß-Krüger coordinates (used in Germany) to the WGS84
format:
> {code:title=Main.java}
> 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)");
> }
> {code}
>  
> Running the program gives the following output:
> {code:title=console.log}
> 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)
> {code}
> 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: http://crs.bkg.bund.de/crseu/crs/descrtrans/BeTA/de_dhdn2etrs_beta.php
> There is a link to the ASCII version [BETA2007.gsa|http://crs.bkg.bund.de/crseu/crs/descrtrans/BeTA/BETA2007.gsa]
and the binary format, which is needed for Apache SIS [BETA2007.gsb|http://crs.bkg.bund.de/crseu/crs/descrtrans/BeTA/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:
> {code:title=console.log}
> 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(DefaultMathTransformFactory.java:1050)
> 	at org.apache.sis.referencing.factory.sql.EPSGDataAccess.createCoordinateOperation(EPSGDataAccess.java:2927)
> 	at org.apache.sis.referencing.factory.AuthorityFactoryProxy$34.create(AuthorityFactoryProxy.java:515)
> 	at org.apache.sis.referencing.factory.AuthorityFactoryProxy$34.create(AuthorityFactoryProxy.java:513)
> 	at org.apache.sis.referencing.factory.ConcurrentAuthorityFactory.create(ConcurrentAuthorityFactory.java:1679)
> 	at org.apache.sis.referencing.factory.ConcurrentAuthorityFactory.createCoordinateOperation(ConcurrentAuthorityFactory.java:1590)
> 	at org.apache.sis.internal.referencing.DeferredCoordinateOperation.create(DeferredCoordinateOperation.java:71)
> 	at org.apache.sis.referencing.operation.CoordinateOperationRegistry.search(CoordinateOperationRegistry.java:506)
> 	at org.apache.sis.referencing.operation.CoordinateOperationRegistry.createOperation(CoordinateOperationRegistry.java:333)
> 	at org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperation(CoordinateOperationFinder.java:236)
> 	at org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperationStep(CoordinateOperationFinder.java:358)
> 	at org.apache.sis.referencing.operation.CoordinateOperationFinder.createOperation(CoordinateOperationFinder.java:250)
> 	at org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory.createOperation(DefaultCoordinateOperationFactory.java:811)
> 	at org.apache.sis.referencing.CRS.findOperation(CRS.java:640)
> 	at de.hechler.apsistest.GK3toWGS84.main(GK3toWGS84.java:23)
> 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>(InterpolatedTransform.java:440)
> 	at org.apache.sis.referencing.operation.transform.InterpolatedTransform2D$Inverse.<init>(InterpolatedTransform2D.java:107)
> 	at org.apache.sis.referencing.operation.transform.InterpolatedTransform2D.createInverse(InterpolatedTransform2D.java:87)
> 	at org.apache.sis.referencing.operation.transform.InterpolatedTransform.<init>(InterpolatedTransform.java:198)
> 	at org.apache.sis.referencing.operation.transform.InterpolatedTransform2D.<init>(InterpolatedTransform2D.java:47)
> 	at org.apache.sis.referencing.operation.transform.InterpolatedTransform.createGeodeticTransformation(InterpolatedTransform.java:235)
> 	at org.apache.sis.internal.referencing.provider.NTv2.createMathTransform(NTv2.java:128)
> 	at org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.createParameterizedTransform(DefaultMathTransformFactory.java:1048)
> 	... 14 more
> {code}
> I debugged into the code and found the following.
> In InterpolatedTransform the DataShiftGrid is checked for its accuracy (getCellPrecision()
returns accuracy/10):
> {code:title=InterpolatedTransform.java}
> tolerance = grid.getCellPrecision();
> if (!(tolerance > 0)) {         // Use ! for catching NaN.
>     throw new IllegalArgumentException(Errors.format(
>         Errors.Keys.ValueNotGreaterThanZero_2, "grid.cellPrecision", tolerance));
> {code}
> In NTv2.java a DatumShiftGridFile.Float instance is created to read in the BETA2007.gsb
file. In DatumShiftGridFile.Float the accuracy member variable is initialized with NaN:
> {code:title=DatumShiftGridFile.java}
>     /**
>      * 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;
> {code}
> The loader, in this case, is NTv2.java 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:
> {code:title=NTv2.java}
> 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;
>   }
> }
> {code}
> 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 0.000000:
> {code:title=BETA2007.gsa}
> ...
> 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
> END
> {code}
> (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:
> !patch_BETA2007_gsb.png! 
> The change would be in ASCII:
> {code:title=BETA2007.gsa(PATCHED)}
> ...
> 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
> END
> {code}
> So the first shift gets an accuracy value greater then 0.0.
> With this patched BETA2007.gsb file the program runs as expected:
> {code}
> Source:   POINT(5500000 3500000)
> Target:   POINT(49.63670826166641 8.99895896840875)
> Expected: POINT(49.63670826166641 8.99895896840875)
> {code}
> 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 NTv2.java, so that it initializes the grid.accuracy
to some default value if it is NaN after checking all shifts.
> LocalizationGridBuilder has some similiair intialization:
> {code}
> (gridPrecision > 0) ? gridPrecision : DEFAULT_PRECISION);
> {code}
> Maybe this can be done in NTv2 for NaN values.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message