Ignore:
Timestamp:
2016-11-17T19:58:39+01:00 (7 years ago)
Author:
michael2402
Message:

Fix #13361: Use a more consistent invalid bbox for primitives.

Patch by Gerd Petermann

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java

    r11237 r11269  
    66import java.util.Collection;
    77import java.util.Iterator;
     8import java.util.LinkedHashSet;
    89import java.util.List;
    910import java.util.NoSuchElementException;
     
    167168
    168169        boolean matches(final T o, final BBox searchBbox) {
    169             if (o instanceof Node) {
    170                 final LatLon latLon = ((Node) o).getCoor();
    171                 // node without coords -> bbox[0,0,0,0]
    172                 return searchBbox.bounds(latLon != null ? latLon : LatLon.ZERO);
    173             }
    174170            return o.getBBox().intersects(searchBbox);
    175171        }
     
    359355    private QBLevel<T> searchCache;
    360356    private int size;
     357    private Collection<T> invalidBBoxPrimitives;
    361358
    362359    /**
     
    370367    public final void clear() {
    371368        root = new QBLevel<>();
     369        invalidBBoxPrimitives = new LinkedHashSet<>();
    372370        searchCache = null;
    373371        size = 0;
     
    376374    @Override
    377375    public boolean add(T n) {
    378         root.add(n);
     376        if (n.getBBox().isValid())
     377            root.add(n);
     378        else
     379            invalidBBoxPrimitives.add(n);
    379380        size++;
    380381        return true;
     
    426427        searchCache = null; // Search cache might point to one of removed buckets
    427428        QBLevel<T> bucket = root.findBucket(t.getBBox());
    428         if (bucket.removeContent(t)) {
     429        boolean removed = bucket.removeContent(t);
     430        if (!removed)
     431            removed = invalidBBoxPrimitives.remove(o);
     432        if (removed)
    429433            size--;
    430             return true;
    431         } else
    432             return false;
     434        return removed;
    433435    }
    434436
     
    437439        @SuppressWarnings("unchecked")
    438440        T t = (T) o;
     441        if (!t.getBBox().isValid())
     442            return invalidBBoxPrimitives.contains(o);
    439443        QBLevel<T> bucket = root.findBucket(t.getBBox());
    440444        return bucket != null && bucket.content != null && bucket.content.contains(t);
     
    466470        private QBLevel<T> currentNode;
    467471        private int contentIndex;
     472        private Iterator<T> invalidBBoxIterator = invalidBBoxPrimitives.iterator();
     473        boolean fromInvalidBBoxPrimitives;
    468474        QuadBuckets<T> qb;
    469475
     
    491497        @Override
    492498        public boolean hasNext() {
    493             if (this.peek() == null)
    494                 return false;
     499            if (this.peek() == null) {
     500                fromInvalidBBoxPrimitives = true;
     501                return invalidBBoxIterator.hasNext();
     502            }
    495503            return true;
    496504        }
     
    513521        @Override
    514522        public T next() {
     523            if (fromInvalidBBoxPrimitives)
     524                return invalidBBoxIterator.next();
    515525            T ret = peek();
    516526            if (ret == null)
     
    522532        @Override
    523533        public void remove() {
    524             // two uses
    525             // 1. Back up to the thing we just returned
    526             // 2. move the index back since we removed
    527             //    an element
    528             contentIndex--;
    529             T object = peek();
    530             if (currentNode.removeContent(object))
     534            if (fromInvalidBBoxPrimitives) {
     535                invalidBBoxIterator.remove();
    531536                qb.size--;
     537            } else {
     538                // two uses
     539                // 1. Back up to the thing we just returned
     540                // 2. move the index back since we removed
     541                //    an element
     542                contentIndex--;
     543                T object = peek();
     544                if (currentNode.removeContent(object))
     545                    qb.size--;
     546
     547            }
    532548        }
    533549    }
     
    555571    public List<T> search(BBox searchBbox) {
    556572        List<T> ret = new ArrayList<>();
     573        if (!searchBbox.isValid()) {
     574            return ret;
     575        }
     576
    557577        // Doing this cuts down search cost on a real-life data set by about 25%
    558578        if (searchCache == null) {
Note: See TracChangeset for help on using the changeset viewer.