// get 4 corners of image public Collection<Geometries.Point> GetFourCorners() { Collection<Geometries.Point> points = new Collection<Geometries.Point>(); double[] dblPoint; if (_gdalDataset != null) { double[] geoTrans = new double[6]; _gdalDataset.GetGeoTransform(geoTrans); // no rotation...use default transform if (!_useRotation && !_haveSpot || (geoTrans[0] == 0 && geoTrans[3] == 0)) geoTrans = new[] { 999.5, 1, 0, 1000.5, 0, -1 }; points.Add(new Geometries.Point(geoTrans[0], geoTrans[3])); points.Add(new Geometries.Point(geoTrans[0] + (geoTrans[1] * _imagesize.Width), geoTrans[3] + (geoTrans[4] * _imagesize.Width))); points.Add( new Geometries.Point(geoTrans[0] + (geoTrans[1] * _imagesize.Width) + (geoTrans[2] * _imagesize.Height), geoTrans[3] + (geoTrans[4] * _imagesize.Width) + (geoTrans[5] * _imagesize.Height))); points.Add(new Geometries.Point(geoTrans[0] + (geoTrans[2] * _imagesize.Height), geoTrans[3] + (geoTrans[5] * _imagesize.Height))); // transform to map's projection if (_transform != null) { for (int i = 0; i < 4; i++) { #if !DotSpatialProjections dblPoint = _transform.MathTransform.Transform(new[] { points[i].X, points[i].Y }); #else dblPoint = points[i].ToDoubleArray(); Reproject.ReprojectPoints(dblPoint, null, _transform.Source, _transform.Target, 0, 1); #endif points[i] = new Geometries.Point(dblPoint[0], dblPoint[1]); } } } return points; }
protected virtual void GetPreview(Dataset dataset, Size size, Graphics g, BoundingBox displayBbox, ProjectionInfo mapProjection, Map map) #endif { double[] geoTrans = new double[6]; _gdalDataset.GetGeoTransform(geoTrans); // not rotated, use faster display method if ((!_useRotation || (geoTrans[1] == 1 && geoTrans[2] == 0 && geoTrans[4] == 0 && Math.Abs(geoTrans[5]) == 1)) && !_haveSpot && _transform == null) { GetNonRotatedPreview(dataset, size, g, displayBbox, mapProjection); return; } // not rotated, but has spot...need default rotation else if ((geoTrans[0] == 0 && geoTrans[3] == 0) && _haveSpot) geoTrans = new[] { 999.5, 1, 0, 1000.5, 0, -1 }; _geoTransform = new GeoTransform(geoTrans); double DsWidth = _imagesize.Width; double DsHeight = _imagesize.Height; double left, top, right, bottom; double GndX = 0, GndY = 0, ImgX = 0, ImgY = 0, PixX, PixY; double[] intVal = new double[Bands]; double imageVal = 0, SpotVal = 0; double bitScalar = 1.0; Bitmap bitmap = null; Point bitmapTL = new Point(), bitmapBR = new Point(); Geometries.Point imageTL = new Geometries.Point(), imageBR = new Geometries.Point(); BoundingBox shownImageBbox, trueImageBbox; int bitmapLength, bitmapHeight; int displayImageLength, displayImageHeight; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((displayBbox.Left > _envelope.Right) || (displayBbox.Right < _envelope.Left) || (displayBbox.Top < _envelope.Bottom) || (displayBbox.Bottom > _envelope.Top)) return; // init histo _histogram = new List<int[]>(); for (int i = 0; i < _lbands + 1; i++) _histogram.Add(new int[256]); // bounds of section of image to be displayed left = Math.Max(displayBbox.Left, _envelope.Left); top = Math.Min(displayBbox.Top, _envelope.Top); right = Math.Min(displayBbox.Right, _envelope.Right); bottom = Math.Max(displayBbox.Bottom, _envelope.Bottom); trueImageBbox = new BoundingBox(left, bottom, right, top); // put display bounds into current projection if (_transform != null) { #if !DotSpatialProjections _transform.MathTransform.Invert(); shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, _transform.MathTransform); _transform.MathTransform.Invert(); #else shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, _transform.Source, _transform.Target); #endif } else shownImageBbox = trueImageBbox; // find min/max x and y pixels needed from image imageBR.X = (int) (Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopLeft).X, Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopRight).X, Math.Max(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).X, _geoTransform.GroundToImage(shownImageBbox.BottomRight).X))) + 1); imageBR.Y = (int) (Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopLeft).Y, Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopRight).Y, Math.Max(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).Y, _geoTransform.GroundToImage(shownImageBbox.BottomRight).Y))) + 1); imageTL.X = (int) Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopLeft).X, Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopRight).X, Math.Min(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).X, _geoTransform.GroundToImage(shownImageBbox.BottomRight).X))); imageTL.Y = (int) Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopLeft).Y, Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopRight).Y, Math.Min(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).Y, _geoTransform.GroundToImage(shownImageBbox.BottomRight).Y))); // stay within image if (imageBR.X > _imagesize.Width) imageBR.X = _imagesize.Width; if (imageBR.Y > _imagesize.Height) imageBR.Y = _imagesize.Height; if (imageTL.Y < 0) imageTL.Y = 0; if (imageTL.X < 0) imageTL.X = 0; displayImageLength = (int)(imageBR.X - imageTL.X); displayImageHeight = (int)(imageBR.Y - imageTL.Y); // find ground coordinates of image pixels Geometries.Point groundBR = _geoTransform.ImageToGround(imageBR); Geometries.Point groundTL = _geoTransform.ImageToGround(imageTL); // convert ground coordinates to map coordinates to figure out where to place the bitmap bitmapBR = new Point((int)map.WorldToImage(trueImageBbox.BottomRight).X + 1, (int)map.WorldToImage(trueImageBbox.BottomRight).Y + 1); bitmapTL = new Point((int)map.WorldToImage(trueImageBbox.TopLeft).X, (int)map.WorldToImage(trueImageBbox.TopLeft).Y); bitmapLength = bitmapBR.X - bitmapTL.X; bitmapHeight = bitmapBR.Y - bitmapTL.Y; // check to see if image is on its side if (bitmapLength > bitmapHeight && displayImageLength < displayImageHeight) { displayImageLength = bitmapHeight; displayImageHeight = bitmapLength; } else { displayImageLength = bitmapLength; displayImageHeight = bitmapHeight; } // scale if (_bitDepth == 12) bitScalar = 16.0; else if (_bitDepth == 16) bitScalar = 256.0; else if (_bitDepth == 32) bitScalar = 16777216.0; // 0 pixels in length or height, nothing to display if (bitmapLength < 1 || bitmapHeight < 1) return; //initialize bitmap bitmap = new Bitmap(bitmapLength, bitmapHeight, PixelFormat.Format24bppRgb); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmapLength, bitmapHeight), ImageLockMode.ReadWrite, bitmap.PixelFormat); try { unsafe { // turn everything to _noDataInitColor, so we can make fill transparent byte cr = _noDataInitColor.R; byte cg = _noDataInitColor.G; byte cb = _noDataInitColor.B; for (int y = 0; y < bitmapHeight; y++) { byte* brow = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < bitmapLength; x++) { Int32 offsetX = x * 3; brow[offsetX++] = cb; brow[offsetX++] = cg; brow[offsetX] = cr; } } // create 3 dimensional buffer [band][x pixel][y pixel] double[][] tempBuffer = new double[Bands][]; double[][][] buffer = new double[Bands][][]; for (int i = 0; i < Bands; i++) { buffer[i] = new double[displayImageLength][]; for (int j = 0; j < displayImageLength; j++) buffer[i][j] = new double[displayImageHeight]; } Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // Double[] noDataValues = new Double[Bands]; Double[] scales = new Double[Bands]; ColorTable colorTable = null; // get data from image for (int i = 0; i < Bands; i++) { tempBuffer[i] = new double[displayImageLength * displayImageHeight]; band[i] = dataset.GetRasterBand(i + 1); //get nodata value if present Int32 hasVal = 0; band[i].GetNoDataValue(out noDataValues[i], out hasVal); if (hasVal == 0) noDataValues[i] = Double.NaN; band[i].GetScale(out scales[i], out hasVal); if (hasVal == 0) scales[i] = 1.0; band[i].ReadRaster( (int)imageTL.X, (int)imageTL.Y, (int)(imageBR.X - imageTL.X), (int)(imageBR.Y - imageTL.Y), tempBuffer[i], displayImageLength, displayImageHeight, 0, 0); // parse temp buffer into the image x y value buffer long pos = 0; for (int y = 0; y < displayImageHeight; y++) { for (int x = 0; x < displayImageLength; x++, pos++) buffer[i][x][y] = tempBuffer[i][pos]; } if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_BlueBand) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GreenBand) ch[i] = 1; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) ch[i] = 2; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_Undefined) { if (Bands > 1) ch[i] = 3; // infrared else { ch[i] = 4; if (_colorBlend == null) { Double dblMin, dblMax; band[i].GetMinimum(out dblMin, out hasVal); if (hasVal == 0) dblMin = Double.NaN; band[i].GetMaximum(out dblMax, out hasVal); if (hasVal == 0) dblMax = double.NaN; if (Double.IsNaN(dblMin) || Double.IsNaN(dblMax)) { double dblMean, dblStdDev; band[i].GetStatistics(0, 1, out dblMin, out dblMax, out dblMean, out dblStdDev); //double dblRange = dblMax - dblMin; //dblMin -= 0.1*dblRange; //dblMax += 0.1*dblRange; } Single[] minmax = new float[] { Convert.ToSingle(dblMin), 0.5f * Convert.ToSingle(dblMin + dblMax), Convert.ToSingle(dblMax) }; Color[] colors = new Color[] { Color.Blue, Color.Yellow, Color.Red }; _colorBlend = new ColorBlend(colors, minmax); } intVal = new Double[3]; } } else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { colorTable = band[i].GetRasterColorTable(); ch[i] = 5; intVal = new Double[3]; } else ch[i] = -1; } // store these values to keep from having to make slow method calls int bitmapTLX = bitmapTL.X; int bitmapTLY = bitmapTL.Y; double imageTop = imageTL.Y; double imageLeft = imageTL.X; double dblMapPixelWidth = map.PixelWidth; double dblMapPixelHeight = map.PixelHeight; double dblMapMinX = map.Envelope.Min.X; double dblMapMaxY = map.Envelope.Max.Y; double geoTop, geoLeft, geoHorzPixRes, geoVertPixRes, geoXRot, geoYRot; // get inverse values geoTop = _geoTransform.Inverse[3]; geoLeft = _geoTransform.Inverse[0]; geoHorzPixRes = _geoTransform.Inverse[1]; geoVertPixRes = _geoTransform.Inverse[5]; geoXRot = _geoTransform.Inverse[2]; geoYRot = _geoTransform.Inverse[4]; double dblXScale = (imageBR.X - imageTL.X) / (displayImageLength - 1); double dblYScale = (imageBR.Y - imageTL.Y) / (displayImageHeight - 1); double[] dblPoint; // get inverse transform // NOTE: calling transform.MathTransform.Inverse() once and storing it // is much faster than having to call every time it is needed #if !DotSpatialProjections IMathTransform inverseTransform = null; if (_transform != null) inverseTransform = _transform.MathTransform.Inverse(); #endif for (PixY = 0; PixY < bitmapBR.Y - bitmapTL.Y; PixY++) { byte* row = (byte*)bitmapData.Scan0 + ((int)Math.Round(PixY) * bitmapData.Stride); for (PixX = 0; PixX < bitmapBR.X - bitmapTL.X; PixX++) { // same as Map.ImageToGround(), but much faster using stored values...rather than called each time GndX = dblMapMinX + (PixX + bitmapTLX) * dblMapPixelWidth; GndY = dblMapMaxY - (PixY + bitmapTLY) * dblMapPixelHeight; // transform ground point if needed if (_transform != null) { #if !DotSpatialProjections dblPoint = inverseTransform.Transform(new[] { GndX, GndY }); #else dblPoint = new double[] { GndX, GndY }; Reproject.ReprojectPoints(dblPoint, null, _transform.Source, _transform.Target, 0, 1); #endif GndX = dblPoint[0]; GndY = dblPoint[1]; } // same as GeoTransform.GroundToImage(), but much faster using stored values... ImgX = (geoLeft + geoHorzPixRes * GndX + geoXRot * GndY); ImgY = (geoTop + geoYRot * GndX + geoVertPixRes * GndY); if (ImgX < imageTL.X || ImgX > imageBR.X || ImgY < imageTL.Y || ImgY > imageBR.Y) continue; // color correction for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][(int)((ImgX - imageLeft) / dblXScale)][ (int)((ImgY - imageTop) / dblYScale)]; imageVal = SpotVal = intVal[i] = intVal[i] / bitScalar; if (ch[i] == 4) { if (imageVal != noDataValues[i]) { Color color = _colorBlend.GetColor(Convert.ToSingle(imageVal)); intVal[0] = color.B; intVal[1] = color.G; intVal[2] = color.R; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else if (ch[i] == 5 && colorTable != null) { if (imageVal != noDataValues[i]) { ColorEntry ce = colorTable.GetColorEntry(Convert.ToInt32(imageVal)); intVal[0] = ce.c3; intVal[1] = ce.c2; intVal[2] = ce.c1; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else { if (_colorCorrect) { intVal[i] = ApplyColorCorrection(imageVal, SpotVal, ch[i], GndX, GndY); // if pixel is within ground boundary, add its value to the histogram if (ch[i] != -1 && intVal[i] > 0 && (_histoBounds.Bottom >= (int)GndY) && _histoBounds.Top <= (int)GndY && _histoBounds.Left <= (int)GndX && _histoBounds.Right >= (int)GndX) { _histogram[ch[i]][(int)intVal[i]]++; } } if (intVal[i] > 255) intVal[i] = 255; } } // luminosity if (_lbands >= 3) _histogram[_lbands][(int)(intVal[2] * 0.2126 + intVal[1] * 0.7152 + intVal[0] * 0.0722)] ++; WritePixel(PixX, intVal, iPixelSize, ch, row); } } } } finally { bitmap.UnlockBits(bitmapData); } } bitmap.MakeTransparent(_noDataInitColor); if (_transparentColor != Color.Empty) bitmap.MakeTransparent(_transparentColor); g.DrawImage(bitmap, new Point(bitmapTL.X, bitmapTL.Y)); }
/// <summary> /// Returns the data associated with the centroid of the bounding box. /// </summary> /// <param name="box">BoundingBox to intersect with</param> /// <param name="ds">FeatureDataSet to fill data into</param> public void ExecuteIntersectionQuery(BoundingBox box, FeatureDataSet ds) { Geometries.Point pt = new Geometries.Point( box.Left + 0.5 * box.Width, box.Top - 0.5 * box.Height); ExecuteIntersectionQuery(pt, ds); }