ThinkGeo.com    |     Documentation    |     Premium Support

How to get the Graphics/Device Context?

Hi,


I wanted to create a customized layer to support ENC chart by inheriting from Layer. On overwriting the DrawCore method, I would first draw the image which generated by the 3rd party control on the map. But the 3rd party control needs  a Graphics/Device Context, how to get it from the GeoCanvas?


Thanks


Rose



 


Rose,
 
Thanks for your post!
 
I think my suggestion solution is as following:
1) Create your own style inheriting from style and override core API.
2) In this style, add an event called something like OnENCChartDrawing.
3) In the override of draw core, call the event to get a bit map from the ENC chart control and then draw this bitmap to the canvas.
 
I did not try the 3rd party control of ENC chart, but personally I think you should create a Graphics to draw the ENC chat.
 
If you still have problem, if possible, you can send some codes to use ENC without using MapSuite component to draw a bitmap to the screen?
 
Any more problems just let me know.
 
Thanks.
 
Yale

Yale:


Thanks for your help!


I checked the 3rd party control, I can create a Graphics and draw the ENC chart on it to return a bitmap. Should I still create a customized layer by extending Layer and overwrite the DrawCore method?


How to overwrite the DrawCore method to draw  the ENC bitmap to the canvas?


Could you please show me some code snippet regarding to your suggestion you mentioned above? Attached is the sample code to use ENC in VB.net.


Thanks


 


Rose


 



871-ENCView.zip (181 KB)

Rose,


 Thanks for your post!
 
Because I cannot compile nor see the APIs in the ENC control, so I am not sure I am full understood how it works.  Attachment is the prototype with my ideas above, you can modify it any as you want!
 
You can put your following logic to generate the encBitmap in the following event of your App.

void encStyle_ENCDrawing(object sender, ENCDrawingEventArgs e)
{
   // Use enc to draw a bitmap as you said.
   Bitmap encBitmap = null;

   e.Bitmap = encBitmap;
}

Any more question just let me know!


 Thanks.
 
Yale

876-Post5961_Prototype.zip (11.7 KB)

Yale:


Thank you very much for the prototype!


Just a quick question, you created an instance of the ENCStyle in the formLoad event, but did not add it onto the winformsMap1, when is the encStyle_ENCDrawing method called? Is it called everytime the windormsMap1 redraws the overlays?


 


Thanks


Rose



Rose,


 I am so sorry I missed one statement , you have to add this style to the CustomeStyle for this Layer as following:

ENCStyle encStyle = new ENCStyle();
encStyle.ENCDrawing += new EventHandler<ENCDrawingEventArgs>(encStyle_ENCDrawing);
worldLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(encStyle);
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

The event will be called everytime the layer to be drawn.


Any more question just let me know!
 
Thanks.
 
Yale

Yale:


I added the code to generate the ENC bitmap using 3rd party control. But I don't quite understand your prototype.


You used the ENCStyle in the ShapeFileFeatureLayer, in the DrawCore() method,  for each feature in the layer, the  the bitmap will be drawn at the center location of the feature. That won't work. The bitmap is like a background chart, should only be drawn once.


Should I create a customized ENC layer?  Any info is greatly appreciated!


Thanks


Rose


 


 



Rose, 
  
 Thanks for your post! 
  
 I am sorry that I misunderstood your original attempt! If you want to set the bitmap from ENC as background, it is better you create your own customized layer which probably inherited from AdormentLayer. 
  
  
 And probably as ENCStyle showed, you can raise the event to get the bitmap from ENC control drawing just at the beginning of the DrawCore of your own ENCBackgroundLayer. 
  
 Let me know if you have any more problems. 
  
 Thanks. 
  
 Yale 


Hi, 
  
 I work for the company that provides the third party ENC drawing engine. 
  
 The answer to the question “how to get the graphics or device context in DrawCore?” is as follows (MapSuite Desktop Ed. evaluation in a control on a winforms app) 
  
         protected override void DrawCore(GeoCanvas canvas, …) 
         { 
             … 
                 
             System.Drawing.Bitmap bm = (System.Drawing.Bitmap)canvas.NativeImage; 
  
             Graphics g = Graphics.FromImage(bm); // here we have a graphics 
  
             System.IntPtr iphDC = g.GetHdc(); // here we have a DC 
  
            // Warning: don’t use the graphics whilst you have the DC - don’t mix and match 
  
             g.ReleaseHdc(iphDC); // release the DC handle when you are done 
         } 
  
 This code seems to work in my test application (with threading mode set to single) and I would be interested in your thoughts on it Yale (or other ThinkGeo people). 
  
 Andy

Andy : Rose 
  
   I wanted to correct one thing from Yale.  I would not inherit from AdornmentLayer as this are for things that are on top of the map and do not really use world coordinates, these would be things like North arrows, legends etc.  I would inherit from Layer or Overlay directly myself.  They function about the same. 
  
 On Andy’s code above I think it exactly what you can do to get the graphics object.  I would stop short of just the Graphics object as you can draw image directly on that and it is a bit safer then going after the handle itself.  Of course if you are careful then it is all good.  I would wrap the handle use in a try/catch just to be 100% sure you don’t want these things hanging around in case there is an exception.  My only other comment would to be really safe and make sure that the natice image is really a bitmap.  You could add a If(nativeimage is Bitmap) kind of thing just incase later you try and pass this the PdfGeocanvas or something that does not take a bitmap.   
  
   If from the third part component you get a bitmap back you an always work with the canvas directly.  It has API to draw bitmaps etc and that way if you wanted to use another kind of native image in the future for say a PDF then there would be no change necessary as the canvas abstracts that. 
  
 David 


Rose, 
  
   Not to post off topic but on your other post I wanted to say that was unprofessional of me to post what I did and am sorry for doing it.  I am very happy you are here in the forums posting and will help you out anyway we can. 
  
 David

Thanks for the information. Good suggestion about exception safety. 
  
 Yes, we inherit just from layer. I watched/listened to a presentation on your website which suggested this most appropriate for this application. 
  
 (If I get some time) I’ll experiment with testing the type of NativeImage first. If it isn’t a bitmap we can fall back to a more laborious technique which I think would be: 
  
 1/ Create bitmap and draw on it. 
 2/ Draw bitmap onto canvas (maybe I need to convert it into a GeoImage first) 
  
 My guess is that going direct to the graphics/dc will be faster. But if I’ve got both I’ll be well placed to check if that really is the case… 
  
 Thanks, 
  
 Andy

Andy, 
  
   If you are never going to use any of the other GeoCanvases such as PDF then they way you have it will be just fine.  I guess no sense engineering for something that may never happen.  Good luck and I am glad you my videos helpful! 
  
 David

Hi, 

I wonder have you ever worked it out? When it
comes to PDF converter process, I have another question, I wonder have
you ever tried to convert pdf to PNG or convert pdf to jpg before? As
for myself, I am testing the related PDF to BMP converting , PDF to PNG converting , and PDF to JPG converting programs these days. Do you have
experience about it? Any suggestion will be appreciated. Thanks in
advance.    







Best regards, 

Pan

Hi Pan, 
  
 I am sorry we don’t have more related experience because general we don’t need to convert PDF to other format. 
  
 About PDF related support, please view our PdfGeoCanvas class for more detail information. 
  
 Regards, 
  
 Don