sascha@3013: package de.intevation.flys.utils;
sascha@3013: 
sascha@3013: import java.util.ArrayList;
sascha@3013: import java.util.Collections;
sascha@3013: import java.util.List;
sascha@3026: import java.util.Iterator;
sascha@3013: 
sascha@3013: import java.io.Serializable;
sascha@3013: 
felix@4318: /** km to value, searchable. Tolerance is at 10cm. */
sascha@3013: public class KMIndex<A>
sascha@3026: implements   Serializable, Iterable<KMIndex.Entry<A>>
sascha@3013: {
sascha@3013:     public static final double EPSILON = 1e-4;
sascha@3013: 
sascha@3013:     public static class Entry<A>
sascha@3013:     implements          Serializable, Comparable<Entry<A>>
sascha@3013:     {
sascha@3013:         protected double km;
sascha@3013:         protected A      value;
sascha@3013: 
sascha@3013:         public Entry(double km) {
sascha@3013:             this.km = km;
sascha@3013:         }
sascha@3013: 
sascha@3013:         public Entry(double km, A value) {
sascha@3013:             this.km    = km;
sascha@3013:             this.value = value;
sascha@3013:         }
sascha@3013: 
sascha@3013:         public double getKm() {
sascha@3013:             return km;
sascha@3013:         }
sascha@3013: 
sascha@3013:         public A getValue() {
sascha@3013:             return value;
sascha@3013:         }
sascha@3013: 
sascha@3013:         public void setValue(A value) {
sascha@3013:             this.value = value;
sascha@3013:         }
sascha@3013: 
sascha@3013:         @Override
sascha@3013:         public int compareTo(Entry<A> other) {
sascha@3013:             double diff = km - other.km;
sascha@3013:             if (diff < -EPSILON) return -1;
sascha@3013:             if (diff > +EPSILON) return +1;
sascha@3013:             return 0;
sascha@3013:         }
sascha@3013: 
sascha@3013:         public boolean epsilonEquals(double km) {
sascha@3013:             return Math.abs(this.km - km) < EPSILON;
sascha@3013:         }
sascha@3013:     } // class Entry
sascha@3013: 
sascha@3013: 
sascha@3013:     protected List<Entry<A>> entries;
sascha@3013: 
sascha@3013:     public KMIndex() {
sascha@3013:         this(10);
sascha@3013:     }
sascha@3013: 
sascha@3013:     public KMIndex(int capacity) {
sascha@3013:         entries = new ArrayList<Entry<A>>(capacity);
sascha@3013:     }
sascha@3013: 
sascha@3013:     public void add(double km, A value) {
sascha@3158:         entries.add(new Entry<A>(km, value));
sascha@3013:     }
sascha@3013: 
sascha@3013:     public void sort() {
sascha@3013:         Collections.sort(entries);
sascha@3013:     }
sascha@3013: 
sascha@3013:     public Entry<A> search(double km) {
sascha@3013:         for (Entry<A> entry: entries) {
sascha@3013:             if (entry.epsilonEquals(km)) {
sascha@3013:                 return entry;
sascha@3013:             }
sascha@3013:         }
sascha@3013:         return null;
sascha@3013:     }
sascha@3013: 
sascha@3013:     public Entry<A> binarySearch(double km) {
sascha@3158:         int index = Collections.binarySearch(entries, new Entry<A>(km));
sascha@3013:         return index >= 0 ? entries.get(index) : null;
sascha@3013:     }
sascha@3026: 
sascha@3026:     public Iterator<Entry<A>> iterator() {
sascha@3026:         return entries.iterator();
sascha@3026:     }
sascha@3013: }
sascha@3013: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :