ThinkGeo.com    |     Blog    |     Wiki    |     Support

Scaling text styles

I want to provide “world units” as a size for some of my TextStyles.

Right now, all my TextStyle sizes are in pixels, so the size of the text doesn’t change regardless of the zoom level. However, I would like to give the user the option of setting the units as nautical miles, degrees, meters, etc. where the size value is that many units. For example, a size of 5 and a unit of “Nautical Mile” would make the text appear as big as 5 nautical miles on the map.

This would be useful for labeling oceans, continents, etc.

So the text should get smaller as I zoom out, and bigger as I zoom in.

Below is an example from a different mapping app. The text unit is set to Nautical Miles, with a size of 10. As you can see, zooming in closer makes the text bigger. I then use the measure tool to confirm the size of the text. It shows ~10 nautical miles (the red text; easier to see if you open the .gif in a new window).

I messed around a bit with the older ScalingTextStyle project on the samples page, but can’t get it working properly from there. Any help would be great! Thanks!

Hi Dan,

Just like you mentioned, we have the ScalingTextStyle sample which dynamic change the the text font follow scale value for different zoomlevels.

But it don’t contains the value conversion between different map unit.

I think your target should contains two parts:

Part A: Font size change follow zoomlevel change, you can find related logic in the sample
Part B: Font size change follow user choose different size and map unit for the same zoomlevel, you should want to implement that by a custom class, I think you can set a base map unit then convert other items around it.

Then you should want to merge the result of part A and part B, then it should be what you want.

Wish that’s helpful.

Regards,

Ethan

How am I supposed to figure out what the max/min scale should be that’s used in the scalingtext example?

Basically I just need to get one unit working properly, then I can convert the rest easily enough. Let’s say I want to use meters. I add a feature with a label whose textstyle has a size of 10. So the font should appear as 10 meters in height on the map. It should get smaller as I zoom out, and bigger as I zoom in.

Hi Dan,

Thanks for your explain about your scenario.

In ScalingTextStyle sample it specified 4 values: MaximumScale, MinimumScale, MaximumSize, MinimumSize

That’s for make the font size get changed follow scale changed, it don’t care about whether the font size is drawn just like the 10 meters you want, so you cannot directly use it’s logic.

Here I provide you some sample code, you can refer it to calculate your font size for different zoomlevel, wish it’s helpful:

        // For meter(map unit) you can just use the same line, but for decimal degree you need to make the line locate in same latitude or near it
        // Here we build a vertical line to calculate font size(font height)
        // In the sample code the map unit we think is meter
        // p1 and p2 is the endpoint of a line with length equal 10 meters
        PointShape p1 = new PointShape(0, 0);
        PointShape p2 = new PointShape(0, 10);

        // We thought the heightInPixel is the font in current zoomlevel
        float heightInPixel = ExtentHelper.GetScreenDistanceBetweenTwoWorldPoints(canvas.CurrentWorldExtent, p1, p2, canvas.Width, canvas.Height);


        GeoFont font = new GeoFont();
        font.Unit = DrawingGraphicsUnit.Pixel; // Set the unit to pixel also
        font.Size = heightInPixel;

Regards,

Ethan

Hi Ethan, thanks for the code snippet. I’m getting closer but not quite there yet. Just to clarify, when I said the map unit was meter, I didn’t mean that the property MapUnit was meters. I just mean that the user wanted the font size to be in meters.

My actual MapUnit will always be in Decimal Degrees.
So let’s again say the user selected the font unit to be in meters, with a size 10.

If I create the two point shapes in your example and then get the heightInPixel, that’s doing it from decimal degrees right? So how can I convert that length into other units, like meters, miles, etc.

Hi Dan,

If your map unit is decimal degree, I think you can did that like this:

        // 33, 42 is just a sample, you should want to modify it in your code
        PointShape p1 = new PointShape(33, 42);

        PointShape p2 = new PointShape(33, 42);
       
        // the value 100 and unit should want to be modified
        p2.TranslateByOffset(0, 100, GeographyUnit.DecimalDegree, DistanceUnit.Meter);

Regards,

Ethan

Thanks Ethan! I’ve tested a few different units and it seems to be working great.

Hi Dan,

I am glad to hear that’s helpful.

Regards,

Ethan