ThinkGeo.com    |     Documentation    |     Premium Support

FindFeatureLayer fails with Serialization

Hello,


I've been working with the new GeoSerializer class and have come to a new problem once XML files are read back in.  Normally, my code uses the FindFeatureLayer call to grab a layer by name and work with it; however, I find that when I load a project from the XML generated by the GeoSerializer class that this function fails to return any layers.


Attached is a test project where I have created an overlay that contains a single red point which is displayed when the program is run.  There are 3 buttons, Find Feature Layer, Read from XML and Save to XML.


If you click Find Feature Layer when the program loads, the call returns a message stating that the layer is found.


If you run the Save to XML and then Read from XML, you will see that the red point object is happily displayed; however, if you then click on the Find Feature Layer button, the call returns null when searching.


Regards,

Damian



Damian,



  Thanks you very much for the sample, it allowed me to find the issue very quickly!  What is happening is that when you add the layer using LayerOverlay.Add["PointLayer"] the string index is what is used by the FindFeatureLayer.  When we serialize it and add it back the keys to the GeoCollection are not getting populated back correctly.  I modified your code a bit below to show you what I mean.  Plug this into your button 3 click. 



  I will pass this on to be fixed but it may take a week or so because the person responsible for this is on vacation.





        private void button3_Click(object sender, EventArgs e)
        {

            // Try this button before loading the XML file.  It will work.
            // If you run the code again after loading the XML file, it will fail.

            FeatureLayer myLayer = winformsMap1.FindFeatureLayer("PointLayer");

            // Even when I am explicit about it, it doesn't work.
            //Layer myLayer = ((LayerOverlay)winformsMap1.Overlays["Point"]).Layers["PointLayer"];

            // This gets the keys and displays the first one.  Notice after you read it from XML it is a guid?  We need to fix this!
            MessageBox.Show(((LayerOverlay)winformsMap1.Overlays[0]).Layers.GetKeys().First().ToString());

            if (myLayer != null)
            {
                MessageBox.Show("Found feature layer by name!");
            }
            else
            {
                MessageBox.Show("Cannot find feature by name!");
            }
        }
 



David



Thanks David.   
  
 Please let me know as soon as a fix is available as I’m not able to deploy my software until the serialization works 100%.   
  
 Regards, 
 Damian

Damian, 
  
   I will let you know when the fix is in.  I would caution you about the serialization at this point.  Currently we are still locking down our private fields, which are used by the serializer, and until we have them stable it may be that a serialized object would not deserialize correctly in the future. 
  
 David

Damian, 
  
   This is now fixed and you can pick it up in the daily developer build 5.5.85.0. 
  
 David

David,


Thanks for the fix.  I can confirm this part is corrected; however, there are still issues.


If you take my previous code example after you find feature name, and then use the zooming/panning several times you will find that you will get another more serious and less understandable error:


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


I confirm it does not occur if I try zooming/panning prior to Save/Read from XML.


This behavior proliferates in my full application as well.


Regards,


Damian



Hi David, 
  
 It’s been a few days.  Do you have an update for me? 
  
 Regards, 
 Damian

Hello Damian, 
  
 Sorry for waiting, I’m working on this now, I will post here as soon as possible. 
  
 Regards, 
  
 Gary

Hi Damian, 
  
 I just downloaded your sample code and tested it with our latest daily build(5.5.94.0). 
 But I can not reproduce the problem that you mentioned. 
 And this is how I tested: 
 Ran the sample, saved the overlay to a xml file; 
 Then loaded the xml file and added the overlay back to the map; 
 Then tried the "find feature layer" button, it worked; 
 Then pan/zoom for a while, but no exception was thrown. 
  
 Can you confirm that you can still reproduce this exception? If so, then please attach the compiled binary since the one I compiled seemed working fine. 
  
 Thanks, 
 Cui

Hi Cui,


Interesting.  I don't get the error when using the executable directly.  The error seems to occurr when I zoom out and then back in with the mouse wheel while running in Visual Studio.  Granted, I have to spin the mouse wheel very quickly to produce the error, but in my main app the same error occurs right after the serialized data are returned so I don't even get a chance to see why. 


I did copy the detail of the error which follows:


System.AccessViolationException was unhandled

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

  Source=System.Drawing

  StackTrace:

       at System.Drawing.SafeNativeMethods.Gdip.IntGdipDeleteBrush(HandleRef brush)

       at System.Drawing.SafeNativeMethods.Gdip.GdipDeleteBrush(HandleRef brush)

       at System.Drawing.Brush.Dispose(Boolean disposing)

       at System.Drawing.SolidBrush.Dispose(Boolean disposing)

       at System.Drawing.Brush.Finalize()

  InnerException: 

 


So, it is an error with System.Drawing, but only after loading a serialized shape file.  Any ideas?


Regards,


Damian



Hi Damian, 
  
 I am sorry to let you know that I am still not able to reproduce this issue. 
 I’ll try it on a different machine tomorrow, and I’ll keep you updated on the results. 
  
 Thanks, 
 Cui

Hi Cui, 
  
 Thanks to continue checking.  However, it may be better/faster if we could do a net meeting or some other kind of screen sharing program so you can see exactly what is happening on my machine. 
  
 Is it possible to do that? 
  
 If not, one thing to try would be to replace my simple diamond shape with a shapefile that is more substantial like the countries02 shape provided in many of the online examples.  Then, the issue may pop-up. 
  
 Regards, 
 Damian

Hi Damian, 
  
 I tested this on a different machine, but still couldn’t reproduce the exception. 
 I have asked our support team(support@thinkgeo.com) to send you two video clips of my screen recording. 
 Please let us know if that is the way how you reproduced the exception. 
 And please feel free to send us your screen recording of running the sample. 
  
 Thanks, 
 Cui

Hi Cui,


I noticed after uploading and using the build 96 that I could no longer replicate the issue with my simple example, but the problem still exists in my main application (which is significantly more complex).  So, I've compiled a new example and passed it on to the sales guy who sent me your video files as it's too big to attach here.  Please get it from him and have a look.


The new project is as follows:


 
1.       Create a shape file overlay for the Countries02.shp file
2.       Create a second shape file overlay for a shape file called GOM_Grid_WGS84.shp (Gulf of Mexico polygons)
3.       Run the program and both layers are displayed. Zooming/Panning is as expected. No issues at this point.
4.       Click Save to XML and the overlays are saved into a text file called SaveFile.txt in the Application.Startup directory.  The original overlays are removed.
5.       Click the Read from XML button. Note that I have to split the SaveFile.txt into individual tmp files and read them back 1 at a time since there can only be 1 initialization of the xml header per document. I question how this works and I am open for alternatives although this is a separate discussion.
6.       Notice the result of the Read from XML call, the first layer loads and then the second layer gives me the same out of memory error related to the System.Drawing object.
7.       You can change the order of the shape files being loaded and you can see the problem follows the Countries02.shp file. So, there is something about that file that the serializer is not saving which is causing big problems. It's not the only type of shapefile that causes this issue either. I tried several. In all cases, GOM_Grid_WGS84.shp would load.
8.       If you then look at the individual tmp files I am saving out, you will immediately see a difference in that the Proj4Projection is defined in the GOM_Grid_WGS84.shp from file 1.tmp, but not with the Countries02.shp from 2.tmp. I think this may be one of the issues we are looking for, but probably not the only one.
 
So, hopefully you can replicate the issue now and we can see what I need to do to move forward.
 
Thanks,
Damian

Hi Damian, 
  
 Thanks for the sample and the detailed description, they both helped a lot. 
  
 But unfortunately, I still can’t reproduce this problem. 
 I will send you another zip file that includes a modified sample and a screen recording video file. Please try the modified sample and see if you can still reproduce it. 
  
 For the fifth thing you mentioned, you don’t have to split the file when you deserialize, you can just save those two overlays into two different files when you serialize. 
 Please see the sample in the zip file for implementation details. 
  
 And for  the the eighth thing you mentioned, I don’t think that is the main problem. Because in the sample, there is a AddShapeFileFeatureLayers method, and that method sets a layer’s projection if that layer has a .prj file. 
 In the “data” folder, there is a GOM_Grid_WGS84.prj file, but there is no countries02.prj file. So the xml for countries02 layer does not contain any projection information. 
  
 Thanks, 
 Cui

Hi Cui,


Thanks for the reply and putting some extra hours in on this.  I am encouraged that you don't get the error.  That probably means we can narrow it down.  I haven't gotten any emails with the updated project though, but will test as soon as it comes through.


Regarding point 5, I need to save to a single file as the idea is that we only have to send 1 file around between users working on the same project.  Right now, I am serializing around 200 objects per session and having them in individual xml files is not practical.


Understood on point 8.  However, I still think there may be an issue deserializing shape layers when a prj file is not supplied even if the xml is being written out as designed.   


Here's the stack trace produced when I get the error on my machine.  Notice that WinformsMap now pops up.  Googling these types of errors, I've seen lots of references where null objects caused the problem.  I see the HxY method/property is unspecified below.


System.AccessViolationException was unhandled

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

  Source=System.Drawing

  StackTrace:

       at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageI(HandleRef graphics, HandleRef image, Int32 x, Int32 y)

       at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.0hU=(IEnumerable`1 0xU=)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.0BU=(RectangleShape 0RU=)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.HxY=()

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.GxY=(Int32 HBY=)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.Refresh(IEnumerable`1 redrawOverlays)

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

       at GeoSerializerTest.Form1.button2_Click(Object sender, EventArgs e) in C:\Users\dhite\Documents\Visual Studio 2010\Projects\MapSuiteExamples\GeoSerializerShapeTest\GeoSerializerTest\Form1.cs:line 144

       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)

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

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

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

       at System.Windows.Forms.Button.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 GeoSerializerTest.Program.Main() in C:\Users\dhite\Documents\Visual Studio 2010\Projects\MapSuiteExamples\GeoSerializerShapeTest\GeoSerializerTest\Program.cs:line 18

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

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

       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: 

 


 


Regards,


Damian



Hi Cui,


I got your files from the sales rep and tried them right away.  Unfortunately, it's the same error.  I sent him a Jing swf file showing my error and asked him to pass it on to you since it's too big to post.


Here is the call stack.  It's got similar information to yesterday:


System.AccessViolationException occurred

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

  Source=System.Drawing

  StackTrace:

       at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageI(HandleRef graphics, HandleRef image, Int32 x, Int32 y)

       at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.0hU=(IEnumerable`1 0xU=)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.0BU=(RectangleShape 0RU=)

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.HxY=()

       at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.GxY=(Int32 HBY=)

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

       at GeoSerializerTest.Form1.Load_Click(Object sender, EventArgs e) in C:\Users\dhite\Desktop\GeoSerializerTest - Cui\GeoSerializerTest\Form1.cs:line 92

  InnerException:


 


Thanks,


Damian



 Hi Damian,


 
Thank you for the Jing swf file, I think I have found and fixed the bug.
Please download a later daily build version(5.5.105.0 or later), I believe the bug will be gone in that daily build.
 
And about point 5, I modified the sample a little bit, now you can save multiple overlays to one XML file. Please download the attached file for more details. (I deleted the shapefiles and the dlls from the sample to make it small enough for the forum.)
 
Thanks,
Cui

SaveMultipleOverlaysToOneXMLFile.zip (13.5 KB)

Hi Cui, 
  
 I’ve been looking for 2 days and haven’t seen a development build past 5.5.103.0.  Is it going to be posted soon? 
  
 Cheers for the recode tip of point 5.  My XML outputs are much improved now. 
  
 Regards, 
 Damian

Hi Damian, 
  
 Sorry for the delay. 
 I have sent an email to our daily build team asking about this issue. 
 I will let you know when they reply me. 
  
 Thanks, 
 Cui