private static void AddIfNotNull(ConcatenatedTransform concatTrans, ICoordinateTransformation trans)
 {
     if (trans != null)
     {
         concatTrans.CoordinateTransformationList.Add(trans);
     }
 }
        /// <summary>
        /// Geographic to geographic transformation
        /// </summary>
        /// <remarks>Adds a datum shift if nessesary</remarks>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        private static ICoordinateTransformation CreateGeog2Geog(IGeographicCoordinateSystem source, IGeographicCoordinateSystem target)
        {
            if (source.HorizontalDatum.EqualParams(target.HorizontalDatum))
            {
                //No datum shift needed
                return(new CoordinateTransformation(source,
                                                    target, TransformType.Conversion, new GeographicTransform(source, target),
                                                    String.Empty, String.Empty, -1, String.Empty, String.Empty));
            }
            else
            {
                //Create datum shift
                //Convert to geocentric, perform shift and return to geographic
                CoordinateTransformationFactory ctFac         = new CoordinateTransformationFactory();
                CoordinateSystemFactory         cFac          = new CoordinateSystemFactory();
                IGeocentricCoordinateSystem     sourceCentric = cFac.CreateGeocentricCoordinateSystem(source.HorizontalDatum.Name + " Geocentric",
                                                                                                      source.HorizontalDatum, LinearUnit.Metre, source.PrimeMeridian);
                IGeocentricCoordinateSystem targetCentric = cFac.CreateGeocentricCoordinateSystem(target.HorizontalDatum.Name + " Geocentric",
                                                                                                  target.HorizontalDatum, LinearUnit.Metre, source.PrimeMeridian);
                var ct = new ConcatenatedTransform();
                AddIfNotNull(ct, ctFac.CreateFromCoordinateSystems(source, sourceCentric));
                AddIfNotNull(ct, ctFac.CreateFromCoordinateSystems(sourceCentric, targetCentric));
                AddIfNotNull(ct, ctFac.CreateFromCoordinateSystems(targetCentric, target));


                return(new CoordinateTransformation(source,
                                                    target, TransformType.Transformation, ct,
                                                    String.Empty, String.Empty, -1, String.Empty, String.Empty));
            }
        }
 private static void SimplifyTrans(ConcatenatedTransform mtrans, ref List <ICoordinateTransformation> MTs)
 {
     foreach (ICoordinateTransformation t in mtrans.CoordinateTransformationList)
     {
         if (t is ConcatenatedTransform)
         {
             SimplifyTrans(t as ConcatenatedTransform, ref MTs);
         }
         else
         {
             MTs.Add(t);
         }
     }
 }
        private static ICoordinateTransformation Geoc2Geog(IGeocentricCoordinateSystem source, IGeographicCoordinateSystem target)
        {
            IMathTransform geocMathTransform = CreateCoordinateOperation(source).Inverse();

            if (source.PrimeMeridian.EqualParams(target.PrimeMeridian))
            {
                return(new CoordinateTransformation(source, target, TransformType.Conversion, geocMathTransform, String.Empty, String.Empty, -1, String.Empty, String.Empty));
            }
            else
            {
                var ct = new ConcatenatedTransform();
                ct.CoordinateTransformationList.Add(new CoordinateTransformation(source, target, TransformType.Conversion, geocMathTransform, String.Empty, String.Empty, -1, String.Empty, String.Empty));
                ct.CoordinateTransformationList.Add(new CoordinateTransformation(source, target, TransformType.Transformation, new PrimeMeridianTransform(source.PrimeMeridian, target.PrimeMeridian), String.Empty, String.Empty, -1, String.Empty, String.Empty));
                return(new CoordinateTransformation(source, target, TransformType.Conversion, ct, String.Empty, String.Empty, -1, String.Empty, String.Empty));
            }
        }
 private static ICoordinateTransformation Proj2Geog(IProjectedCoordinateSystem source, IGeographicCoordinateSystem target)
 {
     if (source.GeographicCoordinateSystem.EqualParams(target))
     {
         IMathTransform mathTransform = CreateCoordinateOperation(source.Projection, source.GeographicCoordinateSystem.HorizontalDatum.Ellipsoid, source.LinearUnit).Inverse();
         return(new CoordinateTransformation(source, target, TransformType.Transformation, mathTransform,
                                             String.Empty, String.Empty, -1, String.Empty, String.Empty));
     }
     else
     {   // Geographic coordinatesystems differ - Create concatenated transform
         ConcatenatedTransform           ct    = new ConcatenatedTransform();
         CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();
         ct.CoordinateTransformationList.Add(ctFac.CreateFromCoordinateSystems(source, source.GeographicCoordinateSystem));
         ct.CoordinateTransformationList.Add(ctFac.CreateFromCoordinateSystems(source.GeographicCoordinateSystem, target));
         return(new CoordinateTransformation(source,
                                             target, TransformType.Transformation, ct,
                                             String.Empty, String.Empty, -1, String.Empty, String.Empty));
     }
 }
        /// <summary>
        /// Geocentric to Geocentric transformation
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        private static ICoordinateTransformation CreateGeoc2Geoc(IGeocentricCoordinateSystem source, IGeocentricCoordinateSystem target)
        {
            var ct = new ConcatenatedTransform();

            //Does source has a datum different from WGS84 and is there a shift specified?
            if (source.HorizontalDatum.Wgs84Parameters != null && !source.HorizontalDatum.Wgs84Parameters.HasZeroValuesOnly)
            {
                ct.CoordinateTransformationList.Add(
                    new CoordinateTransformation(
                        ((target.HorizontalDatum.Wgs84Parameters == null || target.HorizontalDatum.Wgs84Parameters.HasZeroValuesOnly) ? target : GeocentricCoordinateSystem.WGS84),
                        source, TransformType.Transformation,
                        new DatumTransform(source.HorizontalDatum.Wgs84Parameters)
                        , "", "", -1, "", ""));
            }

            //Does target has a datum different from WGS84 and is there a shift specified?
            if (target.HorizontalDatum.Wgs84Parameters != null && !target.HorizontalDatum.Wgs84Parameters.HasZeroValuesOnly)
            {
                ct.CoordinateTransformationList.Add(
                    new CoordinateTransformation(
                        ((source.HorizontalDatum.Wgs84Parameters == null || source.HorizontalDatum.Wgs84Parameters.HasZeroValuesOnly) ? source : GeocentricCoordinateSystem.WGS84),
                        target,
                        TransformType.Transformation,
                        new DatumTransform(target.HorizontalDatum.Wgs84Parameters).Inverse()
                        , "", "", -1, "", ""));
            }

            //If we don't have a transformation in this list, return null
            if (ct.CoordinateTransformationList.Count == 0)
            {
                return(null);
            }
            //If we only have one shift, lets just return the datumshift from/to wgs84
            if (ct.CoordinateTransformationList.Count == 1)
            {
                return(new CoordinateTransformation(source, target, TransformType.ConversionAndTransformation, ct.CoordinateTransformationList[0].MathTransform, "", "", -1, "", ""));
            }

            return(new CoordinateTransformation(source, target, TransformType.ConversionAndTransformation, ct, "", "", -1, "", ""));
        }
        private static ICoordinateTransformation Proj2Proj(IProjectedCoordinateSystem source, IProjectedCoordinateSystem target)
        {
            var ct    = new ConcatenatedTransform();
            var ctFac = new CoordinateTransformationFactory();

            //First transform from projection to geographic
            ct.CoordinateTransformationList.Add(ctFac.CreateFromCoordinateSystems(source, source.GeographicCoordinateSystem));
            //Transform geographic to geographic:
            var geogToGeog = ctFac.CreateFromCoordinateSystems(source.GeographicCoordinateSystem,
                                                               target.GeographicCoordinateSystem);

            if (geogToGeog != null)
            {
                ct.CoordinateTransformationList.Add(geogToGeog);
            }
            //Transform to new projection
            ct.CoordinateTransformationList.Add(ctFac.CreateFromCoordinateSystems(target.GeographicCoordinateSystem, target));

            return(new CoordinateTransformation(source,
                                                target, TransformType.Transformation, ct,
                                                String.Empty, String.Empty, -1, String.Empty, String.Empty));
        }
        /// <summary>
        /// Creates transformation from source coordinate system to specified target system which is the fitted one
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        private static ICoordinateTransformation Any2Fitt(ICoordinateSystem source, IFittedCoordinateSystem target)
        {
            //Transform form base system of fitted to target coordinate system - use invered math transform
            IMathTransform invMt = CreateFittedTransform(target).Inverse();

            //case when source system is equal to base system of the fitted
            if (target.BaseCoordinateSystem.EqualParams(source))
            {
                //Transform form base system of fitted to target coordinate system
                return(CreateTransform(source, target, TransformType.Transformation, invMt));
            }

            ConcatenatedTransform ct = new ConcatenatedTransform();
            //First transform from source to base system of fitted
            CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();

            ct.CoordinateTransformationList.Add(ctFac.CreateFromCoordinateSystems(source, target.BaseCoordinateSystem));

            //Transform form base system of fitted to target coordinate system - use invered math transform
            ct.CoordinateTransformationList.Add(CreateTransform(target.BaseCoordinateSystem, target, TransformType.Transformation, invMt));

            return(CreateTransform(source, target, TransformType.Transformation, ct));
        }
        /// <summary>
        /// Creates transformation from fitted coordinate system to the target one
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        private static ICoordinateTransformation Fitt2Any(IFittedCoordinateSystem source, ICoordinateSystem target)
        {
            //transform from fitted to base system of fitted (which is equal to target)
            IMathTransform mt = CreateFittedTransform(source);

            //case when target system is equal to base system of the fitted
            if (source.BaseCoordinateSystem.EqualParams(target))
            {
                //Transform form base system of fitted to target coordinate system
                return(CreateTransform(source, target, TransformType.Transformation, mt));
            }

            //Transform form base system of fitted to target coordinate system
            ConcatenatedTransform ct = new ConcatenatedTransform();

            ct.CoordinateTransformationList.Add(CreateTransform(source, source.BaseCoordinateSystem, TransformType.Transformation, mt));

            //Transform form base system of fitted to target coordinate system
            CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();

            ct.CoordinateTransformationList.Add(ctFac.CreateFromCoordinateSystems(source.BaseCoordinateSystem, target));

            return(CreateTransform(source, target, TransformType.Transformation, ct));
        }