2011-04-14 49 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