ThinkGeo.com    |     Documentation    |     Premium Support

Markers and GetBitmap

Hello,


I'm attempting to produce an image from a map I have created with several layers.  When producing an image using Map.GetBitmap(), everything shows on the map except any markers.  I have tried using both SimpleMarkerOverlays and InMemoryMarkerOverlays.  Is there a way to go about doing this? Thank you.


-Dustin



Dustin, 
  
 I have the same requirement, and the same problem.  I am going to subscribe to this topic in order to keep informed. 
  
 Al Vigil

 


Hi Guys,
Currently, the GetBitmap method just supports LayerOverlay, SimpleMarkerOverlay and InMemoryMarkerOverlay. In your case, I think it should works normally, I did a demo with SimpleMarkerOverlay, but it works. Can you have a check the attachment?
Thanks for your suggestion, the better way should include all the overlays that can be used in WebEdition, I have submitted it to our work list and will work on that soon.
Thanks,
Johnny

Johnny, 
  
 How can I get the attachment?  You mention to have a check of the attachment, but I cannot find one. 
  
 Thanks, 
  
 Al Vigil

AI,


Sorry that i missed the attachment and thanks for your reminder. Here it is.


Thanks,


Johnny



002_001_Markers.zip (2.27 KB)

I believe I figured out the issue.  It seems that the markers do not appear on a map that hasn’t been loaded to a page.  I was trying to run the GetBitmap before the Map was rendered. If I use an InMemoryMarkerLayer, the markers simply do not appear in the image, but if I use a SimpleMarkerOverlay, an error is thrown stating the Overlay hasn’t been set to a refrence. Is there any way to force the map to load up either type of overlay before it’s rendered on the page?

 


Hi Dustin,
The GetBitmap works if the map object has been initialized, in other words, the map is created with various property and all the overlays has been added.  It doesn’t require the map that has been loaded to page. Please have a look at the code changed based on the sample I attached yesterday. It works fine for our test.


if (!Page.IsPostBack)
            {
                Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
                Map1.CurrentExtent = new RectangleShape(-13939426.6371, 6701997.4056, -7812401.86, 2626987.386962);
                Map1.MapTools.PanZoomBar.Enabled = true;
                Map1.MapTools.MouseCoordinate.Enabled = true;
                Map1.MapUnit = GeographyUnit.Meter;

                GoogleOverlay google = new GoogleOverlay("Google Map");
                google.JavaScriptLibraryUri = new Uri(ConfigurationManager.AppSettings["GoogleUri"]);
                google.GoogleMapType = GoogleMapType.Normal;
                Map1.CustomOverlays.Add(google);

                SimpleMarkerOverlay markerOverlay = new SimpleMarkerOverlay("MarkerOverlay");
                markerOverlay.DragMode = MarkerDragMode.Drag;
                markerOverlay.Markers.Add(new Marker(-8922952.93266, 2984101.58384, new WebImage(21, 25, -10.5f, -25f)));
                markerOverlay.Markers.Add(new Marker(-10830821.09801, 4539747.98328, new WebImage(21, 25, -10.5f, -25f)));
                markerOverlay.Markers.Add(new Marker(-12454955.13517, 4980025.26614, new WebImage(21, 25, -10.5f, -25f)));
                markerOverlay.Markers.Add(new Marker(-10772117.52067, 3864656.14956, new WebImage(21, 25, -10.5f, -25f)));
                markerOverlay.Markers.Add(new Marker(-13164290.75755, 4035875.09290, new WebImage(21, 25, -10.5f, -25f)));
                markerOverlay.Markers.Add(new Marker(-9754587.80028, 5156136.17929, new WebImage(21, 25, -10.5f, -25f)));

                Map1.CustomOverlays.Add(markerOverlay);

                Bitmap bmp = Map1.GetBitmap();
                bmp.Save(@"d:\c.png");
            }


 
Thanks,
Johnny

Johnny,


Yes, that works fine. However, if you add:


Map1 = new Map();


in front of all the code, it does not.  I am trying to declare my map programatically, so this would essentially simulate what I am experiencing. 


-Dustin 



Hi, Dustin 
  
 Can you show us the exception stack track information about this problem?  I am not sure whether the problem you had mentioned in the last reply is the same with mine. I have found that if you just construct a Map and call the GetBitmap method not in the life time of Page, and then the “reference not set to an instance of an object” excpetion will throw, and that’s because you don’t dump the map control into the container(ASP.NET Page), and we have fixed this problem, but I’m sorry to say that maybe you can’t get the latest auto build, because we are on vacation now and I don’t know the status of the auto build. Anyway, any progress about it we will let you konw firstly. 
  
 If you have additional questions about it, please let us know. 
  
 Thanks, 
  
 Khalil

Hi Khalil,


Thanks very much for looking into this.   Would the fix not be in the daily buld from 9/30? 


-Dustin


The stack trace follows:



[NullReferenceException: Object reference not set to an instance of an object.]

   ThinkGeo.MapSuite.WebEdition.Map.x6244ca6a809de265(Bitmap xdb0bfbdbb2208989, GdiPlusGeoCanvas xc140d122988ec053, Collection`1 xf262b00c93290895) +136

   ThinkGeo.MapSuite.WebEdition.Map.GetBitmap(Int32 width, Int32 height) +187

   ThinkGeo.MapSuite.WebEdition.Map.GetBitmap() +60

   CSSamples.UseDraggableMarkers.Page_Load(Object sender, EventArgs e) in D:\Program Files\ThinkGeo\Map Suite Web Full Edition 4.0\Samples\CSharp Samples\Samples\Markers\UseDraggableMarkers.aspx.cs:47

   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14

   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35

   System.Web.UI.Control.OnLoad(EventArgs e) +99

   System.Web.UI.Control.LoadRecursive() +50

   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627


 




Hi, Dustin 
  
 Yes, that’s right, this is the exception we have encountered. We have fixed just a moment ago, and the auto build might be completed in a couple hours, I don’t know when it will be available for you to download. Anyway, it will definitely be ready in tomorrow. Let me know if you still have issues then.  
  
 Thanks, 
  
 Khalil

Khalil,  
 You guys are awesome. Thanks so much.  I won’t be attempting until Monday, but will I just get the auto-build through the daily development download link?  
 -Dustin

Dustin,


Yes, please get it through helpdesk.thinkgeo.com/helpdesk/login.aspx.

If it doesn't fix your problem, or you still have additional questions, please let us know.


Thanks,


Khalil



Khalil, 
 I’ve downloaded the daily build version from yesterday, and now get a different error when trying to use the situation given above with the ‘Map1 = new Map()’ . Without that line, it works fine, however.  The error is: 
 [ArgumentException: The map unit is invalid, please set the MapUnit with a proper value. 
 Parameter name: mapUnit] 
    ThinkGeo.MapSuite.WebEdition.x6d719af406ea4c2c.x047d80e67809a4dd(GeographyUnit x23bf990a35721448) +79 
    ThinkGeo.MapSuite.WebEdition.x772a8f6257cef8ff.x2967fb7f3a43272e(Double xa2d0bc93f6aeaebe, GeographyUnit x254e2e3a28873bf5) +14 
    ThinkGeo.MapSuite.WebEdition.Map.get_ClientResolutions() +117 
  
 Thanks, 
 -Dustin

Dustin,


I can guess your code looks like:
Map map1 = new Map();
Layer layer1 = “todo: instance the layer”;
map1.GetBitMap();
If it is, it’s unable to work. Because the map doesn’t the know the spatial reference of the data, such as GeographyUnit, also there isn’t any information about BoundingBox, the width and height for the Bitmap etc. The webEdition needs them to query the features and calculate the resolution of drawing canvas. I think that’s why the error happened.
Thanks,
Johnny

Johnny,


That's not quite it, no. I have set the MapUnit and current extent, as well as the width of the bitmap.  The code doesn't work regardless of if I'm trying to make a bitmap, or just display it on a web page.  Essentially, it's the same code that Khalil had, plus one line.


 


 



if (!Page.IsPostBack) {
              Map1 = new Map();
              Map1.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
              Map1.CurrentExtent = new RectangleShape(-13939426.6371, 6701997.4056, -7812401.86, 2626987.386962);
              Map1.MapTools.PanZoomBar.Enabled = true;
              Map1.MapTools.MouseCoordinate.Enabled = true;
              Map1.MapUnit = GeographyUnit.Meter;

              GoogleOverlay google = new GoogleOverlay("Google Map");
              google.JavaScriptLibraryUri = new Uri(ConfigurationManager.AppSettings["GoogleUri"]);
              google.GoogleMapType = GoogleMapType.Normal;
              Map1.CustomOverlays.Add(google);

              SimpleMarkerOverlay markerOverlay = new SimpleMarkerOverlay("MarkerOverlay");
              markerOverlay.DragMode = MarkerDragMode.Drag;
              markerOverlay.Markers.Add(new Marker(-8922952.93266, 2984101.58384, new WebImage(21, 25, -10.5f, -25f)));
              markerOverlay.Markers.Add(new Marker(-10830821.09801, 4539747.98328, new WebImage(21, 25, -10.5f, -25f)));
              markerOverlay.Markers.Add(new Marker(-12454955.13517, 4980025.26614, new WebImage(21, 25, -10.5f, -25f)));
              markerOverlay.Markers.Add(new Marker(-10772117.52067, 3864656.14956, new WebImage(21, 25, -10.5f, -25f)));
              markerOverlay.Markers.Add(new Marker(-13164290.75755, 4035875.09290, new WebImage(21, 25, -10.5f, -25f)));
              markerOverlay.Markers.Add(new Marker(-9754587.80028, 5156136.17929, new WebImage(21, 25, -10.5f, -25f)));

              Map1.CustomOverlays.Add(markerOverlay);

              Bitmap bmp = Map1.GetBitmap(300, 150);
              bmp.Save(@"d:\c.png");
           }


Does that help at all?  Thanks.
-Dustin

 


Dustin,
The error comes from the line “Map1 = new Map()”. In this way, you treat the map as a class instead of a Web UI control, there isn’t ViewState, Sessesion state for the map control now. But at the same time, the Map1 comes from the HTML element in .aspx. In other words, the ASP.net will get an idea that there are two Maps in the page, one from HTML element without any property, another one is what you have defined using code “Map1 = new Map()”. When the page begin to load, the map defined in .aspx without any property will throw the exception.
Hope the above is helpful to you. Thanks,
Johnny

Johnny, 
 Thanks for the explanation, I appreciate that.  I guess I’m back to my original question, though. Is there a way to generate an image before the map is rendered on the page?  I’m moving this project to the services version to accomplish pretty much the same thing, but I’m just curious at this point. Thanks again! 
 -Dustin

Dustin,


I’m sorry but I need to say there is no way to generate the cache image for GoogleOverlay and markers before loading the map. In WebEdition, the Google JavaScript library is used to request the Google images on client side, and markers also are request from client side, so the map is unable to get Google Images and the markers if we don’t load the map.
A workaround is that you can use GoogleMapLayer as the base layer, and display the markers with InMemoryFeatureLayer instead. In this way, we can easily use TileCache object in Service Version to generate the cache before loading.
Sorry for the inconvenience.
Johnny

Hi All, 
 I am new to maps and starting to compile 'Helloworld" maps - it would be my first map. I am using Web Edition. I am getting this error and any help would be appreciated: 
  
 Error: 
 The map unit is invalid, please set the MapUnit with a proper value. 
 Parameter name: mapUnit  
 Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.  
  
 Exception Details: System.ArgumentException: The map unit is invalid, please set the MapUnit with a proper value. 
 Parameter name: mapUnit 
  
  
  
 My code looks like this, in page_load : 
  
  // Set the Map Unit. The reason for setting it to DecimalDegrees is that is what the shapefile’s unit of measure is inherently in. 
                 Map1.MapUnit = GeographyUnit.DecimalDegree; 
  
                 // We create a new Layer and pass the path to a Shapefile into its constructor. 
                 ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@“C:\Program Files\ThinkGeo\Map Suite Web Evaluation Edition 5.0\Samples\CSharp Samples\SampleData\World\cntry02.shp”); 
  
                 // Set the worldLayer with a preset Style, as AreaStyles.Country1 has YellowGreen background and black border, our worldLayer will have the same render style.  
                 worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1; 
  
                 // This setting will apply from ZoonLevel01 to ZoomLevel20, that means we can see the world the same style with ZoomLevel01 all the time no matter how far we zoom out/in. 
                 worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; 
  
                 // We need to add the world layer to map’s Static Overlay. 
                 Map1.StaticOverlay.Layers.Add(worldLayer); 
  
                 // Set a proper extent for the map, that’s the place you want it to display. 
                 Map1.CurrentExtent = new RectangleShape(5, 78, 30, 26);