Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Math transform bug #20

Closed
HarelM opened this issue Oct 1, 2017 · 3 comments
Closed

Math transform bug #20

HarelM opened this issue Oct 1, 2017 · 3 comments
Projects

Comments

@HarelM
Copy link

HarelM commented Oct 1, 2017

The following is the code I'm using to create a math transform:

        public static IMathTransform Create()
        {
            var coordinateTransformFactory = new CoordinateTransformationFactory();
            var coordinateSystemFactory = new CoordinateSystemFactory();
            var itmParameters = new List<ProjectionParameter>
            {
                new ProjectionParameter("latitude_of_origin", 31.734393611111109123611111111111),
                new ProjectionParameter("central_meridian", 35.204516944444442572222222222222),
                new ProjectionParameter("false_northing", 626907.390),
                new ProjectionParameter("false_easting", 219529.584),
                new ProjectionParameter("scale_factor", 1.0000067)
            };

            var itmDatum = coordinateSystemFactory.CreateHorizontalDatum("Isreal 1993", DatumType.HD_Geocentric,
                Ellipsoid.GRS80, new Wgs84ConversionInfo(-24.0024, -17.1032, -17.8444, -0.33077, -1.85269, 1.66969, 5.4248));

            var itmGeo = coordinateSystemFactory.CreateGeographicCoordinateSystem("ITM", AngularUnit.Degrees, itmDatum,
                PrimeMeridian.Greenwich, new AxisInfo("East", AxisOrientationEnum.East), new AxisInfo("North", AxisOrientationEnum.North));

            var itmProjection = coordinateSystemFactory.CreateProjection("Transverse_Mercator", "Transverse_Mercator", itmParameters);
            var itm = coordinateSystemFactory.CreateProjectedCoordinateSystem("ITM", itmGeo, itmProjection, LinearUnit.Metre,
                new AxisInfo("East", AxisOrientationEnum.East), new AxisInfo("North", AxisOrientationEnum.North));

            var wgs84 = ProjectedCoordinateSystem.WGS84_UTM(36, true).GeographicCoordinateSystem;
            return coordinateTransformFactory.CreateFromCoordinateSystems(itm, wgs84).MathTransform;
        }

The following is the code, when I tried to run it from immediate window , _itmWgs84MathTransform is the an instance created with the above factory:

_itmWgs84MathTransform.Transform(new Coordinate(200000,600000))
Correct results:
{(34.999654105859982, 31.491929780294662, NaN)}
    CoordinateValue: {(34.999654105859982, 31.491929780294662, NaN)}
    X: 34.999654105859982
    Y: 31.491929780294662
    Z: NaN
_itmWgs84MathTransform.Inverse().Transform(new Coordinate(35,32))
Correct results:
{(200138.59858848609, 656336.21658061759, NaN)}
    CoordinateValue: {(200138.59858848609, 656336.21658061759, NaN)}
    X: 200138.59858848609
    Y: 656336.21658061759
    Z: NaN
Instance is now corrupted:
_itmWgs84MathTransform.Transform(new Coordinate(200000,600000))
Bad results:
{(2.9315235171991696, -27.2988002073075, NaN)}
    CoordinateValue: {(2.9315235171991696, -27.2988002073075, NaN)}
    X: 2.9315235171991696
    Y: -27.2988002073075
    Z: NaN

BTW calling the following code fixes the issue:
_itmWgs84MathTransform.Inverse().Inverse()

I can probably send a pull request if needed, assuming someone will direct me to the right place to look for this.

@HarelM
Copy link
Author

HarelM commented Oct 1, 2017

Further debug reveals the following in ConcatenatedTransform:
Items in the list are not cloned:

                public ConcatenatedTransform Clone()
		{
			var clonedList = new List<ICoordinateTransformation>(_coordinateTransformationList.Count);
			foreach (ICoordinateTransformation ct in _coordinateTransformationList)
				clonedList.Add(ct);
			return new ConcatenatedTransform(clonedList);
		}

Which causes the invert function to invert their math transform on the newly created instance:

		public override void Invert()
		{
			_coordinateTransformationList.Reverse();
			foreach (ICoordinateTransformation ic in _coordinateTransformationList)
				ic.MathTransform.Invert();
		}

I couldn't find a clone method ICoordinateTransformation, any thoughts?

@FObermaier
Copy link
Member

Using IMathTransform.Inverse() is known to be flaky.
Modify your factory IMathTransform Create() function to return either forward or inverse math transform objects and use those instead of Inverse().

@HarelM
Copy link
Author

HarelM commented Oct 2, 2017

This is my plan in order to workaround this issue, but fixing it inside this library is important in order for other people not to experience this issue.

@FObermaier FObermaier added this to Done in ProjNet V2 Mar 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
ProjNet V2
  
Done
Development

No branches or pull requests

2 participants