How do you limit the map extent in ArcGIS Runtime .NET 100.2

697
4
01-12-2018 08:24 AM
NathanRaley
New Contributor III

How can you set the maximum extent for the MapView in the .NET runtime version 100.2?

I've tried intercepting the OnViewPointChanged, but my viewpoint doesn't exactly match the bounds that I had set, I am assuming due to the zoom level scaling or something of that nature?

So then I tried on my setup, 

Snippet

            // Set the current viewpoint/extent of the map and animate to it            await SetViewpointGeometryAsync(MapBounds).ContinueWith((prevTask) =>            {                 _viewPointBounds = GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;                 _prevBounds = _viewPointBounds;             });

and on my event handler:

Snippet

private void OnViewPointChanged(object sender, EventArgs e) {     var newBounds = GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry;       if (!GeometryEngine.Within(newBounds, _viewPointBounds))         SetViewpoint(new Viewpoint(_prevBounds));     else        _prevBounds = newBounds; }

This works great for the first time I load the map, but when I set up the map for another view, it ends up stuck at the old one, despite my _viewPointBounds and _prevBounds being reset via the code above in the setup that is called again.

Any ideas?  I feel like I am pretty close, but I'm just missing something.

4 Replies
MarkCollins
Occasional Contributor

Did you ever find a solution to this? I'm trying to do the same thing.

Reply
0 Kudos
NathanRaley
New Contributor III

None that provided a descent user experience.  It was very choppy and inconsistent.

Reply
0 Kudos
MatthiasPorges
New Contributor

Not nice, but works. Also seems pretty smooth. Probably good enough for production.

Define an envelope:

private Envelope _bounds=
    new Envelope(
        new MapPoint(MAP_BOX_WEST, MAP_BOX_NORTH, SpatialReferences.WebMercator),
        new MapPoint(MAP_BOX_EAST, MAP_BOX_SOUTH, SpatialReferences.WebMercator));

Now make a polygon as well, because some GeometryEngine operations don't work with Envelopes for some reason:

private Polygon _boundsPolygon = EnvelopeToPolygon(_envelope);

private static Polygon EnvelopeToPolygon(Envelope envelope)
{
    return new Polygon(new MapPoint[]
    {
        new MapPoint(envelope.XMin, envelope.YMin, SpatialReferences.WebMercator),
        new MapPoint(envelope.XMax, envelope.YMin, SpatialReferences.WebMercator),
        new MapPoint(envelope.XMax, envelope.YMax, SpatialReferences.WebMercator),
        new MapPoint(envelope.XMin, envelope.YMax, SpatialReferences.WebMercator)
    });
}

Finally add a ViewpointChanged event:

private void MapView_ViewpointChanged(object sender, EventArgs e)
{
    var selected = (MapPoint)MapView.GetCurrentViewpoint(ViewpointType.CenterAndScale).TargetGeometry;
    bool legal = GeometryEngine.Contains(_bounds, selected);

    if (!legal)
    {
        SetViewpoint(GeometryEngine.NearestCoordinate(_boundsPolygon, selected).Coordinate);
        return;
    }
}

This method changes the viewpoint back to a legal state. Also prevents user interaction during the animation.

private async void SetViewpoint(MapPoint point)
{
    MapView.InteractionOptions.IsEnabled = false;   //Make sure to initialize MapView.InteractionOptions to avoid NullReferenceException
    await MapView.SetViewpointCenterAsync(point);
    MapView.InteractionOptions.IsEnabled = true;
}

Reply
0 Kudos
NathanRaley
New Contributor III

Yes, we were trying something like that.  However, since it is on the "changed" event and not a "changing", we were receiving some very weird rubber banding since the viewpoint had already changed and started rendering as opposed to intercepting it prior to the change/render.

Reply
0 Kudos