ThinkGeo.com    |     Documentation    |     Premium Support

Exception with large image

Our product allows the user to specify a background image for use with their map.  We add it to the map by instantiating a GdiPlusRasterLayer and adding it as the first (back) layer of our static layers overlay.  In addition to the (optional) background image, that overlay also can contain (optionally) one or more shape file layers.



We've seen performance problems before when customers use large high resolution images.  The current problem involves use of a JPG with a file size of 70.2MB and resolution of 11410 by 12972.  The customer wants to use this image because it will give him a nice high fidelity image when zoomed in.  However, addition of this image consumes a LOT of resources and slows our product to an almost unusable crawl.  Also, when zooming in, it will eventually produce an exception in GDI+.  Simply compressing the file down to ~30MB did not correct the problem.



The exception call stack is pasted below.




System.Runtime.InteropServices.ExternalException


A generic error occurred in GDI+.

   at System.Drawing.Graphics.CheckErrorStatus(Int32 status)

   at System.Drawing.Graphics.DrawImage(Image image, PointF[] destPoints, RectangleF srcRect, GraphicsUnit srcUnit)

   at ThinkGeo.MapSuite.Core.GdiPlusRasterSource.dyk=(Bitmap sourceBitmap, RectangleF sourceRectangle, Int32 tempReturnWidth, Int32 tempReturnHeight)

   at ThinkGeo.MapSuite.Core.GdiPlusRasterSource.GetImageCore(RectangleShape worldExtent, Int32 canvasWidth, Int32 canvasHeight)

   at ThinkGeo.MapSuite.Core.RasterSource.GetImage(RectangleShape worldExtent, Int32 canvasWidth, Int32 canvasHeight)

   at ThinkGeo.MapSuite.Core.RasterLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.GdiPlusRasterLayer.DrawCore(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, Collection`1 labelsInAllLayers)

   at ThinkGeo.MapSuite.DesktopEdition.LayerOverlay.DrawCore(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.YRQ=(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.Overlay.Draw(GeoCanvas canvas)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.LRQ=(IEnumerable`1 drawingOverlays, RectangleShape extent)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.KxQ=(RectangleShape drawingExtent, RectangleShape extent)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.UhQ=(RectangleShape extent, Overlay overlay, Int32 width, Int32 height, GeographyUnit geographyUnit)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.VRQ=(IEnumerable`1 drawingOverlays)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.TBQ=(RectangleShape extent)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.RBQ=(InteractionArguments interactionArguments)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.ORQ=(Object sender, qxQ= e)

   at ThinkGeo.MapSuite.DesktopEdition.MouseEventAnalyzer.OnMouseEvent(qxQ= e)

   at ThinkGeo.MapSuite.DesktopEdition.MouseEventAnalyzer.qBQ=(Double screenX, Double screenY, Double worldX, Double worldY, MapMouseButton mouseButton)

   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.QxQ=(Object sender, MouseEventArgs e)

   at System.Windows.Forms.Control.OnMouseUp(MouseEventArgs e)

   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

   at System.Windows.Forms.Control.WndProc(Message& m)

   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)

   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

   at System.Windows.Forms.Application.Run(Form mainForm)

   at Toro.Client.ApplicationManager.Main() in d:\Toro\Archer\Solution\Client\ClientHost\ApplicationManager.cs:line 418


 



Hi Russ, 
  
 Sorry that We failed to reproduce this issue. It seems that this exception is thrown by the GDI+, so could you please share your JPG to us and we can work base on it. 
  
 Also we need more information to get to the core of the issue: 
  
 1. Which version of the DLLs do you reference? 
 2. How did you use the GdiPlusRasterLayer and overlay? 
  
 Thanks, 
 Peter

Are you saying you not only do not get the crash, but you also don’t see the excess resource consumption and slow down either? 
  
 I’ll have to get permission to pass along the actual image. 
  
 TG version is 9.5.0.100 
  
  
 The relevant code is very straight forward, but not in one place where I can just copy/paste it. 
  
 This is the creation of the layer. 
  
  gdiPlusRasterLayer = new GdiPlusRasterLayer( imageFilePath ); 
  gdiPlusRasterLayer.Name = path; 
  
 Nothing else is done with this other than to return from the factory method, then this code. 
  
  staticLayerOverlay.Layers.Add( gdiPlusRasterLayer ); 
  
 And that’s it.  The only other code is code checking for valid paths, missing files, that type of stuff.  Nothing configuring or changing anything in TG.

I got approval to provide the image.  However, it seems your server won’t allow me to upload it.  It sits there spinning for a while, then the upload file path edit window shows a “server error” inside the edit window, and the upload never clears.  I tried sending the raw JPG, and also hiding it inside a Zip, but experienced the same error.

drive.google.com/file/d/0By…sp=sharing



That should get you to the image so that you can download it.

Hi Russ,

Thanks for sharing the file. I was still unable to recreate the issue. I viewed the code and guessed there should be a file named “BigImage.jgw” on your side. Could you please share it to us?

For the performance issue, I think we can use the TileCache system. Please see the following:

FileBitmapTileCache bitmapTileCache = new FileBitmapTileCache();
bitmapTileCache.CacheDirectory = “directory”;
bitmapTileCache.CacheId = “World02CachedTiles”;

staticLayerOverlay.TileCache = bitmapTileCache;

More information about the tile cache please refer to http://wiki.thinkgeo.com/wiki/thinkgeo.mapsuite.core.tilecache

NOTE:
The file upload to our server must be not exceed 2MB.

Thanks,
Peter

I have no idea when I will get time to try create another reduced repro. I hope this world file helps with the repro.

Regarding tile caching, we tried that in the past and the number of files created was astronomical resulting in enormous disk IO in normal use, and the resulting performance actually went down. So I don’t think that will be a solution, unless there is some trick to getting it to work that I didn’t apply.

It also wouldn’t let me upload a jgw file, so I tacked on a JPG extension in hopes that it would fool the system into uploading it. It seems to have worked, and “Uploading” shows 100%, but the in process “spinning thing” is still spinning…

I can’t tell whether it uploaded or not, so I’m pasting in the contents here.

0.50000000000000000
0.00000000000000000
0.00000000000000000
-0.50000000000000000
1639615.25000000000000000
14261562.75000000000000000

Hi Russ,

Thanks for the update, I have reproduced the exception which is thrown by GDI+. But we are unable to find out the cause of the issue and our developers are still work on it.

Any progress I will update it here.

Thanks,
Peter

Hmm, not too excited about the new Forum UI. Maybe it will grow on me.

Anyway, can we get an update on this?

Hi Russ,

We still failed to find out the cause of the issue, and our developers are still work on it.

By the way, the JGW seems to be incorrect when the MapUnit is Meter, the image is not match with the background map, so is there any other projection? I sent you a screenshot through message, please check it out.

Thanks,
Emil