ThinkGeo.com    |     Documentation    |     Premium Support

Display memory images

Hi there,


I have a server that send pictures to my client. I would like to be able to display those pictures in Map Suite Desktop Client, without saving them on disk. How can I do that ? I didn't find any way to do this easily yet...


In another hand, I would like to display pictures available via http in another RasterLayer too. Is that possible ?


Thank you very much for your answer,


Regards,


Guillaume.



Ok, I think that I found a solution, by overriding RasterLayer and creating a HttpRasterLayer… But is this the right way to do that ? I don’t know… 
 Is there some “good pactices” for MapSuite somewhere ? 
  
 Thanks, 
 Guillaume.

Guillaume, 
  
 Your method is correct, inheriting a class doesn’t need too much code and the new class is specific for that function, that’s simple and easy to use.  
  
 Also here is an alternate way you can try. GdiPlusRasterSource has an event StreamLoading, which allows you display an image from a stream. Here is some sample code for that. 
  
 
            GdiPlusRasterSource imageSource = new GdiPlusRasterSource();
            imageSource.PathFilename = “a.bmp”; // this file doesn’t exist
            imageSource.StreamLoading += new EventHandler<StreamLoadingEventArgs>(imageSource_StreamLoading);

            imageSource.Open();
// …

         void imageSource_StreamLoading(object sender, StreamLoadingEventArgs e)
        {
            string newBitmapPathName = standardBitmapNamePath.Replace(“GdiplusCommonImageTestStandardBitmap.bmp”, “bitmap.bmp”);
            string newBpwPathName = standardBpwNamePath.Replace(“GdiplusCommonImageTestStandardBitmap.bpw”, “bitmap.bpw”);

            Stream stream = null;
            string extension = e.AlternateStreamName.ToLower();
            if (extension.Contains(“bmp”))
            {
                stream = new FileStream(newBitmapPathName, FileMode.Open);
            }
            else if (extension.Contains(“bpw”))
            {
                stream = new FileStream(newBpwPathName, FileMode.Open);
            }

            e.AlternateStream = stream;
        }
 
  
 We do have some good samples showing how to extend Map Suite, but we do not get them altogether so you can easily browse and download. Which parts are you interested? you can ask here and we are pleased to provide the solution for you. 
  
 Ben 


Ok, thank you for your reply. 
 If it’s a good practice I think I will keep my inherited class, cause it’s right it was easy and that it didn’t need too much code. 
  
 Yet I have another problem, but I already post it in another forum subject :-) 
 I’ll mark this suject as solved. 
 Thanks again, 
 Guillaume.

Thanks, Guillaume. Anything we can do to make your coding easier just let us know, we will try our best to help. 
  
 Ben 


Guillaume, 
  
 I saw your post knew this came up before.  The link below is to a post with some sample code.  It looks like you figured everything out but the post has some comments in the code that may help.  I am including the code after the link below.  In the example we get the image from a web service and we simply inherit from Layer as it is the easiest.  Enjoy… 
  
 gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/12/aft/4207/afv/topic/Default.aspx 
  
 I have put together the code for you new custom layer. The first part is how to use it and the second part is the actually new class.  
  
             // Here I create my custom layer 
             SimpleCustomLayer customLayer = new SimpleCustomLayer(); 
  
             // Here I add my cusotm layer to the layers collection. 
             Map1.StaticLayers.Add("CustomLayer", customLayer); 
  
  
  
 _+_+_+_+_+ 
  
 New Class 
  
 _+_+_+_+_+ 
  
   
  
 using System; 
 using System.Collections.Generic; 
 using System.Text; 
 using System.Drawing; 
  
 // What this sample does is creates your own layer.  You can use this layer just like any other layers  
 // in the system.  The advantage is that you can place it where you want and it will seamlessly integrate 
 // with the rest of the system.  As you can see it is really easy to create your own layers. 
  
 // The basic flow of events is that when the map needs to draw it will first call the OpenCore. 
 // This is where you do anything special to get your source ready.  Then it will call the GetBoundingBox 
 // method to make sure the current extent of the map is within the are you have data.  If not then it will 
 // never call the DrawCore because there is no need.  Then if you are int he extent it wil call the DrawCore. 
 // The DrawCore is where you place your code that need to do the drawing on the canvas.  As you can see below 
 // it is faily simple. 
  
 namespace ThinkGeo.MapSuite.Core 
 { 
     class SimpleCustomLayer : Layer 
     { 
         protected override void OpenCore() 
         { 
             //  Here you should do anything you need to do it initilize your source. 
             //  Maybe for you it is nothing and if so you can leave it blank. 
         } 
  
         protected override void CloseCore() 
         { 
             //  Here you should do anything you need to do it close your source. 
             //  Maybe for you it is nothing and if so you can leave it blank. 
         } 
  
         protected override RectangleShape GetBoundingBoxCore() 
         { 
             // Here you will want to pass back a rectangle that defines the entire extent of 
             // of image source.  So if a user pans outside off of where you have imagry for the map 
             // control we will not try and fetch it.  If your data is for the whole world or you are 
             // fine to just passing back a transparent image if the user goes off the edge then you can use 
             // the default code I added. 
  
             //This assumes that your map is in decimal degrees and covers the whole world, if not you need to know the bounds. 
             return new RectangleShape(-180.0, 83.0, 180.0, -90.0); 
         } 
  
         protected override void DrawCore(GeoCanvas canvas, GeographyUnit mapUnit, System.Collections.ObjectModel.Collection labeledInLayers) 
         { 
             // Here is where you will call your API.  You will get a bitmap back and then draw it in the canvas. 
             // I have provided a mock method call to simulate what you will do. 
  
             Bitmap customImage = GetImage(canvas.CurrentWorldExtent.UpperLeftPoint.X, canvas.CurrentWorldExtent.UpperLeftPoint.Y, canvas.CurrentWorldExtent.LowerRightPoint.X, canvas.CurrentWorldExtent.LowerRightPoint.Y, (int)canvas.CanvasWidth, (int)canvas.CanvasHeight); 
  
             // Here we draw the image you generated to the canvas. 
             canvas.DrawWorldImageWithoutScaling(canvas.ToGeoImage(customImage), canvas.CurrentWorldExtent.GetCenterPoint().X, canvas.CurrentWorldExtent.GetCenterPoint().Y, DrawingLevel.LevelOne); 
  
             customImage.Dispose(); 
         } 
  
         private Bitmap GetImage(double upperLeftX, double upperLeftY, double lowerRightX, double lowerRightY, int screenWidth, int screenHeight) 
         { 
             // In here you would get your image and return it. 
             // I am just returning an image with some text so you can verify it works… 
  
             Bitmap customImage = new Bitmap(screenWidth, screenHeight); 
             Graphics g = Graphics.FromImage(customImage); 
             g.DrawString("SimpleCustomLayer Test", new Font("Arial", 20, FontStyle.Bold), Brushes.Black, new PointF(screenWidth / 2, screenHeight / 2)); 
             g.Dispose(); 
  
             return customImage; 
         } 
  
     } 
 }  
   
  
 David