Labels, rotation, and collision

Topics: SharpMap v0.9 / v1.x
Apr 19, 2013 at 11:06 AM
Hi,

I’ve got a label layer that is labelling major roads, but it’s a complete mess. I’ve tried enabling collision detection, but it doesn’t make any difference. Here’s a sample map tile.

And here’s the code generating the label layer:
LabelLayer labels = new LabelLayer("Labels");
SqlServer2008 labelsData = new SqlServer2008(ConfigurationManager.ConnectionStrings["WebMappingServices"].ConnectionString, "[roads]", "geom", "ID");
labels.DataSource = labelsData;
labels.SRID = 3857;
labels.LabelColumn = "REF";
labels.Style.CollisionDetection = true;
labels.Style.CollisionBuffer = new SizeF(50f, 50f);
map.Layers.Add(osmMotorwayLabels);
As you can see from the sample tile, the labels are overlapping like crazy and there appears to be no collision detection going on at all.

The second problem that I have is that I don’t want the labels to follow the line, but rather want to draw them as badges along the roads like this map on OpenStreetMap. The data doesn’t exist as point data, so I’m stuck using the line data, but I can’t see a way of telling SharpMap not to draw the label along the line—is this possible? If not, can anyone think of a way of processing the data beforehand so that I can generate points along the lines?

Thanks,

Dylan
Coordinator
Apr 20, 2013 at 10:40 PM
You can reduce the number of labels placed by setting the MultipartGeometryBehavior property to MultipartGeometryBehaviorEnum.Largest.
Secondly, you may want to set LabelFilter to LabelCollisionDetection.ThoroughCollisionDetection.

If you want to place a badge like Label on the map, you are probably best off using a CustomTheme, that transforms the line string to a MultiPoint and prepare a symbol to draw. To get those points, you can use some class of the LinearLocation namespace of NetTopologySuite (don't know it out of my head).

Hth FObermaier
Apr 21, 2013 at 11:19 AM
Thanks. The properties to reduce the number of labels work perfectly—it’s a much cleaner looking map now. I’ll look into the CustomTheme that you suggest using for the badge-style labels. Cheers.
Apr 21, 2013 at 3:39 PM
I’ve had a play with the CustomTheme and NetTopologySuite, and I came up with this code:
private LabelStyle GetOsmMajorRoadLabelStyle(FeatureDataRow feature) {
    LabelStyle style = new LabelStyle();

    ILineString linestring = (ILineString)feature.Geometry;
    Coordinate coord = LinearLocation.PointAlongSegmentByFraction(linestring.GetCoordinateN(0), linestring.GetCoordinateN(1), 50);
    feature.Geometry = new NetTopologySuite.Geometries.Point(coord);
    style.ForeColor = Color.Black;
    style.Font = new Font("Arial", 12);

    return style;
}
It transforms the linestring to a point, but has the undesired effect of causing the previous collision detection to stop working. I’m using the MultipartGeometryBehaviour and LabelFilter properties that you suggested earlier, but since adding the CustomTheme, all of the labels that were previously filtered out are now appearing again. Take a look at this sample tile to see what I mean.

Any idea what I could do to stop this from happening? I was happy with the filtering I had before, and I’m also happy to be able to convert the lines to points, but I’d like to be able to do both :)

Thanks,

Dylan