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;
}
}

}
原文地址:https://www.cnblogs.com/yuxichina/p/1771541.html