zoukankan      html  css  js  c++  java
  • IS.NET客户端聚合GoogleMap浅析(三)处理页面的制作

      下面我们就来探讨一下处理页面的写法,熟悉Tilelayer的同志都知道,在处理页面需要获取到JS中传递的参数,比如比例尺,索引,范围等,以便在后台调用TcpMap来出图。但是我们这次是调用GoogleMap的缓存图片,完全脱离TcpMap的处理机制,所以请求参数也简化了,只要传递当前图幅的TileBounds即可。我们就可以根据这个Bounds来获取相应的GoogleMap缓存。

         我们获取对应GoogleMap的缓存过程基本分为如下几个步骤:

         获取当前请求图幅的Bounds(viewBounds)->根据GoogelMap的切图规则算得viewBounds四个角点分别位于哪个GoogleMap缓存图幅->将包含请求图幅范围的GoogleMap缓存图幅下载并组合成一幅比较大的图片,并计算范围(nowViewBounds)->根据实际需要的Bounds在图片上进行裁剪->返回结果图片并保存到本地以便下次使用

    蓝色范围为GoogleMap的缓存,黄色的问题实际添加到地图上的图片,具体代码相见下面代码。 

    代码
    <%@ WebHandler Language="C#" Class="GoogleMap" %>

    using System;
    using System.Web;
    using SuperMap.IS.Web;
    using SuperMap.IS.Utility;
    using System.IO;
    using System.Net;
    using System.Globalization;
    using System.Drawing;
    using System.Text;
    using System.Collections.Generic;


    public class GoogleMap : IHttpHandler
    {
    private Dictionary<string, string> Uris = new Dictionary<string, string>();
    private const string MapTileUri = "http://mt{0}.google.cn/vt/lyrs=m@127&hl=zh-CN&gl=cn&src=api&x={1}&y={2}&z={3}&s=Gal";
    private const string SatelliteTileUri = "http://mt{0}.google.cn/vt/lyrs=s@63&gl=cn&x={1}&s=&y={2}&z={3}&s=Gal";
    private string OutPutPath = @"C:\Program Files\SuperMap\SuperMap IS .NET 6\output";
    private double tileBaseWidth = 400750166.6855785;
    private double tileBaseHeight = 39858478.2258614;
    private string mapType = "Satellite";
    public void ProcessRequest(HttpContext context)
    {
    Uris.Add(
    "Map", MapTileUri);
    Uris.Add(
    "Satellite", SatelliteTileUri);
    //索引
    string tx = context.Request["tx"];
    string ty = context.Request["ty"];
    string msstr = context.Request["ms"];
    string _mapType = context.Request["type"];
    //string offsetX = context.Request["offsetX"];
    //string offsetY = context.Request["offsetY"];
    if (_mapType != null) { mapType = _mapType; }
    int ms = (int)(1 / Double.Parse(msstr));
    //当前请求图幅范围
    MapRect viewBounds = new MapRect(Convert.ToDouble(context.Request["lbx"]), Convert.ToDouble(context.Request["lby"]), Convert.ToDouble(context.Request["rtx"]), Convert.ToDouble(context.Request["rty"]));
    //当前请求图幅比例尺
    int z = GetZoomLevel(viewBounds.Width, viewBounds.Height);
    //缓存图片名称
    string imgName = "gm_" + tx + "_" + ty + "_" + ms.ToString() + ".png";
    //GoogleMap缓存目录
    string fPath = OutPutPath + @"\GoogleMapCache";
    //地图类别目录
    string fyPath = fPath + @"\" + mapType;
    //GoogleMap分级目录
    string zfPath = fyPath + @"\" + ms.ToString();
    //GoogleMap缓存全路径
    string fullPath = zfPath + @"\" + imgName;
    Bitmap returnBitMap
    = null;
    if (!Directory.Exists(fPath)) { Directory.CreateDirectory(fPath); }
    if (!Directory.Exists(fyPath)) { Directory.CreateDirectory(fyPath); }
    if (!Directory.Exists(zfPath)) { Directory.CreateDirectory(zfPath); }

    if (File.Exists(fullPath))
    {
    //returnBitMap = new Bitmap(fullPath);
    context.Response.Redirect("http://localhost/IS/Output/GoogleMapCache/"+mapType+"/"+ms.ToString()+"/"+imgName);
    }
    else
    {
    //leftTop是根据经纬度[-180,85]计算得来的
    //GoogleMap起始坐标
    MapCoord leftTop = new MapCoord(-2.0037508342789244E7, 1.9929239112930678E7);
    //leftTop.X += Double.Parse(offsetX);//1300
    //leftTop.Y += Double.Parse(offsetY); //-6500
    leftTop.X += 1300;
    leftTop.Y
    += -6500;
    double tileWidth = (-leftTop.X) / Math.Pow(2.0, z - 1);
    double tileHeight = leftTop.Y / Math.Pow(2.0, z - 1);
    //角点所在的图幅
    int x1 = (int)((viewBounds.LeftBottom.X - leftTop.X) / tileWidth);
    int y1 = (int)((leftTop.Y - viewBounds.LeftBottom.Y) / tileHeight);
    int x2 = (int)((viewBounds.RightTop.X - leftTop.X) / tileWidth);
    int y2 = (int)((leftTop.Y - viewBounds.RightTop.Y) / tileHeight);
    //拼接图幅的范围
    MapRect nowViewBounds = new MapRect();
    nowViewBounds.LeftBottom
    = new MapCoord();
    nowViewBounds.RightTop
    = new MapCoord();
    nowViewBounds.LeftBottom.X
    = leftTop.X + x1 * tileWidth;
    nowViewBounds.RightTop.X
    = leftTop.X + (x2 + 1) * tileWidth;
    nowViewBounds.RightTop.Y
    = leftTop.Y - y2 * tileHeight;
    nowViewBounds.LeftBottom.Y
    = leftTop.Y - (y1 + 1) * tileHeight;
    Bitmap bitMap
    = null;
    bitMap
    = GetImg(x1, x2, y1, y2, z);
    // bitMap.Save(zfPath + @"\f" + imgName);
    //切图起点
    int imgWidth = 256 * (x2 - x1 + 1);
    int imgHeight = 256 * (y1 - y2 + 1);
    int xt = (int)(((viewBounds.LeftBottom.X - nowViewBounds.LeftBottom.X) / nowViewBounds.Width) * imgWidth);
    int yt = (int)(((nowViewBounds.RightTop.Y - viewBounds.RightTop.Y) / nowViewBounds.Height) * imgHeight);
    int width = (int)((viewBounds.Width / nowViewBounds.Width) * imgWidth); ;
    int height = (int)((viewBounds.Height / nowViewBounds.Height) * imgHeight);
    returnBitMap
    = cutMap(bitMap, xt, yt, width, height);
    if ((width != 256 && width != 257) || (height != 256 && height != 257))
    {
    returnBitMap
    = resizeImg(returnBitMap);
    }
    if (!File.Exists(fullPath))
    {
    returnBitMap.Save(fullPath);
    }
    bitMap.Dispose();
    MemoryStream mss
    = new MemoryStream();
    returnBitMap.Save(mss, System.Drawing.Imaging.ImageFormat.Png);
    byte[] ImgBytes = mss.ToArray();
    context.Response.BinaryWrite(ImgBytes);
    context.Response.End();
    }
    }
    //重置大小
    private Bitmap resizeImg(Bitmap bitMap)
    {
    Bitmap newBitMap
    = new Bitmap(bitMap, 256, 256);
    return newBitMap;
    }
    //获取地图比例尺
    private int GetZoomLevel(double width, double height)
    {
    double h = tileBaseHeight / height;
    double w = tileBaseWidth / width;
    if (h < 1)
    {
    return 0;
    }
    else
    {
    int hi = (int)(Math.Log(h, 2)) + 1;
    int wi = (int)(Math.Log(w, 2)) + 1;
    int returnI = (hi < wi) ? hi : wi;
    if (returnI > 16)
    {
    if (mapType == "Satellite")
    {
    returnI
    = 16;
    }
    else
    {
    returnI
    = 17;
    }
    }
    return returnI;
    }
    }
    //切图
    public Bitmap cutMap(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
    {
    if (b == null) { return null; }
    int w = b.Width;
    int h = b.Height;
    if (StartX >= w || StartY >= h) { return null; }
    if (StartX + iWidth > w) { iWidth = w - StartX; }
    if (StartY + iHeight > h) { iHeight = h - StartY; }
    try
    {
    Bitmap bmpOut
    = new Bitmap(iWidth, iHeight);
    Graphics g
    = Graphics.FromImage(bmpOut);
    g.DrawImage(b,
    new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
    g.Dispose();
    return bmpOut;
    }
    catch
    {
    return null;
    }
    }
    //获取图片
    private Bitmap GetImg(int x1, int x2, int y1, int y2, int z)
    {
    int xCount = x2 - x1 + 1;
    int yCount = y1 - y2 + 1;
    Bitmap[] bitmaps
    = new Bitmap[xCount * yCount];
    int index = 0;
    for (int i = 0; i < yCount; i++)
    {
    for (int j = 0; j < xCount; j++)
    {
    bitmaps[index]
    = new Bitmap(getStream(j + x1, i + y2, z));
    index
    ++;
    }
    }
    Bitmap newBitmap
    = MergerImg(bitmaps, xCount, yCount);
    return newBitmap;
    }
    //合并图片
    private Bitmap MergerImg(Bitmap[] maps, int xCount, int yCount)
    {
    Bitmap backgroudImg
    = new Bitmap(xCount * 256, yCount * 256);
    Graphics g
    = Graphics.FromImage(backgroudImg);
    g.Clear(System.Drawing.Color.White);
    int index = 0;
    for (int j = 0; j < yCount; j++)
    {
    for (int k = 0; k < xCount; k++)
    {
    g.DrawImage(maps[index], k
    * 256, j * 256, 256, 256);
    index
    ++;
    }
    }
    g.Dispose();
    return backgroudImg;
    }
    //获取图片Stream
    public Stream getStream(int x, int y, int z)
    {
    Stream stream
    = null;
    if (x < 0 || y < 0)
    {
    stream
    = WriteImg();
    }
    else
    {
    string imageUrl = GetTileUrl(x, y, z);
    HttpWebRequest myHttpWebRequest
    = null;
    HttpWebResponse myHttpWebResponse
    = null;
    Uri imageUri
    = new Uri(imageUrl, UriKind.RelativeOrAbsolute);
    try
    {
    myHttpWebRequest
    = (HttpWebRequest)WebRequest.Create(imageUri);
    myHttpWebRequest.AllowAutoRedirect
    = true;
    myHttpWebRequest.AllowWriteStreamBuffering
    = true;
    myHttpWebResponse
    = (HttpWebResponse)myHttpWebRequest.GetResponse();
    stream
    = myHttpWebResponse.GetResponseStream();
    }
    catch (System.Net.WebException we)
    {
    stream
    = WriteImg();
    }
    catch (Exception)
    {
    stream
    = WriteImg();
    }
    }
    return stream;
    }
    //获取白图填充
    private Stream WriteImg()
    {
    Stream stream
    = null;
    Bitmap writeImgB
    = null;
    string writeImg = OutPutPath + @"\writeImg.png";
    MemoryStream ms
    = new MemoryStream();
    if (File.Exists(writeImg))
    {
    writeImgB
    = new Bitmap(writeImg);
    }
    else
    {
    //绘制白图
    writeImgB = new Bitmap(256, 256);
    Graphics g
    = Graphics.FromImage(writeImgB);
    Pen penColor
    = new Pen(Color.White, 256);
    g.DrawRectangle(penColor,
    new Rectangle(0, 0, 256, 256));
    penColor.Dispose();
    g.Dispose();
    writeImgB.MakeTransparent(Color.White);
    if (!File.Exists(writeImg))
    {
    writeImgB.Save(writeImg);
    }
    }
    writeImgB.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    stream
    = ms as Stream;
    return stream;
    }
    //获取图片的Url
    private string GetTileUrl(int indexX, int indexY, int level)
    {
    Random r
    = new Random();
    int i = r.Next(0,3);
    return string.Format(Uris[mapType], i, indexX, indexY, level);
    }
    public bool IsReusable
    {
    get
    {
    return false;
    }
    }

    }
  • 相关阅读:
    搜索旋转排序数组
    SpringBoot整合mybatis
    《浪潮之巅》阅读笔记01
    阅读杂记01
    go home or stand up
    关于URL编码/javascript/js url 编码(轉)
    水晶报表 相关。
    Format函数(转)
    asp 亂碼問題。
    圣人不死,大盗不止
  • 原文地址:https://www.cnblogs.com/yuxichina/p/1771541.html
Copyright © 2011-2022 走看看