Do you have an example of how to display multiple labels for a given point or feature?
Let's say I want to display population and city name for all the points on layer.
Label example:
Population: 2000
City: Kansas City
Do you have an example of how to display multiple labels for a given point or feature?
Let's say I want to display population and city name for all the points on layer.
Label example:
Population: 2000
City: Kansas City
Hi Peter,
Thanks for your post.
To implement this requirement, you could add two TextStyles into the CustomStyles collection. Following is some sample code about this using an InMemoryFeatureLayer:
private void DisplayMap_Load(object sender, EventArgs e)
{
winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);
InMemoryFeatureLayer tempLayer = new InMemoryFeatureLayer();
tempLayer.Open();
tempLayer.Columns.Add(new FeatureSourceColumn("Population"));
tempLayer.Columns.Add(new FeatureSourceColumn("City"));
tempLayer.Close();
Dictionary<string, string> columnValues = new Dictionary<string,string>();
columnValues.Add("Population", "2000");
columnValues.Add("City", "Kansas City");
Feature tempFeature = new Feature(new PointShape(0, 0), columnValues);
tempLayer.InternalFeatures.Add(tempFeature);
TextStyle populationLabel = new TextStyle("Population", new GeoFont("Arail", 12, DrawingFontStyles.Bold), new GeoSolidBrush(GeoColor.SimpleColors.Blue));
populationLabel.YOffsetInPixel = -15;
TextStyle cityLabel = new TextStyle("City", new GeoFont("Arail", 12, DrawingFontStyles.Italic), new GeoSolidBrush(GeoColor.SimpleColors.Red));
cityLabel.YOffsetInPixel = 15;
cityLabel.OverlappingRule = LabelOverlappingRule.AllowOverlapping;
tempLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(PointStyles.City1);
tempLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(populationLabel);
tempLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(cityLabel);
tempLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
LayerOverlay overlay = new LayerOverlay();
overlay.Layers.Add(tempLayer);
winformsMap1.Overlays.Add(overlay);
winformsMap1.CurrentExtent = new RectangleShape(-10, 10, 10, -10);
winformsMap1.Refresh();
}
Hope this helps and any more questions please let us know.
Thanks,
Sun
Peter / Sun,
There is even a better way than that. In the TextStyle when you specify the column name you can use brackets to specify more than one field at a time. For example you could use "[City] has a population of [Population]" as the column name and we will parse out brackets and replace them with the field values. you can use as many columns as you want in one text string. Of course you can also use multiple labels as Sun showed but I think using the brackets is a better way to mix the data in one label.
David
Peter,
We have created the Multiple Labels sample on the Code Community according to description by David that we implement both ways.
You can download it from code.thinkgeo.com/projects/show/multiplelabels
Thanks
James
Hi, I am trying to do a similar type of thing, but only one of the labels will show up.
Dictionary<string, string> columnValues = new Dictionary<string, string>();
columnValues.Add("AreaLabel", string.Empty);
columnValues.Add("PerimeterLabel", string.Empty);
Feature feature = inMemoryLayer.InternalFeatures[0];
AreaBaseShape abs = feature.GetShape() as AreaBaseShape;
PointShape ctrPt = abs.GetCenterPoint();
double area = abs.GetArea(map.MapUnit, AreaUnit.Acres);
string areaLb = string.Format("{0:0.000} {1}", area, AreaUnit.Acres.ToString());
columnValues["AreaLabel"] = areaLb;
inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City1("AreaLabel");
double perim = abs.GetPerimeter(map.MapUnit, DistanceUnit.Feet);
string perimLb = string.Format("{0:0.000} {1}", perim, DistanceUnit.Feet.ToString());
columnValues["PerimeterLabel"] = perimLb;
inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City2("PerimeterLabel");
inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping;
Feature label = new Feature(ctrPt, columnValues);
inMemoryLayer.InternalFeatures.Add(label);
So when debugging both the values for the labels are being added, but only the perimeter one will actually be displayed on the map. Any suggestions?
Hi Andy,
Thanks for your post.
There is a mistake in your code: you set the DefaultTextStyle two times, and this just leads to the second one replacing the first one. You have to add both of the TextStyle to the CustomStyles collection if you want to use two or more TextStyle for one layer. The code is just like the block I pasted on this thread.
Hope this helps and any more questions please let us know.
Thanks,
Sun
Hi Sun,
So I suppose the problem I am having is that, I need to have 2 labels that show up independent of each other (Area or Perimeter or Both). I can get either one to show up but when I try to have both of them show up, Only the one that I set
inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.City1("ColumnName");
with will show up. How can I set the DefaultTextStyle to Both the columns so that both of them can show up at the same time? Also, CustomStyles will not work because of existing implementation that uses DefaultTextStyle.
thanks for the help.
nevermind, I figured out how to get it to work. I read David’s post more carefully and that worked great. thanks for the help.
We are glad we could resolve your issue and thank you for giving us the idea for a usefull project for the Code Community. Do not hesitate to check the new projects that get posted daily! code.thinkgeo.com/