[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/SharpMap/SharpMap/main/SharpMap/Map/MapViewportGuard.cs [Back]  [Original]

using System;
using System.Drawing;
using GeoAPI.Geometries;

namespace SharpMap
{
    /// 
    /// Utility class that checks Viewport min/max Zoom and constraint
    /// 
    [Serializable]
    public class MapViewPortGuard
    {
        private double _minimumZoom;
        private double _maximumZoom;
        private Envelope _maximumExtents;
        private double _pixelAspectRatio;
        const double MinMinZoomValue = 2d * double.Epsilon;

        /// 
        /// Gets or sets a value indicating the minimum zoom level.
        /// 
        public double MinimumZoom
        {
            get { return _minimumZoom; }
            set
            {
                if (value < MinMinZoomValue)
                    value = MinMinZoomValue;
                _minimumZoom = value;
            }
        }

        /// 
        /// Gets or sets a value indicating the maximum zoom level.
        /// 
        public double MaximumZoom
        {
            get { return _maximumZoom; }
            set
            {
                if (value < _minimumZoom)
                    value = _minimumZoom;
                _maximumZoom = value;
            }
        }

        /// 
        /// Gets or sets a value indicating the maximum extents
        /// 
        public Envelope MaximumExtents
        {
            get { return _maximumExtents ?? (_maximumExtents = new Envelope()); }
            set { _maximumExtents = value; }
        }

        /// 
        /// Gets or sets the size of the Map in device units (Pixel)
        /// 
        public Size Size { get; set; }

        /// 
        /// Gets or sets the aspect-ratio of the pixel scales. A value less than 
        /// 1 will make the map streach upwards, and larger than 1 will make it smaller.
        /// 
        /// Throws an argument exception when value is 0 or less.
        public double PixelAspectRatio
        {
            get { return _pixelAspectRatio; }
            set
            {
                if (value  _maximumZoom)
                zoom = _maximumZoom;

            if (!EnforceMaximumExtents)
                return zoom;

            double arWidth = (double)Size.Width/Size.Height;

            if (zoom > _maximumExtents.Width)
                zoom = _maximumExtents.Width;
            if (zoom > arWidth * _maximumExtents.Height)
                zoom = arWidth * _maximumExtents.Height;
            zoom = VerifyValidViewport(zoom, center);

            return zoom;
        }

        /// 
        /// Verifies the valid viewport, makes adjustments if required
        /// 
        /// The current zoom
        /// The 
        /// The verified zoom level
        private double VerifyValidViewport(double zoom, Coordinate center)
        {
            var maxExtents = MaximumExtents ?? new Envelope();
            if (maxExtents.IsNull)
                return zoom;

            double halfWidth = 0.5d * zoom;
            double halfHeight = halfWidth * PixelAspectRatio * ((double)Size.Height / Size.Width);

            double maxZoomHeight = _maximumZoom < double.MaxValue ? _maximumZoom : double.MaxValue;
            if (2 * halfHeight > maxZoomHeight)
            {
                halfHeight = 0.5d*maxZoomHeight;
                halfWidth = halfHeight / (_pixelAspectRatio * ((double)Size.Height / Size.Width));
                zoom = 2 * halfWidth;
            }

            var testEnvelope = new Envelope(center.X - halfWidth, center.X + halfWidth,
                                            center.Y - halfHeight, center.Y + halfHeight);

            if (maxExtents.Contains(testEnvelope))
                return zoom;

            double dx = testEnvelope.MinX < maxExtents.MinX
                            ? maxExtents.MinX - testEnvelope.MinX
                            : testEnvelope.MaxX > maxExtents.MaxX 
                                ? maxExtents.MaxX - testEnvelope.MaxX 
                                : 0;

            double dy = testEnvelope.MinY < maxExtents.MinY
                            ? maxExtents.MinY - testEnvelope.MinY
                            : testEnvelope.MaxY > maxExtents.MaxY 
                                ? maxExtents.MaxY - testEnvelope.MaxY 
                                : 0;

            center.X += dx;
            center.Y += dy;

            return zoom;
        }
    }


    /// 
    /// Utility class to lock a map's viewport so it cannot be changed
    /// 
    public class MapViewportLock
    {
        private readonly Map _map;
        private double _minimumZoom;
        private double _maximumZoom;
        private Envelope _maximumExtents;
        private bool _enforce;

        /// 
        /// Creates an instance of this class
        /// 
        /// 
        public MapViewportLock(Map map)
        {
            _map = map;
        }

        /// 
        /// Lock the viewport of the map
        /// 
        public void Lock()
        {
            if (IsLocked)
                return;

            // Signal the viewport as locked
            IsLocked = true;

            // store the current extent settings
            _minimumZoom = _map.MinimumZoom;
            _maximumZoom = _map.MaximumZoom;
            _maximumExtents = _map.MaximumExtents;
            _enforce = _map.EnforceMaximumExtents;

            // Lock the viewport
            _map.MinimumZoom = _map.MaximumZoom = _map.Zoom;
            _map.MaximumExtents = _map.Envelope;
            _map.EnforceMaximumExtents = true;
        }

        /// 
        /// Gets a value indicating that the map's viewport is locked
        /// 
        public bool IsLocked { get; private set; }

        /// 
        /// Unlock the viewport of the map
        /// 
        public void Unlock()
        {
            // Unlock the viewport
            _map.EnforceMaximumExtents = _enforce;
            _map.MaximumExtents = _maximumExtents;
            _map.MinimumZoom = _minimumZoom;
            _map.MaximumZoom = _maximumZoom;

            // Signal the viewport as unlocked
            IsLocked = false;
        }
    }
}

Web Proxy Viewer  |  New URL  |  Original Page