/// <summary> /// This should only be used if the Intersection is not actually required because it uses the Intersection method /// and returns false if the return value is null. /// </summary> /// <param name="self">The <c>IEnvelope</c> that is being extended by this method</param> /// <param name="segment">The segment to be tested against this envelope.</param> /// <returns>The line segment to compare against.</returns> public static bool Intersects(this IEnvelope self, ILineSegment segment) { if (self.Intersection(segment) != null) { return(true); } return(false); }
public virtual Bitmap GetBitmap(IEnvelope envelope, Size pixelSize) { Bitmap result = new Bitmap(pixelSize.Width, pixelSize.Height); Graphics g = Graphics.FromImage(result); foreach (ImageData image in _images) { IEnvelope bounds = envelope.Intersection(image.Envelope); Size ps = new Size((int)((double)pixelSize.Width * bounds.Width/envelope.Width),(int)((double)pixelSize.Height * bounds.Height/envelope.Height)); int x = pixelSize.Width*(int)((bounds.X - envelope.X)/envelope.Width); int y = pixelSize.Height*(int) ((envelope.Y - bounds.Y)/envelope.Height); if(ps.Width > 0 && ps.Height > 0) { Bitmap tile = image.GetBitmap(bounds, ps); g.DrawImageUnscaled(tile, x, y); } } return result; }
/// <summary> /// This draws the back buffer image onto a graphics object that has been scaled and /// translated via the graphics transforms into world coordinates. The bounds /// are specified in geographic coordinates, as are the extents for this graphics object. /// </summary> /// <param name="g">The System.Drawing.Graphics surface to draw on.</param> /// <param name="bounds">The geographic extents to draw</param> public virtual void Draw2D(Graphics g, IEnvelope bounds) { // Ensure we have something on the backbuffer that we want to draw if (_extents == null) return; if (_extents.Width == 0 || _extents.Height == 0) return; if (bounds.Intersects(_extents) == false) return; IEnvelope sourceBounds = bounds.Intersection(_extents); RectangleF sourceRect = ProjToPixel(sourceBounds); //RectangleF destRect = new RectangleF(0, 0,Convert.ToSingle(sourceBounds.Width), Convert.ToSingle(sourceBounds.Height)); float sx = Convert.ToSingle(_extents.Width/bounds.Width); float sy = Convert.ToSingle(_extents.Height/bounds.Height); float tx = 0f; float ty = 0f; if (bounds.Minimum.X < _extents.Minimum.X) tx = Convert.ToSingle((bounds.Minimum.X - _extents.Minimum.X) * Width / bounds.Width); if (bounds.Maximum.Y > _extents.Maximum.Y)ty = Convert.ToSingle((bounds.Maximum.Y - _extents.Maximum.Y) * Height / bounds.Height); RectangleF destRect = new RectangleF(-tx, ty, sourceRect.Width * sx, sourceRect.Height * sy); g.DrawImage(_image, destRect, sourceRect, GraphicsUnit.Pixel); }
/// <summary> /// For big images the scale that is just one step larger than the specified window will be used. /// </summary> /// <param name="envelope"></param> /// <param name="window"></param> /// <returns></returns> public override Bitmap GetBitmap(Extent envelope, Rectangle window) { if (window.Width == 0 || window.Height == 0) { return(null); } if (_header == null) { return(null); } if (_header.ImageHeaders == null) { return(null); } if (_header.ImageHeaders[0] == null) { return(null); } Rectangle expWindow = window.ExpandBy(1); IEnvelope expEnvelope = envelope.ToEnvelope().Reproportion(window, expWindow); IEnvelope env = expEnvelope.Intersection(Bounds.Extent.ToEnvelope()); if (env == null || env.IsNull || env.Height == 0 || env.Width == 0) { return(null); } PyramidImageHeader he = _header.ImageHeaders[0]; int scale; double cwa = expWindow.Width / expEnvelope.Width; double cha = expWindow.Height / expEnvelope.Height; for (scale = 0; scale < _header.ImageHeaders.Length; scale++) { PyramidImageHeader ph = _header.ImageHeaders[scale]; if (cwa > ph.NumColumns / Bounds.Width || cha > ph.NumRows / Bounds.Height) { if (scale > 0) { scale -= 1; } break; } he = ph; } RasterBounds overviewBounds = new RasterBounds(he.NumRows, he.NumColumns, he.Affine); Rectangle r = overviewBounds.CellsContainingExtent(envelope); if (r.Width == 0 || r.Height == 0) { return(null); } byte[] vals = ReadWindow(r.Y, r.X, r.Height, r.Width, scale); Bitmap bmp = new Bitmap(r.Width, r.Height); BitmapData bData = bmp.LockBits(new Rectangle(0, 0, r.Width, r.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); Marshal.Copy(vals, 0, bData.Scan0, vals.Length); bmp.UnlockBits(bData); // Use the cell coordinates to determine the affine coefficients for the cells retrieved. double[] affine = new double[6]; Array.Copy(he.Affine, affine, 6); affine[0] = affine[0] + r.X * affine[1] + r.Y * affine[2]; affine[3] = affine[3] + r.X * affine[4] + r.Y * affine[5]; if (window.Width == 0 || window.Height == 0) { return(null); } Bitmap result = new Bitmap(window.Width, window.Height); Graphics g = Graphics.FromImage(result); // // Gets the scaling factor for converting from geographic to pixel coordinates double dx = (window.Width / envelope.Width); double dy = (window.Height / envelope.Height); double[] a = affine; // gets the affine scaling factors. float m11 = Convert.ToSingle(a[1] * dx); float m22 = Convert.ToSingle(a[5] * -dy); float m21 = Convert.ToSingle(a[2] * dx); float m12 = Convert.ToSingle(a[4] * -dy); float l = (float)(a[0] - .5 * (a[1] + a[2])); // Left of top left pixel float t = (float)(a[3] - .5 * (a[4] + a[5])); // top of top left pixel float xShift = (float)((l - envelope.MinX) * dx); float yShift = (float)((envelope.MaxY - t) * dy); g.Transform = new Matrix(m11, m12, m21, m22, xShift, yShift); g.PixelOffsetMode = PixelOffsetMode.Half; if (m11 > 1 || m22 > 1) { g.InterpolationMode = InterpolationMode.NearestNeighbor; } g.DrawImage(bmp, new PointF(0, 0)); bmp.Dispose(); g.Dispose(); return(result); }
/// <summary> /// Calculates a ratio so that the specified rectangle represents the portion on the window rectangle /// that is equivalent to the region on the view. /// </summary> /// <param name="view"></param> /// <param name="window"></param> /// <param name="region"></param> /// <returns></returns> private Rectangle ProjectRegionToWindow(IEnvelope view, Rectangle window, IEnvelope region) { IEnvelope env = view.Intersection(region); int x = (int)((window.Width / view.Width) * env.X - window.X); int y = (int)(window.Y - (window.Height / env.Height) * env.Y); int w = (int)((window.Width / view.Width) * env.Width); int h = (int)((window.Height / view.Height) * env.Height); return new Rectangle(x, y, w, h); }