zoukankan      html  css  js  c++  java
  • arcgis for silverlight 加载GoogleMap 或 BingMap

    arcgis for silverlight 加载GoogleMap 或 BingMap  可以使用重载 TiledMapServiceLayer

    对于silverlight内的地图进行截屏操作时,会出现跨域问题,目前我的解决方式就是,将加载切片

    数据交给本地服务端,本地服务端加载后的图片再给silverlight,这样就不会出现跨域问题,而无法截屏了

    GoogleMap:

    /// <summary>
        /// Google Title System layer (Google 地图切片系统图层)
        /// </summary>
        public class GoogleMapTileLayer : TiledMapServiceLayer
        {
            /// <summary>
            /// 初始化
            /// </summary>
            public override void Initialize()
            {
                //全图范围
                this.FullExtent = new Envelope(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787);
                {
                    SpatialReference = new SpatialReference(102113);
                };
                //空间投影
                this.SpatialReference = new SpatialReference(102113);
                //切片信息
                this.TileInfo = new TileInfo()
                {
                    Height = 256,
                    Width = 256,
                    Origin = new MapPoint(-20037508.342787, 20037508.342787)
                    {
                        SpatialReference = new SpatialReference(102113)
                    },
                    Lods = new Lod[20]
                };
                double resolution = 156543.033928;
                for (int i = 0; i < TileInfo.Lods.Length; i++)
                {
                    TileInfo.Lods[i] = new Lod() { Resolution = resolution };
                    resolution /= 2;
                }
                //加载
                base.Initialize();
            }
            /// <summary>
            /// Google 切片地址
            /// </summary>
            private static string basicGoogleTitleUrl = "http://mt{0}.google.cn/vt/lyrs=m@156000000&hl=zh-CN&x=";
    
            /// <summary>
            /// 服务器随机数
            /// </summary>
            private static Random RandomTitle = new Random(DateTime.Now.Second);
    
            /// <summary>
            /// 获取切片地址
            /// </summary>
            /// <param name="level"></param>
            /// <param name="row"></param>
            /// <param name="col"></param>
            /// <returns></returns>
            public override string GetTileUrl(int level, int row, int col)
            {
                int Server = RandomTitle.Next(0, 4);
                string url = string.Format(basicGoogleTitleUrl, Server);
                url = url + col.ToString() + "&y=" + row.ToString() + "&z=" + level.ToString() + "&s=";
                return url;
            }
        }

    BingMap:

    /// <summary>
        /// BingMap Title System layer (Google 地图切片系统图层)
        /// </summary>
        public class BingMapTileLayer : TiledMapServiceLayer
        {
    
            /// <summary>
            /// 经纬度转墨卡托
            /// </summary>
            /// <param name="lonLat"></param>
            /// <returns></returns>
            public MapPoint lonLat2Mercator(MapPoint lonLat)
            {
                MapPoint mercator = new MapPoint();
                double x = lonLat.X * 20037508.34 / 180;
                double y = Math.Log(Math.Tan((90 + lonLat.Y) * Math.PI / 360)) / (Math.PI / 180);
                y = y * 20037508.34 / 180;
                mercator.X = x;
                mercator.Y = y;
                return mercator;
            }
    
            /// <summary>
            /// 初始化
            /// </summary>
            public override void Initialize()
            {
    
                MapPoint minPoint = new MapPoint(TileSystem.MinLongitude, TileSystem.MinLatitude);
    
                minPoint = lonLat2Mercator(minPoint);
    
                minPoint.SpatialReference = new ESRI.ArcGIS.Client.Geometry.SpatialReference(102113);
    
                MapPoint maxPoint = new MapPoint(TileSystem.MaxLongitude, TileSystem.MaxLatitude);
    
                maxPoint = lonLat2Mercator(maxPoint);
                maxPoint.SpatialReference = new ESRI.ArcGIS.Client.Geometry.SpatialReference(102113);
    
                //全图范围
                this.FullExtent = new Envelope(minPoint, maxPoint);
                {
                    SpatialReference = new SpatialReference(102113);
                };
                //空间投影
                this.SpatialReference = new SpatialReference(102113);
                //切片信息
                this.TileInfo = new TileInfo()
                {
                    Height = 256,
                    Width = 256,
                    Origin = new MapPoint(-20037508.342787, 20037508.342787)
                    {
                        SpatialReference = new SpatialReference(102113)
                    },
                    Lods = new Lod[23]
                };
                double resolution = 39135.7585 * 4;
                for (int i = 0; i < TileInfo.Lods.Length; i++)
                {
                    TileInfo.Lods[i] = new Lod() { Resolution = resolution };
                    resolution /= 2;
                }
                //加载
                base.Initialize();
            }
            /// <summary>
            /// BingMap 切片地址(由本地页面加载切片,可以使用silverlight的截屏功能,而不会出现权限错误)
            /// </summary>
            private static string basicbingTitleUrl = "http://localhost:18839/BingMapUrl.aspx?r{1}.png?g=94&mkt=zh-cn&b={0}";
    
            /// <summary>
            /// 服务器随机数
            /// </summary>
            private static Random RandomTitle = new Random(DateTime.Now.Second);
    
            /// <summary>
            /// 获取切片地址
            /// </summary>
            /// <param name="level"></param>
            /// <param name="row"></param>
            /// <param name="col"></param>
            /// <returns></returns>
            public override string GetTileUrl(int level, int row, int col)
            {
                return GetUri(level, col, row);
            }
    
    
    
            public string GetUri(int tileLevel, int tilePositionX, int tilePositionY)
            {
                var quadKey = TileSystem.TileXYToQuadKey(tilePositionX, tilePositionY, tileLevel);
                if (string.IsNullOrEmpty(quadKey))
                    quadKey = "0";
                return string.Format(basicbingTitleUrl, RandomTitle.Next(0, 3), quadKey);
            }
        }

    TileSystem:

    /// <summary>
        /// 切片系统
        /// </summary>
        static class TileSystem
        {
            public const double EarthRadius = 6378137;
            public const double MinLatitude = -85.05112878;
            public const double MaxLatitude = 85.05112878;
            public const double MinLongitude = -180;
            public const double MaxLongitude = 180;
    
    
            /// <summary>
            /// Clips a number to the specified minimum and maximum values.
            /// </summary>
            /// <param name="n">The number to clip.</param>
            /// <param name="minValue">Minimum allowable value.</param>
            /// <param name="maxValue">Maximum allowable value.</param>
            /// <returns>The clipped value.</returns>
            private static double Clip(double n, double minValue, double maxValue)
            {
                return Math.Min(Math.Max(n, minValue), maxValue);
            }
    
    
    
            /// <summary>
            /// Determines the map width and height (in pixels) at a specified level
            /// of detail.
            /// </summary>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
            /// to 23 (highest detail).</param>
            /// <returns>The map width and height in pixels.</returns>
            public static uint MapSize(int levelOfDetail)
            {
                return (uint)256 << levelOfDetail;
            }
    
    
    
            /// <summary>
            /// Determines the ground resolution (in meters per pixel) at a specified
            /// latitude and level of detail.
            /// </summary>
            /// <param name="latitude">Latitude (in degrees) at which to measure the ground resolution.</param>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) to 23 (highest detail).</param>
            /// <returns>The ground resolution, in meters per pixel.</returns>
            public static double GroundResolution(double latitude, int levelOfDetail)
            {
                latitude = Clip(latitude, MinLatitude, MaxLatitude);
                return Math.Cos(latitude * Math.PI / 180) * 2 * Math.PI * EarthRadius / MapSize(levelOfDetail);
            }
    
    
    
            /// <summary>
            /// Determines the map scale at a specified latitude, level of detail,
            /// and screen resolution.
            /// </summary>
            /// <param name="latitude">Latitude (in degrees) at which to measure the
            /// map scale.</param>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
            /// to 23 (highest detail).</param>
            /// <param name="screenDpi">Resolution of the screen, in dots per inch.</param>
            /// <returns>The map scale, expressed as the denominator N of the ratio 1 : N.</returns>
            public static double MapScale(double latitude, int levelOfDetail, int screenDpi)
            {
                return GroundResolution(latitude, levelOfDetail) * screenDpi / 0.0254;
            }
    
    
    
            /// <summary>
            /// Converts a point from latitude/longitude WGS-84 coordinates (in degrees)
            /// into pixel XY coordinates at a specified level of detail.
            /// </summary>
            /// <param name="latitude">Latitude of the point, in degrees.</param>
            /// <param name="longitude">Longitude of the point, in degrees.</param>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
            /// to 23 (highest detail).</param>
            /// <param name="pixelX">Output parameter receiving the X coordinate in pixels.</param>
            /// <param name="pixelY">Output parameter receiving the Y coordinate in pixels.</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>
            /// Converts a pixel from pixel XY coordinates at a specified level of detail
            /// into latitude/longitude WGS-84 coordinates (in degrees).
            /// </summary>
            /// <param name="pixelX">X coordinate of the point, in pixels.</param>
            /// <param name="pixelY">Y coordinates of the point, in pixels.</param>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
            /// to 23 (highest detail).</param>
            /// <param name="latitude">Output parameter receiving the latitude in degrees.</param>
            /// <param name="longitude">Output parameter receiving the longitude in degrees.</param>
            public static void PixelXYToLatLong(int pixelX, int pixelY, int levelOfDetail, out double latitude, out double longitude)
            {
                double mapSize = MapSize(levelOfDetail);
                double x = (Clip(pixelX, 0, mapSize - 1) / mapSize) - 0.5;
                double y = 0.5 - (Clip(pixelY, 0, mapSize - 1) / mapSize);
    
                latitude = 90 - 360 * Math.Atan(Math.Exp(-y * 2 * Math.PI)) / Math.PI;
                longitude = 360 * x;
            }
    
    
    
            /// <summary>
            /// Converts pixel XY coordinates into tile XY coordinates of the tile containing
            /// the specified pixel.
            /// </summary>
            /// <param name="pixelX">Pixel X coordinate.</param>
            /// <param name="pixelY">Pixel Y coordinate.</param>
            /// <param name="tileX">Output parameter receiving the tile X coordinate.</param>
            /// <param name="tileY">Output parameter receiving the tile Y coordinate.</param>
            public static void PixelXYToTileXY(int pixelX, int pixelY, out int tileX, out int tileY)
            {
                tileX = pixelX / 256;
                tileY = pixelY / 256;
            }
    
    
    
            /// <summary>
            /// Converts tile XY coordinates into pixel XY coordinates of the upper-left pixel
            /// of the specified tile.
            /// </summary>
            /// <param name="tileX">Tile X coordinate.</param>
            /// <param name="tileY">Tile Y coordinate.</param>
            /// <param name="pixelX">Output parameter receiving the pixel X coordinate.</param>
            /// <param name="pixelY">Output parameter receiving the pixel Y coordinate.</param>
            public static void TileXYToPixelXY(int tileX, int tileY, out int pixelX, out int pixelY)
            {
                pixelX = tileX * 256;
                pixelY = tileY * 256;
            }
    
    
    
            /// <summary>
            /// Converts tile XY coordinates into a QuadKey at a specified level of detail.
            /// </summary>
            /// <param name="tileX">Tile X coordinate.</param>
            /// <param name="tileY">Tile Y coordinate.</param>
            /// <param name="levelOfDetail">Level of detail, from 1 (lowest detail)
            /// to 23 (highest detail).</param>
            /// <returns>A string containing the QuadKey.</returns>
            public static string TileXYToQuadKey(int tileX, int tileY, int levelOfDetail)
            {
                StringBuilder quadKey = new StringBuilder();
                for (int i = levelOfDetail; i > 0; i--)
                {
                    char digit = '0';
                    int mask = 1 << (i - 1);
                    if ((tileX & mask) != 0)
                    {
                        digit++;
                    }
                    if ((tileY & mask) != 0)
                    {
                        digit++;
                        digit++;
                    }
                    quadKey.Append(digit);
                }
                return quadKey.ToString();
            }
    
    
    
            /// <summary>
            /// Converts a QuadKey into tile XY coordinates.
            /// </summary>
            /// <param name="quadKey">QuadKey of the tile.</param>
            /// <param name="tileX">Output parameter receiving the tile X coordinate.</param>
            /// <param name="tileY">Output parameter receiving the tile Y coordinate.</param>
            /// <param name="levelOfDetail">Output parameter receiving the level of detail.</param>
            public static void QuadKeyToTileXY(string quadKey, out int tileX, out int tileY, out int levelOfDetail)
            {
                tileX = tileY = 0;
                levelOfDetail = quadKey.Length;
                for (int i = levelOfDetail; i > 0; i--)
                {
                    int mask = 1 << (i - 1);
                    switch (quadKey[levelOfDetail - i])
                    {
                        case '0':
                            break;
    
                        case '1':
                            tileX |= mask;
                            break;
    
                        case '2':
                            tileY |= mask;
                            break;
    
                        case '3':
                            tileX |= mask;
                            tileY |= mask;
                            break;
    
                        default:
                            throw new ArgumentException("Invalid QuadKey digit sequence.");
                    }
                }
            }
        }

    BingMapUrl.aspx.cs:

    public partial class BingMapUrl : System.Web.UI.Page
        {
    
            public Random random = new Random(DateTime.Now.Second);
    
            private const string BingMapHostUrl = "http://r{0}.tiles.ditu.live.com/tiles/";
    
            private const int BUFFERSIZE = 1048576;
    
            /// <summary>
            /// 页面加载
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    try
                    {
                        this.HandleMapPic();
                    }
                    catch (Exception ex)
                    {
                        Response.Write(ex.Message);
                    }
                }
            }
    
            /// <summary>
            /// 加载图片
            /// </summary>
            private void HandleMapPic()
            {
                string queryParams = Request.Url.Query;
    
                if (string.IsNullOrWhiteSpace(queryParams))
                    return;
                queryParams = queryParams.Substring(1, queryParams.Length - 1);
                string bingMapUrl = string.Format(BingMapHostUrl, random.Next(0, 3));
                string requestUrl = string.Concat(bingMapUrl, queryParams);
    
                HttpWebRequest webRequest = null;
    
                #region Prepare the request object
                webRequest = (HttpWebRequest)WebRequest.Create(Server.UrlDecode(requestUrl));
                webRequest.Method = Request.HttpMethod;
                webRequest.ContentType = Request.ContentType;
                #endregion Prepare the request object
    
                #region Cycle through and return output
                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                System.IO.Stream fileStream = webResponse.GetResponseStream();
                Byte[] buffer = new byte[1048576];
                int bytesRead = 1;
                while (bytesRead > 0)
                {
                    bytesRead = fileStream.Read(buffer, 0, BUFFERSIZE);
                    if (bytesRead == BUFFERSIZE)
                        Response.BinaryWrite(buffer);
                    else if (bytesRead > 0)
                    {
                        byte[] endBuffer = new byte[bytesRead];
                        Array.Copy(buffer, endBuffer, bytesRead);
                        Response.BinaryWrite(endBuffer);
                    }
                }
    
                fileStream.Dispose();
                webResponse.Close();
                #endregion Cycle through and return output
            }
        }
  • 相关阅读:
    容器技术问题
    URL和URL
    容器和注入技术
    云计算应用开发与实践读书 笔记(三)
    云计算应用开发与实践读书 笔记 (二 )
    云计算应用开发与实践读书 笔记
    C++学习之DLL注入
    c语言学习,模拟栈操作
    领悟百分比定位
    强大的第三方工具autoPrefixer
  • 原文地址:https://www.cnblogs.com/zhangbingCoder/p/3387289.html
Copyright © 2011-2022 走看看