#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 System.Drawing; using ProjNet.CoordinateSystems; using GeoAPI.CoordinateSystems; using GeoAPI.Geometries; using GisSharpBlog.NetTopologySuite.Geometries; namespace OSGeo.MapGuide.MaestroAPI.CoordinateSystem { /// /// Represents a coordinate system instance /// internal abstract class CoordinateSystemBase { static ICoordinateSystemFactory _csFact; static CoordinateSystemBase() { _csFact = new CoordinateSystemFactory(); } public static CoordinateSystemBase Create(CoordinateSystemDefinitionBase csDef) { Check.NotNull(csDef, "csDef"); return Create(csDef.WKT); } public static CoordinateSystemBase Create(string csWkt) { Check.NotEmpty(csWkt, "csWkt"); return Create(_csFact.CreateFromWkt(csWkt)); } internal static CoordinateSystemBase Create(ICoordinateSystem coordSys) { CoordinateSystemBase csb = null; try { //This fails because the XY-M projection is not supported csb = new ActualCoordinateSystem(coordSys); } catch { } if (csb == null && coordSys != null) { IUnit unit = coordSys.GetUnits(0); if (unit is IAngularUnit) { double radians = (unit as IAngularUnit).RadiansPerUnit; csb = new DegreeBasedCoordinateSystem(); } else if (unit is ILinearUnit) csb = new MeterBasedCoordinateSystem(((ILinearUnit)unit).MetersPerUnit, ((ILinearUnit)unit).MetersPerUnit); } if (csb == null) csb = new MeterBasedCoordinateSystem(); return csb; } public abstract double MetersPerUnitX { get; } public abstract double MetersPerUnitY { get; } /// /// Calculates the scale of the map, given the bounding box and image size /// /// The map bounding box /// The size of the image /// The scale public double CalculateScale(ObjectModels.Common.IEnvelope bbox, Size size) { Check.NotNull(bbox, "bbox"); return CalculateScale(new Envelope(bbox.MinX, bbox.MaxX, bbox.MinY, bbox.MaxY), size); } /// /// Calculates the scale of the map, given the bounding box and image size /// /// The map bounding box /// The size of the image /// The scale protected abstract double CalculateScale(IEnvelope bbox, Size size); /// /// Adjusts the boundingbox to equal proportions /// /// The actual bounding box /// The scale to fit /// The size to fit to /// A bounding box with the correct ratio public ObjectModels.Common.IEnvelope AdjustBoundingBox(ObjectModels.Common.IEnvelope bbox, double scale, Size size) { Check.NotNull(bbox, "bbox"); var env = AdjustBoundingBox(new Envelope(bbox.MinX, bbox.MaxX, bbox.MinY, bbox.MaxY), scale, size); return OSGeo.MapGuide.ObjectModels.ObjectFactory.CreateEnvelope(env.MinX, env.MinY, env.MaxX, env.MaxY); } /// /// Adjusts the boundingbox to equal proportions /// /// The actual bounding box /// The scale to fit /// The size to fit to /// A bounding box with the correct ratio protected abstract IEnvelope AdjustBoundingBox(IEnvelope bbox, double scale, Size size); /// /// Calculates the distance from one point to another, in meters /// /// /// /// /// /// public double DistanceInMeters(double x1, double y1, double x2, double y2) { return DistanceInMeters( new GisSharpBlog.NetTopologySuite.Geometries.Point(x1, y1), new GisSharpBlog.NetTopologySuite.Geometries.Point(x2, y2)); } /// /// Calculates the distance from one point to another, in meters /// /// One point /// Another point /// The distance in meters protected abstract double DistanceInMeters(IPoint p1, IPoint p2); } }