public Node( Envelope env, int level ) { //this.parent = parent; this._env = env; this._level = level; _centre = new Coordinate(); _centre.X = ( env.MinX + env.MaxX ) / 2; _centre.Y = ( env.MinY + env.MaxY ) / 2; }
public abstract int GetLength(Geometry geometry); //length in 16bit words public static Envelope GetEnvelopeExternal(PrecisionModel precisionModel, Envelope envelope) { // get envelopse in external coordinates Coordinate min = new Coordinate(envelope.MinX, envelope.MinY); Coordinate max = new Coordinate(envelope.MaxX, envelope.MaxY); min = precisionModel.ToExternal(min); max = precisionModel.ToExternal(max); Envelope bounds = new Envelope(min.X, max.X, min.Y, max.Y); return bounds; }
/// <summary> /// Return a square envelope containing the argument envelope, /// whose extent is a power of two and which is based at a power of 2. /// </summary> /// <param name="itemEnv"></param> public void ComputeKey(Envelope itemEnv) { _level = ComputeQuadLevel(itemEnv); _env = new Envelope(); ComputeKey( _level, itemEnv ); // MD - would be nice to have a non-iterative form of this algorithm while ( !_env.Contains( itemEnv ) ) { _level += 1; ComputeKey( _level, itemEnv ); } }
/// <summary> /// Returns the subquad containing the envelope. Creates the subquad if it does not already exist. /// </summary> /// <param name="searchEnv"></param> /// <returns></returns> public Node GetNode( Envelope searchEnv ) { int subnodeIndex = GetSubnodeIndex( searchEnv, _centre); // if subquadIndex is -1 searchEnv is not contained in a subquad if (subnodeIndex != -1) { // create the quad if it does not exist Node node = GetSubnode( subnodeIndex ); // recursively search the found/created quad return node.GetNode( searchEnv ); } else { return this; } }
/// <summary> /// Initializes a new instance of the ShapefileHeader class with values read in from the stream. /// </summary> /// <remarks>Reads the header information from the stream.</remarks> /// <param name="shpBinaryReader">BigEndianBinaryReader stream to the shapefile.</param> public ShapefileHeader(BigEndianBinaryReader shpBinaryReader) { if (shpBinaryReader==null) { throw new ArgumentNullException("shpBinaryReader"); } _fileCode = shpBinaryReader.ReadIntBE(); if (_fileCode!=Shapefile.ShapefileId) { throw new ShapefileException("The first four bytes of this file indicate this is not a shape file."); } // skip 5 unsed bytes shpBinaryReader.ReadIntBE(); shpBinaryReader.ReadIntBE(); shpBinaryReader.ReadIntBE(); shpBinaryReader.ReadIntBE(); shpBinaryReader.ReadIntBE(); _fileLength = shpBinaryReader.ReadIntBE(); _version = shpBinaryReader.ReadInt32(); Debug.Assert(_version==1000, "Shapefile version", String.Format("Expecting only one version (1000), but got {0}",_version)); int shapeType = shpBinaryReader.ReadInt32(); _shapeType = (ShapeType)Enum.Parse(typeof(ShapeType),shapeType.ToString()); //read in and store the bounding box double[] coords = new double[4]; for (int i = 0; i < 4; i++) { coords[i]=shpBinaryReader.ReadDouble(); } _bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]); // skip z and m bounding boxes. for (int i=0; i < 4; i++) { shpBinaryReader.ReadDouble(); } }
private Node CreateSubnode( int index ) { // create a new subquad in the appropriate quadrant double minx = 0.0; double maxx = 0.0; double miny = 0.0; double maxy = 0.0; switch (index) { case 0: minx = _env.MinX; maxx = _centre.X; miny = _env.MinY; maxy = _centre.Y; break; case 1: minx = _centre.X; maxx = _env.MaxX; miny = _env.MinY; maxy = _centre.Y; break; case 2: minx = _env.MinX; maxx = _centre.X; miny = _centre.Y; maxy = _env.MaxY; break; case 3: minx = _centre.X; maxx = _env.MaxX; miny = _centre.Y; maxy = _env.MaxY; break; } Envelope sqEnv = new Envelope( minx, maxx, miny, maxy ); Node node = new Node( sqEnv, _level - 1 ); return node; }
public static Node CreateNode( Envelope env ) { Key key = new Key( env ); Node node = new Node( key.Envelope, key.Level ); return node; }
public ArrayList Query(Envelope searchEnv) { return base.Query(searchEnv); }
protected override object ComputeBounds() { Envelope bounds = null; //for (Iterator i = GetChildBoundables().iterator(); i.hasNext(); ) foreach(object obj in GetChildBoundables()) { IBoundable childBoundable = (IBoundable) obj; if (bounds == null) { bounds = new Envelope((Envelope)childBoundable.GetBounds()); } else { bounds.ExpandToInclude((Envelope)childBoundable.GetBounds()); } } return bounds; }
/// <summary> /// Returns the smallest existing node containing the envelope. /// </summary> /// <param name="searchEnv"></param> /// <returns></returns> public NodeBase Find(Envelope searchEnv) { int subnodeIndex = GetSubnodeIndex( searchEnv, _centre ); if ( subnodeIndex == -1 ) { return this; } if ( _subnode[subnodeIndex] != null ) { // query lies in subquad, so search it Node node = _subnode[subnodeIndex]; return node.Find( searchEnv ); } // no existing subquad, so return this one anyway return this; }
/// <summary> /// Returns the envelope /// </summary> /// <returns></returns> public Envelope GetEnvelope() { if (_env == null) { Coordinate p0 = _pts[_start]; Coordinate p1 = _pts[_end]; _env = new Envelope(p0, p1); } return _env; } // public Envelope GetEnvelope()
public ArrayList Query(Envelope searchEnv) { // the items that are matched are the items in quads which // overlap the search envelope ArrayList foundItems = new ArrayList(); _root.AddAllItemsFromOverlapping(searchEnv, foundItems); return foundItems; }
protected override bool IsSearchMatch(Envelope searchEnv) { return _env.Intersects( searchEnv ); }
/// <summary> /// Ensure that the envelope for the inserted item has non-zero extents. /// Use the current minExtent to pad the envelope, if necessary. /// </summary> /// <param name="itemEnv"></param> /// <param name="minExtent"></param> /// <returns></returns> public static Envelope EnsureExtent( Envelope itemEnv, double minExtent ) { //The names "ensureExtent" and "minExtent" are misleading -- sounds like //this method ensures that the extents are greater than minExtent. //Perhaps we should rename them to "ensurePositiveExtent" and "defaultExtent". //[Jon Aquino] double minx = itemEnv.MinX; double maxx = itemEnv.MaxX; double miny = itemEnv.MinY; double maxy = itemEnv.MaxY; // has a non-zero extent if (minx != maxx && miny != maxy) return itemEnv; // pad one or both extents if (minx == maxx) { minx = minx - minExtent / 2.0; maxx = minx + minExtent / 2.0; } if (miny == maxy) { miny = miny - minExtent / 2.0; maxy = miny + minExtent / 2.0; } return new Envelope(minx, maxx, miny, maxy); }
public void Insert(Envelope itemEnv, object item) { CollectStats(itemEnv); Envelope insertEnv = EnsureExtent(itemEnv, _minExtent); _root.Insert(insertEnv, item); }
private void CollectStats(Envelope itemEnv) { double delX = itemEnv.Width; if (delX < _minExtent && delX > 0.0) { _minExtent = delX; } double delY = itemEnv.Width; if (delY < _minExtent && delY > 0.0) { _minExtent = delY; } }
} // public void Select( Envelope searchEnv, MonotoneChainSelectAction mcs ) private void ComputeSelect( Envelope searchEnv, int start0, int end0, MonotoneChainSelectAction mcs ) { Coordinate p0 = _pts[start0]; Coordinate p1 = _pts[end0]; _env1.Initialize( p0, p1 ); //Trace.WriteLine( "trying:" + p0.ToString() + p1.ToString() + " [ " + start0.ToString() + ", " + end0.ToString() + " ]"); // terminating condition for the recursion if (end0 - start0 == 1) { //Trace.WriteLine("ComputeSelect:" + p0.ToString() + p1.ToString() ); mcs.Select( this, start0 ); return; } // nothing to do if the envelopes don't overlap if ( !searchEnv.Intersects( _env1 ) ) { 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 ); } } // private void ComputeSelect(...
} // public Coordinates GetCoordinates() /// <summary> /// Determine all the line segments in the chain whose envelopes overlap /// the searchEnvelope, and process them /// </summary> /// <param name="searchEnv"></param> /// <param name="mcs"></param> public void Select( Envelope searchEnv, MonotoneChainSelectAction mcs ) { ComputeSelect( searchEnv, _start, _end, mcs ); } // public void Select( Envelope searchEnv, MonotoneChainSelectAction mcs )
public static Node CreateExpanded( Node node, Envelope addEnv ) { Envelope expandEnv = new Envelope(addEnv); if (node != null) expandEnv.ExpandToInclude(node.Envelope); Node largerNode = CreateNode(expandEnv); if (node != null) largerNode.InsertNode(node); return largerNode; }
/// <summary> /// /// </summary> /// <param name="pt"></param> /// <returns></returns> public bool IsInside(Coordinate pt) { _crossings = 0; // test all segments intersected by ray from pt in positive x direction Envelope rayEnv = new Envelope(Double.NegativeInfinity, Double.PositiveInfinity, pt.Y, pt.Y); _interval.Min = pt.Y; _interval.Max = pt.Y; ArrayList segs = _tree.Query( _interval ); //System.out.println("query size = " + segs.size()); MCSelecter mcSelecter = new MCSelecter(this,pt); foreach(object obj in segs) { MonotoneChain mc = (MonotoneChain) obj; TestMonotoneChain(rayEnv, mcSelecter, mc); } //p is inside if number of crossings is odd. if ((_crossings % 2) == 1) { return true; } return false; }
/// <summary> /// Computes the distance between this and another Envelope. /// </summary> /// <remarks> /// The distance between overlapping Envelopes is 0. Otherwise, the /// distance is the Euclidean distance between the closest points. /// </remarks> /// <param name="env">The other envelope to be used for the comparison.</param> /// <returns>A double containing the distance between the two envelopes.</returns> public double Distance(Envelope env) { if ( Intersects(env) ) return 0; if ( _maxX < env.MinX) { // this is left of env if (MaxY < env.MinY) { // this is below left of env return Distance(_maxX, MaxY, env.MinX, env.MinY); } else if (_minY > env.MaxY) { // this is above left of env return Distance(_maxX, _minY, env.MinX, env.MaxY); } else { // this is directly left of env return env.MinX - _maxX; } } else { // this is right of env if (_maxY < env.MinY) { // this is below right of env return Distance(_minX, _maxY, env.MaxX, env.MinY); } else if (_minY > env.MaxY) { // this is above right of env return Distance(_minX, _minY, env.MaxX, env.MaxY); } else { // this is directly right of env return _minX - env.MaxX; } } }
/// <summary> /// Creates an Envelope from an existing Envelope. /// </summary> /// <param name="env">The Envelope to initialize from.</param> public Envelope(Envelope env) { Initialize(env); }
/// <summary> /// Returns true if the Envelope other lies wholely inside this Envelope (inclusive of the boundary). /// </summary> /// <param name="other">The Envelope which this Envelope is being checked for containing</param> /// <returns>True if other is contained in this Envelope</returns> public bool Contains(Envelope other) { return other.MinX >= _minX && other.MaxX <= _maxX && other.MinY >= _minY && other.MaxY <= _maxY; }
/// <summary> /// Check if the Envelope other overlaps (lies inside) the region of this Envelope. /// </summary> /// <param name="other">The Envelope to be tested</param> /// <returns>True if the Envelope other overlaps this Envelope</returns> public bool Overlaps(Envelope other) { return ( Intersects( other ) ); }
private double CentreX(Envelope e) { return Avg( e.MinX, e.MaxX ); }
///<summary> /// Returns the minimum and maximum x and y value1s in this Geometry, or a null Envelope if this Geometry /// is empty. ///</summary> ///<remarks>Unlike getEnvelopeInternal, this method calculates the Envelope each time it is called; /// getEnvelopeInternal caches the result of this method.</remarks> ///<returns> /// Returns this Geometrys bounding box; if the Geometry is empty, Envelope.IsNull will return true ///</returns> protected override Envelope ComputeEnvelopeInternal() { Envelope env = new Envelope(); if(_geometries != null) { foreach(Geometry geom in _geometries) { env.ExpandToInclude(geom.GetEnvelopeInternal()); } } return env; }
/// <summary> /// /// </summary> /// <param name="rayEnv"></param> /// <param name="mcSelecter"></param> /// <param name="mc"></param> private void TestMonotoneChain(Envelope rayEnv, MCSelecter mcSelecter, MonotoneChain mc) { mc.Select(rayEnv, mcSelecter); }
private double CentreY(Envelope e) { return Avg( e.MinY, e.MaxY ); }
} // public override int ComputeOrientation(Coordinate p1, Coordinate p2, Coordinate q) /// <summary> /// Tests to see if point p is in the envelope of ring. /// </summary> /// <param name="p">Point to test.</param> /// <param name="ring">Geometry from which to create envelope.</param> /// <returns>Returns true if point is in envelope of ring.</returns> private bool IsInEnvelope(Coordinate p, Coordinates ring) { Envelope envelope = new Envelope(); for (int i = 0; i < ring.Count; i++) { envelope.ExpandToInclude( ring[i] ); } return envelope.Contains( p ); } // private bool IsInEnvelope(Coordinate p, Coordinates ring)
public void Insert( Envelope itemEnv, object item ) { if ( itemEnv.IsNull() ) { return; } base.Insert( itemEnv, item ); }