相当当中 ,还用到一个很重要的类 ,map地图类

     前一段时间 ,在做一个GPS平台的项目 ,虽然不是很大

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WSGPSGateway.BLL
{
    public enum MapStyle
    {
        Road,
        Aerial,
        Hybrid
    }

    public enum MapLanguageVersion
    {
        Chinese,
        UnitedStates
    }

    /// <summary>
    /// A map displayed on the screen.
    /// </summary>
    public class Map
    {
        private int width, height;
        private int zoomLevel;
        /// <summary>
        /// The X-coordinate of the center of the map, in pixels, in world coordinates (at the current zoom level).
        /// </summary>
        private int x;
        /// <summary>
        /// The Y-coordinate of the center of the map, in pixels, in world coordinates (at the current zoom level).
        /// </summary>
        private int y;
        /// <summary>
        /// The latitude of the center of the map.
        /// </summary>
        private double latitude;
        /// <summary>
        /// The longitude of the center of the map.
        /// </summary>
        private double longitude;
        private MapStyle mapStyle;

        private const int earthRadius = 6378137;
        private const int buffer = 0/*100*/;
        private const double offsetMeters = 20971520;
        private const double baseMetersPerPixel = 163840;

        private const double MinLatitude = -85.05112878;
        private const double MaxLatitude = 85.05112878;
        private const double MinLongitude = -180;
        private const double MaxLongitude = 180;

        public Map()
        {

        }

        /// <summary>
        /// Minimum allowed zoom level
        /// </summary>
        public int MinimumZoom
        {
            get { return 3; }
        }

        /// <summary>
        /// Maximum allowed zoom level
        /// </summary>
        public int MaximumZoom
        {
            get { return 19; }
        }


        /// <summary>
        /// Gets or sets the latitude.
        /// </summary>
        /// <value>The latitude.</value>
        public double Latitude
        {
            get
            {
                if (double.IsNaN(latitude))
                {

                    // We have panned, so we must recalculate the latitude.
                    latitude = YToLatitudeAtZoom(Y, zoomLevel);
                }
                return latitude;
            }
            set
            {
                latitude = value;
                y = LatitudeToYAtZoom(latitude, zoomLevel);

            }
        }

        /// <summary>
        /// Gets or sets the longitude.
        /// </summary>
        /// <value>The longitude.</value>
        public double Longitude
        {
            get
            {
                if (double.IsNaN(longitude))
                {
                    // We have panned, so we must recalculate the longitude.
                    longitude = XToLongitudeAtZoom(X, zoomLevel);
                }
                return longitude;
            }
            set
            {
                longitude = value;
                x = LongitudeToXAtZoom(longitude, zoomLevel);
            }
        }


        /// <summary>
        /// The X-coordinate of the center of the map, in pixels,
        /// in world coordinates (at the current zoom level).
        /// </summary>
        public int X
        {
            get { return x; }
            set
            {
                x = value;
                // We don't bother recalculating the longitude until asked for.
                // So right now, we just invalidate it.
                longitude = double.NaN;
            }
        }

        /// <summary>
        /// The Y-coordinate of the center of the map, in pixels,
        /// in world coordinates (at the current zoom level).
        /// </summary>
        public int Y
        {
            get { return y; }
            set
            {
                y = value;
                // We don't bother recalculating the latitude until asked for.
                // So right now, we just invalidate it.
                latitude = double.NaN;
            }
        }

        /// <summary>
        /// The style of map (road, aerial, or hybrid).
        /// </summary>
        public MapStyle MapStyle
        {
            get { return mapStyle; }
            set { mapStyle = value; }
        }

        private MapLanguageVersion languageVersion;
        /// <summary>
        /// The version of map (chinese,us).
        /// </summary>
        public MapLanguageVersion LanguageVersion
        {
            get { return languageVersion; }
            set { languageVersion = value; }
        }

        /// <summary>
        /// The current zoom level.
        /// </summary>
        public int ZoomLevel
        {
            get { return zoomLevel; }
            set
            {
                // Make sure we have a valid lat/long at the old zoom level
                // before we change the zoom level.
                double lon = Longitude;
                double lat = Latitude;
                zoomLevel = value;
                //x = LongitudeToXAtZoom(lon, zoomLevel);
                //y = LatitudeToYAtZoom(lat, zoomLevel);
            }
        }

        /// <summary>
        /// Zooms the in.
        /// </summary>
        public void ZoomIn()
        {
            if (ZoomLevel < MaximumZoom)
            {
                ZoomLevel = ZoomLevel + 1;
                x = 2 * X;
                y = 2 * Y;
            }
        }

        /// <summary>
        /// Zooms the out.
        /// </summary>
        public void ZoomOut()
        {
            if (ZoomLevel > MinimumZoom)
            {
                ZoomLevel = ZoomLevel - 1;
                x = X / 2;
                y = Y / 2;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Map"/> class.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="latitude">The latitude.</param>
        /// <param name="longitude">The longitude.</param>
        /// <param name="zoomLevel">The zoom level.</param>
        /// <param name="mapStyle">The map style.</param>
        /// <param name="mlv">The MLV.</param>
        public Map(
            int width,
            int height,
            double latitude,
            double longitude,
            int zoomLevel,
            MapStyle mapStyle,
            MapLanguageVersion mlv)
        {
            this.width = width;
            this.height = height;
            this.zoomLevel = zoomLevel;
            this.Latitude = latitude;
            this.Longitude = longitude;
            this.MapStyle = mapStyle;
            this.LanguageVersion = mlv;
        }

        /// <summary>
        /// Lats the long to pixel XY.
        /// </summary>
        /// <param name="latitude">The latitude.</param>
        /// <param name="longitude">The longitude.</param>
        /// <param name="levelOfDetail">The level of detail.</param>
        /// <param name="pixelX">The pixel X.</param>
        /// <param name="pixelY">The pixel Y.</param>
        public static void LatLongToPixelXY(double latitude, double longitude, int levelOfDetail,
            out int pixelX, out int pixelY)
        {
            latitude = Clip(latitude, MinLatitude, MaxLatitude);
            longitude = Clip(longitude, MinLongitude, MaxLongitude);

            double x = (longitude + 180) / 360;
            double sinLatitude = Math.Sin(latitude * Math.PI / 180);
            double y = 0.5 - Math.Log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI);

            uint mapSize = MapSize(levelOfDetail);
            pixelX = (int)Clip(x * mapSize + 0.5, 0, mapSize - 1);
            pixelY = (int)Clip(y * mapSize + 0.5, 0, mapSize - 1);
        }


        /// <summary>
        /// Lats the long to tile XY.
        /// </summary>
        /// <param name="latitude">The latitude.</param>
        /// <param name="longitude">The longitude.</param>
        /// <param name="levelOfDetail">The level of detail.</param>
        /// <param name="tileX">The tile X.</param>
        /// <param name="tileY">The tile Y.</param>
        public static void LatLongToTileXY(double latitude, double longitude, int levelOfDetail, out int tileX, out int tileY)
        {
            int pixelX = 0;
            int pixelY = 0;

            LatLongToPixelXY(latitude, longitude, levelOfDetail, out pixelX, out pixelY);
            PixelXYToTileXY(pixelX, pixelY, out tileX, out tileY);
        }

        /// <summary>
        /// Pixels the XY to tile XY.
        /// </summary>
        /// <param name="pixelX">The pixel X.</param>
        /// <param name="pixelY">The pixel Y.</param>
        /// <param name="tileX">The tile X.</param>
        /// <param name="tileY">The tile Y.</param>
        public static void PixelXYToTileXY(int pixelX, int pixelY, out int tileX, out int tileY)
        {
            tileX = pixelX / 256;
            tileY = pixelY / 256;
        }


        /// <summary>
        /// Maps the size.
        /// </summary>
        /// <param name="levelOfDetail">The level of detail.</param>
        /// <returns></returns>
        public static uint MapSize(int levelOfDetail)
        {
            return (uint)256 << levelOfDetail;
        }

        /// <summary>
        /// Clips the specified n.
        /// </summary>
        /// <param name="n">The n.</param>
        /// <param name="minValue">The min value.</param>
        /// <param name="maxValue">The max value.</param>
        /// <returns></returns>
        private static double Clip(double n, double minValue, double maxValue)
        {
            return Math.Min(Math.Max(n, minValue), maxValue);
        }

        /// <summary>
        /// Meterses the per pixel.
        /// </summary>
        /// <param name="zl">The zl.</param>
        /// <returns></returns>
        private static double MetersPerPixel(int zl)
        {
            return baseMetersPerPixel / (1 << zl);
        }

        /// <summary>
        /// Ys to latitude at zoom.
        /// </summary>
        /// <param name="y">The y.</param>
        /// <param name="zl">The zl.</param>
        /// <returns></returns>
        private double YToLatitudeAtZoom(int y, int zl)
        {
            double metersY = Map.offsetMeters - y * MetersPerPixel(zl);
            return RadToDeg(Math.PI / 2 - 2 * Math.Atan(Math.Exp(-metersY / earthRadius)));
        }

        /// <summary>
        /// Xs to longitude at zoom.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="zl">The zl.</param>
        /// <returns></returns>
        private double XToLongitudeAtZoom(int x, int zl)
        {
            double metersX = x * MetersPerPixel(zl) - offsetMeters;
            return RadToDeg(metersX / earthRadius);
        }

        /// <summary>
        /// Longitudes to X at zoom.
        /// </summary>
        /// <param name="longitude">The longitude.</param>
        /// <param name="zl">The zl.</param>
        /// <returns></returns>
        private int LongitudeToXAtZoom(double longitude, int zl)
        {
            longitude = Clip(longitude, MinLongitude, MaxLongitude);

            double x = (longitude + 180) / 360;

            uint mapSize = MapSize(zl);
            return (int)Clip(x * mapSize + 0.5, 0, mapSize - 1);
        }


        /// <summary>
        /// Latitudes to Y at zoom.
        /// </summary>
        /// <param name="latitude">The latitude.</param>
        /// <param name="zl">The zl.</param>
        /// <returns></returns>
        private int LatitudeToYAtZoom(double latitude, int zl)
        {
            double sinLatitude = Math.Sin(latitude * Math.PI / 180);
            double y = 0.5 - Math.Log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI);

            uint mapSize = MapSize(zl);

            return (int)Clip(y * mapSize + 0.5, 0, mapSize - 1);
        }

        /// <summary>
        /// Degs to RAD.
        /// </summary>
        /// <param name="d">The d.</param>
        /// <returns></returns>
        private static double DegToRad(double d)
        {
            return d * Math.PI / 180.0;
        }

        /// <summary>
        /// RADs to deg.
        /// </summary>
        /// <param name="r">The r.</param>
        /// <returns></returns>
        private static double RadToDeg(double r)
        {
            return r * 180.0 / Math.PI;
        }

        public static double PixelXToLng(double pixelX, int zoom)
        {
            return pixelX * 360 / (256L << zoom) - 180;
        }

        public static double PixelYToLat(double pixelY, int zoom)
        {
            double y = 2 * Math.PI * (1 - pixelY / (128 << zoom));
            double z = Math.Pow(Math.E, y);
            double siny = (z - 1) / (z + 1);
            return Math.Asin(siny) * 180 / Math.PI;
        }
    }
}

。我是第一次做 ,所以为了给自己增加经验和多多总结的机会 ,所以将自己写的代码部分贴出来 。

原文地址:https://www.cnblogs.com/lelese7en/p/2074130.html