Adjust layer coordinates on a reference layer

Topics: Italiano, SharpMap v0.9 / v1.x
Mar 23, 2010 at 11:51 AM
Hi, I can not find a way to adjust the coordinates of a layer to another layer. I would choose 3 points on a reference layer and the corresponding 3 points on a second layer and transform the second on the reference of the first. If A, B and C are 3 points on the reference layer (corners of a building), I want to select 3 points on another layer (the same corners of a building) and transform the second layer so that it overlays the first. I hope that is understandable.
Coordinator
Mar 23, 2010 at 12:28 PM

Hi texamicomio see http://sharpmap.codeplex.com/wikipage?title=Apply%20on%20the%20fly%20transformation%20to%20a%20layer&referringTitle=How%20to... hth jd

Mar 23, 2010 at 5:44 PM

Thank you for your fast response, but I've already see the example.
I still find it difficult to create the reference system. Moreover, the layer that I want to adapt the reference layer may undergo any transformation.
To better express my problem, I created a web page with images.

http://sites.google.com/site/mapoverlay/

I hope you can help me.

Coordinator
Mar 24, 2010 at 10:33 PM

Hello texamicomio,

since there is no plain AffineCoordinateTransformation class in Proj.NET, you have to write one yourself. Derive it from Proj.NET MathTransform class and let it implement ICoordinateTransfrormation interface. You need to implement the Transform- and Inverse function(s) and of course a suitable constructor.

You can set an Instance of this class as CoordinateTransformation property to the Layer.

In respect to the LeastSquaresTransform class,

  • I think the offsets computed in GetAffineTransformation() point in the wrong direction
  • the result gets better the more Points you add, as an alternative you can try to add functionality to set the mean points.

Once I've cleaned up my testcase, I'll post it.

Hth FObermaier

Mar 25, 2010 at 12:42 AM

Hello FObermaier,
I have already found on the web and I adapted the code for calculating the coefficients of the affine transformation (because I found incorrect the results of LeastSquaresTransform class), but I was not able to understand how to use them to create a transformation.
Can you show me an example for the realization of my AffineCoordinateTransformation? If it works I will be happy to make it available to the community.
Thanks for your help.
Good life.

Coordinator
Mar 25, 2010 at 9:35 AM

Here is my AffineCoordinateTransformation2D class. It is "quick and dirty", but serves the purpose.

namespace ExampleCodeSnippets
{
    /// <summary>
    /// Performs an affine 2D coordinate transfromation
    /// X' = _a*X + _b*Y + _c
    /// Y' = _d*X + _e*Y + _f
    /// </summary>
    public class AffineCoordinateTransformation2D : SharpMap.CoordinateSystems.Transformations.MathTransform, SharpMap.CoordinateSystems.Transformations.ICoordinateTransformation
    {
        private readonly double _a, _b, _c, _d, _e, _f;

        /// <summary>
        /// Creates an instance of this class
        /// </summary>
        /// <param name="matrix"><see cref="T:System.Drawing.Drawing2D.Matrix"/> that holds the coefficients and for the coordinate transformation</param>
        public AffineCoordinateTransformation2D(System.Drawing.Drawing2D.Matrix matrix)
            : this(
                matrix.Elements[0], matrix.Elements[1], matrix.OffsetX,
                matrix.Elements[2], matrix.Elements[3], matrix.OffsetY)
        {
        }

        /// <summary>
        /// Creates an instance of this class
        /// </summary>
        /// <param name="affineTransformVector"></param>
        public AffineCoordinateTransformation2D(params double[] affineTransformVector)
        {
            _a = affineTransformVector[0];
            _b = affineTransformVector[1];
            _c = affineTransformVector[2];

            _d = affineTransformVector[3];
            _e = affineTransformVector[4];
            _f = affineTransformVector[5];
        }

        #region Overrides of MathTransform

        public override SharpMap.CoordinateSystems.Transformations.IMathTransform Inverse()
        {
            #warning(System.Drawing.Drawing2D.Matrix uses single precision floating point numbers. This involves reduction of precision, not at all accurate!)
            System.Drawing.Drawing2D.Matrix m = 
                new System.Drawing.Drawing2D.Matrix(
                    (float)_a, (float)_b, (float)_d, (float)_e, (float)_c, (float)_f);

            if (m.IsInvertible)
            {
                m.Invert();
                return new AffineCoordinateTransformation2D(m);
            }
            throw new System.Exception("Not invertible!");
        }

        public override double[] Transform(double[] point)
        {
            /*
            Converting from input (X,Y) to output coordinate system (X',Y') is done by:
            X' = a*X + b*Y + c, 
            Y' = d*X + e*Y + f
             */
            System.Diagnostics.Debug.Assert(point.Length == 2);
            System.Double[] ret = new System.Double[2];
            ret[0] = _a*point[0] + _b*point[1] + _c;
            ret[1] = _d*point[0] + _e*point[1] + _f;

            return ret;
        }

        public override System.Collections.Generic.List<double[]> TransformList(System.Collections.Generic.List<double[]> points)
        {
            System.Collections.Generic.List<System.Double[]> ret = new System.Collections.Generic.List<System.Double[]>(points.Count);
            foreach (double[] d in points)
                ret.Add(Transform(d));
            return ret;
        }

        public override void Invert()
        {
            throw new System.NotImplementedException();
        }

        public override string WKT
        {
            get { throw new System.NotImplementedException(); }
        }

        public override string XML
        {
            get { throw new System.NotImplementedException(); }
        }

        #endregion

        #region Implementation of ICoordinateTransformation

        public string AreaOfUse
        {
            get { throw new System.NotImplementedException(); }
        }

        public string Authority
        {
            get { throw new System.NotImplementedException(); }
        }

        public long AuthorityCode
        {
            get { throw new System.NotImplementedException(); }
        }

        public SharpMap.CoordinateSystems.Transformations.IMathTransform MathTransform
        {
            get { return this; }
        }

        public string Name
        {
            get { return "AffineCoordinateTransformation2D"; }
        }

        public string Remarks
        {
            get { return ""; }
        }

        public SharpMap.CoordinateSystems.ICoordinateSystem SourceCS
        {
            get { return null; }
        }

        public SharpMap.CoordinateSystems.ICoordinateSystem TargetCS
        {
            get { return null; }
        }

        public SharpMap.CoordinateSystems.Transformations.TransformType TransformType
        {
            get { return SharpMap.CoordinateSystems.Transformations.TransformType.Transformation; }
        }

        #endregion
    }

    [NUnit.Framework.TestFixture]
    public class AffineTransformSample
    {

        private static readonly System.Random RandomNumberGenerator = new System.Random();
        static System.Double[] GetRandomOrdinates(System.Int32 size, System.Double min, System.Double max)
        {
            System.Double[] arr = new System.Double[size];
            System.Double width = max - min;
            for (System.Int32 i = 0; i < size; i++)
            {
                System.Double randomValue = RandomNumberGenerator.NextDouble();
                arr[i] = min + randomValue * width;
            }
            return arr;
        }

        private static SharpMap.Data.FeatureDataTable TransformedFeatureDataTable(
            System.Drawing.Drawing2D.Matrix matrix, SharpMap.Data.FeatureDataTable fdt)
        {
            SharpMap.Data.FeatureDataTable fdtClone = new SharpMap.Data.FeatureDataTable(fdt);
            fdtClone.Clear();
            foreach (SharpMap.Data.FeatureDataRow row in fdt)
            {
                SharpMap.Data.FeatureDataRow newRow = fdtClone.NewRow();
                for (System.Int32 i = 0; i < fdtClone.Columns.Count; i++)
                    newRow[i] = row[i];

                SharpMap.Geometries.Point smpt = (SharpMap.Geometries.Point)row.Geometry;
                System.Drawing.PointF[] pts = new System.Drawing.PointF[] 
                    { new System.Drawing.PointF((float)smpt.X, (float)smpt.Y) };
                matrix.TransformPoints(pts);
                newRow.Geometry = new SharpMap.Geometries.Point(pts[0].X, pts[0].Y);

                fdtClone.AddRow(newRow);
            }

            return fdtClone;
        }

        [NUnit.Framework.Test]
        public void TestMatrix()
        {
            System.Drawing.Drawing2D.Matrix mat = new System.Drawing.Drawing2D.Matrix();
            mat.Rotate(30);
            mat.Translate(-20, 20);
            System.Drawing.PointF[] pts = new System.Drawing.PointF[] { new System.Drawing.PointF(50, 50) };

            mat.TransformPoints(pts);
            System.Diagnostics.Debug.WriteLine(string.Format("POINT ({0} {1})", pts[0].X, pts[0].Y));
            System.Drawing.PointF ptt = pts[0];
            System.Drawing.PointF[] ptts = new System.Drawing.PointF[] { new System.Drawing.PointF(ptt.X, ptt.Y) };
            System.Drawing.Drawing2D.Matrix inv = mat.Clone();
            inv.Invert();
            inv.TransformPoints(ptts);
            NUnit.Framework.Assert.LessOrEqual(System.Math.Abs(ptts[0].X - 50f), 0.01);
            NUnit.Framework.Assert.LessOrEqual(System.Math.Abs(ptts[0].Y - 50f), 0.01);
        
        }

        [NUnit.Framework.Test]
        public void TestAffineTransform2D()
        {
            //Setup some affine transformation
            System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();
            matrix.RotateAt(30, new System.Drawing.PointF(0, 0));
            matrix.Translate(-20, -20, System.Drawing.Drawing2D.MatrixOrder.Append);
            matrix.Shear(0.95f, -0.2f, System.Drawing.Drawing2D.MatrixOrder.Append);

            //Create some random sample data
            CreatingData cd = new CreatingData();
            SharpMap.Data.FeatureDataTable fdt1 =
                cd.CreatePointFeatureDataTableFromArrays(GetRandomOrdinates(80, -180, 180),
                                                         GetRandomOrdinates(80, -90, 90), null);

            //Clone random sample data and apply affine transformation on it
            SharpMap.Data.FeatureDataTable fdt2 = TransformedFeatureDataTable(matrix, fdt1);

            //Get affine transformation with LeastSquaresTransform
            SharpMap.Utilities.LeastSquaresTransform lst = new SharpMap.Utilities.LeastSquaresTransform();

            //Add at least three corresponding points
            lst.AddInputOutputPoint(
                ((SharpMap.Data.FeatureDataRow)fdt1.Rows[0]).Geometry as SharpMap.Geometries.Point,
                ((SharpMap.Data.FeatureDataRow)fdt2.Rows[0]).Geometry as SharpMap.Geometries.Point);

            lst.AddInputOutputPoint(
                ((SharpMap.Data.FeatureDataRow)fdt1.Rows[39]).Geometry as SharpMap.Geometries.Point,
                ((SharpMap.Data.FeatureDataRow)fdt2.Rows[39]).Geometry as SharpMap.Geometries.Point);

            lst.AddInputOutputPoint(
                ((SharpMap.Data.FeatureDataRow)fdt1.Rows[79]).Geometry as SharpMap.Geometries.Point,
                ((SharpMap.Data.FeatureDataRow)fdt2.Rows[79]).Geometry as SharpMap.Geometries.Point);

            /*
            //Get affine transformation calculates mean points to improve accuaracy
            //Unfortunately the result is not very good, so, since I know better I manually set these
            //mean points.
            lst.SetMeanPoints(new SharpMap.Geometries.Point(0, 0), 
                              new SharpMap.Geometries.Point(matrix.OffsetX, matrix.OffsetY));
             */

            //Create Affine
            AffineCoordinateTransformation2D at2 = new AffineCoordinateTransformation2D(lst.GetAffineTransformation());

            //Create Map
            SharpMap.Map map = new SharpMap.Map(new System.Drawing.Size(720, 360));

            //Add not transformed layer
            map.Layers.Add(new SharpMap.Layers.VectorLayer("L1",
                                                           new SharpMap.Data.Providers.GeometryFeatureProvider(fdt1)));
            ((SharpMap.Layers.VectorLayer) map.Layers[0]).Style.Symbol =
                new System.Drawing.Bitmap(@"..\..\..\DemoWinForm\Resources\flag.png");

            //Add transformed layer
            map.Layers.Add(new SharpMap.Layers.VectorLayer("L2",
                                                           new SharpMap.Data.Providers.GeometryFeatureProvider(fdt2)));
            ((SharpMap.Layers.VectorLayer) map.Layers[1]).Style.Symbol =
                new System.Drawing.Bitmap(@"..\..\..\DemoWinForm\Resources\women.png");

            //we want to reverse the previously applied transformation.
            ((SharpMap.Layers.VectorLayer) map.Layers[1]).CoordinateTransformation = (AffineCoordinateTransformation2D)at2.Inverse();

            //Render map
            map.ZoomToExtents();

            //Get map and save to file
            System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)map.GetMap();
            bmp.Save("affinetransform.bmp");
            //Hopefully women cover flags ;-).

        }
    }
}

Hth

FObermaier

Sep 15, 2010 at 3:41 PM

 

Very nice example Fob!..  but what happens if i need to transform twice ?   in the sense that i've already a transformation...  then i would like to execute even this one...

Does it exist a sort of list of transformation?  i remembers something ? is it right??

 

Alberto

Coordinator
Sep 15, 2010 at 8:17 PM

Alberto,

you want to use this transform in a regular Proj.NET transform process? Or just two affine transforms in a row?

FObermaier

Sep 16, 2010 at 8:30 AM

Helo,

the final  result would be this one:

 

1) apply this affine transformation to WGS84 Plate Carrè projected data, that simply translate the data of some degree in some direction....

2) apply a projection in order to project using a sort of "google like transformation"....

 

i'm doing something like this...  but i don't know if it is ok!

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProjNet.CoordinateSystems.Transformations;

namespace XXX.Map.GIS.Factories.CoordinateTransformation
{
    /// <summary>
    /// Rappresent a Coordinate TransformChain
    /// </summary> 
    public class CoordinateTransformationChain : ICoordinateTransformation
    {
        #region Members
        
        /// <summary>
        ///  ICoordinateTranformation Chain to aplly
        /// </summary>
        private List<ICoordinateTransformation> _iCoordinateTransformationChain = null; 

        #endregion

        #region Properties
        
        /// <summary>
        /// Gets or Sets the ICoordinateTranformation Chain to aplly
        /// </summary>
        public List<ICoordinateTransformation> ICoordinateTransformationChain
        {
            get { return _iCoordinateTransformationChain; }
            set { _iCoordinateTransformationChain = value; }
        } 

        #endregion
        
        #region Constructors

        /// <summary>
        /// Create a new ICoordinate Transformation basing on the math transform of the base!
        /// </summary>
        /// <param name="iCoordinateTransformationChain"></param>
        public CoordinateTransformationChain(List<ICoordinateTransformation> iCoordinateTransformationChain)
        {
            _iCoordinateTransformationChain = iCoordinateTransformationChain;
        }

        #endregion

        #region ICoordinateTransformation Members

        public string AreaOfUse
        {
            get { throw new NotImplementedException(); }
        }

        public string Authority
        {
            get { throw new NotImplementedException(); }
        }

        public long AuthorityCode
        {
            get { throw new NotImplementedException(); }
        }

        public IMathTransform MathTransform
        {
            get { throw new NotImplementedException(); }
        }

        public string Name
        {
            get { throw new NotImplementedException(); }
        }

        public string Remarks
        {
            get { throw new NotImplementedException(); }
        }

        public ProjNet.CoordinateSystems.ICoordinateSystem SourceCS
        {
            get { throw new NotImplementedException(); }
        }

        public ProjNet.CoordinateSystems.ICoordinateSystem TargetCS
        {
            get { throw new NotImplementedException(); }
        }

        public TransformType TransformType
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }
}

 

Sep 16, 2010 at 8:32 AM

p.s. of course i'll provide then the final "chained" transformation to a Sharp Map Layer...   in order to transform layer's data

Coordinator
Sep 16, 2010 at 10:38 AM

Alberto,

Proj.Net has an internal class called ConcatenatedTransform. I think you should be all set if you mark that as public , add the AffineTransformation and the transformation to google projection and assign that to your layer

Hth FObermaier

Sep 16, 2010 at 10:42 AM

Yes a saw that class but was marked as "internal"...   should be nice to mark as public ;)  even under sub version?   what you think? 

I'll try that....   (in the class i've put over i was taking code from that classes in the end... )

Coordinator
Sep 16, 2010 at 11:54 AM

Alberto, you can always issue a feature request on Proj.NET

Cheers FObermaier

Feb 15, 2011 at 12:40 AM

Hi @ALL

I started to work on my project after a long pause and today I'm trying to develop the affine transformation, but I not founded the package SharpMap.CoordinateSystem.

I tried with ProjNet, but if run

            SharpMap.Geometries.Polygon poly = ProjNet.CoordinateSystems.Transformations.GeometryTransform.TransformPolygon(pol, HELPME);

the compilation failed with:

C:\Documents and Settings\Tex\Documenti\Visual Studio 2008\Projects\UGR\UGR\Main.cs(673,61): error CS0234: The type or namespace name 'IMathTransform' does not exist in the namespace 'ProjNet.CoordinateSystems.Transformations' (are you missing an assembly reference?)

I'm using SharpMap 0.9 (update 2010-10-21) and in my project there are ShrpMap.dll (0.9.0.0), ProjNet.dll (1.2.0.0) and BruTile.dll (0.4.0.0).

Where am I doing wrong?

Good life

Coordinator
Feb 15, 2011 at 4:03 PM

Hello texamicomio,

please get the sharpmap source from the repository and compile the solution yourself. Regarding the codesnipplet from above,

public class AffineCoordinateTransformation2D : SharpMap.CoordinateSystems.Transformations.MathTransform, SharpMap.CoordinateSystems.Transformations.ICoordinateTransformation

should be changed to

public class AffineCoordinateTransformation2D : ProjNet.CoordinateSystems.Transformations.MathTransform, ProjNet.CoordinateSystems.Transformations.ICoordinateTransformation

Hth FObermaier

Feb 24, 2011 at 12:59 AM

Hi @ALL

I written ("copied" is the correct word) LeastSquaresTransform and AffineCoordinateTransformation2D.

My transformation method is:

        public void transformLayer()
        {
            //Get affine transformation with LeastSquaresTransform
            SharpMap.Utilities.LeastSquaresTransform lst = new SharpMap.Utilities.LeastSquaresTransform();

            for (int i = 0; i < pointListRef.Count; i++)
                lst.AddInputOutputPoint(pointListRef[i].point, pointListOut[i].point);

            AffineCoordinateTransformation2D at2 = new AffineCoordinateTransformation2D(lst.GetAffineTransformation());

            String tabella = sheetsMan.getLayerByID(idLayerToTransform).tabella;
            String colonna = sheetsMan.getLayerByID(idLayerToTransform).colonna;
            int indexLayer = map.getIndexLayerByName(tabella + "_" + colonna);
            map.getLayer(indexLayer).CoordinateTransformation = (AffineCoordinateTransformation2D)at2;

            map.refresh();
        }

but after the refresh function on my map, the layer map.getLayer(indexLayer) is transformed, and is not visible on the GUI.

Where is my error?

Tanx

Coordinator
Feb 24, 2011 at 8:31 AM

hello texamicomio,

what are the elements of the transformation matrix.

try either

map.ZoomToExtents()

or

map.ZoomToBox(map.getLayer(indexLayer).GetExtents())

cheers FObermaier

 

Feb 26, 2011 at 10:58 AM

There Is a wrapper class that gets the points for transformation matrix calculate. The for cycle

            for (int i = 0; i < pointListRef.Count; i++)
                lst.AddInputOutputPoint(pointListRef[i].point, pointListOut[i].point);

sets the point list at LeastSquaresTransform instance.

I trying with map.ZoomToExtents(), but I have the same result (my map.refresh() execute a zoom also).

My unique modify at your code is in AffineCoordinateTransformation2D class where I'm commented the NotImplementedException

        public override void Invert()
        {
            //throw new System.NotImplementedException();
        }

When I perform the zoom on tha map after the transformation, in this function there is an exception. But this is an override function: What should I put in this function?

I'm very confused.

Please help me.

Coordinator
Feb 28, 2011 at 9:03 AM
Edited Feb 28, 2011 at 2:06 PM

Your AffineTransformation2D class needs a private boolean field called isInverse.

On every call to the Invert function you need to change its value.

In the Transform function you need to check for isInverse and for the case it is true you need to implement the inverse transformation.

Hth FObermaier

Mar 1, 2011 at 12:50 AM

I inserted the property "isInverse"

        protected bool isInverse = false;

my Invert function:

        public override void Invert()
        {
            isInverse = !isInverse;
        }

my Transform function:

        public SharpMap.Geometries.Point Transform(SharpMap.Geometries.Point point)
        {
            SharpMap.Geometries.Point ret = new SharpMap.Geometries.Point();
            ret.X = _a * point.X + _b * point.Y + _c;
            ret.Y = _d * point.X + _e * point.Y + _f;
            return ret;
        }

but, with a breakpoint, in debug mode, the Transform function is not called.

The transformed layer is disappeared.

If you can see this page https://sites.google.com/site/mapoverlay/2 I report a view of my application after the transformation and the watch in debug of AffineCoordinateTransformation2D instance.

Best regards.

TANX.

Coordinator
Mar 1, 2011 at 8:47 AM

The Invert() function is an abstract function of ProjNet's MathTransform class, so you must override it. For AffineTransformation2D the implementation you used is fine.

The transfrom function has the wrong signature, that is why it is not called. It must be

        public override double[] Transform(double[] point)
        {
            /*
            Converting from input (X,Y) to output coordinate system (X',Y') is done by:
            X' = a*X + b*Y + c, 
            Y' = d*X + e*Y + f
             */
            System.Diagnostics.Debug.Assert(point.Length == 2);
            System.Double[] ret = new System.Double[2];
            ret[0] = _a*point[0] + _b*point[1] + _c;
            ret[1] = _d*point[0] + _e*point[1] + _f;

            return ret;
        }

(see code above). Now in this routine you must branch depending on isInverse.

If you know how to determine the coefficients for the inverse transformation, fine, if not you could e.g. use NPack (http://npack.codeplex.com) or ALGLIB (http://www.alglib.net/) to setup a matrix with values _a, _b, _c, _d, _e and _f and let those libraries compute the inverse matrix and then assign the values to e.g. private double _ainv = m[0,0];

Hth FObermaier

Mar 3, 2011 at 1:08 AM

As Homer Simpson says: "DOH!".

I have two Transform functions, one with double[] and one with Point in input. Do you think it's correct the function looks like this?

        public override double[] Transform(double[] point)
        {
            System.Diagnostics.Debug.Assert(point.Length == 2);
            System.Double[] ret = new System.Double[2];
            if (!isInverse)
            {
                ret[0] = _a * point[0] + _b * point[1] + _c;
                ret[1] = _d * point[0] + _e * point[1] + _f;
            }
            else
            {
                ret[0] = _ainv * point[0] + _binv * point[1] + _cinv;
                ret[1] = _dinv * point[0] + _einv * point[1] + _finv;
            }

            return ret;
        }?

The inverted coefficients were calculated in the costructor as:

            System.Drawing.Drawing2D.Matrix m = new System.Drawing.Drawing2D.Matrix((float)_a, (float)_b, (float)_d, (float)_e, (float)_c, (float)_f);
            if (m.IsInvertible)
            {
                m.Invert();
                _ainv = m.Elements[0];
                _binv = m.Elements[1];
                _cinv = m.Elements[2];
                _dinv = m.Elements[3];
                _einv = m.Elements[4];
                _finv = m.Elements[5];
            }

I found an interesting thing: if I do zoom out many times, the transformed layer appears. With the debug, the function TransformList is called only when the layer appears. I view the source code of SharpMap and this function is called in GeometryTransform class.
Now I think the problem is an "render area" too small (some BoundingBox?). It's possible?
You can view the screen shot at https://sites.google.com/site/mapoverlay/3
Do you have any idea?

Coordinator
Mar 3, 2011 at 8:53 AM

I don't know for sure, but with using System.Drawing.Drawing2D.Matrix you only calculate single precision coefficients. That might lead to the wrong calculation of the bounding box to display.

TransfromList is only called for lineal geometries or multipoints. I don't know what kind of geometries you have and how much there are. If it is just one Point the scenario pointed out above is very likely.

Have you tried applying the inverse of the affine transformation to your layers CoordinateTransformation? maybe that works better?

Hth FObermaier

Mar 8, 2011 at 6:11 PM

Hi FObermaier,
I finally had to make the layer's affine transformation. The problem is an traslation after the affine transformation.

    public void adaptTraslation(SharpMap.Geometries.Point pin, SharpMap.Geometries.Point pout)
    {
        SharpMap.Geometries.Point pin_t = new SharpMap.Geometries.Point(_a * pin.X + _b * pin.Y, _d * pin.X + _e * pin.Y);
        traslation = new SharpMap.Geometries.Point(pin_t.X - pin.X + (pin.X - pout.X), pin_t.Y - pin.Y + (pin.Y - pout.Y));
    }

        public override double[] Transform(double[] point)
        {
            System.Diagnostics.Debug.Assert(point.Length == 2);
            System.Double[] ret = new System.Double[2];

            ret[0] = _a * point[0] + _b * point[1] - traslation.X;
            ret[1] = _d * point[0] + _e * point[1] - traslation.Y;

            return ret;
        }

pin e pout are the firsts points selected by the user.

I have 2 problem again:

1) if you see the link https://sites.google.com/site/mapoverlay/4

How can I not make disappears the layer?

2) if I want save the transformated layer on the database (SQL Server), How?

Thank you at all for your endless patience.

Coordinator
Mar 8, 2011 at 7:58 PM

Before I can answer your questions, i need to know

  • where  your data comes from(which provider) and
  • what kind of geometries you are applying the transformation on

For storing the geometries to your database you have to provide the code yourself. Maybe SharpMap.SqlServerSpatialObjects can be of some assistance.

SharpMap v2's providers are updatable, you should be able to find some code there.

Hth FObermaier

Mar 10, 2011 at 12:16 AM

Hi,

the layers that can be transformed come from shape file or drawing with a tool available by the application. The geometries that I accept are all the kinds: point, lines, polygons, multipoint, ecc.

I can write code myself, but I can not find a way to extract the complete list of transformed geometries from a vector layer.

I'm using SharpMap v. 0.9... I have to upgrade my application to version 2?

Coordinator
Mar 10, 2011 at 8:42 AM

Something like this:

var oids = provider.GetObjectIdsInView(provider.GetExtents());
foreach (var oid in oids)
{
var geom = provider.GetGeometryByOid(oid);
//Apply AffineTransformation
var tgeom = GeometryTransform.TransformGeometry(geom, affineTransform);

InsertOrUpdate(oid, tgeom);
}

This code has not seen a compiler. InsertOrUpdate would be your part :)

Hth FObermaier