2011-04-14 107 views
0

我有一个Heatmap,目前可以在我移植到Azure存储的独立服务器上运行。我如何着手保存Azure存储中的butmap文件。最初,我在我的web.config文件中有一个条目,将图像缓存指向另一个驱动器(IE)上的直接路径。现在,所有内容都将位于存储帐户的〜/ map_cache文件夹中。如何在Azure中本地存储此存储。尝试将生成的热图保存在Azure存储中

protected void Page_Load(object sender, EventArgs e) 
{ 
    xxxxxxxdb = new xxxxxxx(ConfigurationManager.AppSettings["xxxxxxx"]); 

    string imageCachePath = Server.MapPath("/map_cache/HotSpots"); 
    int fileExpirationTime = int.Parse(ConfigurationManager.AppSettings["HotspotImageExpirationTime"]); 
    Bitmap bitmap; 

    string requestParam = Page.Request.Params["id"]; 
    string bitmapFileName = Path.Combine(imageCachePath, requestParam + ".png"); 
    if (File.Exists(bitmapFileName) && File.GetCreationTime(bitmapFileName) > DateTime.Now.AddHours(-fileExpirationTime)) 
    { 
     bitmap = (Bitmap)Image.FromFile(bitmapFileName); 
    } 
    else 
    { 
     int zoomLevel = requestParam.Length; 

     double tileX = 0; 
     double tileY = 0; 
     for (int index = 0; index < zoomLevel; index++) 
     { 
      int digit = int.Parse(requestParam[index].ToString()); 
      tileY += ((digit & 2)/2) * Math.Pow(2, (zoomLevel - index - 1)); 
      tileX += (digit & 1) * Math.Pow(2, (zoomLevel - index - 1)); 
     } 
     double pixelXMin = tileX * 256; 
     double pixelYMin = tileY * 256; 
     double pixelXMax = (tileX + 1) * 256 - 1; 
     double pixelYMax = (tileY + 1) * 256 - 1; 

     double longMin = ((pixelXMin * 360)/(256 * Math.Pow(2, zoomLevel))) - 180; 
     double longMax = ((pixelXMax * 360)/(256 * Math.Pow(2, zoomLevel))) - 180; 
     double latMin = Math.Asin((Math.Exp((0.5 - pixelYMin/256/Math.Pow(2, zoomLevel)) * 4 * Math.PI) - 1)/
            (Math.Exp((0.5 - pixelYMin/256/Math.Pow(2, zoomLevel)) * 4 * Math.PI) + 1)) * 180/
         Math.PI; 
     double latMax = Math.Asin((Math.Exp((0.5 - pixelYMax/256/Math.Pow(2, zoomLevel)) * 4 * Math.PI) - 1)/
            (Math.Exp((0.5 - pixelYMax/256/Math.Pow(2, zoomLevel)) * 4 * Math.PI) + 1)) * 180/
         Math.PI; 

     double pixelResolution = (Math.Cos(latMax * Math.PI/180) * 2 * Math.PI * 6378137)/(256 * Math.Pow(2, zoomLevel)); 
     double pixelArea = Math.Pow(pixelResolution, 2); 

     double maxHotspotDensity = Math.Max(120.0/zoomLevel, 3.0)/pixelArea; 

     bitmap = GenerateBlankBitmap(); 

     var accidents = from hs in db.cs_PT_VEGeoDatas 
         where hs.Latitude <= latMin && hs.Latitude >= latMax 
           && hs.Longitude >= longMin && hs.Longitude <= longMax 
         select new { hs.Latitude, hs.Longitude }; 

     Dictionary<Point, HotSpot> hotSpots = new Dictionary<Point, HotSpot>(); 
     foreach (var accident in accidents) 
     { 
      int pixelX, pixelY; 
      LatLongToPixelXY(accident.Latitude, accident.Longitude, zoomLevel, out pixelX, out pixelY); 
      pixelX %= 256; 
      pixelY %= 256; 
      for (int ix = -doublePixelSize; ix <= doublePixelSize; ix++) 
      { 
       for (int iy = -doublePixelSize; iy <= doublePixelSize; iy++) 
       { 
        Point point; 
        bool borderPoint = false; 
        if (zoomLevel < doublePixelZoomLevel) 
        { 
         point = new Point(pixelX, pixelY); 
        } 
        else 
        { 
         if (pixelX + ix >= 0 && pixelX + ix <= 255 && pixelY + iy >= 0 && pixelY + iy <= 255) 
         { 
          point = new Point(pixelX + ix, pixelY + iy); 
          borderPoint = (ix == -doublePixelSize) || (iy == -doublePixelSize) || 
               (ix == doublePixelSize) || (iy == doublePixelSize); 
         } 
         else 
         { 
          break; 
         } 
        } 
        HotSpot hotSpot; 
        if (hotSpots.ContainsKey(point)) 
        { 
         hotSpot = hotSpots[point]; 
         hotSpot.borderPoint &= borderPoint; 
         hotSpot.count += 1; 
        } 
        else 
        { 
         hotSpot = new HotSpot { borderPoint = borderPoint, count = 1 }; 
         hotSpots.Add(point, hotSpot); 
        } 
        if (zoomLevel < doublePixelZoomLevel) 
        { 
         break; 
        } 
       } 
       if (zoomLevel < doublePixelZoomLevel) 
       { 
        break; 
       } 
      } 
     } 
     foreach (var hotspotPixel in hotSpots) 
     { 
      double hc = hotspotPixel.Value.count; 
      double hcDensity = hc/pixelArea; 

      Color color; 
      if (!hotspotPixel.Value.borderPoint) 
      { 
       color = Color.FromArgb(255, 255, 
             (int) 
             Math.Max((maxHotspotDensity - hcDensity)/maxHotspotDensity * 255, 0.0), 
             0); 
      } 
      else 
      { 
       color = Color.Black; 
      } 
      bitmap.SetPixel(hotspotPixel.Key.X, hotspotPixel.Key.Y, color); 
     } 
     bitmap.Save(bitmapFileName); 
    } 

    WritePngToStream(bitmap, Response.OutputStream); 
} 

目前我收到以下错误消息

A generic error occurred in GDI+. 

说明:在当前Web请求的执行过程中发生未处理的异常。请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的位置。

异常详细信息:System.Runtime.InteropServices.ExternalException:在GDI +中发生了一般性错误。

源错误:

在当前web请求的执行过程中生成未处理的异常。关于异常的来源和位置的信息可以使用下面的异常堆栈跟踪来标识。

堆栈跟踪:

[ExternalException(0X80004005):在GDI +发生一般性错误] System.Drawing.Image.Save(字符串文件名,ImageCodecInfo编码器,EncoderParameters encoderParams)772265 HotSpotTileServer.Page_Load(对象发件人,EventArgs e)在C:\ Projects \ xxx \ xxx \ SpeedTrap \ HotSpotTileServer.aspx.cs中:141 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,Object o,Object t,EventArgs e)+25 ()对象发件人,EventArgs e)+0 System.Web.UI.Control.LoadRecursive()+71 System.Web.UI.Page.ProcessRequestMain(Boolean includeStag esBeforeAsyncPoint,布尔includeStagesAfterAsyncPoint)+3048

版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.0.30319.1

回答

4

有三件事情你可以尝试:

当然最后这些就是我建议你 - 它的快速,灵活和可扩展。

1

(我同意斯图尔特100%。)这里有更多的原因,我建议你考虑使用Azure的Blob存储用于存储热图png文件:

  1. 本地硬盘,但不保证耐用。(但是,如果它们可以很容易地重新生成,这对您可能并不重要)。
  2. Blob可以公开显示(例如,它们可以直接从带有img标签的HTML代码引用)。
  3. 可以轻松地在AppFabric CDN中提供Blob(以获得更好的性能,其中包括大约24个全球分发点)。
  4. Blob将以使用本地文件系统的方式缩放。例如,如果您想扩展您的站点以使用多个Heatmap生成器角色实例(在云中不同的计算机上运行其中的两个),您将希望位于Blob存储上,因为其他选项都不起作用。
  5. Blob针对云规模和可靠性以及高可用性进行了优化。

我建议您使用非常方便的Windows Azure SDK编写您的斑点。 SDK将正式的REST接口包装成一套非常好的类,这些类在.NET代码中非常易于使用。具体来说,您可以使用CloudBlobClient类和UploadByteArray方法。您可以下载Azure SDK 1.4 here