/// <summary> /// /// </summary> /// <param name="searchEnv"></param> /// <param name="start0"></param> /// <param name="end0"></param> /// <param name="mcs"></param> private void ComputeSelect(IEnvelope searchEnv, int start0, int end0, MonotoneChainSelectAction mcs) { ICoordinate p0 = pts[start0]; ICoordinate p1 = pts[end0]; mcs.TempEnv1.Init(p0, p1); // terminating condition for the recursion if (end0 - start0 == 1) { mcs.Select(this, start0); return; } // nothing to do if the envelopes don't overlap if (!searchEnv.Intersects(mcs.TempEnv1)) { return; } // the chains overlap, so split each in half and iterate (binary search) int mid = (start0 + end0) / 2; // Assert: mid != start or end (since we checked above for end - start <= 1) // check terminating conditions before recursing if (start0 < mid) { ComputeSelect(searchEnv, start0, mid, mcs); } if (mid < end0) { ComputeSelect(searchEnv, mid, end0, mcs); } }
/// <summary> /// /// </summary> /// <param name="element"></param> protected override void Visit(IGeometry element) { IEnvelope elementEnv = element.EnvelopeInternal; // disjoint if (!rectEnv.Intersects(elementEnv)) { return; } // fully contained - must intersect if (rectEnv.Contains(elementEnv)) { intersects = true; return; } /* * Since the envelopes intersect and the test element is connected, * if its envelope is completely bisected by an edge of the rectangle * the element and the rectangle must touch. * (Note it is NOT possible to make this conclusion * if the test envelope is "on a corner" of the rectangle * envelope) */ if (elementEnv.MinX >= rectEnv.MinX && elementEnv.MaxX <= rectEnv.MaxX) { intersects = true; return; } if (elementEnv.MinY >= rectEnv.MinY && elementEnv.MaxY <= rectEnv.MaxY) { intersects = true; return; } }
public List <long> CollectNIDsPlus(IEnvelope envelope) { // envelope fully contains bounds -> all nodes -> return Zero! if (envelope == null || envelope.Contains(_bounds)) { return(null); } List <long> ids = new List <long>(); NodeNumbers nn = new NodeNumbers(_nodeNumbers); // Query Envelope is outside bounds if (!envelope.Intersects(_bounds)) { if (nn.Contains(0)) // if features outside bounds exists -> add zero node { ids.Add(0); } return(ids); } CollectPlus(0, 0, envelope, _bounds, nn, ids); return(ids); }
/// <summary> /// /// </summary> /// <param name="geom"></param> /// <returns></returns> public bool Intersects(IGeometry geom) { if (!rectEnv.Intersects(geom.EnvelopeInternal)) { return(false); } // test envelope relationships EnvelopeIntersectsVisitor visitor = new EnvelopeIntersectsVisitor(rectEnv); visitor.ApplyTo(geom); if (visitor.Intersects()) { return(true); } // test if any rectangle corner is contained in the target ContainsPointVisitor ecpVisitor = new ContainsPointVisitor(rectangle); ecpVisitor.ApplyTo(geom); if (ecpVisitor.ContainsPoint()) { return(true); } // test if any lines intersect LineIntersectsVisitor liVisitor = new LineIntersectsVisitor(rectangle); liVisitor.ApplyTo(geom); if (liVisitor.Intersects()) { return(true); } return(false); }
/// <summary> /// /// </summary> /// <param name="geom"></param> protected override void Visit(IGeometry geom) { if (!(geom is Polygon)) { return; } IEnvelope elementEnv = geom.EnvelopeInternal; if (!rectEnv.Intersects(elementEnv)) { return; } // test each corner of rectangle for inclusion Coordinate rectPt = new Coordinate(); for (int i = 0; i < 4; i++) { rectSeq.GetCoordinate(i, rectPt); if (!elementEnv.Contains(rectPt)) { continue; } // check rect point in poly (rect is known not to touch polygon at this point) if (SimplePointInAreaLocator.ContainsPointInPolygon(rectPt, (Polygon)geom)) { containsPoint = true; return; } } }
public IEnumerable<IFeature> GetFeatures(IEnvelope bbox, string filter, double scale) { LinkedList<IFeature> ret = new LinkedList<IFeature>(); foreach (MapInfoObject f in m_miffile) { //linear cull if (bbox.Intersects(f.Geometry.EnvelopeInternal)) ret.AddLast(f); } return ret; }
// Actually calculates the distance, given the specified number of dimensions. private static double DoDistance(IEnvelope self, IEnvelope other, int numDimensions) { if (self == null || other == null) { return(-1); } if (self.IsNull || other.IsNull) { return(-1); } if (self.NumOrdinates < numDimensions && other.NumOrdinates < numDimensions) { throw new InsufficientDimensionsException("both envelopes"); } if (self.NumOrdinates < numDimensions) { throw new InsufficientDimensionsException("this envelope"); // assuming used as an extension } if (self.NumOrdinates < numDimensions) { throw new InsufficientDimensionsException("the other envelope"); } if (self.Intersects(other)) { return(0); } Coordinate c = new Coordinate(); for (int i = 0; i < c.NumOrdinates; i++) { if (self.Maximum[i] < other.Minimum[i]) { c[i] = other.Minimum.X - self.Maximum.X; } if (self.Minimum[i] > other.Maximum[i]) { c[i] = self.Minimum[i] - other.Minimum[i]; } } double sumSquares = 0; for (int i = 0; i < numDimensions; i++) { sumSquares += c[i] * c[i]; if (c[i] == 0) { return(0); // an extra check. If any distance is zero, the distance is zero. } } return(Math.Sqrt(sumSquares)); }
//private List<long> history; private void Collect(long number, int level, IEnvelope rect, IEnvelope NodeEnvelope, NodeNumbers nn, List <long> ids, bool checkDuplicates) { //history.Add(number); long reachable = ReachableNodes(number, level); //(long)(number + (long)Math.Pow(2, _maxLevels - level + 1) - 2); if (nn.Cancel || nn.Value > reachable) { return; } if (!rect.Intersects(NodeEnvelope)) { return; } //int nodeIndex = _nodeNumbers.BinarySearch(number); //if (nodeIndex > -1 && ids.BinarySearch(number) < 0) ids.Add(number); int added = 0; if (nn.SetTo(number)) { if (checkDuplicates) { if (ids.BinarySearch(number) < 0) { ids.Add(number); } } else { ids.Add(number); added = 1; } } if (rect.Contains(NodeEnvelope)) { if (level <= _maxLevels) { Collect(number + added, reachable, nn, ids, checkDuplicates); return; } } if (level < _maxLevels) { long c1, c2; ChildNodeNumbers(number, level, out c1, out c2); Collect(c1, level + 1, rect, this.SplitEnvelope(NodeEnvelope, true), nn, ids, checkDuplicates); Collect(c2, level + 1, rect, this.SplitEnvelope(NodeEnvelope, false), nn, ids, checkDuplicates); } }
private void CollectPlus(long number, int level, IEnvelope rect, IEnvelope NodeEnvelope, NodeNumbers nn, List <long> ids) { long reachable = ReachableNodes(number, level); //(long)(number + (long)Math.Pow(2, _maxLevels - level + 1) - 2); if (nn.Cancel || nn.Value > reachable) { return; // ??? } if (!rect.Intersects(NodeEnvelope)) { return; } if (!nn.Contains(number, reachable)) { return; } if (number > 0 && rect.Contains(NodeEnvelope)) { int index = ids.IndexOf(number - 1); if (index > 0 && ids[index - 1] < 0) { // Optimierung: // voriger knoten schon mit Between abgefragt wird -> // Vorigen Between gleich mit neuem Reachable Wert versehen -> weniger Statements!! ids[index] = reachable; } else { ids.Add(-number); ids.Add(reachable); } return; } if (nn.SetTo(number)) { ids.Add(number); } if (level < _maxLevels) { long c1, c2; ChildNodeNumbers(number, level, out c1, out c2); CollectPlus(c1, level + 1, rect, this.SplitEnvelope(NodeEnvelope, true), nn, ids); CollectPlus(c2, level + 1, rect, this.SplitEnvelope(NodeEnvelope, false), nn, ids); } }
/// <summary> /// Returns features within the specified bounding box. /// </summary> /// <param name="bbox"></param> /// <returns></returns> public Collection <IGeometry> GetGeometriesInView(IEnvelope bbox) { // Identifies all the features within the given BoundingBox Collection <IGeometry> geoms = new Collection <IGeometry>(); foreach (IFeature feature in features) { if (bbox.Intersects(feature.Geometry.EnvelopeInternal)) { geoms.Add(feature.Geometry); } } return(geoms); }
/// <summary> /// /// </summary> /// <param name="start0"></param> /// <param name="end0"></param> /// <param name="mce"></param> /// <param name="start1"></param> /// <param name="end1"></param> /// <param name="ei"></param> private void ComputeIntersectsForChain(int start0, int end0, MonotoneChainEdge mce, int start1, int end1, SegmentIntersector ei) { ICoordinate p00 = pts[start0]; ICoordinate p01 = pts[end0]; ICoordinate p10 = mce.pts[start1]; ICoordinate p11 = mce.pts[end1]; // terminating condition for the recursion if (end0 - start0 == 1 && end1 - start1 == 1) { ei.AddIntersections(e, start0, mce.e, start1); return; } // nothing to do if the envelopes of these chains don't overlap env1.Init(p00, p01); env2.Init(p10, p11); if (!env1.Intersects(env2)) { return; } // the chains overlap, so split each in half and iterate (binary search) int mid0 = (start0 + end0) / 2; int mid1 = (start1 + end1) / 2; // check terminating conditions before recursing if (start0 < mid0) { if (start1 < mid1) { ComputeIntersectsForChain(start0, mid0, mce, start1, mid1, ei); } if (mid1 < end1) { ComputeIntersectsForChain(start0, mid0, mce, mid1, end1, ei); } } if (mid0 < end0) { if (start1 < mid1) { ComputeIntersectsForChain(mid0, end0, mce, start1, mid1, ei); } if (mid1 < end1) { ComputeIntersectsForChain(mid0, end0, mce, mid1, end1, ei); } } }
/// <summary> /// Gets the object IDs in the view. /// </summary> /// <param name="envelope">The bbox.</param> /// <returns></returns> public ICollection <int> GetObjectIDsInView(IEnvelope envelope) { // Identifies all the features within the given BoundingBox Collection <int> geoms = new Collection <int>(); for (int i = 0; i < features.Count; i++) { if (envelope.Intersects(((IFeature)features[i]).Geometry.EnvelopeInternal)) { geoms.Add(i); } } return(geoms); }
public IEnumerable <IFeature> GetFeatures(IEnvelope bbox, string filter, double scale) { LinkedList <IFeature> ret = new LinkedList <IFeature>(); foreach (MapInfoObject f in m_miffile) { //linear cull if (bbox.Intersects(f.Geometry.EnvelopeInternal)) { ret.AddLast(f); } } return(ret); }
/// <summary> /// /// </summary> /// <param name="box"></param> public IList GetFeatures(IEnvelope box) { // Identifies all the features within the given BoundingBox IList results = new ArrayList(features.Count); foreach (IFeature feature in features) { if (box.Intersects(feature.Geometry.EnvelopeInternal)) { results.Add(feature); } } return(results); }
/// <summary> /// /// </summary> /// <param name="box"></param> public IEnumerable <IFeature> GetFeatures(IEnvelope box) { // Identifies all the features within the given BoundingBox var results = new List <IFeature>(features.Count); foreach (IFeature feature in features) { if (box.Intersects(feature.Geometry.EnvelopeInternal)) { results.Add(feature); } } return(results); }
/// <summary> /// Overlaps is defined as intersecting, but having some part of each envelope that is also outside /// of the other envelope. Therefore it would amount to saying "Intersects And Not Contains And Not Within" /// </summary> /// <param name="self">The IEnvelope to use with this method</param> /// <param name="other"></param> /// <returns></returns> public static bool Overlaps(this IEnvelope self, IEnvelope other) { if (self.Intersects(other) == false) { return(false); } if (self.Contains(other)) { return(false); } if (other.Contains(self)) { return(false); } return(true); }
/// <summary> /// /// </summary> /// <param name="geom"></param> protected override void Visit(IGeometry geom) { IEnvelope elementEnv = geom.EnvelopeInternal; if (!_rectEnv.Intersects(elementEnv)) { return; } // check if general relate algorithm should be used, since it's faster for large inputs if (geom.NumPoints > RectangleIntersects.MAXIMUM_SCAN_SEGMENT_COUNT) { _intersects = _rectangle.Relate(geom).IsIntersects(); return; } ComputeSegmentIntersection(geom); }
/// <summary> /// /// </summary> /// <param name="geom"></param> protected override void Visit(IGeometry geom) { IEnvelope elementEnv = geom.EnvelopeInternal; if (!rectEnv.Intersects(elementEnv)) { return; } // check if general relate algorithm should be used, since it's faster for large inputs if (geom.NumPoints > RectangleIntersects.MaximumScanSegmentCount) { intersects = rectangle.Relate(geom).IsIntersects(); return; } ComputeSegmentIntersection(geom); }
/// <summary> /// Returns geometry Object IDs whose bounding box intersects 'envelope' /// </summary> /// <param name="envelope"></param> /// <returns></returns> public virtual ICollection <int> GetObjectIDsInView(IEnvelope envelope) { if (!IsOpen) { Open(Path); } // Identifies all the features within the given BoundingBox System.Collections.ObjectModel.Collection <int> geoms = new System.Collections.ObjectModel.Collection <int>(); foreach (FeatureDataRow fdr in _FeatureTable) { if (envelope.Intersects(((IFeature)fdr).Geometry.EnvelopeInternal)) { geoms.Add(Convert.ToInt32(fdr.Attributes["DXF_ID"])); } } return(geoms); }
static bool Intersect(IEnvelope envelope, List <IPolygon> polygons) { foreach (var polygon in polygons) { var polygonEnvelope = polygon.Envelope; if (!envelope.Intersects(polygonEnvelope) && !envelope.Contains(polygonEnvelope) && !polygonEnvelope.Contains(envelope)) { continue; } if (envelope.Contains(polygon.Envelope)) { return(true); } if (Algorithm.IntersectBox(polygon, envelope)) { return(true); } } return(false); }
/// <summary> /// Finds an envelope that represents the intersection between this /// envelope and the specified <c>IEnvelope</c>. The number of dimensions of the /// returned envelope is the maximum of the NumOrdinates between the two envelopes, /// since a 2D envelope will only constrain a cube in 2 dimensions, and allow the /// z bounds to remain unaltered. /// </summary> /// <param name="self">The <c>IEnvelope</c> that is being extended by this method</param> /// <param name="env">An <c>IEnvelope</c> to compare against</param> /// <returns>an <c>IEnvelope</c> that bounds the intersection area</returns> public static IEnvelope Intersection(this IEnvelope self, IEnvelope env) { if (self.IsNull || env.IsNull || !self.Intersects(env)) { return(new Envelope()); } IEnvelope bigDimension; IEnvelope smallDimension; if (env.NumOrdinates > self.NumOrdinates) { bigDimension = env; smallDimension = self; } else { bigDimension = self; smallDimension = env; } Coordinate min = bigDimension.Minimum.Copy(); Coordinate max = bigDimension.Maximum.Copy(); for (int i = 0; i < smallDimension.NumOrdinates; i++) { if (smallDimension.Minimum[i] > min[i]) { min[i] = smallDimension.Minimum[i]; } if (smallDimension.Maximum[i] < max[i]) { max[i] = smallDimension.Maximum[i]; } } return(new Envelope(min, max)); }
/// <summary> /// Using an envelope intersection has some optimizations by checking against the envelope /// of the geometry. In the worst case scenario, the envelope crops the geometry, and a new geometry is created. /// This will be much faster if the envelope contains the geometries envelope, however, simply returning /// the original geometry. /// </summary> /// <param name="self">The <c>IEnvelope</c> that is being extended by this method</param> /// <param name="geom">A geometric intersection against the area of this envelope</param> /// <returns>A geometry, cropped to the space of this envelope if necessary.</returns> public static IBasicGeometry Intersection(this IEnvelope self, IBasicGeometry geom) { if (self == null || geom == null) { return(null); } if (self.IsNull) { return(null); } IEnvelope env = geom.Envelope; if (env.Intersects(self) == false) { return(null); } if (self.Contains(env)) { return(geom); } IGeometry g = Geometry.FromBasicGeometry(geom); return(g.Intersection(self.ToPolygon())); }
/// <summary> /// This uses extent checking (rather than full polygon intersection checking). It will add /// any members that are either contained by or intersect with the specified region /// depending on the SelectionMode property. The order of operation is the region /// acting on the feature, so Contains, for instance, would work with points. /// </summary> /// <param name="region"></param> /// <param name="affectedArea">The affected area of this addition</param> /// <returns>True if any item was actually added to the collection</returns> public bool AddRegion(IEnvelope region, out IEnvelope affectedArea) { bool added = false; SuspendChanges(); affectedArea = new Envelope(); #if DEBUG var total = new Stopwatch(); total.Start(); #endif foreach (IFeature f in FeatureList) { bool doAdd = false; if (_selectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } IGeometry reg; if (region.Width == 0 && region.Height == 0) { reg = new Point(region.X, region.Y); } else if (region.Height == 0 || region.Width == 0) { Coordinate[] coords = new Coordinate[2]; coords[0] = new Coordinate(region.X, region.Y); coords[1] = new Coordinate(region.Bottom(), region.Right()); reg = new LineString(coords); } else { reg = region.ToPolygon(); } IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (_selectionMode) { case SelectionMode.Contains: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) { doAdd = true; } } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) { doAdd = true; } break; case SelectionMode.Covers: if (reg.Covers(geom)) { doAdd = true; } break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) { doAdd = true; } break; case SelectionMode.Intersects: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) { doAdd = true; } } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) { doAdd = true; } break; case SelectionMode.Touches: if (reg.Touches(geom)) { doAdd = true; } break; case SelectionMode.Within: if (reg.Within(geom)) { doAdd = true; } break; } if (doAdd) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } #if DEBUG var sw = new Stopwatch(); sw.Start(); #endif ResumeChanges(); #if DEBUG sw.Stop(); total.Stop(); Debug.WriteLine("Geometry Intersection Time: " + sw.ElapsedMilliseconds); Debug.WriteLine("Total Intersection Time: " + total.ElapsedMilliseconds); #endif return(added); }
/// <summary> /// /// </summary> /// <param name="searchEnv"></param> /// <param name="start0"></param> /// <param name="end0"></param> /// <param name="mcs"></param> private void ComputeSelect(IEnvelope searchEnv, int start0, int end0, MonotoneChainSelectAction mcs) { ICoordinate p0 = pts[start0]; ICoordinate p1 = pts[end0]; mcs.TempEnv1.Init(p0, p1); // terminating condition for the recursion if (end0 - start0 == 1) { mcs.Select(this, start0); return; } // nothing to do if the envelopes don't overlap if (!searchEnv.Intersects(mcs.TempEnv1)) return; // the chains overlap, so split each in half and iterate (binary search) int mid = (start0 + end0) / 2; // Assert: mid != start or end (since we checked above for end - start <= 1) // check terminating conditions before recursing if (start0 < mid) ComputeSelect(searchEnv, start0, mid, mcs); if (mid < end0) ComputeSelect(searchEnv, mid, end0, mcs); }
public virtual IEnumerable <IFeature> GetFeatures(IEnvelope box) { return(features.Where(f => box.Intersects(f.Geometry.Envelope.EnvelopeInternal))); }
/// <summary> /// /// </summary> /// <param name="region"></param> /// <param name="affectedArea"></param> /// <returns></returns> public bool InvertSelection(IEnvelope region, out IEnvelope affectedArea) { SuspendChanges(); bool flipped = false; Extent affected = new Extent(); IPolygon reg = region.ToPolygon(); for (int shp = 0; shp < _layer.DrawnStates.Length; shp++) { if (_regionCategory != null && _layer.DrawnStates[shp].Category != _regionCategory) { continue; } bool doFlip = false; ShapeRange shape = _shapes[shp]; if (_selectionMode == SelectionMode.Intersects) { // Prevent geometry creation (which is slow) and use ShapeRange instead ShapeRange env = new ShapeRange(region); if (env.Intersects(shape)) { _layer.DrawnStates[shp].Selected = !_layer.DrawnStates[shp].Selected; affected.ExpandToInclude(shape.Extent); flipped = true; OnChanged(); } } else if (_selectionMode == SelectionMode.IntersectsExtent) { if (shape.Extent.Intersects(region)) { _layer.DrawnStates[shp].Selected = !_layer.DrawnStates[shp].Selected; affected.ExpandToInclude(shape.Extent); flipped = true; OnChanged(); } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (shape.Extent.Within(region)) { _layer.DrawnStates[shp].Selected = !_layer.DrawnStates[shp].Selected; affected.ExpandToInclude(shape.Extent); flipped = true; OnChanged(); } } else if (_selectionMode == SelectionMode.Disjoint) { if (shape.Extent.Intersects(region)) { IBasicGeometry g = _layer.DataSet.Features[shp].BasicGeometry; IGeometry geom = Geometry.FromBasicGeometry(g); if (reg.Disjoint(geom)) { doFlip = true; } } else { doFlip = true; } } else { if (!shape.Extent.Intersects(region)) { continue; } IFeature f = _layer.DataSet.Features[shp]; // only get this if envelopes intersect IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (SelectionMode) { case SelectionMode.Contains: if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) { doFlip = true; } } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) { doFlip = true; } break; case SelectionMode.Covers: if (reg.Covers(geom)) { doFlip = true; } break; case SelectionMode.Intersects: if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) { doFlip = true; } } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) { doFlip = true; } break; case SelectionMode.Touches: if (reg.Touches(geom)) { doFlip = true; } break; case SelectionMode.Within: if (reg.Within(geom)) { doFlip = true; } break; } } if (!doFlip) { continue; } flipped = true; _layer.DrawnStates[shp].Selected = !_layer.DrawnStates[shp].Selected; affected.ExpandToInclude(shape.Extent); } affectedArea = affected.ToEnvelope(); ResumeChanges(); return(flipped); }
/// <summary> /// For a point, or coordinate, this is a degenerate case and /// will simply perform an intersection test instead. /// </summary> /// <param name="self">The IEnvelope to use with this method</param> /// <param name="x">The x coordinate</param> /// <param name="y">The y coordinate</param> /// <returns>Boolean, true if the specified point intersects with this envelope</returns> public static bool Overlaps(this IEnvelope self, double x, double y) { return(self.Intersects(new Coordinate(x, y))); }
/// <summary> /// Inverts the selection based on the current SelectionMode /// </summary> /// <param name="region">The geographic region to reverse the selected state</param> /// <param name="affectedArea">The affected area to invert</param> public bool InvertSelection(IEnvelope region, out IEnvelope affectedArea) { SuspendChanges(); bool flipped = false; affectedArea = new Envelope(); IDictionary<IFeature, IDrawnState> states = Filter.DrawnStates; foreach (KeyValuePair<IFeature, IDrawnState> kvp in states) { bool doFlip = false; IFeature f = kvp.Key; if (SelectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { kvp.Value.IsSelected = !kvp.Value.IsSelected; affectedArea.ExpandToInclude(f.Envelope); } } else if (SelectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { kvp.Value.IsSelected = !kvp.Value.IsSelected; affectedArea.ExpandToInclude(f.Envelope); } } IPolygon reg = region.ToPolygon(); IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (SelectionMode) { case SelectionMode.Contains: if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) doFlip = true; } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) doFlip = true; break; case SelectionMode.Covers: if (reg.Covers(geom)) doFlip = true; break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) doFlip = true; break; case SelectionMode.Intersects: if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) doFlip = true; } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) doFlip = true; break; case SelectionMode.Touches: if (reg.Touches(geom)) doFlip = true; break; case SelectionMode.Within: if (reg.Within(geom)) doFlip = true; break; } if (doFlip) { flipped = true; kvp.Value.IsSelected = !kvp.Value.IsSelected; affectedArea.ExpandToInclude(f.Envelope); } } ResumeChanges(); return flipped; }
/// <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> /// Gets the object IDs in the view. /// </summary> /// <param name="envelope">The bbox.</param> /// <returns></returns> public ICollection<int> GetObjectIDsInView(IEnvelope envelope) { // Identifies all the features within the given BoundingBox Collection<int> geoms = new Collection<int>(); for(int i = 0; i < features.Count; i++) if (envelope.Intersects(((IFeature)features[i]).Geometry.EnvelopeInternal)) geoms.Add(i); return geoms; }
// Actually calculates the distance, given the specified number of dimensions. private static double doDistance(IEnvelope self, IEnvelope other, int numDimensions) { if (self == null || other == null) return -1; if (self.IsNull || other.IsNull) return -1; if (self.NumOrdinates < numDimensions && other.NumOrdinates < numDimensions) { throw new InsufficientDimensionsException("both envelopes"); } if (self.NumOrdinates < numDimensions) { throw new InsufficientDimensionsException("this envelope"); // assuming used as an extension } if (self.NumOrdinates < numDimensions) { throw new InsufficientDimensionsException("the other envelope"); } if (self.Intersects(other)) return 0; Coordinate c = new Coordinate(); for (int i = 0; i < c.NumOrdinates; i++) { if (self.Maximum[i] < other.Minimum[i]) c[i] = other.Minimum.X - self.Maximum.X; if (self.Minimum[i] > other.Maximum[i]) c[i] = self.Minimum[i] - other.Minimum[i]; } double sumSquares = 0; for (int i = 0; i < numDimensions; i++) { sumSquares += c[i] * c[i]; if (c[i] == 0) return 0; // an extra check. If any distance is zero, the distance is zero. } return Math.Sqrt(sumSquares); }
/// <summary> /// /// </summary> /// <param name="searchEnv"></param> /// <returns></returns> protected override bool IsSearchMatch(IEnvelope searchEnv) { return(env.Intersects(searchEnv)); }
/// <summary> /// Inverts the selection based on the current SelectionMode /// </summary> /// <param name="region">The geographic region to reverse the selected state</param> /// <param name="affectedArea">The affected area to invert</param> public bool InvertSelection(IEnvelope region, out IEnvelope affectedArea) { SuspendChanges(); bool flipped = false; affectedArea = new Envelope(); IDictionary <IFeature, IDrawnState> states = Filter.DrawnStates; foreach (KeyValuePair <IFeature, IDrawnState> kvp in states) { bool doFlip = false; IFeature f = kvp.Key; if (SelectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { kvp.Value.IsSelected = !kvp.Value.IsSelected; affectedArea.ExpandToInclude(f.Envelope); } } else if (SelectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { kvp.Value.IsSelected = !kvp.Value.IsSelected; affectedArea.ExpandToInclude(f.Envelope); } } IPolygon reg = region.ToPolygon(); IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (SelectionMode) { case SelectionMode.Contains: if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) { doFlip = true; } } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) { doFlip = true; } break; case SelectionMode.Covers: if (reg.Covers(geom)) { doFlip = true; } break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) { doFlip = true; } break; case SelectionMode.Intersects: if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) { doFlip = true; } } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) { doFlip = true; } break; case SelectionMode.Touches: if (reg.Touches(geom)) { doFlip = true; } break; case SelectionMode.Within: if (reg.Within(geom)) { doFlip = true; } break; } if (doFlip) { flipped = true; kvp.Value.IsSelected = !kvp.Value.IsSelected; affectedArea.ExpandToInclude(f.Envelope); } } ResumeChanges(); return(flipped); }
/// <summary> /// Tests each member currently in the selected features based on /// the SelectionMode. If it passes, it will remove the feature from /// the selection. /// </summary> /// <param name="region">The geographic region to remove</param> /// <param name="affectedArea">A geographic area that was affected by this change.</param> /// <returns>Boolean, true if the collection was changed</returns> public bool RemoveRegion(IEnvelope region, out IEnvelope affectedArea) { SuspendChanges(); bool removed = false; affectedArea = new Envelope(); var query = from pair in _filter.DrawnStates where pair.Value.IsSelected select pair.Key; List <IFeature> selectedFeatures = query.ToList(); foreach (IFeature f in selectedFeatures) { bool doRemove = false; if (_selectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { if (Remove(f)) { removed = true; affectedArea.ExpandToInclude(f.Envelope); } } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { if (Remove(f)) { removed = true; affectedArea.ExpandToInclude(f.Envelope); } } } IPolygon reg = region.ToPolygon(); IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (_selectionMode) { case SelectionMode.Contains: if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) { doRemove = true; } } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) { doRemove = true; } break; case SelectionMode.Covers: if (reg.Covers(geom)) { doRemove = true; } break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) { doRemove = true; } break; case SelectionMode.Intersects: if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) { doRemove = true; } } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) { doRemove = true; } break; case SelectionMode.Touches: if (reg.Touches(geom)) { doRemove = true; } break; case SelectionMode.Within: if (reg.Within(geom)) { doRemove = true; } break; } if (doRemove) { if (Remove(f)) { affectedArea.ExpandToInclude(f.Envelope); removed = true; } } } ResumeChanges(); return(removed); }
/// <summary> /// /// </summary> /// <param name="box"></param> public IList GetFeatures(IEnvelope box) { // Identifies all the features within the given BoundingBox IList results = new ArrayList(features.Count); foreach (IFeature feature in features) if (box.Intersects(feature.Geometry.EnvelopeInternal)) results.Add(feature); return results; }
/// <summary> /// This uses extent checking (rather than full polygon intersection checking). It will add /// any members that are either contained by or intersect with the specified region /// depending on the SelectionMode property. The order of operation is the region /// acting on the feature, so Contains, for instance, would work with points. /// </summary> /// <param name="region"></param> /// <param name="affectedArea">The affected area of this addition</param> /// <returns>True if any item was actually added to the collection</returns> public bool AddRegion(IEnvelope region, out IEnvelope affectedArea) { bool added = false; SuspendChanges(); affectedArea = new Envelope(); Stopwatch sw = new Stopwatch(); Stopwatch total = new Stopwatch(); total.Start(); foreach (IFeature f in FeatureList) { bool doAdd = false; if (_selectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } IGeometry reg; if (region.Width == 0 && region.Height == 0) { reg = new Point(region.X, region.Y); } else if (region.Height == 0 || region.Width == 0) { Coordinate[] coords = new Coordinate[2]; coords[0] = new Coordinate(region.X, region.Y); coords[1] = new Coordinate(region.Bottom(), region.Right()); reg = new LineString(coords); } else { reg = region.ToPolygon(); } IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (_selectionMode) { case SelectionMode.Contains: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) doAdd = true; } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) doAdd = true; break; case SelectionMode.Covers: if (reg.Covers(geom)) doAdd = true; break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) doAdd = true; break; case SelectionMode.Intersects: if (region.Contains(f.Envelope)) { doAdd = true; } else if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) doAdd = true; } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) doAdd = true; break; case SelectionMode.Touches: if (reg.Touches(geom)) doAdd = true; break; case SelectionMode.Within: if (reg.Within(geom)) doAdd = true; break; } if (doAdd) { Add(f); affectedArea.ExpandToInclude(f.Envelope); added = true; } } sw.Start(); ResumeChanges(); sw.Stop(); total.Stop(); Debug.WriteLine("Geometry Intersection Time: " + sw.ElapsedMilliseconds); Debug.WriteLine("Total Intersection Time: " + total.ElapsedMilliseconds); return added; }
/// <summary> /// Returns features within the specified bounding box. /// </summary> /// <param name="bbox"></param> /// <returns></returns> public Collection<IGeometry> GetGeometriesInView(IEnvelope bbox) { // Identifies all the features within the given BoundingBox Collection<IGeometry> geoms = new Collection<IGeometry>(); foreach (IFeature feature in features) if (bbox.Intersects(feature.Geometry.EnvelopeInternal)) geoms.Add(feature.Geometry); return geoms; }
/// <summary> /// Tests each member currently in the selected features based on /// the SelectionMode. If it passes, it will remove the feature from /// the selection. /// </summary> /// <param name="region">The geographic region to remove</param> /// <param name="affectedArea">A geographic area that was affected by this change.</param> /// <returns>Boolean, true if the collection was changed</returns> public bool RemoveRegion(IEnvelope region, out IEnvelope affectedArea) { SuspendChanges(); bool removed = false; affectedArea = new Envelope(); var query = from pair in _filter.DrawnStates where pair.Value.IsSelected select pair.Key; List<IFeature> selectedFeatures = query.ToList(); foreach (IFeature f in selectedFeatures) { bool doRemove = false; if (_selectionMode == SelectionMode.IntersectsExtent) { if (region.Intersects(f.Envelope)) { if (Remove(f)) { removed = true; affectedArea.ExpandToInclude(f.Envelope); } } } else if (_selectionMode == SelectionMode.ContainsExtent) { if (region.Contains(f.Envelope)) { if (Remove(f)) { removed = true; affectedArea.ExpandToInclude(f.Envelope); } } } IPolygon reg = region.ToPolygon(); IGeometry geom = Geometry.FromBasicGeometry(f.BasicGeometry); switch (_selectionMode) { case SelectionMode.Contains: if (region.Intersects(f.Envelope)) { if (reg.Contains(geom)) doRemove = true; } break; case SelectionMode.CoveredBy: if (reg.CoveredBy(geom)) doRemove = true; break; case SelectionMode.Covers: if (reg.Covers(geom)) doRemove = true; break; case SelectionMode.Disjoint: if (reg.Disjoint(geom)) doRemove = true; break; case SelectionMode.Intersects: if (region.Intersects(f.Envelope)) { if (reg.Intersects(geom)) doRemove = true; } break; case SelectionMode.Overlaps: if (reg.Overlaps(geom)) doRemove = true; break; case SelectionMode.Touches: if (reg.Touches(geom)) doRemove = true; break; case SelectionMode.Within: if (reg.Within(geom)) doRemove = true; break; } if (doRemove) { if (Remove(f)) { affectedArea.ExpandToInclude(f.Envelope); removed = true; } } } ResumeChanges(); return removed; }
/// <summary> /// For a point, or coordinate, this is a degenerate case and /// will simply perform an intersection test instead. /// </summary> /// <param name="self">The IEnvelope to use with this method</param> /// <param name="p"></param> /// <returns></returns> public static bool Overlaps(this IEnvelope self, Coordinate p) { return(self.Intersects(p)); }