Changeset 5476 in josm


Ignore:
Timestamp:
2012-08-25T16:06:22+02:00 (12 years ago)
Author:
Don-vip
Message:

OsmChange downloading:

  • download nodes for incomplete ways. This increases download time but ensures the downloaded data is correct (currently it can lead to 0-nodes ways)
  • fix progress monitor advancement
  • Try/catch and display error message on stderr in case of AssertionError
Location:
trunk/src/org/openstreetmap/josm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java

    r5345 r5476  
    11package org.openstreetmap.josm.actions.downloadtasks;
    22
    3 import java.util.ArrayList;
    43import java.util.Date;
    5 import java.util.HashSet;
     4import java.util.HashMap;
    65import java.util.Iterator;
    76import java.util.List;
    8 import java.util.Set;
     7import java.util.Map;
    98import java.util.concurrent.Future;
    109
     
    1211import org.openstreetmap.josm.data.Bounds;
    1312import org.openstreetmap.josm.data.osm.DataSet;
     13import org.openstreetmap.josm.data.osm.Node;
    1414import org.openstreetmap.josm.data.osm.NodeData;
    1515import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    1617import org.openstreetmap.josm.data.osm.PrimitiveData;
    1718import org.openstreetmap.josm.data.osm.PrimitiveId;
    1819import org.openstreetmap.josm.data.osm.RelationData;
     20import org.openstreetmap.josm.data.osm.RelationMemberData;
    1921import org.openstreetmap.josm.data.osm.WayData;
    2022import org.openstreetmap.josm.data.osm.history.History;
     
    3032import org.openstreetmap.josm.io.OsmServerReader;
    3133import org.openstreetmap.josm.io.OsmTransferException;
    32 import org.openstreetmap.josm.tools.Pair;
    3334
    3435public class DownloadOsmChangeTask extends DownloadOsmTask {
     
    8990                return; // user canceled download or error occurred
    9091            try {
    91                 // A changeset does not contain all referred primitives, this is the list of incomplete ones
    92                 Set<OsmPrimitive> toLoad = new HashSet<OsmPrimitive>();
     92                // A changeset does not contain all referred primitives, this is the map of incomplete ones
    9393                // For each incomplete primitive, we'll have to get its state at date it was referred
    94                 List<Pair<OsmPrimitive, Date>> toMonitor = new ArrayList<Pair<OsmPrimitive, Date>>();
     94                Map<OsmPrimitive, Date> toLoad = new HashMap<OsmPrimitive, Date>();
    9595                for (OsmPrimitive p : downloadedData.allNonDeletedPrimitives()) {
    9696                    if (p.isIncomplete()) {
     
    102102                            }
    103103                        }
    104                         if (toLoad.add(p)) {
    105                             toMonitor.add(new Pair<OsmPrimitive, Date>(p, timestamp));
    106                         }
     104                        toLoad.put(p, timestamp);
    107105                    }
    108106                }
    109107                if (isCanceled()) return;
    110                 // Updating process is asynchronous and done after each history request
    111                 HistoryDataSet.getInstance().addHistoryDataSetListener(new HistoryListener(toMonitor));
    112108                // Let's load all required history
    113                 Main.worker.submit(new HistoryLoadTask().add(toLoad));
     109                Main.worker.submit(new HistoryLoaderAndListener(toLoad));
    114110            } catch (Exception e) {
    115111                rememberException(e);
     
    118114        }
    119115    }
     116   
    120117    /**
    121      * Asynchroneous updater of incomplete primitives.
    122      *
     118     * Loads history and updates incomplete primitives.
    123119     */
    124     private static class HistoryListener implements HistoryDataSetListener {
    125 
    126         private final List<Pair<OsmPrimitive, Date>> toMonitor;
    127 
    128         public HistoryListener(List<Pair<OsmPrimitive, Date>> toMonitor) {
    129             this.toMonitor = toMonitor;
     120    private static class HistoryLoaderAndListener extends HistoryLoadTask implements HistoryDataSetListener {
     121
     122        private final Map<OsmPrimitive, Date> toLoad;
     123
     124        public HistoryLoaderAndListener(Map<OsmPrimitive, Date> toLoad) {
     125            this.toLoad = toLoad;
     126            add(toLoad.keySet());
     127            // Updating process is done after all history requests have been made
     128            HistoryDataSet.getInstance().addHistoryDataSetListener(this);
    130129        }
    131130
    132131        @Override
    133132        public void historyUpdated(HistoryDataSet source, PrimitiveId id) {
    134             for (Iterator<Pair<OsmPrimitive, Date>> it = toMonitor.iterator(); it.hasNext();) {
    135                 Pair<OsmPrimitive, Date> pair = it.next();
    136                 History history = source.getHistory(pair.a.getPrimitiveId());
     133            Map<OsmPrimitive, Date> toLoadNext = new HashMap<OsmPrimitive, Date>();
     134            for (Iterator<OsmPrimitive> it = toLoad.keySet().iterator(); it.hasNext();) {
     135                OsmPrimitive p = it.next();
     136                History history = source.getHistory(p.getPrimitiveId());
     137                Date date = toLoad.get(p);
    137138                // If the history has been loaded and a timestamp is known
    138                 if (history != null && pair.b != null) {
     139                if (history != null && date != null) {
    139140                    // Lookup for the primitive version at the specified timestamp
    140                     HistoryOsmPrimitive hp = history.getByDate(pair.b);
     141                    HistoryOsmPrimitive hp = history.getByDate(date);
    141142                    if (hp != null) {
    142143                        PrimitiveData data = null;
    143144
    144                         switch (pair.a.getType()) {
     145                        switch (p.getType()) {
    145146                        case NODE:
    146147                            data = new NodeData();
     
    149150                        case WAY:
    150151                            data = new WayData();
    151                             ((WayData)data).setNodes(((HistoryWay)hp).getNodes());
     152                            List<Long> nodeIds = ((HistoryWay)hp).getNodes();
     153                            ((WayData)data).setNodes(nodeIds);
     154                            // Find incomplete nodes to load at next run
     155                            for (Long nodeId : nodeIds) {
     156                                if (p.getDataSet().getPrimitiveById(nodeId, OsmPrimitiveType.NODE) == null) {
     157                                    Node n = new Node(nodeId);
     158                                    p.getDataSet().addPrimitive(n);
     159                                    toLoadNext.put(n, date);
     160                                }
     161                            }
    152162                            break;
    153163                        case RELATION:
    154164                            data = new RelationData();
    155                             ((RelationData)data).setMembers(((HistoryRelation)hp).getMembers());
     165                            List<RelationMemberData> members = ((HistoryRelation)hp).getMembers();
     166                            ((RelationData)data).setMembers(members);
    156167                            break;
    157                         default: throw new AssertionError();
     168                        default: throw new AssertionError("Unknown primitive type");
    158169                        }
    159170
     
    162173                            data.setVisible(hp.isVisible());
    163174                        } catch (IllegalStateException e) {
    164                             System.err.println("Cannot change visibility for "+pair.a+": "+e.getMessage());
     175                            System.err.println("Cannot change visibility for "+p+": "+e.getMessage());
    165176                        }
    166177                        data.setTimestamp(hp.getTimestamp());
     
    169180
    170181                        // Load the history data
    171                         pair.a.load(data);
    172                         // Forget this primitive
    173                         it.remove();
     182                        try {
     183                            p.load(data);
     184                            // Forget this primitive
     185                            it.remove();
     186                        } catch (AssertionError e) {
     187                            System.err.println("Cannot load "+p + ": " + e.getMessage());
     188                        }
    174189                    }
    175190                }
    176191            }
    177             if (toMonitor.isEmpty()) {
     192            source.removeHistoryDataSetListener(this);
     193            if (toLoadNext.isEmpty()) {
    178194                // No more primitive to update. Processing is finished
    179                 source.removeHistoryDataSetListener(this);
    180195                // Be sure all updated primitives are correctly drawn
    181196                Main.map.repaint();
     197            } else {
     198                // Some primitives still need to be loaded
     199                // Let's load all required history
     200                Main.worker.submit(new HistoryLoaderAndListener(toLoadNext));
    182201            }
    183202        }
  • trunk/src/org/openstreetmap/josm/gui/history/HistoryLoadTask.java

    r5266 r5476  
    178178        loadedData = new HistoryDataSet();
    179179        try {
     180            progressMonitor.setTicksCount(toLoad.size());
    180181            for(PrimitiveId pid: toLoad) {
    181182                if (canceled) {
Note: See TracChangeset for help on using the changeset viewer.