ThinkGeo.com    |     Blog    |     Wiki    |     Support

Overriding DrawCore custom point style very slow

I have a custom pointstyle where extra shapes are drawn around the point (an ellipse, a line through the point, etc.) in the overriden DrawCore function. I noticed that the canvas.DrawArea + canvas.DrawLine functions are very slow when used together. Sometimes it takes >5 seconds to refresh the map when the point is in the current extent.

Below is the overriden DrawCore function in my custom pointstyle class.
I loop through the features, check if the feature is of my custom class type, and then draw a line on the map from the feature to 0, 0 as well as an ellipse around the feature.

protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
    foreach (Feature feature in features)
    {
        if (feature is VehicleFeature) //if the feature is my custom type VehicleFeature which inherits from Feature
        {
            PointShape location = (PointShape)feature.GetShape(); //get the pointshape from the feature

            var packageColor = new GeoPen(GeoColors.Red)
            {
                DashStyle = LineDashStyle.Dash
            };

            Collection<Vertex> vertices = new Collection<Vertex> { new Vertex(location), new Vertex(0, 0) };
            LineShape connectingLine = new LineShape(vertices); //create the connecting line

            //draw to the map
            canvas.DrawLine(connectingLine, packageColor, DrawingLevel.LevelOne);
            EllipseShape es = new EllipseShape(location, 30, ThinkGeo.MapSuite.GeographyUnit.DecimalDegree, DistanceUnit.Meter);
            canvas.DrawArea(es, packageColor, DrawingLevel.LevelOne);
       }
    }
    base.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers);
}

Now, if I remove either the DrawLine or DrawArea function so only one Draw function is there, it’s plenty fast enough.

Update: I tested with multiple DrawArea functions and it is fast. As soon as I add in a DrawLine function it’s slow.

Hi Dan,

I build a sample based on your code, but it looks the render speed is OK.

Could you please modify the sample to reproduce your problem?

9571.zip (101.8 KB)

Regards,

Ethan

Hi Ethan, you can see the problem reproduced if you zoom in close to one of the features. If you’re zoomed out far where the ellipse shape isn’t shown, it’s fast. But as soon as both the line and ellipse shape show, it’s really slow. I timed both .draw functions, and the drawarea function is ~500ms or less, where the drawline function is ~5000ms or more.

Hi Dan,

Thanks to point that, I found why it’s so slow.

You choose DashStyle = LineDashStyle.Dash for the line, and when you zoom into deeper, the dot density don’t reduce, so the line on screen(Most parts is out of screen but it still need be drawn because it’s one feature) is so long, and the dot number is so big. That’s the reason why it render so slow.

Please try the code as below:

                    Collection<Vertex> vertices = new Collection<Vertex> { new Vertex(location), new Vertex(0, 0) };
                LineShape connectingLine = new LineShape(vertices); //create the connecting line

                MultilineShape tmpLine = connectingLine.GetIntersection(canvas.CurrentWorldExtent);

                if (!tmpLine.Validate(ShapeValidationMode.Simple).IsValid)
                {
                    continue;
                }

                //draw to the map
                canvas.DrawLine(tmpLine, packageColor, DrawingLevel.LevelOne);

This code will split the line to only draw the part in current extent, so it’s very fast.

Because your logic is draw line follow current feature, so please choose layerOverlay.TileType = TileType.SingleTile, orelse the line in other tile won’t be drawn. And if current extent don’t contains base feature, the line won’t be drawn.

So, if your requirement is draw a line based on current feature, I suggest you build the line shape, and add it into other temproray layer, you can remove it after don’t need it. Caculate the feature and let other layer to render it is better choice.

Regards,

Ethan

Thanks Ethan! I will try your suggestion and get back to you on the status.

Edit: works great, thanks!

Hi Dan,

I am glad to hear that works!

Regards,

Ethan