Problem with WGS84 -> UTM33 transformation, envelop transformation problem

Topics: Algorithms, SharpMap v0.9 / v1.x
Jan 15, 2014 at 3:14 PM
Hi,

We are using SharpMap as tile generator for map tiles in our application. We need UTM33 (EPSG:32633) projection (and others) and data are stored in WGS-84, so we perform on-the-fly transformations. I have found that there is probably bug in tranformation of Envelope (boundingBox) when filtering features of vector layer, that should be rendered. Original method TransformBox calculates transformed envelop from transformed Min and Max points, but these points are not necessary Min and Max of the transformed envelope (when envelope is considered to be a rectangle). My rendered map (tile) is missing some of the features.

See code of the original method:
public static Envelope TransformBox(Envelope box, IMathTransform transform)
{
    if (box == null)
        return null;
    var corners = new Coordinate[4];
    var ll = box.Min().ToDoubleArray();
    var ur = box.Max().ToDoubleArray();
    var llTrans = transform.Transform(ll);
    var urTrans = transform.Transform(ur);
    corners[0] = new Coordinate(llTrans[0], llTrans[1]); //lower left
    corners[2] = new Coordinate(llTrans[0], urTrans[1]); //upper left
    corners[1] = new Coordinate(urTrans[0], urTrans[1]); //upper right
    corners[3] = new Coordinate(urTrans[0], llTrans[1]); //lower right

    var result = new Envelope(corners[0]);
    for (var i = 1; i < 4; i++)
        result.ExpandToInclude(corners[i]);
    return result;
}
I have changed TransformBox method, now transformed envelope is created as envelop that includes all transformed vertex of the original envelop. All features are rendered now.

See changed code. Change is done in file SharpMap/CoordinateSystems/Transformations/GeometryTransform.cs - Here
public static Envelope TransformBox(Envelope box, IMathTransform transform)
{
    if (box == null)
        return null;
    var corners = new Coordinate[4];

    corners[0] = transform.Transform(new Coordinate(box.MinX, box.MinY));
    corners[1] = transform.Transform(new Coordinate(box.MinX, box.MaxY));
    corners[2] = transform.Transform(new Coordinate(box.MaxX, box.MinY));
    corners[3] = transform.Transform(new Coordinate(box.MaxX, box.MaxY));

    var result = new Envelope(corners[0]);
    for (var i = 1; i < 4; i++)
        result.ExpandToInclude(corners[i]);
    return result;
}
Best regards
Dusan
Coordinator
Jan 15, 2014 at 10:29 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jan 16, 2014 at 1:19 PM
OK.