Hi all,
today I was looking into http://jira.codehaus.org/browse/GEOT-3570
and had some disappointing realization about our blasted envelope
situation.

Now, you all know already the GeoTools code has has an envelope for
every occasion and every mood.
You can use JTS Envelope if you feel like 2d cartesian, you can pump
up and use ReferencedEnvelope if you feel venturing in map projection
land, or GeneralEnvelope if you want to go ND and so on (there are
unfortunately more).

Now, generally speaking the GeoTools implementation world is split
today in two factions: the vector code uses ReferencedEnvelope
pretty much solid, whilst the coverage code uses GeneralEnvelope
almost everywhere.
Both are classes, implementations, not interfaces, as such they are
not interchangeable.

Now, when it's time to reproject an envelope the vector code does
referencedEnvelope.transform(targetCrs, lenient).
This is actually the most advanced envelope reprojection code we have.
If first gets the CoordinateOperation from source to target crs, calls
onto CRS.transform(operation, envelope), and then takes into account
five extra points per side to account for reprojecting bending and
"bubbling" the sides.

First off, CRS.transform(operation, envelope) is a smart method that
can take into account degenerate cases like people asking to reproject
[-300, -150, 300, 150] in WGS84 to something else, the code will
recognize the source crs is geographic and compensate for the absurd
request considering the whole world as the source (if you roll -300, -150
it becomes -120, -30).

Then the densification, by default 5 extra points per side, takes care of
the cases in considering just the point by point reprojection would result
in a smaller bbox than actually needed (see attached picture).

So ok, vector code is good.
Most of the raster code does instead this:
MathTransform mt = CRS.findMathTransform(source, target, true);
GeneralEnvelope ge = CRS.transform(mt, sourceEnvelope)

This approach is unfortunately piss poor instead:
- the math transform does not carry around source and target CRS,
  (CoordinateOperation would) so there are no smarts to correct
  "larger than world" requests
- there is no densification going on

As a result we get http://jira.codehaus.org/browse/GEOT-3570, the
code is trying to envelope a larger than world envelope in NAD83
back in WGS84, coordinate rolling happens, and we end up with
a much smaller than world area, thus the missing parts in the
rendering.
Adding insult to the injury, that smaller area is used to select
the overview in the tiff file, making the code think we are
actually much more zoomed in than we are, thus getting
a much higher resolution overview: not only a wrong result,
but also slower!

To fix this we have to get the coverage code either call
CRS.transform(envelope, targetCRS) or
CRS.transform(coordinateOperation, envelope)

Given the code is setup to extract a MathTransform already
it's probably easier to add a
CRS.findCoordinateOperation(source, target, lenient)
method and then have the coverage reader code around use
CoordinateOperation instead of MathTransform, getting
the math transform out of the coordinate operation as needed.
Though in many cases we can just go straight for
CRS.transform(envelope, targetCRS)

Now, that is not so hard, but there are 65 points in the
code base calling CRS.transform(mathTransform, envelope)
plus 6 calling the CRS.transform(mathTransform, sourceRectangle,
targetRectangle)
Soo.. it's not a small change.
I'm up to do it, but I think I'll need some review.
Since this is bug fixing I'd like to backport the results to 2.7.x

Mind though, this would only solve part of the problem,
since even CRS.transform(envelope, targetCRS) does not
do the densification.
I guess we also want to add the densified reproject code
into CRS, and have ReferencedEnvelope (and the JTS utility
class) use it instead.

Opinions, suggestions? (someone burning to do this work
in my place or feeling like helping out?) :-p

Cheers
Andrea


-- 
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054  Massarosa (LU)
Italy

phone: +39 0584 962313
fax:      +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------

<<attachment: ReprojectEnvelope.png>>

------------------------------------------------------------------------------
Simplify data backup and recovery for your virtual environment with vRanger.
Installation's a snap, and flexible recovery options mean your data is safe,
secure and there when you need it. Discover what all the cheering's about.
Get your free trial download today. 
http://p.sf.net/sfu/quest-dev2dev2 
_______________________________________________
Geotools-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to