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
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
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 }