ThinkGeo.com    |     Documentation    |     Premium Support

IsoLines questions - Serializing, cropping

I have been working with the GridDefinition, GridIsoLineLayer, and GridFatureLayer to generate isoline (contours) on the map display.  Now we would like to save the generated isolines and reload them without regenerating from the original data points.  Several questions have come up:


The IsoLineLayer has the SerializableAttribute but I do not know how serialization should be used.  Is it as simple as streaming the Layer to some type of output stream?  Are the graphics for the contour isolines a raster or vector graphics or do the graphics use some other custom graphics representation?   Are there any samples that would demostrate serialization of MapSuite layers?


We also generate the isolines within a given boundary area.  However, because of the interpolation algorithm being used sometimes the isolines are generated outside of our boundary area even though we have "noDataValue" points in these areas. GridFeatureLayer always generates the AreaStyle classBreaks over the entire rectanular region for the ioslines.  We would like to be able to crop the ioslines and areaStyle to restrict the display within our boundary area.  Are there any "cropping tools" available in MapSuite?  Could we create a cropping effect with a "masking" layer which would hide the graphics outside of our boundary?


I would greatly appreciate any help that anyone can provide?


Thanks


Richard


 



Richard,


 To respond to your question on cropping the isolines to restrict the display as a masking layer, I think that RestrictionLayer will work for you. We have an example on how to use that in our "How Do I" samples. The sample is "Create a Restriction Layer" and it is under the "Moving Around The Map" section. Here we show how to restrict the display of the map to one continent. I think that from this example, we will know how to adapt it for your case.


 For the serialization issue for IsoLineLayers, let me look more into that and I will get back to you.


Thank you.



Richard,


 After talking to a member of the Development Team, here is what I can recommend you about serialization:


 To save the generated isolines, you don't need to serialize the IsoLineLayer which just stores the fields of an IsoLineLayer instance, instead you need to serialize the collection of the generated isolines.


 Here is a code snippet. You can use GridIsolLIneLayer.GetIsoFeatures (static method, it returns a polygon if the polygon if the IsoLine is closed. You can also use the instant method GridIsoLineLayer.GetIsoLineFeatures) to get the isolines, and serialize them to stream.


 



Collection<Feature> features = GridIsoLineLayer.GetIsoFeatures(,,,);
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
//save
formatter.Serialize(stream,features);
//load
stream.Seek(0, SeekOrigin.Begin);
Collection<Feature> newFeatures = (Collection<Feature>)formatter.Deserialize(stream);



I tried to add some code to serialize the IsoLines as described in the response above but I am getting an exception:


Type 'System...BinaryFormatter' in Assembly '...' is not marked as serializable.


I am attaching the source code I used and the exception call stack.   Do I need to set some indicator that the Features are serializable? 


Also, I looked at the Sample for "Restriction" but I haven't had time to play with it.   The description seems to indicated that the restriction layer is limiting the area for "panning or zooming" the map layer.   I am not interested in restricting the display (zooming) of the map layer.   I would like to "restrict" the area where graphics (lineshape and areashape) are rendered on the map layer.  I would still want to be able to pan and zoom anywhere and to see the map layer with all the other features displayed except the "restricted' graphics.  Does the "RestrictionLayer" provide this functionality as well?



Richard, 
  
 There is a bug in your code where you trying to serialize the BinaryFormatter instance 
  formatter.Serialize(isolineFileStream, formatter); 
  
 Instead you should serialize the features as following.  
  formatter.Serialize(isolineFileStream, features); 
  
 I see what you mean by “Restriction”, maybe restriction layer is not for you and we need some other ways to work it around. I think you can inherit the GridIsoLineLayer and override the DrawCore method as following 
  
 protected override void DrawCore(GeoCanvas canvas, Collection<SimpleCandidate> labelsInAllLayers)
    {
        // Get the restrictionAreaOnScreen, which is the area we will draw the IsoLine in
        RectangleShape restrictionArea = new RectangleShape();
        RectangleShape restrictionAreaOnScreen = canvas.CurrentWorldExtent.GetIntersection(restrictionArea);
 
        // Create a GeoCanvas and draw the IsoLine on the area. 
        GdiPlusGeoCanvas myCanvas = new GdiPlusGeoCanvas();
        GeoImage image = new GeoImage((int)canvas.Width, (int)canvas.Height);
        myCanvas.BeginDrawing(image, restrictionAreaOnScreen, canvas.MapUnit);
        base.DrawCore(myCanvas, labelsInAllLayers);
        myCanvas.Flush();
 
        // We then draw the image on the canvas. We need to calculate the right position based on the restrictionAreaOnScreen and canvas.CurrentWorldExtent
        canvas.DrawScreenImage(image, 300, 300, 300, 300, DrawingLevel.LevelOne, 0, 0, 0);
    }
  
  
 Generally we need to draw the IsoLines on an image only within the “restriction area”, and then draw that image on the main canvas. You can do the same thing for GridFeatureLayer.  
  
 Thanks, 
  
 Ben

Ben, 
 Thanks for catching the typo of fomatter for features in that code sample.  I should have seen that but I didn’t spend enough time on it when I got the exception.   It serializes to the file now. 
  
 Also thanks for the sample code on the GridIsoLineLayer DrawCore.  I will try to test this out when I have a chance. 
 Richard

Hello Richard, 
  
 Please feel free to let us know if you have any other queries. 
  
 Regards, 
  
 Gary