ThinkGeo.com    |     Documentation    |     Premium Support

Options for adding Labels to a marker layer

Hi,


 


We used an InMemoryMarkerOverlay with an WebImage of a vehicle to represent the location of vehicles for our customer.


We need to display a label for the truck registration on the map so the plan was to place this over the icon for the vehicle.


This turned out not to be possibe as the label was clipped as we used the offset to move the label towards the top of the image. There was no issue in placeing the label over the icon for the vehicle but this would not do for our requirements.


This left 2 other options to consider



        
  1. Change the InMemoryMarkerOverlay  to an InMemoryFeatureLayer and have more percise control over the labellling

  2.     
  3. Retain the InMemoryMarkerOverlay  and add a seperate inMemoryFeature layer for the labels only


There was an issue with option 1. I could get PointShapes displaying on the map without any problems but was not sucessful in changing the image of the PointFeature to the required image that we need.


Can you have a brief look and let me know where I've gone wrong [The code below is taken from 2 different methods but joined here for the purpose of the post]


 // Create Layer

            LayerOverlay overLayer = new LayerOverlay(layerName);

            overLayer.IsBaseOverlay = false;

            overLayer.IsVisibleInOverlaySwitcher = true;


            InMemoryFeatureLayer vehicleLayer = new InMemoryFeatureLayer();

            vehicleLayer.Name = "Vehicles";

            vehicleLayer.FeatureSource.Open();

            vehicleLayer.Columns.Add(new FeatureSourceColumn(VEHICLEREG_LABEL_COLUMN, "string", 100));

            vehicleLayer.FeatureSource.Close();


           

            GeoImage truck = new GeoImage(markerWidth, markerHieght);

            string fullpath = MapPath(iconUrl);

            truck.PathFilename = fullpath;


            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.Image = truck;

     // vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(truck);


            vehicleLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.IsActive = true;

            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.BestPlacement = true;

            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.RequiredColumnNames.Add(VEHICLEREG_LABEL_COLUMN);

            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextColumnName = VEHICLEREG_LABEL_COLUMN;

            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.XOffsetInPixel = markerImageOffsetX;

            vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.YOffsetInPixel = markerImageOffsetY;

            vehicleLayer.IsVisible = true;


            overLayer.Layers.Add("Vehicles", vehicleLayer);


            this.Map1.CustomOverlays.Add(overLayer);


///////////////////////////////////////////

            // Code in Seperate method to add the features

            LayerOverlay overlay = (LayerOverlay)this.Map1.CustomOverlays[targetLayer];

            InMemoryFeatureLayer vehicleLayer = (InMemoryFeatureLayer)overlay.Layers["Vehicles"];

           


            Feature vehicle = new Feature(longitude.Value, lattitude.Value, id);

            vehicle.ColumnValues[VEHICLEREG_LABEL_COLUMN] = "vehicle reg";


            vehicleLayer.InternalFeatures.Add(vehicle);

            vehicleLayer.IsVisible = true;

            overlay.Redraw();




With respect to Option 2 above - Is this a viable option.


What would the impact of creating a InMemoryFeatureLayer seperate layer for labels be [outside from the fact that the layers could be switched on or off as required and also that that the Vehcile layer is independant fromthe labels]. Are there performance considerations.


We have to take into account with the decision above that we will proablably be adding a vehicle breadcrumb also but there are some fairly good samples on this in your site,


Rgds,


Liam



Liam, 
  
 Thanks for your post,  
  
 For your two solutions, I talked them one by one below: 
  
 1, The first solution, the track image cannot be changed correctly, that is not our problem, please use the following code to instead of the current code: 
  
  vehicleLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(Server.MapPath(“YourIconUrl”))); 
  
 I tested it, the code above can display the icon correctly. 
  
 2, I don’t suggest you to use seperate layers to control the truck and truck label, first the performance considerations, second, more much code, you should code the logic to control the label location exactly with the truck. If it is unnecessary, please keep your first solution, it is easy to control the label, just need to through the text style. 
  
 Any more questions please let us know, 
  
 Thanks, 
  
 Scott,

Hi Scott, 
  
 I had similar question based on these requirements. I ran into similar problem what Liam is mentioning. 
  
 For some data I have used solution 1  and for some data solution 2 (to take advantage of  markers features to provide poup on hover). 
  
 Is it possible to avoid  clipping of label in InMemoryMarkerOverlay ? 
  
 For solution 1, I want the images (InMemoryFeatureLayer) to go over  marker images in other overlay. Or in other words can we have InMemoryFeature layer (overlay) placed on top of a InMemoryMarkerOverlay and yet be able to see popups from underlying marker overlay. 
  
 Regards, 
 Anil

Anil,


I think your requirements is that you need an InMemoryFeatureLayer to display the truck with its label and there is another InMemoryMarkerOverlay to display the poppup when you click on the truck, is that right? If that, please follow the steps below:


1, Create the InMemoryFeatureLayer first for truck images and its label,  it is easy to do, you just need to set the point style and text style for the InMemoryFeatureLayer.


2, Create the InMemoryMakerOverlay and set the properties for the popup according to your requirements.


Also about the truck label issue, please refer the following code sample:


wiki.thinkgeo.com/wiki/File:...100126.zip


Any more questions please let us know again,


Thanks,


Scott,



Hi Scott, 
  
 Step 1 is clear. 
 For Step 2, I have following questions: 
 a) For InMemoryMarkerOverlay can we have popups without markers? Should we use PointMarkerStyle or its child classes? 
 b) I want to display different popup information based on certain column values on the feature object. How do we achieve this one? There is no method GetPopups() to override similar to GetMarkers(). 
  
 Regards, 
 Anil

Anil,


For your questions I answered them one by one below:


(a), Yes, you can have popups without markers, you can add the popups to the map directly, here is the sample code below:


 



 PointShape position = new PointShape(-95.28109, 38.95363);
                StringBuilder contentHtml = new StringBuilder();

                contentHtml.Append("                    .Append("src='../../theme/default/samplepic/lawrencecity.jpg'/> Lawrence is a city in Northeastern Kansas")
                    .Append("in the United States. Lawrence serves as the county seat of Douglas County, Kansas. Located 41 miles west ")
                    .Append("of Kansas City, Lawrence is situated along the banks of the Kansas (Kaw) and Wakarusa Rivers. It is considered ")
                    .Append("governmentally independent and is the principal city within the Lawrence, Kansas, Metropolitan Statistical Area, ")
                    .Append("which encompasses all of Douglas County. As of the 2000 census, the city had a population of 80,098, making it ")
                    .Append("the sixth largest city in Kansas. 2006 estimates[3] place the city's population at 89,110. A quintessential")
                    .Append("college town, Lawrence is home to The University of Kansas and Haskell Indian Nations University.
")
                    .Append("                     .Append("target='_blank'>
more about Lawrence city...</a>");

                CloudPopup samplePopup = new CloudPopup("samplePopup", position, contentHtml.ToString(), 400, 290);
                samplePopup.AutoSize = true;
                samplePopup.AutoPan = true;
                samplePopup.HasCloseButton = true;
                Map1.Popups.Add(samplePopup);
(b), You can get the certain information of feature through the following code:


 



PointShape position = new PointShape(-95.28109, 38.95363);
                StringBuilder contentHtml = new StringBuilder();

                contentHtml.Append("" + yourFeature.ColumnValues["YourKey"] + "");

                CloudPopup samplePopup = new CloudPopup("samplePopup", position, contentHtml.ToString(), 400, 290);
                samplePopup.AutoSize = true;
                samplePopup.AutoPan = true;
                samplePopup.HasCloseButton = true;
                Map1.Popups.Add(samplePopup);
Any more questions please let me know again,


Thanks,


Scott,



Hi Scott,


That worked perfectly, thank you and apologies for the late feedback.


One thing I did notice though is that the features are not available at client side in the same way as markers are available at client side from the InmemoryMarker overlay. [For performance reasons we had where possible added markers on client side and recreated them at server side on postback.]


However we can probably in this case work around this as the screen in question needs to regularily go back to the database to update the vehicle, vehicle breadcrumb (and other item) positions.


Best Regards,


Liam



Hi,


I have another related query.


Our map uses a combination of InMemoryMarkerLayers [standard markers] and InMemoryFeatureLayers [vehicle tracking with labels for the reg.]


The page has a grid and a map and the map displayes the vehicle(s) selected in the grid.


The map was in an update panel along with the grid and all worked fine untill IE ran out of memory :)'


I fully understand that this is not an issue with ThinkGeo but rather an AJAX issue but was wondering if there is a workaround.


The Callback for fleet tracker sample seems to use client side markers but it would for us need to work with the inMemoryFeature Layer


The InMemory feature layer that we use would also need to be refreshed [I'm unsure if it can be done in the sme way as the sample] and I have a concern whether using the map layer refresh functionality would easily allow me to update the grid also without any AJAX memory issues.


Any ideas?


Liam



Liam, 
  
 Thanks for your post, 
  
 For your solution, if you want to use InMemoryMarkerLayers for vehicles and InMemoryFeatureLayers for vehicle labels by ajax way, the update panel is the only way to implement it, because the InMeoryMarkerLayers and InMemoryFeatureLayers are the objects of server side, not the client side, if you want to implement it by client side, please use the callback method just like the fleet tracker sample. It can increase the performance vastly. I really don’t know why you have to use the InMemoryMarkerLayers and InMemoryFeatureLayers to deal with the vehicles. 
  
 So I have suggestions for your solution below: 
  
 1, Use the callback way to deal with the vehicles and their labels.  
 2, Use the update panel to wrap the datagrid control so that it could be implemented the ajax functionality. 
  
 If it is possible I think you can develop your own application based on the FleetTrackerAjax sample according to my suggestions above,  
  
 Any more questions please let me know, 
  
 Thanks, 
  
 Scott,

Hi Scott,


Just to clarify, we were using the InMemoryMarker overlays exclusively up to now and only last week has to change the layer that we displayed the vehicles on to an InMemoryFeature layer due to the requirement to display Vehicle Labels and to have more percise control over labeling. [See my original post].


We are using InMemoryMarker overlays for other items on the map and the InMemoryMarker Overlays are not used for the vehicles


Our solution currently consists of 2-3  InMemoryMarker overlays and an Overlay containing 2 InMemoryFeatureLayers [One for the truck and one for the breadcrumb]. If there was a way to control the labels with the InMemoryMarker Overlay without the labels getting clipped then it would have been better for us.


I referred to the sample here for guidance wiki.thinkgeo.com/wiki/File:...100126.zip which used the InMemoryFeatureLayer for the vehicle.


With the FleetTrackerAjax sample you refer to, I assume its the one here vehicletracking.thinkgeo.com/ajax/ in which case as I understand it we would need to purchase the FleetTrackerAjax sample to use the code or is everything we need here wiki.thinkgeo.com/wiki/Map_S...order=desc. Can you confirm.


Thanks for your help,


Liam


 



Liam,


For your first question about control the labels with InMemoryMarkerOverlay, there is a way can implement your requirement below:


 



  InMemoryMarkerOverlay markerOverlay = new InMemoryMarkerOverlay("MarkerOverlay");
                markerOverlay.ZoomLevelSet.ZoomLevel01.DefaultMarkerStyle.WebImage.ImageWidth = 21;
                markerOverlay.ZoomLevelSet.ZoomLevel01.DefaultMarkerStyle.WebImage.ImageHeight = 25;
                markerOverlay.ZoomLevelSet.ZoomLevel01.DefaultMarkerStyle.WebImage.ImageOffsetX = -10.5f;
                markerOverlay.ZoomLevelSet.ZoomLevel01.DefaultMarkerStyle.WebImage.ImageOffsetY = -25f;
                markerOverlay.ZoomLevelSet.ZoomLevel01.DefaultMarkerStyle.WebImage.ImageVirtualPath = "../../theme/default/img/marker_blue.gif";
                markerOverlay.ZoomLevelSet.ZoomLevel01.DefaultMarkerStyle.WebImage.Text = "Test";
                markerOverlay.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
                Map1.CustomOverlays.Add(markerOverlay);   
You just need to set the properties for WebImage of MarkerOverlay, you can set the image offset values to control the label's location on the marker.


For your second question, the FleetTrackSample is our product that include two samples, one is ajax sample, another is client-server sides sample, it shows the detail information and code for you, but you should purchase it first. Also here is a free sample for you, maybe you can check it first as you mentioned:


wiki.thinkgeo.com/wiki/File:...ker_CS.zip


This is a ajax sample for fleettracker, but it is just a light version than the product version of FleetTracker. You can try it first.


Any more questions please let me know,


Thanks,


Scott,



Hi Scott,


Thanks for your response. With respect to the marker label, our requirement was to have the label sitting above the marker and we found that the label was clipped once the label was moved above the marker, but I will give it another go.


Thanks for the link and the clarification.


Will let you know how it goes.


Liam



Liam, 
  
 That’s great! When you work on the application if you encounter any problems please let us know again, also just let you know currently, if you want to display the label on the marker layer, this is the only way to implement it what I mentioned above, I suggest you to use InMemoryFeatureLayers to instead of it and it can control the label’s placement better. 
  
 So when you encountered any new problems please let us know again and if it is possible please send simple sample so that we can reproduce it properly. 
  
 Thanks, 
  
 Scott,