<%@ 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 = @"E:\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;
}
}
}