Labels.AddLabel() Crashed

Hi all. Can anyone help me? Thank you.
I want to draw a line with 3 labels. I do not want to use the Labels.Generate() method, because the position of the labels is constrained by enum tkLabelPositioning. The code is as follows.When I add one label, it is OK. But it is crashed when I add 2 or 3 labels.

        Shapefile sf = new Shapefile();
        sf.CreateNew("", ShpfileType.SHP_POLYLINE);
        Shape shp = new Shape();
        shp.Create(ShpfileType.SHP_POLYLINE);

        MapWinGIS.Point pt1 = new MapWinGIS.Point();
        pt1.x = 1;
        pt1.y = 1;
        MapWinGIS.Point pt2 = new MapWinGIS.Point();
        pt2.x = 5;
        pt2.y = 5;

        int index = shp.numPoints;
        shp.InsertPoint(pt1, ref index);
        index = shp.numPoints;
        shp.InsertPoint(pt2, ref index);

        int shpindex = sf.NumShapes;
        sf.EditInsertShape(shp, ref shpindex);

        sf.Labels.AddLabel("label0", 1, 1);
        sf.Labels.AddLabel("label1", 3, 3);
        //sf.Labels.AddLabel("label1", 5, 5);

        axMap1.AddLayer(sf, true);

Hello @Henry, and welcome.

Shapefile labels are 1-to-1 with the Shapes, in other words, you can only have one label per Shape (unless it is a multi-part Shape, but that’s a separate discussion). Since you only had one Shape in this Shapefile, it crashed when attempting to add the second label. [I don’t think this is documented very well].

Instead, for free-standing labels, you should use a Drawing layer, something like,

int handle = axMap1.NewDrawing(tkDrawReferenceList.dlSpatiallyReferencedList);
axMap1.DrawLabelEx(handle, "label11", 1, 1, 0);
axMap1.DrawLabelEx(handle, "label55", 5, 5, 0);

which results in

image

Regards,
Jerry.

1 Like

Thanks a lot. It works.
Now the labels and the line are in different layers. I want to move the line with the 3 labels follow. Can you give me some suggestions. The following code shows how to move the vertices on the line. Then how to move the labels with the line ? Thank you very much.

            Shapefile sf = axMap1.get_Shapefile(handle);
            sf.FastMode = true;
            sf.get_Shape(0).put_XY(0, 2, 2);
            axMap1.Redraw();

Sure.

Because the drawing layer was set up with the spatially-referenced coordinate system, you can use the same coordinates as your points in the line.

Now there’s good news and bad news regarding the Drawing Labels. On one hand, you can edit both the text and position of the labels by getting the list of labels, iterating them, and editing them.

Labels labs = axMap1.get_DrawingLabels(handle);
// change the position of the Label at index 0
labs.Label(0, 0).x = 2;
labs.Label(0, 0).y = 2;
labs.Label(0, 0).Text = "label22";

The down side is that you have to iterate the labels to find the one you want to edit - there is not an easy way to know which is which (since they don’t return distinct 'handle’s like Shapes do).

The alternative is to maintain your own .NET collection of the labels and their positions. When edits take place, you can clear the drawing labels, and re-add them all. If there are not many labels, the operation will be fast.

Hopefully that helps.
Jerry.

1 Like

Thank you for your patience.
The drawing labels are drawn on a " drawing layer". I have noticed this layer before. But I do not know the difference between the drawing layer and other layers. For example, if I want to draw a line, I have 2 ways to achieve it.
(1)

    Shapefile sf = new Shapefile();
    sf.CreateNew("", ShpfileType.SHP_POLYLINE);
    Shape shp = new Shape();
    shp.Create(ShpfileType.SHP_POLYLINE);

    MapWinGIS.Point pt1 = new MapWinGIS.Point();
    pt1.x = 1;
    pt1.y = 1;
    MapWinGIS.Point pt2 = new MapWinGIS.Point();
    pt2.x = 5;
    pt2.y = 5;

    int index = shp.numPoints;
    shp.InsertPoint(pt1, ref index);
    index = shp.numPoints;
    shp.InsertPoint(pt2, ref index);

    int shpindex = sf.NumShapes;
    sf.EditInsertShape(shp, ref shpindex);

    axMap1.AddLayer(sf, true);

(2)Another method:

    axMap1.DrawLineEx(0, 1, 1, 5, 5, 1, 1);

Then what is the difference between the 2 ways.

Best Regards,
Henry.

Hello @Henry

The Drawing layers are more intended for transient data (that which is displayed at run-time, but not part of the persisted data). For example, I’ve used them for sketch tools (drawing during mouse moves to collect geometry). And as we discussed, using it for Labels can get you past the 1-to-1 Shape-to-Label limit. But the Drawing layers have no built-in spatial smarts.

The standard Shapefile layers provide much more control for rendering, geospatial operations, and persistence to files or databases. These are generally the layers you should use for most operations. And if you still need fast processing (for example, moving vehicles), you can set Shapefiles Volatile property so that they are still drawn along with the Drawing layers (separately from the other data layers).

Regards,
Jerry.

1 Like

Great explanation. Your explanation is very clear. Now I have understood the difference and use of the two layers.
Thanks again for your answers.
Best Regards,
Henry.