#region Disclaimer / License
// Copyright (C) 2010, Jackie Ng
// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using GeoAPI.CoordinateSystems.Transformations;
using GeoAPI.CoordinateSystems;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
namespace OSGeo.MapGuide.MaestroAPI.CoordinateSystem
{
///
/// A simple coordinate transformation interface
///
public interface ISimpleTransform : IDisposable
{
///
/// Transforms the specified point
///
/// The X coordinate
/// The Y coordinate
/// The transformed X coordinate
/// The transformed Y coordinate
void Transform(double x, double y, out double tx, out double ty);
}
///
/// A simple transform that wraps the NTS coordinate system transformation APIs
///
public class DefaultSimpleTransform : ISimpleTransform
{
private ICoordinateSystem _source;
private ICoordinateSystem _target;
private ICoordinateTransformation _trans;
const string CSMAP_WGS84_PSEUDO_MERCATOR = @"PROJCS[""WGS84.PseudoMercator"",GEOGCS[""LL84"",DATUM[""WGS84"",SPHEROID[""WGS84"",6378137.000,298.25722293]],PRIMEM[""Greenwich"",0],UNIT[""Degree"",0.017453292519943295]],PROJECTION[""Popular Visualisation Pseudo Mercator""],PARAMETER[""false_easting"",0.000],PARAMETER[""false_northing"",0.000],PARAMETER[""central_meridian"",0.00000000000000],UNIT[""Meter"",1.00000000000000]]";
// Proj.Net cannot handle the WGS84.PseudoMercator WKT. Here's an alternative WKT that is Proj.Net compatible and produces
// approximately similar results:
//
// http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/
//
const string POPULAR_VISUALISATION_CRS =
@"PROJCS[""Popular Visualisation CRS / Mercator"",
GEOGCS[""Popular Visualisation CRS"",
DATUM[""WGS84"",
SPHEROID[""WGS84"", 6378137.0, 298.257223563, AUTHORITY[""EPSG"",""7059""]],
AUTHORITY[""EPSG"",""6055""]],
PRIMEM[""Greenwich"", 0, AUTHORITY[""EPSG"", ""8901""]],
UNIT[""degree"", 0.0174532925199433, AUTHORITY[""EPSG"", ""9102""]],
AXIS[""E"", EAST], AXIS[""N"", NORTH], AUTHORITY[""EPSG"",""4055""]],
PROJECTION[""Mercator""],
PARAMETER[""semi_minor"",6378137],
PARAMETER[""False_Easting"", 0],
PARAMETER[""False_Northing"", 0],
PARAMETER[""Central_Meridian"", 0],
PARAMETER[""Latitude_of_origin"", 0],
UNIT[""metre"", 1, AUTHORITY[""EPSG"", ""9001""]],
AXIS[""East"", EAST], AXIS[""North"", NORTH],
AUTHORITY[""EPSG"",""3785""]]";
///
/// Initializes a new instance of the class.
///
/// The source cs WKT.
/// The target cs WKT.
internal DefaultSimpleTransform(string sourceCsWkt, string targetCsWkt)
{
//Check for and replace the WGS84.PseudoMercator WKT
string srcWkt = sourceCsWkt == CSMAP_WGS84_PSEUDO_MERCATOR ? POPULAR_VISUALISATION_CRS : sourceCsWkt;
string dstWkt = targetCsWkt == CSMAP_WGS84_PSEUDO_MERCATOR ? POPULAR_VISUALISATION_CRS : targetCsWkt;
var fact = new CoordinateSystemFactory();
_source = fact.CreateFromWkt(srcWkt);
_target = fact.CreateFromWkt(dstWkt);
var tfact = new CoordinateTransformationFactory();
_trans = tfact.CreateFromCoordinateSystems(_source, _target);
}
///
/// Transforms the specified point
///
/// The X coordinate
/// The Y coordinate
/// The transformed X coordinate
/// The transformed Y coordinate
public void Transform(double x, double y, out double tx, out double ty)
{
tx = Double.NaN;
ty = Double.NaN;
double [] pts = _trans.MathTransform.Transform(new double[] { x, y });
tx = pts[0];
ty = pts[1];
}
public void Dispose()
{
}
}
}