@@ -276,8 +276,7 @@ func (e entry) String() string {
276276// R树上存储对象的接口。以提供存储和查询功能。
277277type Spatial interface {
278278 Bounds () Rect
279- SetParent (parent * node ) Spatial
280- GetParent () * node
279+ AppendTraceBox (bb Rect ) Spatial
281280}
282281
283282// Insertion
@@ -711,8 +710,8 @@ func (tree *Rtree) condenseTree(n *node) {
711710// 内部实现涉及遍历和递归调用。
712711// 其实现依据是 A. 古特曼(A. Guttman)所著《R - 树:一种用于空间搜索的动态索引结构》的第 3.1 节,
713712// 该内容出自 1984 年美国计算机协会数据管理专业组(ACM SIGMOD)的会议论文集,第 47 至 57 页。
714- func (tree * Rtree ) SearchIntersect (bb Rect , filters ... Filter ) []Spatial {
715- return tree .searchIntersect ([]Spatial {}, tree .root , bb , filters )
713+ func (tree * Rtree ) SearchIntersect (bb Rect , needTrace bool , filters ... Filter ) []Spatial {
714+ return tree .searchIntersect ([]Spatial {}, tree .root , bb , needTrace , filters )
716715}
717716
718717// SearchIntersectWithLimit is similar to SearchIntersect, but returns
@@ -725,32 +724,34 @@ func (tree *Rtree) SearchIntersect(bb Rect, filters ...Filter) []Spatial {
725724// (带限制的交集搜索) 与 “SearchIntersect(交集搜索)” 类似,
726725// 但在找到前 k 个结果时会立即返回。当 k 为负数时,其行为与 “SearchIntersect” 完全一样,会返回所有结果。
727726// 保留该功能是为了向后兼容,不过请使用带有 “LimitFilter(限制过滤器)” 的 “SearchIntersect” 来实现相应操作。
728- func (tree * Rtree ) SearchIntersectWithLimit (k int , bb Rect ) []Spatial {
727+ func (tree * Rtree ) SearchIntersectWithLimit (k int , bb Rect , needTrace bool ) []Spatial {
729728 // backwards compatibility, previous implementation didn't limit results if
730729 // k was negative.
731730 if k < 0 {
732- return tree .SearchIntersect (bb )
731+ return tree .SearchIntersect (bb , needTrace )
733732 }
734- return tree .SearchIntersect (bb , LimitFilter (k ))
733+ return tree .SearchIntersect (bb , needTrace , LimitFilter (k ))
735734}
736735
737736// searchIntersect 搜索指定矩形 bb 在 n 节点中相交的所有对象。
738737// 会涉及到遍历和递归调用
739- func (tree * Rtree ) searchIntersect (results []Spatial , n * node , bb Rect , filters []Filter ) []Spatial {
738+ func (tree * Rtree ) searchIntersect (results []Spatial , n * node , bb Rect , needTrace bool , filters []Filter ) []Spatial {
740739 for _ , e := range n .entries {
741740 if ! intersect (e .bb , bb ) {
742741 continue
743742 }
744743
745744 if ! n .leaf {
746- results = tree .searchIntersect (results , e .child , bb , filters )
745+ results = tree .searchIntersect (results , e .child , bb , needTrace , filters )
747746 continue
748747 }
749748
750749 refuse , abort := applyFilters (results , e .obj , filters )
751750 if ! refuse {
752751 searchOut := e .obj
753- // searchOut = searchOut.SetParent(n)
752+ if needTrace {
753+ searchOut = searchOut .AppendTraceBox (n .ComputeBoundingBox ())
754+ }
754755 results = append (results , searchOut )
755756 }
756757
@@ -763,8 +764,8 @@ func (tree *Rtree) searchIntersect(results []Spatial, n *node, bb Rect, filters
763764
764765// NearestNeighbor returns the closest object to the specified point.
765766// Implemented per "Nearest Neighbor Queries" by Roussopoulos et al
766- func (tree * Rtree ) NearestNeighbor (p Point ) Spatial {
767- obj , _ := tree .nearestNeighbor (p , tree .root , math .MaxFloat64 , nil )
767+ func (tree * Rtree ) NearestNeighbor (p Point , needTrace bool ) Spatial {
768+ obj , _ := tree .nearestNeighbor (p , tree .root , math .MaxFloat64 , nil , needTrace )
768769 return obj
769770}
770771
@@ -825,13 +826,16 @@ func pruneEntriesMinDist(d float64, entries []entry, minDists []float64) []entry
825826 return entries [:i ]
826827}
827828
828- func (tree * Rtree ) nearestNeighbor (p Point , n * node , d float64 , nearest Spatial ) (Spatial , float64 ) {
829+ func (tree * Rtree ) nearestNeighbor (p Point , n * node , d float64 , nearest Spatial , needTrace bool ) (Spatial , float64 ) {
829830 if n .leaf {
830831 for _ , e := range n .entries {
831832 dist := math .Sqrt (p .minDist (e .bb ))
832833 if dist < d {
833834 d = dist
834835 nearest = e .obj
836+ if needTrace {
837+ nearest = nearest .AppendTraceBox (n .ComputeBoundingBox ())
838+ }
835839 }
836840 }
837841 } else {
@@ -858,19 +862,18 @@ func (tree *Rtree) nearestNeighbor(p Point, n *node, d float64, nearest Spatial)
858862 continue
859863 }
860864
861- subNearest , dist := tree .nearestNeighbor (p , e .child , d , nearest )
865+ subNearest , dist := tree .nearestNeighbor (p , e .child , d , nearest , needTrace )
862866 if dist < d {
863867 d = dist
864868 nearest = subNearest
865869 }
866870 }
867871 }
868- nearest = nearest .SetParent (n )
869872 return nearest , d
870873}
871874
872875// NearestNeighbors gets the closest Spatials to the Point.
873- func (tree * Rtree ) NearestNeighbors (k int , p Point , filters ... Filter ) []Spatial {
876+ func (tree * Rtree ) NearestNeighbors (k int , p Point , needTrace bool , filters ... Filter ) []Spatial {
874877 // preallocate the buffers for sortings the branches. At each level of the
875878 // tree, we slide the buffer by the number of entries in the node.
876879 maxBufSize := tree .MaxChildren * tree .Depth ()
@@ -881,7 +884,7 @@ func (tree *Rtree) NearestNeighbors(k int, p Point, filters ...Filter) []Spatial
881884 dists := make ([]float64 , 0 , k )
882885 objs := make ([]Spatial , 0 , k )
883886
884- objs , _ , _ = tree .nearestNeighbors (k , p , tree .root , dists , objs , filters , branches , branchDists )
887+ objs , _ , _ = tree .nearestNeighbors (k , p , tree .root , dists , objs , filters , branches , branchDists , needTrace )
885888 return objs
886889}
887890
@@ -918,7 +921,7 @@ func insertNearest(k int, dists []float64, nearest []Spatial, dist float64, obj
918921 return dists , nearest , false
919922}
920923
921- func (tree * Rtree ) nearestNeighbors (k int , p Point , n * node , dists []float64 , nearest []Spatial , filters []Filter , b []entry , bd []float64 ) ([]Spatial , []float64 , bool ) {
924+ func (tree * Rtree ) nearestNeighbors (k int , p Point , n * node , dists []float64 , nearest []Spatial , filters []Filter , b []entry , bd []float64 , needTrace bool ) ([]Spatial , []float64 , bool ) {
922925 var abort bool
923926 if n .leaf {
924927 for _ , e := range n .entries {
@@ -935,7 +938,7 @@ func (tree *Rtree) nearestNeighbors(k int, p Point, n *node, dists []float64, ne
935938 branches = pruneEntriesMinDist (dists [l - 1 ], branches , branchDists )
936939 }
937940 for _ , e := range branches {
938- nearest , dists , abort = tree .nearestNeighbors (k , p , e .child , dists , nearest , filters , b [len (n .entries ):], bd [len (n .entries ):])
941+ nearest , dists , abort = tree .nearestNeighbors (k , p , e .child , dists , nearest , filters , b [len (n .entries ):], bd [len (n .entries ):], needTrace )
939942 if abort {
940943 break
941944 }
0 commit comments