Details
Description
Using the sample attached mosaic and trying to display the image in a CRS other than the native one the image quality get compromised, a sort of heavy subsampling occurs during reprojection.
The original mosaic is in an ESRI crs that needs to be registered in user_projections/espg.properties:
102643=PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",
GEOGCS["NAD83",DATUM["North_American_Datum_1983",
SPHEROID["GRS 1980",6378137,298.2572221010002,AUTHORITY["EPSG","7019"]],
AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],
PARAMETER["standard_parallel_1",37.06666666666667],
PARAMETER["standard_parallel_2",38.43333333333333],
PARAMETER["latitude_of_origin",36.5],PARAMETER["central_meridian",-120.5],
PARAMETER["false_easting",6561666.666666666],PARAMETER["false_northing",1640416.666666667],
UNIT["US survey foot",0.3048006096012192,AUTHORITY["EPSG","102643"]]]
And here is a reprojected request (from 102643 to 4326) that shows the quality reduction. This happens both on 1.6.x and on trunk:
http://localhost:8080/geoserver/wms?bbox=-122.45973,37.7722,-122.45882,37.77292&styles=&Format=application/openlayers&request=GetMap&layers=topp:level0&width=600&height=550&srs=EPSG:4326
-
Hide
- mosaicReprojectionQuality.zip
- 01/Feb/08 8:25 AM
- 593 kB
- Andrea Aime
-
- level0.dbf 1 kB
- level0.prj 0.6 kB
- level0.properties 0.1 kB
- level0.sbn 0.2 kB
- level0.sbx 0.1 kB
- level0.shp 0.6 kB
- level0.shx 0.1 kB
- test_3_5.tif 196 kB
- test_3_6.tif 196 kB
- test_4_5.tif 196 kB
- test_4_6.tif 196 kB
-
- TestResampleBug.java
- 01/Feb/08 11:21 AM
- 1.0 kB
- Andrea Aime
-
- afterFix.jpg
- 27 kB
- 24/Mar/08 2:33 PM
-
- afterWarp.png
- 109 kB
- 01/Feb/08 8:27 AM
-
- beforeWarp.png
- 346 kB
- 01/Feb/08 8:26 AM
Issue Links
Activity
Rendered image chain browser, the step before the final warping (used for the reprojection)
And then after the warp operation, showing the quality degradation (the image size in pixels is the same as the previous one, but a very visible subsampling is occurring here...)
This preliminar analysis shows that the quality degradation is occurring when the Resample operation is called in GridCoverageRenderer.resample(...), line 881 (geotools trunk)
The "Scale" operation should not be in the chain, unless it has been added as a workaround for some issue I'm not aware of... The GeoTools Resampler2D class is designed in order to performs the scale itself if it can. Unless there is some issue that I'm missing, the "imagemosaic" module should not try to scale itself and rely directly on Resampler2D instead. If there is any issue with the result, the could be reported as Resampler2D bug. However it is not sure that this work can be done on GeoTools 2.4 since Resampler2D has been reviewed (and hopefully improved) in GeoTools 2.5.
Hum, the scale operation is not what's causing the issue, as you can see, the output of scale has a perfectly acceptable quality (it's beforeWarp). As for the difference between branches, the screenshots have been taken on geoserver trunk (geotools trunk) but the same result occurrs to geoserver 1.6.x (gt2 2.4.x) so the improvements on trunk did not affect the issue at hand
Could be a bug in Resampler2D then. But is it the operation used? Any change to trace the place where the JAI "Warp" operation is created? If you can trace it down to a call to Resampler2D.reproject, would it be possible to post the println of arguments given to that method please? Since I'm working on Resampler2D, it would be good time for fixing it.
P.S.: Would it be possible to split the WKT in the description into multilines please (I means add some cariage returns). It would allows JIRA to make this page less width. Current width is a little bit large for my latop screen...
I have inspected a bit the code and it seems something related to the Warp operation but I am not sure yet. I am going to separate a test case which does not use anything else to isolate the problem. There are too many transformations involved (see http://rafb.net/p/r8WLnb86.html) for my taste ![]()
btw I see tis message on the console
01 feb 17:37:03 WARN [referencing.factory] - Ambiguity between inverse flattening and semi minor axis length. Using inverse flattening.
Actually I would be highly interrested in a test case reproducing the MathTransform posted by Simone. Having a "Geocentric to Ellipsoid" followed by "Molodenski" transform is a little bit surprising (the later could have been merged with the former), so it may be an issue for the referencing module. However it should not be the cause for the issue reported here.
Splitted the wkt on a few lines. If someone tries to paste it into the epsg.properties file he'll have to make it back on a single line
Sample, stand alone test to reproduce the reprojection problems. The geotiff file can be found in the sample data attached to this issue.
Thanks to Simone for cooking it up.
The easiest way to make ithe test run is by dropping it into the geotiff test package
Any comment on this one? Btw, the "too many trasforms" created by the referencing package was already a known problem, it has been reported in http://jira.codehaus.org/browse/GEOT-1419
Hum, looked a little better into GEOT-1419, it's not the same, but it may be related.
Not sure what sort of comment you are soliciting so I'll go with the -verbose flag
Yes - we (City and County of San Francisco) are interested in a patch here.
The case described in GEOT-1419 will be much slower than it would be without the extra steps, and maybe we would have a slight difference after some decimal digits, but I don't think that it is responsible of this issue. The extra transformation steps mentioned here are rather transformations requested explicitly by the render (or any other "user" of referencing) rather than the chain built "under the hood" by referencing.
Martin, we showed you proof that the renderer itself has nothing to do with the image degradation with the sample java file I attached more than one month ago.
To cite the code explicitly:
final GeoTiffReader reader = new GeoTiffReader(new File("c:\\progetti\\gisData\\mosaicReprojectionQuality\\test_3_5.tif")); final GridCoverage2D source= (GridCoverage2D) reader.read(null); source.show(); final GridCoverage2D destination = (GridCoverage2D) Operations.DEFAULT.resample(source, DefaultGeographicCRS.WGS84); destination.show();
If anything is going on, it's not in the rendering code itself, but in the Resample operation used to perform the grid coverage reprojection.
If I can be of any further assistance just let me know what you need.
final GeoTiffReader reader = new GeoTiffReader(new File("c:\\progetti\\gisData\\mosaicReprojectionQuality\\test_3_5.tif")); final GridCoverage2D source= (GridCoverage2D) reader.read(null); source.show(); final GridCoverage2D destination = (GridCoverage2D) Operations.DEFAULT.resample(source, DefaultGeographicCRS.WGS84); destination.show();
Right I reproduced the issue. Sorry for having suspecting the renderer - but given that this issue was reported against GeoServer rather than GeoTools referencing module I didn't realized that the test case was using referencing only. I though that it was showing GeoServer output, in which case the number of classes involved would have been too high for an investigation.
Investigating now...
Package org.geotools.referencing.operation.transform, class WarpAdapter, line 102 on trunk. A breakpoint on this line shows that the destRect array contains increasing values on input as expected, but contains many coordinates set to the same values on output. The later is unexpected and needs more investigations.
The bug is caused by the large amount of transformation steps involved in this particular projection and arrays of float primitive type not having enough precision for holding some intermediate results. Will try to switch to array of double primitive type (it will imply the creation of temporary arrays).
In a future version, reducing the amount of transformation steps inferred by the referencing module may help to reduce the risk of precision lost, so Andrea was right to point-out GEOT-1419 as possibly related to this issue.
Fixed on trunk as of revision 29699 by forcing ConcatenatedTransform.transform(float[], ...) to use an intermediate buffer of type double[]. Source array of type float[] is partially copied in this temporary array before to be transformed. This solve the lost of precision which was the cause of this issue.
Here is the output for a single tile after the fix. A lot better, the only hint that reprojection occurred is along the roof of the white building. I guess that one can't be helped. Great job!
Tested on GeoServer as well, seems to be working fine. Closing it, please reopen if the solution is not satisfactory.
Mass close all issues that have been resolved for more than one month without further comments (assuming they are fixed for good since there is no more discussion)
The image mosaic needed to reproduce the problem