/// <summary> /// Inserts a node into the tree using <see cref="EntryStrategy"/> /// </summary> /// <param name="key">Key for the geometry</param> /// <param name="region">Bounding box of the geometry to enter into the index</param> public virtual void Insert(UInt32 key, SharpMap.Converters.Geometries.BoundingBox region) { RTreeIndexEntry entry = new RTreeIndexEntry(key, region); Node newSiblingFromSplit; EntryInsertStrategy.InsertEntry(entry, Root, _nodeSplitStrategy, Heuristic, out newSiblingFromSplit); // Add the newly split sibling if (newSiblingFromSplit is LeafNode) { if (Root is LeafNode) { LeafNode oldRoot = Root as LeafNode; Root = CreateIndexNode(); (Root as IndexNode).Add(oldRoot); } (Root as IndexNode).Add(newSiblingFromSplit); newSiblingFromSplit = null; } else if (newSiblingFromSplit is IndexNode) // Came from a root split { Node oldRoot = Root; Root = CreateIndexNode(); (Root as IndexNode).Add(oldRoot); (Root as IndexNode).Add(newSiblingFromSplit); } }
/// <summary> /// Reads a node from a stream recursively /// </summary> /// <param name="tree">R-Tree instance</param> /// <param name="br">Binary reader reference</param> private static Node ReadNode(DynamicRTree tree, BinaryReader br) { if (br.BaseStream.Position == br.BaseStream.Length) { return(null); } Node node; bool isLeaf = br.ReadBoolean(); if (isLeaf) { node = tree.CreateLeafNode(); } else { node = tree.CreateIndexNode(); } node.Box = new SharpMap.Converters.Geometries.BoundingBox(br.ReadDouble(), br.ReadDouble(), br.ReadDouble(), br.ReadDouble()); if (isLeaf) { LeafNode leaf = node as LeafNode; int featureCount = br.ReadInt32(); for (int i = 0; i < featureCount; i++) { RTreeIndexEntry entry = new RTreeIndexEntry(); entry.Box = new SharpMap.Converters.Geometries.BoundingBox(br.ReadDouble(), br.ReadDouble(), br.ReadDouble(), br.ReadDouble()); entry.Id = br.ReadUInt32(); leaf.Add(entry); } } else { IndexNode index = node as IndexNode; uint childNodes = br.ReadUInt32(); for (int c = 0; c < childNodes; c++) { Node child = ReadNode(tree, br); if (child != null) { index.Add(child); } } } return(node); }
/// <summary> /// Removes an entry and adjusts <see cref="Node.Box">bounding box</see> to accomodate new /// set of entries. /// </summary> /// <param name="entry">Entry to remove</param> /// <returns>True if the entry was found and removed, false if not found or not removed.</returns> public bool Remove(RTreeIndexEntry entry) { bool removed = _entries.Remove(entry); if (removed && Box.Borders(entry.Box)) { Box = SharpMap.Converters.Geometries.BoundingBox.Empty; foreach (RTreeIndexEntry e in _entries) { Box = Box.Join(e.Box); } } return(removed); }
/// <summary> /// Removes an entry and adjusts <see cref="Node.Box">bounding box</see> to accomodate new /// set of entries. /// </summary> /// <param name="entry">Entry to remove</param> /// <returns>True if the entry was found and removed, false if not found or not removed.</returns> public bool Remove(RTreeIndexEntry entry) { bool removed = _entries.Remove(entry); //if (removed && Box.Borders(entry.Box)) if (removed && Borders(Box, entry.Box)) { Box = new GisSharpBlog.NetTopologySuite.Geometries.Envelope(); foreach (RTreeIndexEntry e in _entries) { Box = Join(Box, e.Box); //Box.Join(e.Box); } } return(removed); }
/// <summary> /// Adds entry to <see cref="Entries"/> collection and expands node's /// <see cref="Box">bounding box</see> to contain <paramref name="entry"/> /// bounding box. /// </summary> /// <param name="entry">Entry to add</param> public void Add(RTreeIndexEntry entry) { _entries.Add(entry); Box = Box.Join(entry.Box); }