📄 mapprojection.cs
字号:
// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap 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 of the License, or
// (at your option) any later version.
//
// SharpMap 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 SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// SOURCECODE IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
/*
* Copyright (C) 2002 Urban Science Applications, Inc.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SharpMap.Geometries;
using SharpMap.CoordinateSystems;
using SharpMap.CoordinateSystems.Transformations;
using System.Text;
namespace SharpMap.CoordinateSystems.Projections
{
/// <summary>
/// Projections inherit from this abstract class to get access to useful mathematical functions.
/// </summary>
internal abstract class MapProjection : MathTransform, IProjection
{
protected bool _isInverse = false;
protected bool _isSpherical = false;
protected double _e;
protected double _es;
protected double _semiMajor;
protected double _semiMinor;
protected Collection<ProjectionParameter> _Parameters;
protected MathTransform _inverse;
protected MapProjection(Collection<ProjectionParameter> parameters, bool isInverse)
: this(parameters)
{
_isInverse = isInverse;
}
protected MapProjection(Collection<ProjectionParameter> parameters)
{
_Parameters = parameters;
//todo. Should really convert to the correct linear units??
ProjectionParameter semimajor = GetParameter("semi_major");
ProjectionParameter semiminor = GetParameter("semi_minor");
if(semimajor == null)
throw new ArgumentException("Missing projection parameter 'semi_major'");
if (semiminor == null)
throw new ArgumentException("Missing projection parameter 'semi_minor'");
this._semiMajor = semimajor.Value;
this._semiMinor = semiminor.Value;
this._isSpherical = (_semiMajor == _semiMinor);
this._es = 1.0 - (_semiMinor * _semiMinor ) / ( _semiMajor * _semiMajor);
this._e = Math.Sqrt(_es);
}
#region Implementation of IProjection
public ProjectionParameter GetParameter(int Index)
{
return this._Parameters[Index];
}
/// <summary>
/// Gets an named parameter of the projection.
/// </summary>
/// <remarks>The parameter name is case insensitive</remarks>
/// <param name="name">Name of parameter</param>
/// <returns>parameter or null if not found</returns>
public ProjectionParameter GetParameter(string name)
{
//return _Parameters.Find(delegate(ProjectionParameter par)
// { return par.Name.Equals(name, StringComparison.OrdinalIgnoreCase); });
for (int i = 0; i < _Parameters.Count; i++)
if (String.Equals(_Parameters[i].Name, name, StringComparison.OrdinalIgnoreCase))
return _Parameters[i];
return null;
}
public int NumParameters
{
get { return this._Parameters.Count; }
}
public string ClassName
{
get { return this.ClassName; }
}
private string _Abbreviation;
/// <summary>
/// Gets or sets the abbreviation of the object.
/// </summary>
public string Abbreviation
{
get { return _Abbreviation; }
set { _Abbreviation = value; }
}
private string _Alias;
/// <summary>
/// Gets or sets the alias of the object.
/// </summary>
public string Alias
{
get { return _Alias; }
set { _Alias = value; }
}
private string _Authority;
/// <summary>
/// Gets or sets the authority name for this object, e.g., "EPSG",
/// is this is a standard object with an authority specific
/// identity code. Returns "CUSTOM" if this is a custom object.
/// </summary>
public string Authority
{
get { return _Authority; }
set { _Authority = value; }
}
private long _Code;
/// <summary>
/// Gets or sets the authority specific identification code of the object
/// </summary>
public long AuthorityCode
{
get { return _Code; }
set { _Code = value; }
}
private string _Name;
/// <summary>
/// Gets or sets the name of the object.
/// </summary>
public string Name
{
get { return _Name; }
set { _Name = value; }
}
private string _Remarks;
/// <summary>
/// Gets or sets the provider-supplied remarks for the object.
/// </summary>
public string Remarks
{
get { return _Remarks; }
set { _Remarks = value; }
}
/// <summary>
/// Returns the Well-known text for this object
/// as defined in the simple features specification.
/// </summary>
public override string WKT
{
get
{
StringBuilder sb = new StringBuilder();
if (_isInverse)
sb.Append("INVERSE_MT[");
sb.AppendFormat("PARAM_MT[\"{0}\"", this.Name);
for (int i = 0; i < this.NumParameters; i++)
sb.AppendFormat(", {0}", this.GetParameter(i).WKT);
//if (!String.IsNullOrEmpty(Authority) && AuthorityCode > 0)
// sb.AppendFormat(", AUTHORITY[\"{0}\", \"{1}\"]", Authority, AuthorityCode);
sb.Append("]");
if (_isInverse)
sb.Append("]");
return sb.ToString();
}
}
/// <summary>
/// Gets an XML representation of this object
/// </summary>
public override string XML
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append("<CT_MathTransform>");
if (_isInverse)
sb.AppendFormat("<CT_InverseTransform Name=\"{0}\">", ClassName);
else
sb.AppendFormat("<CT_ParameterizedMathTransform Name=\"{0}\">", ClassName);
for (int i = 0; i < this.NumParameters; i++)
sb.AppendFormat(this.GetParameter(i).XML);
if (_isInverse)
sb.Append("</CT_InverseTransform>");
else
sb.Append("</CT_ParameterizedMathTransform>");
sb.Append("</CT_MathTransform>");
return sb.ToString();
}
}
#endregion
#region IMathTransform
public abstract SharpMap.Geometries.Point MetersToDegrees(SharpMap.Geometries.Point p);
public abstract SharpMap.Geometries.Point DegreesToMeters(SharpMap.Geometries.Point lonlat);
/// <summary>
/// Reverses the transformation
/// </summary>
public override void Invert()
{
_isInverse = !_isInverse;
}
/// <summary>
/// Returns true if this projection is inverted.
/// Most map projections define forward projection as "from geographic to projection", and backwards
/// as "from projection to geographic". If this projection is inverted, this will be the other way around.
/// </summary>
internal bool IsInverse
{
get { return _isInverse; }
}
public override SharpMap.Geometries.Point Transform(SharpMap.Geometries.Point cp)
{
Point projectedPoint = new Point();
if (!_isInverse)
return this.DegreesToMeters(cp);
else
return this.MetersToDegrees(cp);
}
public override Collection<SharpMap.Geometries.Point> TransformList(Collection<SharpMap.Geometries.Point> ord)
{
//Collection<SharpMap.Geometries.Point> result = new Collection<SharpMap.Geometries.Point>(ord.Count);
Collection<SharpMap.Geometries.Point> result = new Collection<SharpMap.Geometries.Point>();
for(int i=0; i<ord.Count; i++)
{
SharpMap.Geometries.Point point = ord[i];
result.Add(Transform(point));
}
return result;
}
/// <summary>
/// Checks whether the values of this instance is equal to the values of another instance.
/// Only parameters used for coordinate system are used for comparison.
/// Name, abbreviation, authority, alias and remarks are ignored in the comparison.
/// </summary>
/// <param name="obj"></param>
/// <returns>True if equal</returns>
public bool EqualParams(object obj)
{
if (!(obj is MapProjection))
return false;
MapProjection proj = obj as MapProjection;
if (proj.NumParameters != this.NumParameters)
return false;
for (int i = 0; i < _Parameters.Count; i++)
{
//ProjectionParameter param = _Parameters.Find(delegate(ProjectionParameter par) { return par.Name.Equals(proj.GetParameter(i).Name, StringComparison.OrdinalIgnoreCase); });
ProjectionParameter param = null;
for (int j = 0; j < proj.NumParameters; j++)
if (String.Equals(proj.GetParameter(j).Name, _Parameters[i].Name, StringComparison.OrdinalIgnoreCase))
param = proj.GetParameter(j);
if (param == null)
return false;
if (param.Value != proj.GetParameter(i).Value)
return false;
}
if (this.IsInverse != proj.IsInverse)
return false;
return true;
}
#endregion
#region Helper mathmatical functions
// defines some usefull constants that are used in the projection routines
/// <summary>
/// PI
/// </summary>
protected const double PI = Math.PI;
/// <summary>
/// Half of PI
/// </summary>
protected const double HALF_PI = (PI*0.5);
/// <summary>
/// PI * 2
/// </summary>
protected const double TWO_PI = (PI*2.0);
/// <summary>
/// EPSLN
/// </summary>
protected const double EPSLN = 1.0e-10;
/// <summary>
/// S2R
/// </summary>
protected const double S2R = 4.848136811095359e-6;
/// <summary>
/// MAX_VAL
/// </summary>
protected const double MAX_VAL = 4;
/// <summary>
/// prjMAXLONG
/// </summary>
protected const double prjMAXLONG = 2147483647;
/// <summary>
/// DBLLONG
/// </summary>
protected const double DBLLONG = 4.61168601e18;
/// <summary>
/// Returns the cube of a number.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -