jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • GeoServer
  • GEOS-1720

Grid coverage reprojection degrades image quality in an unacceptable way

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.6.0-RC3
  • Fix Version/s: 1.6.3
  • Component/s: WMS
  • Labels:
    None

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

  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. Hide
    Zip Archive
    mosaicReprojectionQuality.zip
    01/Feb/08 8:25 AM
    593 kB
    Andrea Aime
    1. File
      level0.dbf 1 kB
    2. File
      level0.prj 0.6 kB
    3. File
      level0.properties 0.1 kB
    4. File
      level0.sbn 0.2 kB
    5. File
      level0.sbx 0.1 kB
    6. File
      level0.shp 0.6 kB
    7. File
      level0.shx 0.1 kB
    8. File
      test_3_5.tif 196 kB
    9. File
      test_3_6.tif 196 kB
    10. File
      test_4_5.tif 196 kB
    11. File
      test_4_6.tif 196 kB
    Download Zip
    Show
    Zip Archive
    mosaicReprojectionQuality.zip
    01/Feb/08 8:25 AM
    593 kB
    Andrea Aime
  2. Java Source File
    TestResampleBug.java
    01/Feb/08 11:21 AM
    1.0 kB
    Andrea Aime
  1. afterFix.jpg
    27 kB
    24/Mar/08 2:33 PM
  2. afterWarp.png
    109 kB
    01/Feb/08 8:27 AM
  3. beforeWarp.png
    346 kB
    01/Feb/08 8:26 AM

Issue Links

depends upon

Improvement - An improvement or enhancement to an existing feature or task. GEO-143 Add transform(float[], ... double[], ...) methods in MathTransform

  • Minor - Minor loss of function, or other problem where easy workaround is present.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.

Task - A task that needs to be done. GEOT-2117 Review GeoToolkit fixes

  • Minor - Minor loss of function, or other problem where easy workaround is present.
  • Open - The issue is open and ready for the assignee to start work on it.
is related to

Bug - A problem which impairs or prevents the functions of the product. GEOT-1419 Extra transformations chained unexpectedly

  • Minor - Minor loss of function, or other problem where easy workaround is present.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 8:25 AM

The image mosaic needed to reproduce the problem

Show
Andrea Aime added a comment - 01/Feb/08 8:25 AM The image mosaic needed to reproduce the problem
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 8:26 AM

Rendered image chain browser, the step before the final warping (used for the reprojection)

Show
Andrea Aime added a comment - 01/Feb/08 8:26 AM Rendered image chain browser, the step before the final warping (used for the reprojection)
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 8:27 AM

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...)

Show
Andrea Aime added a comment - 01/Feb/08 8:27 AM 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...)
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 8:36 AM

This preliminar analysis shows that the quality degradation is occurring when the Resample operation is called in GridCoverageRenderer.resample(...), line 881 (geotools trunk)

Show
Andrea Aime added a comment - 01/Feb/08 8:36 AM This preliminar analysis shows that the quality degradation is occurring when the Resample operation is called in GridCoverageRenderer.resample(...), line 881 (geotools trunk)
Hide
Permalink
Martin Desruisseaux added a comment - 01/Feb/08 8:39 AM

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.

Show
Martin Desruisseaux added a comment - 01/Feb/08 8:39 AM 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.
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 8:59 AM

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

Show
Andrea Aime added a comment - 01/Feb/08 8:59 AM 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
Hide
Permalink
Martin Desruisseaux added a comment - 01/Feb/08 10:34 AM

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.

Show
Martin Desruisseaux added a comment - 01/Feb/08 10:34 AM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 01/Feb/08 10:36 AM

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...

Show
Martin Desruisseaux added a comment - 01/Feb/08 10:36 AM 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...
Hide
Permalink
Simone Giannecchini added a comment - 01/Feb/08 10:39 AM

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

Show
Simone Giannecchini added a comment - 01/Feb/08 10:39 AM 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
Hide
Permalink
Simone Giannecchini added a comment - 01/Feb/08 10:41 AM

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.

Show
Simone Giannecchini added a comment - 01/Feb/08 10:41 AM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 01/Feb/08 10:44 AM

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.

Show
Martin Desruisseaux added a comment - 01/Feb/08 10:44 AM 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.
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 10:49 AM

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

Show
Andrea Aime added a comment - 01/Feb/08 10:49 AM 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
Hide
Permalink
Andrea Aime added a comment - 01/Feb/08 11:21 AM - edited

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.

Show
Andrea Aime added a comment - 01/Feb/08 11:21 AM - edited 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.
Hide
Permalink
Simone Giannecchini added a comment - 01/Feb/08 11:27 AM

The easiest way to make ithe test run is by dropping it into the geotiff test package

Show
Simone Giannecchini added a comment - 01/Feb/08 11:27 AM The easiest way to make ithe test run is by dropping it into the geotiff test package
Hide
Permalink
Andrea Aime added a comment - 20/Mar/08 12:57 PM

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

Show
Andrea Aime added a comment - 20/Mar/08 12:57 PM 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
Hide
Permalink
Andrea Aime added a comment - 20/Mar/08 12:58 PM

Hum, looked a little better into GEOT-1419, it's not the same, but it may be related.

Show
Andrea Aime added a comment - 20/Mar/08 12:58 PM Hum, looked a little better into GEOT-1419, it's not the same, but it may be related.
Hide
Permalink
Paul McCullough added a comment - 20/Mar/08 1:07 PM

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.

Show
Paul McCullough added a comment - 20/Mar/08 1:07 PM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 20/Mar/08 2:18 PM

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.

Show
Martin Desruisseaux added a comment - 20/Mar/08 2:18 PM 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.
Hide
Permalink
Andrea Aime added a comment - 21/Mar/08 4:24 AM

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.

Show
Andrea Aime added a comment - 21/Mar/08 4:24 AM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 21/Mar/08 5:16 AM

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...

Show
Martin Desruisseaux added a comment - 21/Mar/08 5:16 AM 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...
Hide
Permalink
Martin Desruisseaux added a comment - 21/Mar/08 4:21 PM

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.

Show
Martin Desruisseaux added a comment - 21/Mar/08 4:21 PM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 21/Mar/08 4:26 PM

Will continue investigations later this weekend.

Show
Martin Desruisseaux added a comment - 21/Mar/08 4:26 PM Will continue investigations later this weekend.
Hide
Permalink
Martin Desruisseaux added a comment - 23/Mar/08 9:21 AM

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.

Show
Martin Desruisseaux added a comment - 23/Mar/08 9:21 AM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 23/Mar/08 1:05 PM

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.

Show
Martin Desruisseaux added a comment - 23/Mar/08 1:05 PM 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.
Hide
Permalink
Martin Desruisseaux added a comment - 24/Mar/08 6:53 AM

Merged on the 2.4 branch as of revision 29704.

Show
Martin Desruisseaux added a comment - 24/Mar/08 6:53 AM Merged on the 2.4 branch as of revision 29704.
Hide
Permalink
Andrea Aime added a comment - 24/Mar/08 2:33 PM

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!

Show
Andrea Aime added a comment - 24/Mar/08 2:33 PM 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!
Hide
Permalink
Andrea Aime added a comment - 25/Mar/08 12:19 PM

Tested on GeoServer as well, seems to be working fine. Closing it, please reopen if the solution is not satisfactory.

Show
Andrea Aime added a comment - 25/Mar/08 12:19 PM Tested on GeoServer as well, seems to be working fine. Closing it, please reopen if the solution is not satisfactory.
Hide
Permalink
Andrea Aime added a comment - 03/Jul/09 9:52 AM

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)

Show
Andrea Aime added a comment - 03/Jul/09 9:52 AM 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)

People

  • Assignee:
    Andrea Aime
    Reporter:
    Andrea Aime
Vote (1)
Watch (3)

Dates

  • Created:
    01/Feb/08 8:24 AM
    Updated:
    03/Jul/09 9:52 AM
    Resolved:
    25/Mar/08 12:19 PM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.