How to include drawing layers in maps extent

2.9k Views Asked by At

I have added a MapPointLayer to a DotSpatial map so that I can draw a vehicles location on a map by updating a single feature in its feature set.

When a user then adds another layer, e.g. a shape file, I reset the map and zoom to its full extent. The issue I am having is that the drawing layers do not seem to be taken into account when this happens and if the drawing layers feature is located outside of the loaded layer, it is not displayed on the screen.

I've tried to determine the total extent required and set the maps ViewExtents to this value but it doesn't seem to work:

         var mapsMaxExtent = _mapControl.GetMaxExtent();

        _mapControl.MapFrame.DrawingLayers.ForEach(layer => mapsMaxExtent.ExpandToInclude(layer.Extent));

        _mapControl.ViewExtents = mapsMaxExtent;
2

There are 2 best solutions below

3
On BEST ANSWER

Adding the layer to the normal layers like gouldos suggested will also make the layer appear in the legend, which you may not want, and also adding it to drawing layers is not a good idea, since now you are drawing it twice.

You may want to take the approach of simply calculating what the combined extent would be using the ExpandToInclude method to expand the layer's extent to include the new points. The sample code below was working for me. This is actually a trick, and not the simple setting of the map's ViewExtent like it would seem. This will not work, for instance, if you simply grab the Extent of the Map or define a custom extent. Notice, I am very specifically grabbing the layer's extent, and not creating a copy or anything. When I call ExpandToInclude, I actually make the layer's extent larger. In this way, afterward the map is happy to accept zooms to views that include your new points. The down side is that if you attempt to zoom to that layer in the future, you will get the combined extent.

Possibly the best solution is to add a background layer that you can live with that covers the full extent. It could even be a white image layer set to the full extent that you need, or a point layer that you add to the MapLayer that simply has the minimum and maximum points or something. But that can be a little weird too.

As to why you can't zoom to points outside of the extent of your loaded layer, I have no earthly idea. This must be the consequence of some recently added feature because it used to not have this problem. It may be that this "feature" can be disabled, but I'm not sure how yet.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Topology;

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        private Extent env;
        IMapLayer layer;
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonOpen_Click(object sender, EventArgs e)
        {
            layer = map1.AddLayer();
        }

        private void buttonZoomToPoints_Click(object sender, EventArgs e)
        {
            Extent ext = layer.Extent;
            ext.ExpandToInclude(env);
            map1.ViewExtents = ext;
        }

        private void addLayer_Click(object sender, EventArgs e)
        {
            // Add
            Coordinate c = new Coordinate(1, 1);
            Coordinate c1 = new Coordinate(2, 2);
            FeatureSet fs = new FeatureSet(FeatureType.Point);
            fs.AddFeature(new DotSpatial.Topology.Point(c));
            fs.AddFeature(new DotSpatial.Topology.Point(c1));
            env = fs.Extent;
            MapPointLayer layer = new MapPointLayer(fs);
            map1.MapFrame.DrawingLayers.Add(layer);
            map1.Refresh();
        }
    }
}
0
On

Not sure if this is the intended way it should be used but by adding the drawing layer to the maps main layer collection this seems to mainly solve the issue. Only other issue is that when the layer has no data, it seems to default to a maxumum size which isn't ideal.

  var featureSet = new FeatureSet(FeatureType.Point);

  var mapLayer = new MapPointLayer(_featureSet) {Projection = _mapControl.Projection};

  // add to drawing layers so is superimposed on top of all other layers
  _mapControl.MapFrame.DrawingLayers.Add(_mapLayer );

  // need to add to main layer collection too so that it gets taken into account when zooming to full extent
  _mapControl.Layers.Add(_mapLayer);