ThinkGeo.com    |     Documentation    |     Premium Support

Problem With GeoTiffRasterLayer

Hi,


We have been loading raster layers of various types as we build our application. I came across a .Tif raster file that causes a System.OutOfMemoryException whenever I try to load it. This same raster layer works fine in our other applications and also in ArcMap. So I'm trying to figure out what the problem is. The layer is not particularly large for a raster, about 60MB, but too big to attach here or email. Maybe there is a way I could FTP the layer and you could have a try?


Thanks,


Steve


 


 


 



Steve, 
  
  I believe a ThinkGeo FTP account was set for you last week. Can you, please, upload your tif file to it and let us know in this post when this is done? Thank you.

Thanks Val. I have uploaded the problem data. The file name is TifRasterData.zip. 
  
 Steve

Steven, 
  
 I can reprodure your problem that when you call GeoTiffRasterLayer.Draw the memory will quickly up to almost 2G, and I found the incorrect code is from GeoTiff which is a thrid-part opensource library, we couldn’t fix it immediately, I have added it to our working track system and hope we can solve it at next public release. The workaround you can try to set  
 geoTiffRasterLayer.LibraryType = GeoTiffLibraryType.UnmanagedLibTiff; 
  
 Thanks, 
 James

Hi James,


I tried your succession. When the map refreshes after adding the layer I get the following exception:


System.Reflection.TargetInvocationException was unhandled

  Message=Exception has been thrown by the target of an invocation.

  Source=mscorlib

  StackTrace:

       at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)

       at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)

       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)

       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

       at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)

       at ThinkGeo.MapSuite.Core.UnmanagedGeoTiffRasterSource.RetrieveImageByteArray(Byte[] filePath, Int32 offsetX, Int32 offsetY, Int32 sourceWidth, Int32 sourceHeight, Int32 targetWidth, Int32 targetHeight, Int32 drawingQuality)

       at ThinkGeo.MapSuite.Core.UnmanagedGeoTiffRasterSource.GetSmoothImage(Int32 screenX, Int32 screenY, Int32 overlapWidth, Int32 overlapHeight, Int32 tempReturnWidth, Int32 tempReturnHeight)

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

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

       at ThinkGeo.MapSuite.Core.GeoTiffRasterSource.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.GeoTiffRasterLayer.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.MainDraw(GeoCanvas canvas)

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

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x03e3d48bcfe7bb6c(IEnumerable`1 xa6f0db4f183189f1)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xff5b27c00f9678c2(RectangleShape x178b193eec228e6e)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xe3cee4adb9c72451()

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x9ac8c50f434f4b39(Int32 xb565f4681f05557a)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.Refresh()

       at SerializeWMSLayer.Form1.LoadGeoTifLayer() in C:\Users\steller\Documents\Visual Studio 2010\Projects\ThinkGeo\RasterMemoryProblem\Form1.vb:line 32

       at SerializeWMSLayer.Form1.Form1_Load(Object sender, EventArgs e) in C:\Users\steller\Documents\Visual Studio 2010\Projects\ThinkGeo\RasterMemoryProblem\Form1.vb:line 40

       at System.EventHandler.Invoke(Object sender, EventArgs e)

       at System.Windows.Forms.Form.OnLoad(EventArgs e)

       at System.Windows.Forms.Form.OnCreateControl()

       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)

       at System.Windows.Forms.Control.CreateControl()

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

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

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

       at System.Windows.Forms.Form.WmShowWindow(Message& m)

       at System.Windows.Forms.Form.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.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)

       at System.Windows.Forms.Control.SetVisibleCore(Boolean value)

       at System.Windows.Forms.Form.SetVisibleCore(Boolean value)

       at System.Windows.Forms.Control.set_Visible(Boolean value)

       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(ApplicationContext context)

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)

       at SerializeWMSLayer.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81

       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)

       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

       at System.Threading.ThreadHelper.ThreadStart()

  InnerException: System.AccessViolationException

       Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

       Source=TiffWrapperX86

       StackTrace:

            at RetrieveImageByteArray(SByte* , Int32 , Int32 , Int32 , Int32 , Int32 , Int32 , Int32 )

            at TiffWrapper.TiffWrapperX86.RetrieveImage(Byte[] filePath, Int32 offsetX, Int32 offsetY, Int32 sourceWidth, Int32 sourceHeight, Int32 targetWidth, Int32 targetHeight, Int32 drawingQuality)

       InnerException: 

 


Any idea what the problem is?


Thanks,


Steve


 



 


Steven,
 
In ManagedLibTiff, it caused by lack of memory. Because the tiff file has a large dimension(20951 x 23246). So the program will take up amount of memory(20951* 23246*4=1.8GB). If the memory of your machine is not big enough, we don’t recommend using ManagedLibTiff.
 
In UnmanagedLibTiff, I tested it on win7(64bit, 8GB memory). It won’t throw exception but the map display incorrectly as the following screenshot. On win7(3GB memory), it will throw a exception which is the same as yours. I think it caused by lack of memory, too.
 
So I suggest you use class GdiPlusRasterLayer  to display your tiff file. Maybe it displays slowly but it won’t throw a exception and the result is correct.
Sorry for the conveniences.
 
Thanks,
James

screenshot.zip (208 KB)

James, 
  
 Thanks for your response, I appreciate your investigating this issue. This is the first time I have tested very much with raster layers. The GdiPlusRasterLayer class does display the layer properly, however it is so slow that is is not usable. I hope ThinkGeo will implement something more robust in the coming versions. 
  
 Thanks for you help! 
  
 Steve

James, 
  
   The ManagedLibTiff should not have to load all of that into memory.  It should read the scan lines and construct a much smaller image based on just a subset of the data.  This assumes that you are not at the native resolution on some huge bank of monitors.  Can we get together to discuss this?   
  
 Steve:  This should work just fine, we will get to the bottom of this.  Typically when you have very large raster files that are intended for viewing they are encoded using MrSid, ECW or Jpeg2000.  These methods not only get the file size down but also are encoded to quick reading at higher scales.  They are much more efficient than TIFF which is usually just a reference file used to maintain the original image and not for direct drawing. 
  
 Thanks, 
  
 David

Hi David, 
  
 Thanks for the clarification. Unfortunately, we don’t get to choose the image format our clients use, and some of them have TIFFs. I have found that MrSids, Jpegs and ECWs seem to work just fine in ThinkGeo. WMSRasterLayer performance is also fine. 
  
 Steve 
  


Steve, 
  
   I figured as much. :-)  We are going to look into the memory issue.  I am fairly sure that we can read the larger tiff files with a little digging.  
  
 I believe that there are open source Jpeg2000 compressors out there.  We may look at that as well to integrate.  In that way when a user wants to open it then they could have the choice to compress it, lossy or lossless.  Just an idea and even if not applicable to you I think others might like it. 
  
 Thanks, 
  
 David

same problem here. (I just posted so this goes to "my topics". easier to find. :D )

 I think that GeoTiff is the most used format for displaying maps due to the functionalities it gives and also the displaying speed. If you use Gdal (opensource library) you can create internal tiling on a Tiff and also internal overview to rock in smaller scales. So with internal tiling you dont need to load all the image 2 gb or more (knowing that a GeoTiff is up to 4Gb) but only the tiles that are requested for drawing the map (500-1000 kb) Also it has overviews so you get them for displaying when you zoom out. Thats why GeoTiff is recommended for maps, but MapSuite doesnt support these techniques. Im having this problem too right now. I created a GdalRasterLayer too, but i think it loads all the image not only the requested tiles thats why its very slow.



Edi, 
  
  I think that Map Suite supports those imaging techniques. You will have someone from the development team give a more detailed answer on this. Thank you for your participation.

Tsui 3/6/2011 11:49:08 PM said: 
 Hi Edi, 
  
  
 Thanks for the detailed explanation. 
  
 Currently, Map Suite does not support using a shapefile as a raster tile index, we’re sorry for the inconvenience. 
  
 I will inform the team that is in charge of raster layers, I belive they will talk to the manager and finally decide whether we’ll add this feature to Map Suite. 
  
  
 Regards, 
  
 Tsui 
  
  
  
  
 Ivan 3/7/2011 8:54:56 PM said: 
 Hi Edi, 
  
 Here are answers for your questions: 
  
 1. Is there any other method how to add multiple raster tiles in a map and draw only those that are requested by the client? 
  
 Currently, Map Suite doesn’t support these functions. These new features are still under discussion, hopefully we could add them in the next main release. 
  
 Thanks, 
  
 Ivan 
  
  
 ************************************************************************************************************ 
 They said that it is not possible right now to implement those functionalities so i just created a wms for the raster data and added it in mapsuite. 
 It works very fast right now

I start using MapServer to provide WMS Service, then in ThinkGEO I consume it. 
 It’s really simple and effective. Even with shape file for tileindex. 


Edi, 
  
 I think Tsui and Ivan are correct that we don’t support this feature for now. It’s a good workaround to use WMS like what you guys are doing and we will have a discussion to see how/when we can support this tiling feature. 
  
 Thanks, 
  
 Ben