private void Identify(IEnumerable<ILayer> layers, Extent strict, Extent tolerant) { foreach (IMapLayer layer in layers) { IGroup grp = layer as IGroup; if (grp != null) { Identify(grp, strict, tolerant); } else { var gfl = layer as IMapFeatureLayer; if (gfl != null) { if (gfl.DataSet.FeatureType == FeatureType.Polygon) { _frmFeatureIdentifier.Add(gfl, strict); } else { _frmFeatureIdentifier.Add(gfl, tolerant); } } var rl = layer as IMapRasterLayer; if (rl != null) { _frmFeatureIdentifier.Add(rl, strict); } } } }
/// <summary> /// This function creates the HDR of Gridfile /// </summary> /// <param name="inExtents"> Extension of grid</param> /// <param name="cellSize">Size cell of the grid</param> /// <param name="projection">Projection (the same that shapefile)</param> /// <param name="noDataValue">No value definition</param> /// <param name="outGridPath">Path of the output</param> /// <param name="outGrid">Name of the output grid</param> public static void CreateGridFromExtents( Extent inExtents, double cellSize, ProjectionInfo projection, double noDataValue, string outGridPath, out IRaster outGrid) { double height = Math.Abs(inExtents.MaxY - inExtents.MinY); double width = Math.Abs(inExtents.MaxX - inExtents.MinX); int numberRows = Convert.ToInt32(Math.Ceiling(height / cellSize)) + 1; int numberCols = Convert.ToInt32(Math.Ceiling(width / cellSize)) + 1; // outGrid = Raster.CreateRaster(@outGridPath, null, demRaster.NumColumns, demRaster.NumRows, 1, demRaster.DataType, rasterOptions); outGrid = Raster.CreateRaster(@outGridPath, null, numberCols, numberRows, 1, typeof(float), new String[] { }); outGrid.NoDataValue = noDataValue; outGrid.Projection = projection; outGrid.CellHeight = cellSize; outGrid.CellWidth = cellSize; //if (inExtents.MinX < 0) // outGrid.Xllcenter = inExtents.MinX + (cellSize / 2.0); //else outGrid.Xllcenter = inExtents.MinX;// -(cellSize / 2.0); //if (inExtents.MinY < 0) // outGrid.Yllcenter = inExtents.MinY + (cellSize / 2.0); //else outGrid.Yllcenter = inExtents.MinY;// -(cellSize / 2.0); }
/// <summary> /// Creates a new raster bounds that is georeferenced to the specified envelope. /// </summary> /// <param name="numRows">The number of rows</param> /// <param name="numColumns">The number of columns</param> /// <param name="bounds">The bounding envelope</param> public RasterBounds(int numRows, int numColumns, Extent bounds) { _affine = new double[6]; _numRows = numRows; _numColumns = numColumns; Extent = bounds; }
static double[] ToSequence(Extent extent) { const int horizontal = 72; const int vertical = 36; var res = new double[horizontal * vertical * 2]; var dx = extent.Width / (horizontal - 1); var dy = extent.Height / (vertical - 1); var minY = extent.MinY; var k = 0; for (var i = 0; i < vertical; i++) { var minX = extent.MinX; for (var j = 0; j < horizontal; j++) { res[k++] = minX; res[k++] = minY; minX += dx; } minY += dy; } return res; }
/// <summary> /// Creates an instance of this class using some tile source configuration. /// </summary> /// <param name="configuration">The tile source configuration. If the configuration /// hasn't been initialized yet, <see cref="IConfiguration.Initialize"/> will /// be called.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> /// is <c>null</c>.</exception> /// <exception cref="CannotFindTileSourceException">Thrown when <paramref name="configuration"/> /// is not initialized and during initialization no tile source can be found.</exception> /// <exception cref="CannotCreateTileCacheException">Thrown when <paramref name="configuration"/> /// is not initialized and during initialization a critical error prevents the creation /// of the persistent tile cache.</exception> /// <exception cref="CannotReceiveTilesException">Thrown when <paramref name="configuration"/> /// is not initialized and during initialization no tiles can be received from the tile source.</exception> public BruTileLayer(IConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (!configuration.Initialized) { configuration.Initialize(); } this.configuration = configuration; ITileSchema tileSchema = configuration.TileSchema; sourceProjection = GetTileSourceProjectionInfo(tileSchema.Srs); Projection = sourceProjection; BruTileExtent extent = tileSchema.Extent; MyExtent = new DotSpatialExtent(extent.MinX, extent.MinY, extent.MaxX, extent.MaxY); IsVisible = true; tileFetcher = configuration.TileFetcher; tileFetcher.TileReceived += HandleTileReceived; tileFetcher.QueueEmpty += HandleQueueEmpty; // Set the wrap mode imageAttributes = new ImageAttributes(); imageAttributes.SetWrapMode(WrapMode.TileFlipXY); }
/// <summary> /// Creates a new instance of an Extent Param with the specified name /// and the specified projection as the default projection that will /// appear if no changes are made. /// </summary> /// <param name="name"></param> /// <param name="defaultExtent"></param> public ExtentParam(string name, Extent defaultExtent) { Name = name; Value = defaultExtent; ParamVisible = ShowParamInModel.No; ParamType = "DotSpatial Extent Param"; DefaultSpecified = true; }
/// <summary> /// Converts a single geographic envelope into an equivalent Rectangle /// as it would be drawn on the screen. /// </summary> /// <param name="env">The geographic IEnvelope</param> /// <returns>A Rectangle</returns> public static Rectangle ProjToPixel(this IBasicMap map, Extent env) { var mapFrame = map.MapFrame as MapFrame; if (mapFrame != null) return mapFrame.ProjToPixel(env); else return Rectangle.Empty; }
/// <summary> /// The constructor for the ToolDialog /// </summary> /// <param name="tool">The ITool to create the dialog box for</param> /// <param name="dataSets">The list of available DataSets available</param> /// <param name="mapExtent">Creates a new instance of the tool dialog with map extent.</param> public ToolDialog(ITool tool, List<DataSetArray> dataSets, Extent mapExtent) { // Required by the designer InitializeComponent(); DataSets = dataSets; _extent = mapExtent; Initialize(tool); }
static Extent Reproject(Extent extent, ProjectionInfo source, ProjectionInfo target, int depth = 0) { var xy = ToSequence(extent); DotSpatial.Projections.Reproject.ReprojectPoints(xy, null, source, target, 0, xy.Length / 2); var res = ToExtent(xy); return res; }
/// <summary> /// Creates an instanc of this class using the given <paramref name="configuration"/> /// </summary> /// <param name="configuration">The configuration</param> public BruTileLayer(IConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException("configuration"); } var data = base.ContextMenuItems.Find(m => m.Name == "Data"); if (data != null) { base.ContextMenuItems.Remove(data); } /* * data = base.ContextMenuItems.Find(m => m.Name.StartsWith("Attrib")); * if (data != null) base.ContextMenuItems.Remove(data); */ // Initialize the configuration prior to usage configuration.Initialize(); // _configuration = configuration; var tileSource = configuration.TileSource; _projectionInfo = AuthorityCodeHandler.Instance[tileSource.Schema.Srs]; if (_projectionInfo == null) { _projectionInfo = AuthorityCodeHandler.Instance["EPSG:3857"]; } // WebMercator: set datum to WGS1984 for better accuracy if (tileSource.Schema.Srs == "EPSG:3857") { _projectionInfo.GeographicInfo.Datum = KnownCoordinateSystems.Geographic.World.WGS1984.GeographicInfo.Datum; } Projection = _projection; var extent = tileSource.Schema.Extent; MyExtent = new Extent(extent.MinX, extent.MinY, extent.MaxX, extent.MaxY); base.LegendText = configuration.LegendText; base.LegendItemVisible = true; base.IsVisible = base.Checked = true; base.LegendSymbolMode = SymbolMode.Symbol; LegendType = LegendType.Custom; _tileFetcher = configuration.TileFetcher; _tileFetcher.TileReceived += HandleTileReceived; _tileFetcher.QueueEmpty += HandleQueueEmpty; //Set the wrap mode _imageAttributes = new ImageAttributes(); _imageAttributes.SetWrapMode(WrapMode.TileFlipXY); }
public void SetAreaRectangle(Extent extent, ProjectionInfo rectangleProjection) { var xMin = extent.MinX; var yMin = extent.MinY; var xMax = extent.MaxX; var yMax = extent.MaxY; var box = new Box(xMin, xMax, yMin, yMax); SetAreaRectangle(box, rectangleProjection); }
public LiDARDataSet(string filename) { //here read the maxX, maxY from the las file header //and change the Extent property LasReader Reader = new LasReader(filename); Reader.initialize(); ulong PointNum = Reader.getNumPoints(); int ArrayLength = (int)PointNum; //Range_double range = Reader.getBounds(); //Reader.getBounds //Bounds_double ll = Reader.getBounds(); Schema schema = Reader.getSchema(); PointBuffer data = new PointBuffer(schema, (uint)PointNum); // get the dimensions (fields) of the point record for the X, Y, and Z values int offsetX = schema.getDimensionIndex(DimensionId.Id.X_i32); int offsetY = schema.getDimensionIndex(DimensionId.Id.Y_i32); int offsetZ = schema.getDimensionIndex(DimensionId.Id.Z_i32); Dimension dimensionX = schema.getDimension((uint)offsetX); Dimension dimensionY = schema.getDimension((uint)offsetY); Dimension dimensionZ = schema.getDimension((uint)offsetZ); // make the iterator to read from the file StageSequentialIterator iter = Reader.createSequentialIterator(); uint numRead = iter.read(data); int xraw = data.getField_Int32(0, offsetX); int yraw = data.getField_Int32(0, offsetY); // LAS stores the data in scaled integer form: undo the scaling // so we can see the real values as doubles double MinX, MaxX, MinY, MaxY; MinX = MaxX = dimensionX.applyScaling_Int32(xraw); MinY = MaxY = dimensionY.applyScaling_Int32(yraw); for (int i = 1; i < ArrayLength; i++) { xraw = data.getField_Int32((uint)i, offsetX); yraw = data.getField_Int32((uint)i, offsetY); // LAS stores the data in scaled integer form: undo the scaling // so we can see the real values as doubles double x = dimensionX.applyScaling_Int32(xraw); double y = dimensionY.applyScaling_Int32(yraw); if (x < MinX) MinX = x; if (x > MaxX) MaxX = x; if (y < MinY) MinY = y; if (y > MaxY) MaxY = y; } setupExtent = new Extent(MinX, MinY, MaxX, MaxY); }
/// <summary> /// The geographic envelope gives the region that the image should be created for. /// The window gives the corresponding pixel dimensions for the image, so that /// images matching the resolution of the screen can be used. /// </summary> /// <param name="envelope"> /// The geographic extents to retrieve data for /// </param> /// <param name="window"> /// The rectangle that defines the size of the drawing area in pixels /// </param> /// <returns> /// A bitmap captured from the main image /// </returns> public Bitmap GetBitmap(Extent envelope, Rectangle window) { if (window.Width == 0 || window.Height == 0) return null; if (Bounds == null || Bounds.Extent == null || Bounds.Extent.IsEmpty()) return null; // 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 = Bounds.AffineCoefficients; // 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); Bitmap tempResult = null; Bitmap result = null; Graphics g = null; try { tempResult = new Bitmap(window.Width, window.Height); g = Graphics.FromImage(tempResult); g.Transform = new Matrix(m11, m12, m21, m22, xShift, yShift); g.PixelOffsetMode = PixelOffsetMode.Half; if (m11 > 1 || m22 > 1) g.InterpolationMode = InterpolationMode.NearestNeighbor; if (!g.VisibleClipBounds.IsEmpty) g.DrawImage(_myImage, new PointF(0, 0)); result = tempResult; tempResult = null; } catch (OverflowException) { } //Raised by g.DrawImage if the new images extent is to small finally { if (tempResult != null) tempResult.Dispose(); if (g != null) g.Dispose(); } return result; }
/// <summary> /// This method simulates loading the array of points from the LAS file. /// Right now it is generating random points that are within the /// view extent. /// </summary> /// <param name="boundingBox">the view extent</param> /// <returns>array of the points in [x y x y ... order]</returns> public double[] GetPointArray(Extent boundingBox) { double[] pointArray = new double[1000]; Random rnd = new Random(); double xMin = boundingBox.MinX; double yMin = boundingBox.MinY; for (int i = 0; i < 1000; i++) { double randomX = xMin + rnd.NextDouble() * boundingBox.Width; double randomY = yMin + rnd.NextDouble() * boundingBox.Height; pointArray[i] = randomX; i = i + 1; pointArray[i] = randomY; } return pointArray; }
public SearchResult GetSeriesCatalogInPolygon(IList<IFeature> polygons, string[] keywords, double tileWidth, double tileHeight, DateTime startDate, DateTime endDate, WebServiceNode[] serviceIDs, BusinessObjects.Models.IProgressHandler bgWorker) { if (polygons == null) throw new ArgumentNullException("polygons"); if (bgWorker == null) throw new ArgumentNullException("bgWorker"); if (polygons.Count == 0) { throw new ArgumentException("The number of polygons must be greater than zero."); } if (keywords == null || keywords.Length == 0) { keywords = new[] { String.Empty }; } var fullSeriesList = new List<BusinessObjects.Models.SeriesDataCartModel.SeriesDataCart>(); for (int index = 0; index < polygons.Count; index++) { if (polygons.Count > 1) { bgWorker.ReportMessage(string.Format("Processing polygons: {0} of {1}", index + 1, polygons.Count)); } bgWorker.CheckForCancel(); var polygon = polygons[index]; var extentBox = new Extent(polygon.Envelope); var seriesForPolygon = GetSeriesListForExtent(extentBox, keywords, tileWidth, tileHeight, startDate, endDate, serviceIDs, bgWorker, item => polygon.Intersects(new Coordinate(item.Longitude, item.Latitude))); fullSeriesList.AddRange(seriesForPolygon); } SearchResult resultFs = null; if (fullSeriesList.Count > 0) { bgWorker.ReportMessage("Calculating Points..."); resultFs = SearchHelper.ToFeatureSetsByDataSource(fullSeriesList); } bgWorker.CheckForCancel(); var message = string.Format("{0} Series found.", totalSeriesCount); bgWorker.ReportProgress(100, "Search Finished. " + message); return resultFs; }
/// <summary> /// Clears form and search-generated objects, resets UI to prepare for search. /// </summary> public void ResetInterface() { #region Reset Map and Map-affiliated parameters SpatialTemporalCommitted = false; // map1.ZoomToMaxExtent(); // map1.ClearSelection(); SrchExt = new DotSpatial.Data.Extent(); #endregion #region Reset default DateTime values // BeginTimePicker.Value = DateTime.Parse("1/1/1911 1:00 AM"); // EndTimePicker.Value = DateTime.Now; #endregion #region Clear and Disable Faceted Search interface ResetFacetFlowPanel(); #endregion }
/// <summary> /// Gets the bitmap for the specified geographic envelope scaled to fit on a bitmap of the specified size in pixels. /// </summary> /// <param name="envelope"></param> /// <param name="pixelSize"></param> /// <returns></returns> public virtual Bitmap GetBitmap(Extent envelope, Size pixelSize) { Bitmap result = new Bitmap(pixelSize.Width, pixelSize.Height); Graphics g = Graphics.FromImage(result); foreach (ImageData image in _images) { Extent bounds = envelope.Intersection(image.Extent); Size ps = new Size((int)(pixelSize.Width * bounds.Width / envelope.Width), (int)(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> /// Divides the search bounding box into several 'tiles' to prevent /// </summary> /// <param name="bigBoundingBox">the original bounding box</param> /// <param name="tileWidth">The tile width in decimal degrees</param> /// <param name="tileHeight">The tile height (south-north) in decimal degrees</param> /// <returns></returns> public static List<Extent> CreateTiles(Extent bigBoundingBox, double tileWidth, double tileHeight) { var tiles = new List<Extent>(); double fullWidth = Math.Abs(bigBoundingBox.MaxX - bigBoundingBox.MinX); double fullHeight = Math.Abs(bigBoundingBox.MaxY - bigBoundingBox.MinY); if (fullWidth < tileWidth || fullHeight < tileHeight) { tiles.Add(bigBoundingBox); return tiles; } double yll = bigBoundingBox.MinY; //y-coordinate of the tile's lower left corner var numColumns = (int)(Math.Ceiling(fullWidth / tileWidth)); var numRows = (int)(Math.Ceiling(fullHeight / tileHeight)); var lastTileWidth = fullWidth - ((numColumns - 1) * tileWidth); var lastTileHeight = fullHeight - ((numRows - 1) * tileHeight); int r; for (r = 0; r < numRows; r++) { double xll = bigBoundingBox.MinX; //x-coordinate of the tile's lower left corner if (r == numRows - 1) { tileHeight = lastTileHeight; } int c; for (c = 0; c < numColumns; c++) { var newTile = c == (numColumns - 1) ? new Extent(xll, yll, xll + lastTileWidth, yll + tileHeight) : new Extent(xll, yll, xll + tileWidth, yll + tileHeight); tiles.Add(newTile); xll = xll + tileWidth; } yll = yll + tileHeight; } return tiles; }
public void GetNoDataCellCountTest() { string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\..\..\..\Data\GetNoDataCellCountTest.BGD"; const double xllcorner = 3267132.224761; const double yllcorner = 5326939.203029; const int ncols = 512; const int nrows = 128; const int frequencyOfNoValue = 5; const double cellsize = 500; double x2 = xllcorner + (cellsize * ncols); double y2 = yllcorner + (cellsize * nrows); Extent myExtent = new Extent(xllcorner, yllcorner, x2, y2); Raster target; target = Raster.Create(path, String.Empty, ncols, nrows, 1, typeof(double), new[] { String.Empty }) as Raster; target.Bounds = new RasterBounds(nrows, ncols, myExtent); target.NoDataValue = -9999; int mRow = target.Bounds.NumRows; int mCol = target.Bounds.NumColumns; for (int row = 0; row < mRow; row++) { for (int col = 0; col < mCol; col++) { if (row % frequencyOfNoValue == 0) target.Value[row, col] = -9999d; else target.Value[row, col] = 2d; } } target.Save(); long expected = (nrows / frequencyOfNoValue) * ncols + ncols; long actual; actual = target.GetNoDataCellCount(); Assert.AreEqual(expected, actual); System.IO.File.Delete(path); }
public KriggingSimulator(Map map, IFeatureSet selectedDataset, Extent extent, Clip clip, string field, string layerName, string pixel) { this._field = field; this._map = map; this._selectedDataset = selectedDataset; this._layerName = layerName; this._extent = extent; this._clip = clip; this._pixel = pixel; this._prefixPath = this._field + "-" + Guid.NewGuid().ToString(); this._folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TempFiles"); zedGraphControl1 = new ZedGraphControl(); theoreticalModelControl1 = new TheoreticalModelControl(); uxSearchNeighborhoodControl1 = new SearchNeighborhoodControl(); uxOutputRaster1 = new OutputRaster(); zedGraphControl2 = new ZedGraphControl(); kriggingResult = new KriggingResult(); }
public void RasterMath_OutputHasSameBounds() { // Prepare input raster const double xllcorner = 3267132.224761; const double yllcorner = 5326939.203029; const int ncols = 39; const int nrows = 57; const double cellsize = 500; const double x2 = xllcorner + (cellsize * ncols); const double y2 = yllcorner + (cellsize * nrows); var myExtent = new Extent(xllcorner, yllcorner, x2, y2); var source = new Raster<int>(nrows, ncols) { Bounds = new RasterBounds(nrows, ncols, myExtent), NoDataValue = -9999 }; var mRow = source.Bounds.NumRows; var mCol = source.Bounds.NumColumns; var i = 0; for (var row = 0; row < mRow; row++) { for (var col = 0; col < mCol; col++) { source.Value[row, col] = i++; } } var target = new RasterMultiply(); IRaster outRaster = new Raster {Filename = FileTools.GetTempFileName(".bgd")}; target.Execute(source, source, outRaster, new MockProgressHandler()); outRaster = Raster.Open(outRaster.Filename); File.Delete(outRaster.Filename); Assert.AreEqual(source.NumColumns, outRaster.NumColumns); Assert.AreEqual(source.NumRows, outRaster.NumRows); Assert.AreEqual(source.Bounds.Extent, outRaster.Bounds.Extent); }
/// <summary> /// The geographic envelope gives the region that the image should be created for. /// The window gives the corresponding pixel dimensions for the image, so that /// images matching the resolution of the screen can be used. /// </summary> /// <param name="envelope"> /// The geographic extents to retrieve data for /// </param> /// <param name="window"> /// The rectangle that defines the size of the drawing area in pixels /// </param> /// <returns> /// A bitmap captured from the main image /// </returns> public Bitmap GetBitmap(Extent envelope, Rectangle window) { 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 = Bounds.AffineCoefficients; // 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(_myImage, new PointF(0, 0)); g.Dispose(); return result; }
/// <summary> /// Creates a new instance of the ImageGraphics class for assisting with drawing. /// </summary> /// <param name="inExtent"></param> /// <param name="inDestRectangle"></param> public ImageProjection(Extent inExtent, Rectangle inDestRectangle) { _extents = inExtent; _destRectangle = inDestRectangle; }
/// <summary> /// Initializes a new instance of the ProjectionHelper class. /// </summary> /// <param name="geographicExtents">The geographic extents to project to and from.</param> /// <param name="viewRectangle">The view rectangle in pixels to transform with.</param> public ProjectionHelper(Extent geographicExtents, Rectangle viewRectangle) { GeographicExtents = geographicExtents; ImageRectangle = viewRectangle; }
/// <summary> /// The geographic envelope gives the region that the image should be created for. /// The window gives the corresponding pixel dimensions for the image, so that /// images matching the resolution of the screen can be used. /// </summary> /// <param name="envelope"> /// The geographic extents to retrieve data for. /// </param> /// <param name="window"> /// The rectangle that defines the size of the drawing area in pixels. /// </param> /// <returns> /// A bitmap captured from the main image. /// </returns> public Bitmap GetBitmap(Extent envelope, Rectangle window) { if (window.Width == 0 || window.Height == 0) { return(null); } if (Bounds == null || Bounds.Extent == null || Bounds.Extent.IsEmpty()) { return(null); } // 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 = Bounds.AffineCoefficients; // 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); double l = a[0] - (.5 * (a[1] + a[2])); // Left of top left pixel double t = 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); Bitmap tempResult = null; Bitmap result = null; Graphics g = null; try { tempResult = new Bitmap(window.Width, window.Height); g = Graphics.FromImage(tempResult); g.Transform = new Matrix(m11, m12, m21, m22, xShift, yShift); g.PixelOffsetMode = PixelOffsetMode.Half; if (m11 > 1 || m22 > 1) { g.InterpolationMode = InterpolationMode.NearestNeighbor; } if (!g.VisibleClipBounds.IsEmpty) { g.DrawImage(_myImage, new PointF(0, 0)); } result = tempResult; tempResult = null; } catch (OverflowException) { // Raised by g.DrawImage if the new images extent is to small } finally { tempResult?.Dispose(); g?.Dispose(); } return(result); }
/// <summary> /// Notifies the layer that the next time an area that intersects with this region /// is specified, it must first re-draw content to the image buffer. /// </summary> /// <param name="region">The envelope where content has become invalidated.</param> public void Invalidate(Extent region) { }
/// <summary> /// Given a geographic extent, this tests the "IsVisible", "UseDynamicVisibility", /// "DynamicVisibilityMode" and "DynamicVisibilityWidth" /// In order to determine if this layer is visible. /// </summary> /// <param name="geographicExtent">The geographic extent, where the width will be tested.</param> /// <returns>Boolean, true if this layer should be visible for this extent.</returns> public bool VisibleAtExtent(Extent geographicExtent) { return(Extent.Intersects(geographicExtent)); }
/// <summary> /// Takes spatial temporal constraints from main form /// </summary> /// <param name="SearchRegion"></param> /// <param name="sTime"></param> /// <param name="eTime"></param> public void SetSearchParameters(Extent SearchRegion, DateTime sTime, DateTime eTime) { SrchExt = SearchRegion; BeginDateTime = sTime; EndDateTime = eTime; }
/// <inheritdoc /> public Bitmap GetBitmap(Extent envelope, Rectangle window) { return(GetBitmap(envelope, new Size(window.Width, window.Height))); }
/// <summary> /// For each coordinate in the other part, if it falls in the extent of this polygon, a /// ray crossing test is used for point in polygon testing. If it is not in the extent, /// it is skipped. /// </summary> /// <param name="polygonShape">The part of the polygon to analyze polygon</param> /// <param name="otherPart">The other part</param> /// <returns>Boolean, true if any coordinate falls inside the polygon</returns> private static bool ContainsVertex(ShapeRange polygonShape, PartRange otherPart) { // Create an extent for faster checking in most cases Extent ext = polygonShape.Extent; foreach (Vertex point in otherPart) { // This extent check shortcut should help speed things up for large polygon parts if (!ext.Intersects(point)) { continue; } // Imagine a ray on the horizontal starting from point.X -> infinity. (In practice this can be ext.XMax) // Count the intersections of segments with that line. If the resulting count is odd, the point is inside. Segment ray = new Segment(point.X, point.Y, ext.MaxX, point.Y); int[] numCrosses = new int[polygonShape.NumParts]; // A cross is a complete cross. Coincident doesn't count because it is either 0 or 2 crosses. int totalCrosses = 0; int iPart = 0; foreach (PartRange ring in polygonShape.Parts) { foreach (Segment segment in ring.Segments) { if (segment.IntersectionCount(ray) != 1) { continue; } numCrosses[iPart]++; totalCrosses++; } iPart++; } // If we didn't actually have any polygons we cant intersect with anything if (polygonShape.NumParts < 1) { return(false); } // For shapes with only one part, we don't need to test part-containment. if (polygonShape.NumParts == 1 && totalCrosses % 2 == 1) { return(true); } // This used to check to see if totalCrosses == 1, but now checks to see if totalCrosses is an odd number. // This change was made to solve the issue described in HD Issue 8593 (http://hydrodesktop.codeplex.com/workitem/8593). if (totalCrosses % 2 == 1) { return(true); } totalCrosses = 0; for (iPart = 0; iPart < numCrosses.Length; iPart++) { int count = numCrosses[iPart]; // If this part does not contain the point, don't bother trying to figure out if the part is a hole or not. if (count % 2 == 0) { continue; } // If this particular part is a hole, subtract the total crosses by 1, otherwise add one. // This takes time, so we want to do this as few times as possible. if (polygonShape.Parts[iPart].IsHole()) { totalCrosses--; } else { totalCrosses++; } } return(totalCrosses > 0); } return(false); }
/// <summary> /// For big images the scale that is just one step larger than the specified window will be used. /// </summary> /// <param name="envelope">The envelope containing the geographic extent.</param> /// <param name="window">The rectangle containing the window extent.</param> /// <returns>The bitmap.</returns> public override Bitmap GetBitmap(Extent envelope, Rectangle window) { if (window.Width == 0 || window.Height == 0) { return(null); } if (Header?.ImageHeaders?[0] == null) { return(null); } Rectangle expWindow = window.ExpandBy(1); Envelope expEnvelope = envelope.ToEnvelope().Reproportion(window, expWindow); Envelope 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> /// Instructs the map to change the perspective to include the entire drawing content, and /// in the case of 3D maps, changes the perspective to look from directly overhead. /// </summary> public void ZoomToMaxExtent() { // to prevent exception when zoom to map with one layer with one point const double eps = 1e-7; if (Extent.Width < eps || Extent.Height < eps) { Extent newExtent = new Extent(Extent.MinX - eps, Extent.MinY - eps, Extent.MaxX + eps, Extent.MaxY + eps); ViewExtents = newExtent; } else { ViewExtents = Extent; } }
/// <summary> /// This calculates the extent for the category and caches it in the extents collection /// </summary> /// <param name="category"> /// </param> protected virtual Extent CalculateCategoryExtent(IFeatureCategory category) { Extent ext = new Extent(new[] { double.MaxValue, double.MaxValue, double.MinValue, double.MinValue }); if (_editMode) { IDictionary<IFeature, IDrawnState> features = _drawingFilter.DrawnStates; foreach (IFeature f in DataSet.Features) { if (category == features[f].SchemeCategory) { ext.ExpandToInclude(new Extent(f.Envelope)); } } if (_categoryExtents.Keys.Contains(category)) { _categoryExtents[category] = ext.Copy(); } else { _categoryExtents.Add(category, ext.Copy()); } } else { FastDrawnState[] states = DrawnStates; List<ShapeRange> ranges = DataSet.ShapeIndices; for (int shp = 0; shp < DrawnStates.Length; shp++) { if (states[shp].Category != null) { if (!_categoryExtents.ContainsKey(states[shp].Category)) { _categoryExtents.Add(states[shp].Category, ranges[shp].Extent.Copy()); } else { _categoryExtents[states[shp].Category].ExpandToInclude(ranges[shp].Extent); } } } } return ext; }
private void Configure(IImageData baseImage) { _bufferRectangle = new Rectangle(0, 0, baseImage.Width, baseImage.Height); _bufferExtent = baseImage.Bounds.Extent; base.IsVisible = true; MyExtent = baseImage.Extent; base.LegendText = Path.GetFileName(baseImage.Filename); OnFinishedLoading(); }
public void SetExtents(DotSpatial.Data.Extent extent) { //throw new NotImplementedException(); }
/// <summary> /// This allows overriding layers to handle any memory cleanup. /// </summary> /// <param name="disposeManagedResources">True if managed resources should be set to null.</param> protected virtual void Dispose(bool disposeManagedResources) { if (_isDisposed) { return; } if (disposeManagedResources) { LayerSelected = null; ZoomToLayer = null; ShowProperties = null; FinishedLoading = null; SelectionChanged = null; base.ContextMenuItems = null; MyExtent = null; base.LegendText = null; _progressHandler = null; _progressMeter = null; _invalidatedRegion = null; _mapFrame = null; _propertyDialogProvider = null; } // Since the InnerDataset likely contains unmanaged memory constructs, dispose of it here. if (_dataSet != null) { _dataSet.UnlockDispose(); if (!_dataSet.IsDisposeLocked) { _dataSet.Dispose(); } } if (_editCopy != null) _editCopy.Dispose(); _isDisposed = true; }
/// <summary> /// Given a geographic extent, this tests the "IsVisible", "UseDynamicVisibility", /// "DynamicVisibilityMode" and "DynamicVisibilityWidth" /// In order to determine if this layer is visible for the specified scale. /// </summary> /// <param name="geographicExtent">The geographic extent, where the width will be tested.</param> /// <returns>Boolean, true if this layer should be visible for this extent.</returns> public bool VisibleAtExtent(Extent geographicExtent) { if (!IsVisible) return false; if (UseDynamicVisibility) { if (DynamicVisibilityMode == DynamicVisibilityMode.ZoomedIn) { if (geographicExtent.Width > DynamicVisibilityWidth) { return false; // skip the geoLayer if we are zoomed out too far. } } else { if (geographicExtent.Width < DynamicVisibilityWidth) { return false; // skip the geoLayer if we are zoomed out too far. } } } return true; }
// X Y MultiPoints: Total Length = 28 Bytes // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- // Byte 0 Record Number Integer 1 Big // Byte 4 Content Length Integer 1 Big // Byte 8 Shape Type 8 Integer 1 Little // Byte 12 Xmin Double 1 Little // Byte 20 Ymin Double 1 Little // Byte 28 Xmax Double 1 Little // Byte 36 Ymax Double 1 Little // Byte 48 NumPoints Integer 1 Little // Byte X Points Point NumPoints Little // X Y M MultiPoints: Total Length = 34 Bytes // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- // Byte 0 Record Number Integer 1 Big // Byte 4 Content Length Integer 1 Big // Byte 8 Shape Type 28 Integer 1 Little // Byte 12 Box Double 4 Little // Byte 44 NumPoints Integer 1 Little // Byte X Points Point NumPoints Little // Byte Y* Mmin Double 1 Little // Byte Y + 8* Mmax Double 1 Little // Byte Y + 16* Marray Double NumPoints Little // X Y Z M MultiPoints: Total Length = 44 Bytes // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- // Byte 0 Record Number Integer 1 Big // Byte 4 Content Length Integer 1 Big // Byte 8 Shape Type 18 Integer 1 Little // Byte 12 Box Double 4 Little // Byte 44 NumPoints Integer 1 Little // Byte X Points Point NumPoints Little // Byte Y Zmin Double 1 Little // Byte Y + 8 Zmax Double 1 Little // Byte Y + 16 Zarray Double NumPoints Little // Byte Z* Mmin Double 1 Little // Byte Z+8* Mmax Double 1 Little // Byte Z+16* Marray Double NumPoints Little private void FillPoints(string fileName, IProgressHandler progressHandler) { // Check to ensure the fileName is not null if (fileName == null) { throw new NullReferenceException(DataStrings.ArgumentNull_S.Replace("%S", fileName)); } if (File.Exists(fileName) == false) { throw new FileNotFoundException(DataStrings.FileNotFound_S.Replace("%S", fileName)); } // Get the basic header information. ShapefileHeader header = new ShapefileHeader(fileName); Extent = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax }); // Check to ensure that the fileName is the correct shape type if (header.ShapeType != ShapeType.MultiPoint && header.ShapeType != ShapeType.MultiPointM && header.ShapeType != ShapeType.MultiPointZ) { throw new ArgumentException(DataStrings.FileNotLines_S.Replace("%S", fileName)); } // Reading the headers gives us an easier way to track the number of shapes and their overall length etc. List <ShapeHeader> shapeHeaders = ReadIndexFile(fileName); // This will set up a reader so that we can read values in huge chunks, which is much faster than one value at a time. BufferedBinaryReader bbReader = new BufferedBinaryReader(fileName, progressHandler); if (bbReader.FileLength == 100) { // The shapefile is empty so we can simply return here bbReader.Close(); return; } // Skip the shapefile header by skipping the first 100 bytes in the shapefile bbReader.Seek(100, SeekOrigin.Begin); int numShapes = shapeHeaders.Count; byte[] bigEndians = new byte[numShapes * 8]; byte[] allBounds = new byte[numShapes * 32]; ByteBlock allCoords = new ByteBlock(BLOCKSIZE); bool isM = (header.ShapeType == ShapeType.MultiPointZ || header.ShapeType == ShapeType.MultiPointM); bool isZ = (header.ShapeType == ShapeType.PolyLineZ); ByteBlock allZ = null; ByteBlock allM = null; if (isZ) { allZ = new ByteBlock(BLOCKSIZE); } if (isM) { allM = new ByteBlock(BLOCKSIZE); } int pointOffset = 0; for (int shp = 0; shp < numShapes; shp++) { // Read from the index file because some deleted records // might still exist in the .shp file. long offset = (shapeHeaders[shp].ByteOffset); bbReader.Seek(offset, SeekOrigin.Begin); // time: 200 ms ShapeRange shape = new ShapeRange(FeatureType.MultiPoint) { RecordNumber = bbReader.ReadInt32(false), ContentLength = bbReader.ReadInt32(false), ShapeType = (ShapeType)bbReader.ReadInt32(), StartIndex = pointOffset }; //bbReader.Read(bigEndians, shp * 8, 8); if (shape.ShapeType == ShapeType.NullShape) { continue; } bbReader.Read(allBounds, shp * 32, 32); shape.NumParts = 1; shape.NumPoints = bbReader.ReadInt32(); allCoords.Read(shape.NumPoints * 16, bbReader); pointOffset += shape.NumPoints; if (header.ShapeType == ShapeType.MultiPointM) { // These are listed as "optional" but there isn't a good indicator of // how to determine if they were added. // To handle the "optional" M values, check the contentLength for the feature. // The content length does not include the 8-byte record header and is listed in 16-bit words. if (shape.ContentLength * 2 > 44 + 4 * shape.NumParts + 16 * shape.NumPoints) { IExtentM mExt = (IExtentM)MyExtent; mExt.MinM = bbReader.ReadDouble(); mExt.MaxM = bbReader.ReadDouble(); if (allM != null) { allM.Read(shape.NumPoints * 8, bbReader); } } } if (header.ShapeType == ShapeType.MultiPointZ) { bool hasM = shape.ContentLength * 2 > 60 + 4 * shape.NumParts + 24 * shape.NumPoints; IExtentZ zExt = (IExtentZ)MyExtent; zExt.MinZ = bbReader.ReadDouble(); zExt.MaxZ = bbReader.ReadDouble(); // For Z shapefiles, the Z part is not optional. if (allZ != null) { allZ.Read(shape.NumPoints * 8, bbReader); } // These are listed as "optional" but there isn't a good indicator of // how to determine if they were added. // To handle the "optional" M values, check the contentLength for the feature. // The content length does not include the 8-byte record header and is listed in 16-bit words. if (hasM) { IExtentM mExt = (IExtentM)MyExtent; mExt.MinM = bbReader.ReadDouble(); mExt.MaxM = bbReader.ReadDouble(); if (allM != null) { allM.Read(shape.NumPoints * 8, bbReader); } } } // Now that we have read all the values, create the geometries from the points and parts arrays. ShapeIndices.Add(shape); } double[] vert = allCoords.ToDoubleArray(); Vertex = vert; if (isM) { M = allM.ToDoubleArray(); } if (isZ) { Z = allZ.ToDoubleArray(); } Array.Reverse(bigEndians); List <ShapeRange> shapes = ShapeIndices; double[] bounds = new double[numShapes * 4]; Buffer.BlockCopy(allBounds, 0, bounds, 0, allBounds.Length); for (int shp = 0; shp < numShapes; shp++) { ShapeRange shape = shapes[shp]; shape.Extent = new Extent(bounds, shp * 4); int endIndex = shape.NumPoints + shape.StartIndex; int startIndex = shape.StartIndex; int count = endIndex - startIndex; PartRange partR = new PartRange(vert, shape.StartIndex, 0, FeatureType.MultiPoint) { NumVertices = count }; shape.Parts.Add(partR); } bbReader.Dispose(); }
/// <summary> /// Converts a single geographic envelope into an equivalent Rectangle /// as it would be drawn on the screen. /// </summary> /// <param name="env">The geographic IEnvelope</param> /// <returns>A Rectangle</returns> public Rectangle ProjToPixel(Extent env) { return _geoMapFrame.ProjToPixel(env); }
/// <inheritdocs/> public Dictionary <int, Shape> GetShapes(ref int startIndex, int count, Envelope envelope) { Dictionary <int, Shape> result = new Dictionary <int, Shape>(); ShapefileIndexFile shx = CacheShapeIndexFile(); // Check to ensure the fileName is not null if (Filename == null) { throw new NullReferenceException(Filename); } if (!File.Exists(Filename)) { throw new FileNotFoundException(Filename); } // Get the basic header information. ShapefileHeader header = new ShapefileHeader(Filename); Extent ext = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax }); if (envelope != null) { if (!ext.Intersects(envelope)) { return(result); } } // Check to ensure that the fileName is the correct shape type if (header.ShapeType != ShapeType && header.ShapeType != ShapeTypeM && header.ShapeType != ShapeTypeZ) { throw new ArgumentException("Wrong feature type."); } FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read); if (fs.Length == 100) { // The shapefile is empty so we can simply return here fs.Close(); return(result); } int shapesTested = 0; int shapesReturned = 0; // Use spatial index if we have one if (null != _spatialIndex && null != envelope) { IList <int> spatialQueryResults = _spatialIndex.Query(envelope); // Sort the results from low to high index var sqra = new int[spatialQueryResults.Count]; spatialQueryResults.CopyTo(sqra, 0); Array.Sort(sqra); foreach (int shp in sqra) { if (shp >= startIndex) { Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope); shapesTested++; if (null != myShape) { shapesReturned++; result.Add(shp, myShape); if (shapesReturned >= count) { break; } } } } } else { int numShapes = shx.Shapes.Count; for (int shp = startIndex; shp < numShapes; shp++) { Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope); shapesTested++; if (null != myShape) { shapesReturned++; result.Add(shp, myShape); if (shapesReturned >= count) { break; } } } } startIndex += shapesTested; fs.Close(); return(result); }
/// <summary> /// Instead of using the usual buffers, this bypasses any buffering and instructs the layers /// to draw directly to the specified target rectangle on the graphics object. This is useful /// for doing vector drawing on much larger pages. The result will be centered in the /// specified target rectangle bounds. /// </summary> /// <param name="device">The graphics device to print to</param> /// <param name="targetRectangle">the rectangle where the map content should be drawn.</param> /// <param name="targetEnvelope">the extents to print in the target rectangle</param> public void Print(Graphics device, Rectangle targetRectangle, Extent targetEnvelope) { MapFrame.Print(device, targetRectangle, targetEnvelope); }
/// <summary> /// Tests the intersection with an extents /// </summary> /// <param name="ext"></param> /// <returns></returns> public bool Intersects(Extent ext) { return(Intersects(new Shape(ext).Range)); }
private static BruTile.Extent ToBrutileExtent(DotSpatial.Data.Extent extent) { return(new BruTile.Extent(extent.MinX, extent.MinY, extent.MaxX, extent.MaxY)); }
/// <summary> /// This tests each feature of the input. /// </summary> /// <param name="self">This featureSet.</param> /// <param name="other">The featureSet to perform intersection with.</param> /// <param name="joinType">The attribute join type.</param> /// <param name="progHandler">A progress handler for status messages.</param> /// <returns>An IFeatureSet with the intersecting features, broken down based on the join Type.</returns> public static IFeatureSet Intersection(this IFeatureSet self, IFeatureSet other, FieldJoinType joinType, IProgressHandler progHandler) { IFeatureSet result = null; ProgressMeter pm = new(progHandler, "Calculating Intersection", self.Features.Count); if (joinType == FieldJoinType.All) { result = CombinedFields(self, other); // Intersection is symmetric, so only consider I X J where J <= I if (!self.AttributesPopulated) { self.FillAttributes(); } if (!other.AttributesPopulated) { other.FillAttributes(); } for (int i = 0; i < self.Features.Count; i++) { IFeature selfFeature = self.Features[i]; List <IFeature> potentialOthers = other.Select(selfFeature.Geometry.EnvelopeInternal.ToExtent()); foreach (IFeature otherFeature in potentialOthers) { selfFeature.Intersection(otherFeature, result, joinType); } pm.CurrentValue = i; } pm.Reset(); } else if (joinType == FieldJoinType.LocalOnly) { if (!self.AttributesPopulated) { self.FillAttributes(); } result = new FeatureSet(); result.CopyTableSchema(self); result.FeatureType = self.FeatureType; if (other.Features != null && other.Features.Count > 0) { pm = new ProgressMeter(progHandler, "Calculating Union", other.Features.Count); IFeature union = other.Features[0]; for (int i = 1; i < other.Features.Count; i++) { union = union.Union(other.Features[i].Geometry); pm.CurrentValue = i; } pm.Reset(); pm = new ProgressMeter(progHandler, "Calculating Intersections", self.NumRows()); Extent otherEnvelope = union.Geometry.EnvelopeInternal.ToExtent(); for (int shp = 0; shp < self.ShapeIndices.Count; shp++) { if (!self.ShapeIndices[shp].Extent.Intersects(otherEnvelope)) { continue; } IFeature selfFeature = self.GetFeature(shp); selfFeature.Intersection(union, result, joinType); pm.CurrentValue = shp; } pm.Reset(); } } else if (joinType == FieldJoinType.ForeignOnly) { if (!other.AttributesPopulated) { other.FillAttributes(); } result = new FeatureSet(); result.CopyTableSchema(other); result.FeatureType = other.FeatureType; if (self.Features != null && self.Features.Count > 0) { pm = new ProgressMeter(progHandler, "Calculating Union", self.Features.Count); IFeature union = self.Features[0]; for (int i = 1; i < self.Features.Count; i++) { union = union.Union(self.Features[i].Geometry); pm.CurrentValue = i; } pm.Reset(); if (other.Features != null) { pm = new ProgressMeter(progHandler, "Calculating Intersection", other.Features.Count); for (int i = 0; i < other.Features.Count; i++) { other.Features[i].Intersection(union, result, FieldJoinType.LocalOnly); pm.CurrentValue = i; } } pm.Reset(); } } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="InRamImageData"/> class. /// Uses a bitmap and a geographic envelope in order to define a new imageData object. /// </summary> /// <param name="rawImage"> /// The raw image. /// </param> /// <param name="bounds"> /// The envelope bounds. /// </param> public InRamImageData(Bitmap rawImage, Extent bounds) { _myImage = rawImage; Width = _myImage.Width; Height = _myImage.Height; Bounds = new RasterBounds(_myImage.Height, _myImage.Width, bounds); MemorySetup(); }
/// <summary> /// The geographic envelope gives the region that the image should be created for. /// The window gives the corresponding pixel dimensions for the image, so that /// images matching the resolution of the screen can be used. /// </summary> /// <param name="envelope">The geographic extents to retrieve data for</param> /// <param name="size">The rectangle that defines the size of the drawing area in pixels</param> /// <returns>A bitmap captured from the main image </returns> public Bitmap GetBitmap(Extent envelope, Size size) { return(GetBitmap(envelope, new Rectangle(new Point(0, 0), size))); }
/// <summary> /// Notifies the layer that the next time an area that intersects with this region /// is specified, it must first re-draw content to the image buffer. /// </summary> /// <param name="region">The envelope where content has become invalidated.</param> public virtual void Invalidate(Extent region) { if (_invalidatedRegion != null) { // This is set to null when we do the redrawing, so we would rather expand // the redraw region than forget to update a modified area. _invalidatedRegion.ExpandToInclude(region); } else { _invalidatedRegion = region; } }
/// <summary> /// The geographic envelope gives the region that the image should be created for. /// The window gives the corresponding pixel dimensions for the image, so that /// images matching the resolution of the screen can be used. /// </summary> /// <param name="envelope">The geographic extents to retrieve data for</param> /// <param name="window">The rectangle that defines the size of the drawing area in pixels</param> /// <returns>A bitmap captured from the main image </returns> public virtual Bitmap GetBitmap(Extent envelope, Rectangle window) { return(null); }
/// <summary> /// Generates a new extent from the shape header. This will infer the whether the ExtentMZ, ExtentM /// or Extent class is the best implementation. Casting is required to access the higher /// values from the Extent return type. /// </summary> /// <returns>Extent, which can be Extent, ExtentM, or ExtentMZ</returns> public Extent ToExtent() { if (ShapeType == ShapeType.MultiPointZ || ShapeType == ShapeType.PointZ || ShapeType == ShapeType.PolygonZ || ShapeType == ShapeType.PolyLineZ) { return new ExtentMZ(_xMin, _yMin, _mMin, _zMin, _xMax, _yMax, _mMax, _zMax); } if (ShapeType == ShapeType.MultiPointM || ShapeType == ShapeType.PointM || ShapeType == ShapeType.PolygonM || ShapeType == ShapeType.PolyLineM) { return new ExtentM(_xMin, _yMin, _mMin, _xMax, _yMax, _mMax); } Extent ext = new Extent(_xMin, _yMin, _xMax, _yMax); return ext; }
// X Y Poly Lines: Total Length = 28 Bytes // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- // Byte 0 Record Number Integer 1 Big // Byte 4 Content Length Integer 1 Big // Byte 8 Shape Type 3 Integer 1 Little // Byte 12 Xmin Double 1 Little // Byte 20 Ymin Double 1 Little // Byte 28 Xmax Double 1 Little // Byte 36 Ymax Double 1 Little // Byte 44 NumParts Integer 1 Little // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little // Byte X Points Point NumPoints Little // X Y M Poly Lines: Total Length = 34 Bytes // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- // Byte 0 Record Number Integer 1 Big // Byte 4 Content Length Integer 1 Big // Byte 8 Shape Type 23 Integer 1 Little // Byte 12 Box Double 4 Little // Byte 44 NumParts Integer 1 Little // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little // Byte X Points Point NumPoints Little // Byte Y* Mmin Double 1 Little // Byte Y + 8* Mmax Double 1 Little // Byte Y + 16* Marray Double NumPoints Little // X Y Z M Poly Lines: Total Length = 44 Bytes // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- // Byte 0 Record Number Integer 1 Big // Byte 4 Content Length Integer 1 Big // Byte 8 Shape Type 13 Integer 1 Little // Byte 12 Box Double 4 Little // Byte 44 NumParts Integer 1 Little // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little // Byte X Points Point NumPoints Little // Byte Y Zmin Double 1 Little // Byte Y + 8 Zmax Double 1 Little // Byte Y + 16 Zarray Double NumPoints Little // Byte Z* Mmin Double 1 Little // Byte Z+8* Mmax Double 1 Little // Byte Z+16* Marray Double NumPoints Little private void FillPolygons(string fileName, IProgressHandler progressHandler) { // Check to ensure the fileName is not null if (fileName == null) { throw new NullReferenceException(DataStrings.ArgumentNull_S.Replace("%S", fileName)); } if (File.Exists(fileName) == false) { throw new FileNotFoundException(DataStrings.FileNotFound_S.Replace("%S", fileName)); } // Get the basic header information. ShapefileHeader header = new ShapefileHeader(fileName); Extent = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax }); // Check to ensure that the fileName is the correct shape type if (header.ShapeType != ShapeType.Polygon && header.ShapeType != ShapeType.PolygonM && header.ShapeType != ShapeType.PolygonZ) { throw new ArgumentException(DataStrings.FileNotLines_S.Replace("%S", fileName)); } // Reading the headers gives us an easier way to track the number of shapes and their overall length etc. List <ShapeHeader> shapeHeaders = ReadIndexFile(fileName); // TO DO: replace with a normal reader. We no longer need Buffered Binary reader as // the buffer can be set on the underlying file stream. BufferedBinaryReader bbReader = new BufferedBinaryReader(fileName, progressHandler); if (bbReader.FileLength == 100) { // The shapefile is empty so we can simply return here bbReader.Close(); return; } // Skip the shapefile header by skipping the first 100 bytes in the shapefile bbReader.Seek(100, SeekOrigin.Begin); int numShapes = shapeHeaders.Count; int[] partOffsets = new int[numShapes]; //byte[] allBounds = new byte[numShapes * 32]; // probably all will be in one block, but use a byteBlock just in case. ByteBlock allParts = new ByteBlock(BLOCKSIZE); ByteBlock allCoords = new ByteBlock(BLOCKSIZE); bool isM = (header.ShapeType == ShapeType.PolygonM || header.ShapeType == ShapeType.PolygonZ); bool isZ = (header.ShapeType == ShapeType.PolygonZ); ByteBlock allZ = null; ByteBlock allM = null; if (isZ) { allZ = new ByteBlock(BLOCKSIZE); } if (isM) { allM = new ByteBlock(BLOCKSIZE); } int pointOffset = 0; for (int shp = 0; shp < numShapes; shp++) { // Read from the index file because some deleted records // might still exist in the .shp file. long offset = (shapeHeaders[shp].ByteOffset); bbReader.Seek(offset, SeekOrigin.Begin); // Position Value Type Number Byte Order ShapeRange shape = new ShapeRange(FeatureType.Polygon); //------------------------------------ shape.RecordNumber = bbReader.ReadInt32(false); // Byte 0 Record Integer 1 Big shape.ContentLength = bbReader.ReadInt32(false); // Byte 4 Length Integer 1 Big // Setting shape type also controls extent class type. shape.ShapeType = (ShapeType)bbReader.ReadInt32(); // Byte 8 Type Integer 1 Little shape.StartIndex = pointOffset; if (shape.ShapeType == ShapeType.NullShape) { continue; } shape.Extent.MinX = bbReader.ReadDouble(); shape.Extent.MinY = bbReader.ReadDouble(); shape.Extent.MaxX = bbReader.ReadDouble(); shape.Extent.MaxY = bbReader.ReadDouble(); shape.NumParts = bbReader.ReadInt32(); // Byte 44 #Parts Integer 1 Little shape.NumPoints = bbReader.ReadInt32(); // Byte 48 #Points Integer 1 Little partOffsets[shp] = allParts.IntOffset(); allParts.Read(shape.NumParts * 4, bbReader); allCoords.Read(shape.NumPoints * 16, bbReader); pointOffset += shape.NumPoints; if (header.ShapeType == ShapeType.PolygonM) { // These are listed as "optional" but there isn't a good indicator of // how to determine if they were added. // To handle the "optional" M values, check the contentLength for the feature. // The content length does not include the 8-byte record header and is listed in 16-bit words. if (shape.ContentLength * 2 > 44 + 4 * shape.NumParts + 16 * shape.NumPoints) { IExtentM mExt = (IExtentM)shape.Extent; mExt.MinM = bbReader.ReadDouble(); mExt.MaxM = bbReader.ReadDouble(); if (allM != null) { allM.Read(shape.NumPoints * 8, bbReader); } } } if (header.ShapeType == ShapeType.PolygonZ) { bool hasM = shape.ContentLength * 2 > 60 + 4 * shape.NumParts + 24 * shape.NumPoints; IExtentZ zExt = (IExtentZ)shape.Extent; zExt.MinZ = bbReader.ReadDouble(); zExt.MaxZ = bbReader.ReadDouble(); // For Z shapefiles, the Z part is not optional. if (allZ != null) { allZ.Read(shape.NumPoints * 8, bbReader); } // These are listed as "optional" but there isn't a good indicator of // how to determine if they were added. // To handle the "optional" M values, check the contentLength for the feature. // The content length does not include the 8-byte record header and is listed in 16-bit words. if (hasM) { IExtentM mExt = (IExtentM)shape.Extent; mExt.MinM = bbReader.ReadDouble(); mExt.MaxM = bbReader.ReadDouble(); if (allM != null) { allM.Read(shape.NumPoints * 8, bbReader); } } } ShapeIndices.Add(shape); } double[] vert = allCoords.ToDoubleArray(); Vertex = vert; if (isM) { M = allM.ToDoubleArray(); } if (isZ) { Z = allZ.ToDoubleArray(); } List <ShapeRange> shapes = ShapeIndices; //double[] bounds = new double[numShapes * 4]; //Buffer.BlockCopy(allBounds, 0, bounds, 0, allBounds.Length); int[] parts = allParts.ToIntArray(); ProgressMeter = new ProgressMeter(ProgressHandler, "Testing Parts and Holes", shapes.Count); for (int shp = 0; shp < shapes.Count; shp++) { ShapeRange shape = shapes[shp]; //shape.Extent = new Extent(bounds, shp * 4); for (int part = 0; part < shape.NumParts; part++) { int offset = partOffsets[shp]; int endIndex = shape.NumPoints + shape.StartIndex; int startIndex = parts[offset + part] + shape.StartIndex; if (part < shape.NumParts - 1) { endIndex = parts[offset + part + 1] + shape.StartIndex; } int count = endIndex - startIndex; PartRange partR = new PartRange(vert, shape.StartIndex, parts[offset + part], FeatureType.Polygon); partR.NumVertices = count; shape.Parts.Add(partR); } ProgressMeter.CurrentValue = shp; } ProgressMeter.Reset(); }