ThinkGeo.com    |     Blog    |     Wiki    |     Support

Displaying Labels of 2 or more layers with the same fontstyle

Is there a way to reuse the same FontStyle for multiple layers without creating multiple FontStyle instances?

For example, take a basic WpfMap with one overlay.

Create a new TextStyle instance.

Create a new ShapeFileFeatureLayer from an existing shp file, and set its ZoomLevel01.DefaultTextStyle to the single instance.

Create a second ShapeFileFeatureLayer from a different shp file, and also set its ZoomLevel01.DefaultTextStyle to the same instance.

Add both to the map’s overlay and refresh the map.

Only the second layer’s labels will show.

Hi Fred,

Thanks for your question, one instance of TextStyle can be reused for more than 1 layer, could you please paste some demo codes here or please check the attached sample to see if there is any difference compared with yours? It includes the demo shapefiles - “world country” and “World Major cities” in “Bin” folder, it’s based on the stable ThinkGeo WPF version 12.1.3. In this demo, one instance of TextStyle is used for showing country names and the names of major cities in the world, all works fine on my side, could you please take a check?

One thing is that a similar demo with ThinkGeo.MapSuite.WPF 10.6 based on .NET Framework is checked on my side as well.

Any question or idea please feel free to let me know. Hope it helped.

Regards,
Johnny

WpfLabelingSample.zip (3.2 MB)

Greetings, Johnny

Thank you for the response and full code example.

That example looks great if the database column you want displayed is the same name for both shapefiles.

How would that example work if say you wanted to display “CURR_TYPE” from world layer and “MED_AGE” from the major cities shape layer, and didn’t want 2 TextStyle instances?

When trying to set the TextColumnName property:

worldLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextColumnName = “CURR_TYPE”;
majorCitiesShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextColumnName = “MED_AGE”;

…only the major cities shape layer labels display.

Fred,

Yes, if 2 columns are different, only the 2nd works, the reason is that the “TextStyle” is “Reference Type”, instead of “Value Type”. From my experience, I suggest creating different instance of “TextStyle” for different shape files, it decreases the risk of the application, it also simplify the complex of application maintenance. “TextStyle” is not a big object, better that avoiding too many global variables in an application.

Here is an option of only creating 1 copy of TextStyle, but use it for more than 1 layer. However, it doesn’t work as expected in WPF. Here are some codes:

majorCitiesShapeLayer.DrawingFeatures += MajorCitiesShapeLayer_DrawingFeatures;
majorCitiesShapeLayer.FeatureSource.GettingFeaturesByIds += majorCitiesFeatureSource_GettingFeaturesByIds;

In the 2 events, we can change the drawing column as expected:

private void majorCitiesFeatureSource_GettingFeaturesByIds(object sender, GettingFeaturesByIdsFeatureSourceEventArgs e)
{
    e.ReturningColumnNames.Add("NAME");
}

private void MajorCitiesShapeLayer_DrawingFeatures(object sender, DrawingFeaturesEventArgs e)
{
    e.DrawingZoomLevel.DefaultTextStyle.TextColumnName = "NAME";
}

Very sorry for the inconvenience. Please try creating different instances temporarily.

Thanks,
Johnny

We’re using WPF, so went with the new instance approach. Thanks.

You are welcome, Fred. I was thinking that this should be a bug in WPF under multi-thread mode, I have submit it to our internal issue tracking system, and then someone can dig into further in future.

Regards,
Johnny

Greetings - any chance this issue has been dug into? Thanks.

Hi Fred,

In fact our team discuss about that, and we think it’s not a bug, as below is some detail description about it.

  1. The reason we need to set different style instance for each layer is our map work under multiply thread mode, in one layer each tile will render tile image with the same style. if you use same style to different layer and change the value (for example “TextColumnName”) when map is drawing(refresh, pan, zoom), the result is uncontrolled.

  1. We think there are two scenarios here:
    Scenario one, you want to set the same style to different layer, target is if you modify the value of the style, all layers get changed. Because the style is reference type, you can just assign the same instance to different layers and make it works.

Scenario two, you want to declare one object StyleA, then use it for different layers with small change. We suggest you build a simple function for example GetTextStyleByColumnName(“ColumnName”) to avoid duplication code. Because you need to make sure the styles works correct in different layers, which means the styles have to be different instances, keep one object cannot save your resource. You can choose CloneDeep the style every time, but the StyleA only point to the last layer.

  1. TextStyle nearly don’t takes system resource, because for font we have inner cache logic.

  2. If you think you still need to use the style like you mentioned before, could you please give us more detail description about your scenario, so our development team and discuss about it. You can also build a simple sample to let us know the scenario.

I hope that’s helpful.

Regards,

Ethan