Ticket #20658: 20658.patch

File 20658.patch, 5.1 KB (added by GerdP, 4 years ago)
  • src/org/openstreetmap/josm/data/osm/DataSet.java

     
    6161import org.openstreetmap.josm.spi.preferences.Config;
    6262import org.openstreetmap.josm.tools.ListenerList;
    6363import org.openstreetmap.josm.tools.Logging;
     64import org.openstreetmap.josm.tools.Stopwatch;
    6465import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    6566
    6667/**
     
    191192        // Transparently register as projection change listener. No need to explicitly remove
    192193        // the listener, projection change listeners are managed as WeakReferences.
    193194        ProjectionRegistry.addProjectionChangeListener(this);
     195        spatialIndexFilled = false;
    194196    }
    195197
    196198    /**
     
    359361     */
    360362    private final Map<String, String> changeSetTags = new HashMap<>();
    361363
     364    private boolean spatialIndexFilled;
     365
    362366    /**
    363367     * Replies the set of changeset tags to be applied when or if this is ever uploaded.
    364368     * @return the set of changeset tags
     
    392396    public List<Node> searchNodes(BBox bbox) {
    393397        lock.readLock().lock();
    394398        try {
     399            assertIndexFilled();
    395400            return store.searchNodes(bbox);
    396401        } finally {
    397402            lock.readLock().unlock();
     
    407412    public List<Way> searchWays(BBox bbox) {
    408413        lock.readLock().lock();
    409414        try {
     415            assertIndexFilled();
    410416            return store.searchWays(bbox);
    411417        } finally {
    412418            lock.readLock().unlock();
     
    417423    public List<Relation> searchRelations(BBox bbox) {
    418424        lock.readLock().lock();
    419425        try {
     426            assertIndexFilled();
    420427            return store.searchRelations(bbox);
    421428        } finally {
    422429            lock.readLock().unlock();
     
    423430        }
    424431    }
    425432
     433    private void assertIndexFilled() {
     434        if (!spatialIndexFilled) {
     435            Stopwatch stopwatch = Stopwatch.createStarted();
     436            allPrimitives.forEach(p -> {
     437                p.updatePosition();
     438                store.addPrimitive(p);
     439            });
     440            spatialIndexFilled = true;
     441            Logging.info(stopwatch.toString("Creation of spatial index for " + allPrimitives.size() + " objects"));
     442        }
     443    }
     444
    426445    /**
    427446     * Searches for all primitives in the given bounding box
    428447     *
     
    453472     */
    454473    @Override
    455474    public boolean containsNode(Node n) {
     475        assertIndexFilled();
    456476        return store.containsNode(n);
    457477    }
    458478
     
    466486     */
    467487    @Override
    468488    public boolean containsWay(Way w) {
     489        assertIndexFilled();
    469490        return store.containsWay(w);
    470491    }
    471492
     
    479500     */
    480501    @Override
    481502    public boolean containsRelation(Relation r) {
     503        assertIndexFilled();
    482504        return store.containsRelation(r);
    483505    }
    484506
     
    500522
    501523            allPrimitives.add(primitive);
    502524            primitive.setDataset(this);
    503             primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reindexRelation to work properly)
    504             store.addPrimitive(primitive);
     525            if (spatialIndexFilled) {
     526                primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reindexRelation to work properly)
     527                store.addPrimitive(primitive);
     528            }
    505529            firePrimitivesAdded(Collections.singletonList(primitive), false);
    506530        });
    507531    }
     
    532556        if (primitive.isSelected()) {
    533557            throw new DataIntegrityProblemException("Primitive was re-selected by a selection listener: " + primitive);
    534558        }
    535         store.removePrimitive(primitive);
     559        if (spatialIndexFilled) {
     560            store.removePrimitive(primitive);
     561        }
    536562        allPrimitives.remove(primitive);
    537563        primitive.setDataset(null);
    538564    }
     
    10251051    }
    10261052
    10271053    void fireRelationMembersChanged(Relation r) {
    1028         store.reindexRelation(r, Relation::updatePosition);
     1054        if (spatialIndexFilled) {
     1055            store.reindexRelation(r, Relation::updatePosition);
     1056        }
    10291057        fireEvent(new RelationMembersChangedEvent(this, r));
    10301058    }
    10311059
    10321060    void fireNodeMoved(Node node, LatLon newCoor, EastNorth eastNorth) {
    1033         store.reindexNode(node, n -> n.setCoorInternal(newCoor, eastNorth), Way::updatePosition, Relation::updatePosition);
     1061        if (spatialIndexFilled) {
     1062            store.reindexNode(node, n -> n.setCoorInternal(newCoor, eastNorth), Way::updatePosition, Relation::updatePosition);
     1063        } else {
     1064            node.setCoorInternal(newCoor, eastNorth);
     1065        }
    10341066        fireEvent(new NodeMovedEvent(this, node));
    10351067    }
    10361068
    10371069    void fireWayNodesChanged(Way way) {
    1038         if (!way.isEmpty()) {
     1070        if (spatialIndexFilled && !way.isEmpty() ) {
    10391071            store.reindexWay(way, Way::updatePosition, Relation::updatePosition);
    10401072        }
    10411073        fireEvent(new WayNodesChangedEvent(this, way));