View Javadoc
1   package com.github.davidmoten.rtree.internal;
2   
3   
4   import java.util.ArrayList;
5   import java.util.Collections;
6   import java.util.List;
7   import java.util.Optional;
8   
9   import com.github.davidmoten.rtree.Context;
10  import com.github.davidmoten.rtree.Entry;
11  import com.github.davidmoten.rtree.Leaf;
12  import com.github.davidmoten.rtree.Node;
13  import com.github.davidmoten.rtree.geometry.Geometry;
14  import com.github.davidmoten.rtree.geometry.ListPair;
15  
16  import rx.Subscriber;
17  import rx.functions.Func1;
18  
19  import static java.util.Optional.of;
20  
21  public final class LeafHelper {
22  
23      private LeafHelper() {
24          // prevent instantiation
25      }
26  
27      public static <T, S extends Geometry> NodeAndEntries<T, S> delete(
28              Entry<? extends T, ? extends S> entry, boolean all, Leaf<T, S> leaf) {
29          List<Entry<T, S>> entries = leaf.entries();
30          if (!entries.contains(entry)) {
31              return new NodeAndEntries<>(of(leaf), Collections.emptyList(), 0);
32          } else {
33              final List<Entry<T, S>> entries2 = new ArrayList<>(entries);
34              entries2.remove(entry);
35              int numDeleted = 1;
36              // keep deleting if all specified
37              while (all && entries2.remove(entry))
38                  numDeleted += 1;
39  
40              if (entries2.size() >= leaf.context().minChildren()) {
41                  Leaf<T, S> node = leaf.context().factory().createLeaf(entries2, leaf.context());
42                  return new NodeAndEntries<>(of(node), Collections.emptyList(),
43                          numDeleted);
44              } else {
45                  return new NodeAndEntries<T, S>(Optional.empty(), entries2,
46                          numDeleted);
47              }
48          }
49      }
50  
51      public static <T, S extends Geometry> List<Node<T, S>> add(
52              Entry<? extends T, ? extends S> entry, Leaf<T, S> leaf) {
53          List<Entry<T, S>> entries = leaf.entries();
54          Context<T, S> context = leaf.context();
55          @SuppressWarnings("unchecked")
56          final List<Entry<T, S>> entries2 = Util.add(entries, (Entry<T, S>) entry);
57          if (entries2.size() <= context.maxChildren())
58              return Collections
59                      .singletonList((Node<T, S>) context.factory().createLeaf(entries2, context));
60          else {
61              ListPair<Entry<T, S>> pair = context.splitter().split(entries2, context.minChildren());
62              return makeLeaves(pair, context);
63          }
64      }
65  
66      private static <T, S extends Geometry> List<Node<T, S>> makeLeaves(ListPair<Entry<T, S>> pair,
67              Context<T, S> context) {
68          List<Node<T, S>> list = new ArrayList<Node<T, S>>(2);
69          list.add(context.factory().createLeaf(pair.group1().list(), context));
70          list.add(context.factory().createLeaf(pair.group2().list(), context));
71          return list;
72      }
73  
74      public static <T, S extends Geometry> void search(Func1<? super Geometry, Boolean> condition,
75              Subscriber<? super Entry<T, S>> subscriber, Leaf<T, S> leaf) {
76  
77          if (!condition.call(leaf.geometry().mbr())) {
78              return;
79          }
80  
81          for (int i = 0; i < leaf.count(); i++) {
82              Entry<T, S> entry = leaf.entry(i);
83              if (subscriber.isUnsubscribed()) {
84                  return;
85              } else {
86                  if (condition.call(entry.geometry())) {
87                      subscriber.onNext(entry);
88                  }
89              }
90          }
91      }
92  
93  }