GeoTools
  1. GeoTools
  2. GEOT-925

Rederer fails to project world data

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.2.0
    • Fix Version/s: 2.7-M0
    • Component/s: render
    • Labels:
      None

      Description

      When a global data set (extending to the poles) is projected as meractor, the renderer chokes on the exception:

      Aug 18, 2006 9:27:40 AM org.geotools.renderer.lite.StreamingRenderer$DefaultRenderListener errorOccurred
      SEVERE: Latitude 9000.0'S is too close to a pole.
      org.geotools.referencing.operation.projection.ProjectionException: Latitude 9000.0'S is too close to a pole.
      at org.geotools.referencing.operation.projection.Mercator.transformNormalized(Mercator.java:136)
      at org.geotools.referencing.operation.projection.MapProjection.transform(MapProjection.java:637)
      at org.geotools.referencing.operation.projection.MapProjection.transform(MapProjection.java:678)
      at org.geotools.referencing.operation.transform.ConcatenatedTransformDirect.transform(ConcatenatedTransformDirect.java:81)
      at org.geotools.renderer.lite.Decimator.decimateTransformGeneralize(Decimator.java:249)
      at org.geotools.renderer.lite.Decimator.decimateTransformGeneralize(Decimator.java:123)
      at org.geotools.renderer.lite.Decimator.decimateTransformGeneralize(Decimator.java:114)
      at org.geotools.renderer.lite.Decimator.decimateTransformGeneralize(Decimator.java:103)
      at org.geotools.renderer.lite.LiteShape2.<init>(LiteShape2.java:131)
      at org.geotools.renderer.lite.StreamingRenderer.getTransformedShape(StreamingRenderer.java:1388)
      at org.geotools.renderer.lite.StreamingRenderer.processSymbolizers(StreamingRenderer.java:1361)
      at org.geotools.renderer.lite.StreamingRenderer.process(StreamingRenderer.java:1281)
      at org.geotools.renderer.lite.StreamingRenderer.processStylers(StreamingRenderer.java:1231)
      at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:506)
      at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:412)
      at org.geotools.gui.swing.JMapPane.paintComponent(JMapPane.java:414)
      ...

      The renderer could apparently handle the exception and keep going.

      Assigned to Andrea since he asked for it.

      Attached is the file that causes the exception. Simply run the file's main() method

        Activity

        Hide
        Andrea Aime added a comment -
        Fixed on trunk by skipping features with projection errors. A more complete fix requires to cut the in the validity area of the current transformation, if available, instead of throwing them away.

        Waiting for people to confirm it works fine, then we may backport it to 2.2.0
        Show
        Andrea Aime added a comment - Fixed on trunk by skipping features with projection errors. A more complete fix requires to cut the in the validity area of the current transformation, if available, instead of throwing them away. Waiting for people to confirm it works fine, then we may backport it to 2.2.0
        Hide
        Adrian Custer added a comment -
        Good timing! I wanted a place to record some initial thoughts...

        In the current state, we need to explain to users how to convert their data into something Geotools can handle. This involves outlining the general solution to the problem.

        The general solution however requires a new topologically aware geometry, something linked to the feature but which (1) can be renderered and (2) knows that it comes from a different original topology. For example, an island that spanned the anti-merridian would be split into two polygons that actually share a common original topological edge and know that this edge is purely virtual. For another example, antarctica would be split down the antimerridian to the pole with two edges in the new polygon that know they are topologically the same, and the bottom edge that knows it is topologically a point. So we need to be able to build geometires which have 'virtual' elements (edges that don't actually exist, edges which are actually points).
          1) If we could create these, how would we associate them with the original feature? Would they live in the renderer or would we expand the feature?
          2) Any ideas how hard it would be to build these new geometries with 'artificial' internal elements?

        The solution is therefore quite hard. However it gives us some power for free. It strikes me that this correct fix requires the same functionality that a tiling renderer would have to have. In a tiling renderer, featureGeometries might be split into several componentGeometires that still know they came from a coherent whole. Similarly, the fix provides us a lot in terms of working in 2D, e.g. buffers that work correctly over the poles and dateline...

        *********

        Conceptually, the correct conversion chain would be:

        1) Data in 3D
            - any valid geom is ok

        2) Data in Clean 2D
            - all geoms in +/- 90;+/-180
            - REQUIRES: a topologicalGeometry for geometries that span the pole/dateline
            - the robust solution would allow us to 'recenter' the data set on another meridian by recomputing this step.

        3) Data clipped to area of computability (area for which the transform gives an answer)
            - Any featureGeometry that is non transformable gets converted to an artifical geometry which can be transformed. (Note this step may involve yet more artificialTopology since now antartica will loose its edgeThatIsReallyAPoint and gain an edgeThatIsAdjacentToAVoidWhichIsReallyAContinousAreaToAPoint. I haven't thought this part through.)

        4) Data are shown relative to area of validity (area for which the transform makes sense)
            - Either we clip or overlay the area of validity
            - or we overlay a layer with colour intensity showing departure from accuracy

        **********

        Note in the current renderer this is done in a different order:
          ==> Try to project
          ==> if exception
            - For now, we drop

            - In future, we could calculate new topoAwareArtificalGeom
          ==> Transform to Clean 2D; Try to project
          ==> if exception
            - Create clipGeometries to bound data into the area of computablitity
            - Clip topoAwareArtificialGeom with clipGeom => get a newTopoAwareArtificalGeomWithFakeVoids
              
         ==> Project
         ==> If area of validity is known,
            - could overlay a layer with a greyed out 'area of non-validity'
            - could overlay a layer greyed out by 'intensity of non-validity'

        This second approach follows the same computational steps in the first but works feature by feature instead of tackling the whole data set at once.

        **********

        So the questions are:
          1) Can we come up with a system for topologicalAwareGeometries?
          2) Would these geometries live in the feature or the renderer?
          3) Is the work worth it?

        --adrian
        Show
        Adrian Custer added a comment - Good timing! I wanted a place to record some initial thoughts... In the current state, we need to explain to users how to convert their data into something Geotools can handle. This involves outlining the general solution to the problem. The general solution however requires a new topologically aware geometry, something linked to the feature but which (1) can be renderered and (2) knows that it comes from a different original topology. For example, an island that spanned the anti-merridian would be split into two polygons that actually share a common original topological edge and know that this edge is purely virtual. For another example, antarctica would be split down the antimerridian to the pole with two edges in the new polygon that know they are topologically the same, and the bottom edge that knows it is topologically a point. So we need to be able to build geometires which have 'virtual' elements (edges that don't actually exist, edges which are actually points).   1) If we could create these, how would we associate them with the original feature? Would they live in the renderer or would we expand the feature?   2) Any ideas how hard it would be to build these new geometries with 'artificial' internal elements? The solution is therefore quite hard. However it gives us some power for free. It strikes me that this correct fix requires the same functionality that a tiling renderer would have to have. In a tiling renderer, featureGeometries might be split into several componentGeometires that still know they came from a coherent whole. Similarly, the fix provides us a lot in terms of working in 2D, e.g. buffers that work correctly over the poles and dateline... ********* Conceptually, the correct conversion chain would be: 1) Data in 3D     - any valid geom is ok 2) Data in Clean 2D     - all geoms in +/- 90;+/-180     - REQUIRES: a topologicalGeometry for geometries that span the pole/dateline     - the robust solution would allow us to 'recenter' the data set on another meridian by recomputing this step. 3) Data clipped to area of computability (area for which the transform gives an answer)     - Any featureGeometry that is non transformable gets converted to an artifical geometry which can be transformed. (Note this step may involve yet more artificialTopology since now antartica will loose its edgeThatIsReallyAPoint and gain an edgeThatIsAdjacentToAVoidWhichIsReallyAContinousAreaToAPoint. I haven't thought this part through.) 4) Data are shown relative to area of validity (area for which the transform makes sense)     - Either we clip or overlay the area of validity     - or we overlay a layer with colour intensity showing departure from accuracy ********** Note in the current renderer this is done in a different order:   ==> Try to project   ==> if exception     - For now, we drop     - In future, we could calculate new topoAwareArtificalGeom   ==> Transform to Clean 2D; Try to project   ==> if exception     - Create clipGeometries to bound data into the area of computablitity     - Clip topoAwareArtificialGeom with clipGeom => get a newTopoAwareArtificalGeomWithFakeVoids         ==> Project  ==> If area of validity is known,     - could overlay a layer with a greyed out 'area of non-validity'     - could overlay a layer greyed out by 'intensity of non-validity' This second approach follows the same computational steps in the first but works feature by feature instead of tackling the whole data set at once. ********** So the questions are:   1) Can we come up with a system for topologicalAwareGeometries?   2) Would these geometries live in the feature or the renderer?   3) Is the work worth it? --adrian
        Hide
        Andrea Aime added a comment -
        > Good timing! I wanted a place to record some initial thoughts...
        >
        > In the current state, we need to explain to users how to convert their data into something
        > Geotools can handle. This involves outlining the general solution to the problem.
        >
        > The general solution however requires a new topologically aware geometry, something linked to the
        > feature but which (1) can be renderered and (2) knows that it comes from a different original
        > topology.
        ...
        > The solution is therefore quite hard. However it gives us some power for free. It strikes me that
        > this correct fix requires the same functionality that a tiling renderer would have to have.

        Agreed on the tiling renderer, but as a renderer we don't need to get this fancy in my opinion.
        Splitting the polygons may be nice but there's no need to create an in memory topologic
        geometries, because you can answer the queries a renderer may get (that is, "what's under this point?" without the need for topologic geometries, just do a point in polygon, either in the
        original or projected crs, since projections are suspposed to be invertible).

        Just take the original geometry and split it in two, and fix the coordinates of the part that
        goes beyond the [-180, 180, -90, 90] envelope.

        It would also be quite interesting to do the opposite, that is, recognize that the bottom
        edge of antartica is not to be there and remove it (and the same goes for every two split
        polygons that cross the dateline but are really the same... too bad we would need some soft
        info from outside to tell the two polygons are really the same (the feature id would be different,
        at least if generated by the current data stores, and I don't see a clean way to fix this)).

        >
        > 4) Data are shown relative to area of validity (area for which the transform makes sense) -
        > Either we clip or overlay the area of validity - or we overlay a layer with colour intensity
        > showing departure from accuracy

        That is a nice application for a user that needs to understand the nature of
        projections and where the errors do increase, but I would not like to see this in the
        renderer itself. If you need to teach projections to somebody, setup a polygonal map
        with different intervals of accuracy and overlay it graphically with a base projected map.

        > **********
        >
        > Note in the current renderer this is done in a different order: ==> Try to project ==> if
        > exception - For now, we drop

        Yep

        > - In future, we could calculate new topoAwareArtificalGeom ==> Transform to Clean 2D; Try to
        > project ==> if exception - Create clipGeometries to bound data into the area of computablitity -
        > Clip topoAwareArtificialGeom with clipGeom => get a newTopoAwareArtificalGeomWithFakeVoids

        I'm opening a separate bug for this approach, so that I won't forget.
        Cheers
        Andrea
        Show
        Andrea Aime added a comment - > Good timing! I wanted a place to record some initial thoughts... > > In the current state, we need to explain to users how to convert their data into something > Geotools can handle. This involves outlining the general solution to the problem. > > The general solution however requires a new topologically aware geometry, something linked to the > feature but which (1) can be renderered and (2) knows that it comes from a different original > topology. ... > The solution is therefore quite hard. However it gives us some power for free. It strikes me that > this correct fix requires the same functionality that a tiling renderer would have to have. Agreed on the tiling renderer, but as a renderer we don't need to get this fancy in my opinion. Splitting the polygons may be nice but there's no need to create an in memory topologic geometries, because you can answer the queries a renderer may get (that is, "what's under this point?" without the need for topologic geometries, just do a point in polygon, either in the original or projected crs, since projections are suspposed to be invertible). Just take the original geometry and split it in two, and fix the coordinates of the part that goes beyond the [-180, 180, -90, 90] envelope. It would also be quite interesting to do the opposite, that is, recognize that the bottom edge of antartica is not to be there and remove it (and the same goes for every two split polygons that cross the dateline but are really the same... too bad we would need some soft info from outside to tell the two polygons are really the same (the feature id would be different, at least if generated by the current data stores, and I don't see a clean way to fix this)). > > 4) Data are shown relative to area of validity (area for which the transform makes sense) - > Either we clip or overlay the area of validity - or we overlay a layer with colour intensity > showing departure from accuracy That is a nice application for a user that needs to understand the nature of projections and where the errors do increase, but I would not like to see this in the renderer itself. If you need to teach projections to somebody, setup a polygonal map with different intervals of accuracy and overlay it graphically with a base projected map. > ********** > > Note in the current renderer this is done in a different order: ==> Try to project ==> if > exception - For now, we drop Yep > - In future, we could calculate new topoAwareArtificalGeom ==> Transform to Clean 2D; Try to > project ==> if exception - Create clipGeometries to bound data into the area of computablitity - > Clip topoAwareArtificialGeom with clipGeom => get a newTopoAwareArtificalGeomWithFakeVoids I'm opening a separate bug for this approach, so that I won't forget. Cheers Andrea
        Hide
        Andrea Aime added a comment -
        This has been fixed with the "advanced projection handling" option on trunk.
        Show
        Andrea Aime added a comment - This has been fixed with the "advanced projection handling" option on trunk.

          People

          • Assignee:
            Andrea Aime
            Reporter:
            Adrian Custer
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: