diff --git a/Changelog.md b/Changelog.md index a33b30c9a..ce70615f3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -84,6 +84,7 @@ All notable changes to this project will be documented in this file. - FeatureSet.Open(".shp") throws wrong error if .shx is missing (#903) - Wrong Expression at Expression Editor mess up Layer Feature Set. (#904) - Incorrect selection of polygons with Holes (#905) +- ExtendBuffer Map property fixed (#661) - Polygon Hatch Style is not displayed (#851) - Is this a bug in DotSpatial.WebControls? (#496) - NmeaSentence.ParseDilution produces an exception when an nmea string with dilution of precision not greater than 0 is used. (#909) diff --git a/Contributors b/Contributors index ee6b47014..8f014b931 100644 --- a/Contributors +++ b/Contributors @@ -23,3 +23,4 @@ Florian Fuchs Peder Wikstrom Jan Paolo Go Bart de Groot +Hugo Dejaune diff --git a/Source/DotSpatial.Controls.Tests/TestFiles/testprojectExtendBuffer.dspx b/Source/DotSpatial.Controls.Tests/TestFiles/testprojectExtendBuffer.dspx new file mode 100644 index 000000000..04d253d41 --- /dev/null +++ b/Source/DotSpatial.Controls.Tests/TestFiles/testprojectExtendBuffer.dspx @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/DotSpatial.Controls/DefaultMenuBars.cs b/Source/DotSpatial.Controls/DefaultMenuBars.cs index 91a2d3946..a04d15c66 100644 --- a/Source/DotSpatial.Controls/DefaultMenuBars.cs +++ b/Source/DotSpatial.Controls/DefaultMenuBars.cs @@ -409,6 +409,12 @@ private void ZoomToLayer(IMapLayer layerToZoom) { const double eps = 1e-7; Envelope layerEnvelope = layerToZoom.Extent.ToEnvelope(); + + if (App.Map.MapFrame.ExtendBuffer) + { + layerEnvelope.ExpandBy(layerEnvelope.Width, layerEnvelope.Height); + } + if (layerEnvelope.Width > eps && layerEnvelope.Height > eps) { layerEnvelope.ExpandBy(layerEnvelope.Width / 10, layerEnvelope.Height / 10); // work item #84 diff --git a/Source/DotSpatial.Controls/IMapFrame.cs b/Source/DotSpatial.Controls/IMapFrame.cs index 597dcbf26..a910b6a13 100644 --- a/Source/DotSpatial.Controls/IMapFrame.cs +++ b/Source/DotSpatial.Controls/IMapFrame.cs @@ -205,6 +205,14 @@ public interface IMapFrame : IFrame, IMapGroup, IProj /// bool ExtendBuffer { get; set; } + /// + /// Gets the coefficient used for ExtendBuffer. This coefficient should not be modified. + /// + int ExtendBufferCoeff + { + get; + } + /// /// Gets or sets whether this map frame is currently in the process of redrawing the /// stencils after a pan operation. Drawing should not take place if this is true. diff --git a/Source/DotSpatial.Controls/LayoutMap.cs b/Source/DotSpatial.Controls/LayoutMap.cs index 85c47d683..22798e380 100644 --- a/Source/DotSpatial.Controls/LayoutMap.cs +++ b/Source/DotSpatial.Controls/LayoutMap.cs @@ -49,7 +49,15 @@ public LayoutMap(Map mapControl) Name = "Map"; _mapControl = mapControl; - _envelope = _mapControl.ViewExtents.ToEnvelope(); + + Envelope viewExtentEnvelope = new Envelope(_mapControl.ViewExtents.ToEnvelope()); + if (_mapControl.ExtendBuffer) + { + // if ExtendBuffer, Envelope must be three times smaller + viewExtentEnvelope.ExpandBy(-viewExtentEnvelope.Width / _mapControl.MapFrame.ExtendBufferCoeff, -viewExtentEnvelope.Height / _mapControl.MapFrame.ExtendBufferCoeff); + } + _envelope = viewExtentEnvelope; + ResizeStyle = ResizeStyle.NoScaling; } @@ -151,7 +159,9 @@ protected override void OnSizeChanged() { //If the size has never been set before we set the maps extent to that of the map if (_oldRectangle.Width == 0 && _oldRectangle.Height == 0) - Envelope = MapControl.ViewExtents.ToEnvelope(); + { + ZoomViewExtent(); + } else { double dx = Envelope.Width / _oldRectangle.Width; @@ -191,7 +201,14 @@ public virtual void ZoomToFullExtent() /// public virtual void ZoomViewExtent() { - Envelope = _mapControl.ViewExtents.ToEnvelope(); + Envelope viewExtentEnvelope = new Envelope(_mapControl.ViewExtents.ToEnvelope()); + if (_mapControl.ExtendBuffer) + { + // if ExtendBuffer, Envelope must be three times smaller + viewExtentEnvelope.ExpandBy(-viewExtentEnvelope.Width / _mapControl.MapFrame.ExtendBufferCoeff, -viewExtentEnvelope.Height / _mapControl.MapFrame.ExtendBufferCoeff); + } + Envelope = viewExtentEnvelope; + } /// diff --git a/Source/DotSpatial.Controls/Map.cs b/Source/DotSpatial.Controls/Map.cs index 0af95ffe8..e25789c3b 100644 --- a/Source/DotSpatial.Controls/Map.cs +++ b/Source/DotSpatial.Controls/Map.cs @@ -602,6 +602,8 @@ public Extent GetMaxExtent(bool expand = false) ? new Extent(Extent.MinX - eps, Extent.MinY - eps, Extent.MaxX + eps, Extent.MaxY + eps) : Extent; + if (ExtendBuffer) maxExtent.ExpandBy(maxExtent.Width, maxExtent.Height); + if (expand) maxExtent.ExpandBy(maxExtent.Width / 10, maxExtent.Height / 10); // work item #84 (Expand target envelope by 10%) return maxExtent; diff --git a/Source/DotSpatial.Controls/MapFrame.cs b/Source/DotSpatial.Controls/MapFrame.cs index d8e6bfe34..3ca95c11f 100644 --- a/Source/DotSpatial.Controls/MapFrame.cs +++ b/Source/DotSpatial.Controls/MapFrame.cs @@ -338,7 +338,12 @@ public virtual void Initialize(List regions) _buffer = _backBuffer; if (setView) _view = _backView; - bufferDevice.Clip = new Region(ImageRectangle); + + Rectangle rectangle = ImageRectangle; + if (ExtendBuffer) + rectangle = new Rectangle(_width / ExtendBufferCoeff, _height / ExtendBufferCoeff, _width / ExtendBufferCoeff, _height / ExtendBufferCoeff); + + bufferDevice.Clip = new Region(rectangle); gp.Dispose(); List rects = args.ProjToPixel(regions); OnBufferChanged(this, new ClipArgs(rects)); @@ -479,8 +484,8 @@ private Bitmap CreateBuffer() { _backView.X = _width; _backView.Y = _height; - _width = _width * 3; - _height = _height * 3; + _width = _width * ExtendBufferCoeff; + _height = _height * ExtendBufferCoeff; } return new Bitmap(_width, _height); @@ -738,27 +743,6 @@ public List ClipRegions set { _clipRegions = value; } } - /// - /// Gets or sets the geographic extents to be drawn to a buffer. - /// If "ExtendBuffer" is true, then these extents are larger - /// than the geographic extents of the parent client, - /// and care should be taken when using PixelToProj, - /// as it will work differently. - /// - public Extent BufferExtents - { - get - { - if (_extendBuffer) - { - Extent ext = CloneableEM.Copy(ViewExtents); - ext.ExpandBy(ext.Width, ext.Height); - return ext; - } - return ViewExtents; - } - } - /// /// Gets or sets the height /// @@ -825,7 +809,19 @@ public Extent GeographicExtents public bool ExtendBuffer { get { return _extendBuffer; } - set { _extendBuffer = value; } + set { + _extendBuffer = value; + IProjExtensions.ExtendBuffer = value; + } + } + + /// + /// Gets the coefficient used for ExtendBuffer. This coefficient should not be modified. + /// + public int ExtendBufferCoeff + { + get { return IProjExtensions.ExtendBufferCoeff; } + set { IProjExtensions.ExtendBufferCoeff = value; } } /// @@ -1041,7 +1037,7 @@ public void Draw(PaintEventArgs pe) /// An ICoordinate describing the geographic position public Coordinate BufferToProj(Point position) { - Envelope view = BufferExtents.ToEnvelope(); + Envelope view = ViewExtents.ToEnvelope(); if (base.ViewExtents == null) return new Coordinate(0, 0); double x = Convert.ToDouble(position.X); double y = Convert.ToDouble(position.Y); @@ -1058,8 +1054,15 @@ public Coordinate BufferToProj(Point position) /// An Envelope interface public Extent BufferToProj(Rectangle rect) { + if (ExtendBuffer) + { + rect = rect.ExpandBy(rect.Width, rect.Height); + } + Point tl = new Point(rect.X, rect.Y); Point br = new Point(rect.Right, rect.Bottom); + + Coordinate topLeft = BufferToProj(tl); Coordinate bottomRight = BufferToProj(br); return new Extent(topLeft.X, bottomRight.Y, bottomRight.X, topLeft.Y); @@ -1073,7 +1076,7 @@ public Extent BufferToProj(Rectangle rect) /// A Point with the new location. public Point ProjToBuffer(Coordinate location) { - Envelope view = BufferExtents.ToEnvelope(); + Envelope view = ViewExtents.ToEnvelope(); if (_width == 0 || _height == 0) return new Point(0, 0); int x = Convert.ToInt32((location.X - view.MinX) * (_width / view.Width)); int y = Convert.ToInt32((view.MaxY - location.Y) * (_height / view.Height)); @@ -1132,7 +1135,7 @@ public Rectangle ImageRectangle { get { - if (_extendBuffer) return new Rectangle(_width / 3, _height / 3, _width / 3, _height / 3); + if (_extendBuffer) return new Rectangle(-_width / ExtendBufferCoeff, -_height / ExtendBufferCoeff, _width, _height); return new Rectangle(0, 0, _width, _height); } } @@ -1268,6 +1271,8 @@ private void LayerColection_LayerAdded(object sender, LayerEventArgs e) if (desired.Height > 0 && desired.Height < 1E300) { Extent env = CloneableEM.Copy(desired); + + if (ExtendBuffer) env.ExpandBy(env.Width, env.Height); env.ExpandBy(env.Width / 10, env.Height / 10); // Work item #84 ViewExtents = env; } diff --git a/Source/DotSpatial.Data/IProjExtensions.cs b/Source/DotSpatial.Data/IProjExtensions.cs index 9aafd1a88..e17867010 100644 --- a/Source/DotSpatial.Data/IProjExtensions.cs +++ b/Source/DotSpatial.Data/IProjExtensions.cs @@ -23,7 +23,11 @@ namespace DotSpatial.Data /// Extension methods for interface. /// public static class IProjExtensions - { + { + + private static bool _extendBuffer; + private static int _extendBufferCoeff = 3; + #region Methods /// @@ -37,9 +41,9 @@ public static Coordinate PixelToProj(this IProj self, Point position) double x = Convert.ToDouble(position.X); double y = Convert.ToDouble(position.Y); if (self != null && self.GeographicExtents != null) - { - x = x * self.GeographicExtents.Width / self.ImageRectangle.Width + self.GeographicExtents.MinX; - y = self.GeographicExtents.MaxY - y * self.GeographicExtents.Height / self.ImageRectangle.Height; + { + x = (x - self.ImageRectangle.X) * self.GeographicExtents.Width / self.ImageRectangle.Width + self.GeographicExtents.MinX; + y = self.GeographicExtents.MaxY - (y - self.ImageRectangle.Y) * self.GeographicExtents.Height / self.ImageRectangle.Height; } return new Coordinate(x, y, 0.0); } @@ -87,11 +91,12 @@ public static Point ProjToPixel(this IProj self, Coordinate location) { if (self.GeographicExtents.Width == 0 || self.GeographicExtents.Height == 0) return Point.Empty; try - { - int x = Convert.ToInt32((location.X - self.GeographicExtents.MinX) * - (self.ImageRectangle.Width / self.GeographicExtents.Width)); - int y = Convert.ToInt32((self.GeographicExtents.MaxY - location.Y) * - (self.ImageRectangle.Height / self.GeographicExtents.Height)); + { + int x = Convert.ToInt32(self.ImageRectangle.X + (location.X - self.GeographicExtents.MinX) * + (self.ImageRectangle.Width / self.GeographicExtents.Width)); + int y = Convert.ToInt32(self.ImageRectangle.Y + (self.GeographicExtents.MaxY - location.Y) * + (self.ImageRectangle.Height / self.GeographicExtents.Height)); + return new Point(x, y); } catch (OverflowException) @@ -145,6 +150,29 @@ public static double ProjToPixel(this IProj self, double distance) return (distance * self.ImageRectangle.Width / self.GeographicExtents.Width); } - #endregion + #endregion + + #region Properties + + /// + /// Gets or sets whether this map frame should define its buffer + /// region to be the same size as the client, or three times larger. + /// + public static bool ExtendBuffer + { + get { return _extendBuffer; } + set { _extendBuffer = value; } + } + + /// + /// Gets the coefficient used for ExtendBuffer. This coefficient should not be modified. + /// + public static int ExtendBufferCoeff + { + get { return _extendBufferCoeff; } + set { _extendBufferCoeff = value; } + } + #endregion + } } \ No newline at end of file diff --git a/Source/DotSpatial.Plugins.WebMap/WebMapPlugin.cs b/Source/DotSpatial.Plugins.WebMap/WebMapPlugin.cs index 0522e89af..09d967f7f 100644 --- a/Source/DotSpatial.Plugins.WebMap/WebMapPlugin.cs +++ b/Source/DotSpatial.Plugins.WebMap/WebMapPlugin.cs @@ -33,6 +33,7 @@ public class WebMapPlugin : Extension private ServiceProvider _emptyProvider; private IMapFeatureLayer _featureSetLayer; private Int16 _opacity = 100; + private int _extendBufferCoeff = 3; private TileManager _tileManager; private bool _busySet; @@ -524,7 +525,11 @@ private void UpdateStichedBasemap(DoWorkEventArgs e) }); var rectangle = map.Bounds; - var webMercExtent = map.ViewExtents; + var webMercExtent = map.ViewExtents.Clone() as Extent; + //If ExtendBuffer, correct the displayed extent + if (map.ExtendBuffer) + webMercExtent.ExpandBy(-webMercExtent.Width / _extendBufferCoeff, -webMercExtent.Height / _extendBufferCoeff); + //Clip the reported Web Merc Envelope to be within possible Web Merc extents // This fixes an issue with Reproject returning bad results for very large (impossible) web merc extents reported from the Map