ThinkGeo.com    |     Documentation    |     Premium Support

How to display raster image with rotated north

Hello

In my project I receive from my client images that are not aligned to the true north, meaning the images have rotation angle.

To may understanding tour WpfMap control works under the assumption that raster images are aligned to the north, so i started to search for a way to open my aligned images in a RasterLayer in  a way that will keep the geographic coordinates correct.



I saw some examples on rotation of ShapeFileFeatureLayer, and thought that i will be able to do similar operation on my raster layer

this is my code: (I set Angle = 30 in order to align the image to the true north)



GeoTiffRasterLayer rasterLayer = new GeoTiffRasterLayer(filePath);

Projections.CustomRotationProjection customRotationProjection = new Projections.CustomRotationProjection(ManagedProj4Projection.GetEpsgParametersString(28350), ManagedProj4Projection.GetEpsgParametersString(28350));
customRotationProjection.Angle = 30;


rasterLayer.Open();
customRotationProjection.PivotVertex = new Vertex(rasterLayer.GetBoundingBox().GetCenterPoint());
rasterLayer.Close();



rasterLayer.ImageSource.Projection = customRotationProjection;




the  "CustomRotationProjection" class is taken from your example: "Custom rotation projection"



this method did not worked, I got the following exception: 

"Convert Raster to Exsternal Projection by default is not implemented, please override this method if needed"



I searched for more data  on the subject. In the following links, it seams that you do not support in rotation of raster layer:

thinkgeo.com/forums/MapSuite/tabid/143/aft/9216/Default.aspx

thinkgeo.com/forums/MapSuite/tabid/143/aft/8451/Default.aspx

thous posts are from 2010,2011



and then I saw the following thread (from 2013), which note that setting the projection of raster layer IS supported

-thinkgeo.com/forums/MapSuite/tabid/143/aft/11093/Default.aspx



see the code attached by your representative in that thread



            ManagedProj4Projection proj4 = new ManagedProj4Projection();
            proj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(28350);
            proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString();
            proj4.Open();

            GdiPlusRasterLayer rasterLayer = new GdiPlusRasterLayer();
            rasterLayer.ImageSource.Projection = proj4;

So In conclusion ,my questions are:
1.Is it possible to set projection for raster layer by setting rasterLayer.ImageSource.Projection
2.Is using the CustomRotationProjection will work to display a raster image that has rotation (the image is not aligned to the true north)
3. can you explain/provide a sample code regarding to displaying rotated raster image on the map (the source image is roted, and I assume i need to align it to the true north in order to geek on correct geographic coordinates)

Thank you

Hi Miri, 
  
 1. Projection will works for raster layer by the API you mentioned. 
 2. CustomRotationProjection won’t works by this way for raster layer. 
 3. We are implementing rotate for raster layer, but it hadn’t been released. 
  
 Regards, 
  
 Don

Hi Don,

I’m reopening this old thread because we’ve also tried to run your example: “Custom rotation projection” with the most current version and still get this exception:

“Convert Raster to Exsternal Projection by default is not implemented, please override this method if needed”

Is there a time frame when your implementation to rotate a raster layer will be released?
Thank you for your help.

Regards,
Peter

Hi Peter,

We have implemented that last year.

And I tested this sample with latest version today, it works well. The latest version number is 9.0.372.0.

Regards,

Don

Hi Don,

thank your for your fast answer,
Since what version is this feature implemented?

The most current - at least for me - in the Customer Portal available production build of the Desktop Edition is 9.0.0.361. As we cannot use a development build I cannot recreate your test with version 9.0.372.0.

This sample also returns only a “NotImplementedException”:

Regards,
Peter

Hi Peter,

Please try the code as below:

using System;
using System.Windows;
using System.Windows.Input;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WpfDesktopEdition;

namespace CustomRotationProjection
{
public partial class TestWindow : Window
{
private RotationProjection rotationProjection;

    public TestWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        wpfMap1.MapUnit = GeographyUnit.Meter;
        wpfMap1.CurrentExtent = new RectangleShape(-10000000, 10000000, 10000000, -10000000);

        EcwRasterLayer ecwImageLayer = new EcwRasterLayer(@"..\..\SampleData\Data\World.ecw");
        ecwImageLayer.Open();
        ecwImageLayer.UpperThreshold = double.MaxValue;
        ecwImageLayer.LowerThreshold = 0;

        rotationProjection = new RotationProjection(20);
        rotationProjection.Open();

        ecwImageLayer.ImageSource.Projection = rotationProjection;


        LayerOverlay layerOverlay = new LayerOverlay();
        layerOverlay.Layers.Add("ecwImageLayer", ecwImageLayer);
        wpfMap1.Overlays.Add("StreetOverlay", layerOverlay);

        wpfMap1.CurrentExtent = ecwImageLayer.GetBoundingBox();
        wpfMap1.Refresh();
    }

    private void btnRotateClockWise_Click(object sender, RoutedEventArgs e)
    {
        LayerOverlay streetLayerOverlay = (LayerOverlay)wpfMap1.Overlays["StreetOverlay"];
        EcwRasterLayer ecwImageLayer = (EcwRasterLayer)streetLayerOverlay.Layers["ecwImageLayer"];

        //Set the Angle property of RotationProjection. Substract 5 to go clockwise.
        ecwImageLayer.Open();
        rotationProjection.Angle = rotationProjection.Angle - 5;
        ecwImageLayer.Close();

        wpfMap1.Refresh(streetLayerOverlay);
    }

    private void btnRotateCounterClockWise_Click(object sender, RoutedEventArgs e)
    {
        LayerOverlay streetLayerOverlay = (LayerOverlay)wpfMap1.Overlays["StreetOverlay"];
        EcwRasterLayer ecwImageLayer = (EcwRasterLayer)streetLayerOverlay.Layers["ecwImageLayer"];

        //Set the Angle property of RotationProjection. Adds 5 to go clockwise.
        ecwImageLayer.Open();
        rotationProjection.Angle = rotationProjection.Angle + 5;
        ecwImageLayer.Close();

        wpfMap1.Refresh(streetLayerOverlay);
    }


    private void wpfMap1_MouseMove(object sender, MouseEventArgs e)
    {
        //Gets the PointShape in world coordinates from screen coordinates.
        Point point = e.MouseDevice.GetPosition(null);

        ScreenPointF screenPointF = new ScreenPointF((float)point.X, (float)point.Y);
        PointShape pointShape = ExtentHelper.ToWorldCoordinate(wpfMap1.CurrentExtent, screenPointF, (float)wpfMap1.Width, (float)wpfMap1.Height);

        textBox1.Text = "X: " + Math.Round(pointShape.X) +
                      "  Y: " + Math.Round(pointShape.Y);
    }
}

}

Regards,

Don