Changeset 18711 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2023-04-24T19:55:08+02:00 (20 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java
r17838 r18711 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.io.IOException; 6 7 import java.time.Instant; 7 8 import java.util.Arrays; … … 13 14 import java.util.concurrent.Future; 14 15 import java.util.concurrent.RejectedExecutionException; 16 import java.util.function.Function; 15 17 import java.util.regex.Matcher; 18 import java.util.stream.Collectors; 16 19 17 20 import org.openstreetmap.josm.data.Bounds; … … 24 27 import org.openstreetmap.josm.data.osm.PrimitiveData; 25 28 import org.openstreetmap.josm.data.osm.PrimitiveId; 29 import org.openstreetmap.josm.data.osm.Relation; 26 30 import org.openstreetmap.josm.data.osm.RelationData; 31 import org.openstreetmap.josm.data.osm.Way; 27 32 import org.openstreetmap.josm.data.osm.WayData; 28 33 import org.openstreetmap.josm.data.osm.history.History; … … 37 42 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 38 43 import org.openstreetmap.josm.io.Compression; 44 import org.openstreetmap.josm.io.MultiFetchServerObjectReader; 39 45 import org.openstreetmap.josm.io.OsmApi; 40 46 import org.openstreetmap.josm.io.OsmServerLocationReader; … … 43 49 import org.openstreetmap.josm.io.UrlPatterns.OsmChangeUrlPattern; 44 50 import org.openstreetmap.josm.tools.Logging; 51 import org.xml.sax.SAXException; 45 52 46 53 /** … … 105 112 106 113 @Override 114 public void realRun() throws IOException, SAXException, OsmTransferException { 115 super.realRun(); 116 final Map<OsmPrimitive, Instant> toLoadNext = new HashMap<>(); 117 final Map<OsmPrimitive, Instant> toLoad = getToLoad(dataSet); 118 while (!toLoad.isEmpty()) { 119 loadLastVersions(toLoad, toLoadNext); 120 toLoad.putAll(toLoadNext); 121 toLoadNext.clear(); 122 } 123 } 124 125 /** 126 * This gets the last versions of references primitives. This may enough for many of the primitives. 127 * @param toLoad The primitives to load 128 * @param toLoadNext The primitives to load next (filled by this method) 129 */ 130 private void loadLastVersions(Map<OsmPrimitive, Instant> toLoad, Map<OsmPrimitive, Instant> toLoadNext) throws OsmTransferException { 131 final Map<OsmPrimitiveType, Map<OsmPrimitive, Instant>> typeMap = toLoad.entrySet().stream() 132 .collect(Collectors.groupingBy(entry -> entry.getKey().getType(), Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); 133 final Map<PrimitiveId, OsmPrimitive> idMap = toLoad.keySet().stream() 134 .collect(Collectors.toMap(OsmPrimitive::getPrimitiveId, Function.identity())); 135 for (OsmPrimitiveType type : Arrays.asList(OsmPrimitiveType.NODE, OsmPrimitiveType.WAY, OsmPrimitiveType.RELATION)) { 136 if (!typeMap.containsKey(type)) { 137 continue; 138 } 139 final MultiFetchServerObjectReader reader = MultiFetchServerObjectReader.create(); 140 typeMap.get(type).forEach((primitive, instant) -> reader.append(primitive)); 141 final DataSet ds = reader.parseOsm(this.progressMonitor.createSubTaskMonitor(1, false)); 142 switch (type) { 143 case NODE: 144 for (Node node : ds.getNodes()) { 145 Node original = (Node) idMap.get(node.getPrimitiveId()); 146 if (original != null && toLoad.get(original).isAfter(node.getInstant())) { 147 original.load(node.save()); 148 } 149 toLoad.remove(original); 150 } 151 break; 152 case WAY: 153 for (Way way : ds.getWays()) { 154 Way original = (Way) idMap.get(way.getPrimitiveId()); 155 if (original != null && toLoad.get(original).isAfter(way.getInstant())) { 156 Instant date = toLoad.get(original); 157 original.load(way.save()); 158 for (Long nodeId : way.getNodeIds()) { 159 if (way.getDataSet().getPrimitiveById(nodeId, OsmPrimitiveType.NODE) == null) { 160 Node n = new Node(nodeId); 161 way.getDataSet().addPrimitive(n); 162 toLoadNext.put(n, date); 163 } 164 } 165 } 166 toLoad.remove(original); 167 } 168 break; 169 case RELATION: 170 for (Relation relation : ds.getRelations()) { 171 Relation original = (Relation) idMap.get(relation.getPrimitiveId()); 172 if (original != null && toLoad.get(original).isAfter(relation.getInstant())) { 173 original.load(relation.save()); 174 } 175 toLoad.remove(relation); 176 } 177 break; 178 default: 179 throw new IllegalStateException("Only Node, Ways, and Relations should be returned by the API"); 180 } 181 } 182 } 183 184 @Override 107 185 protected void finish() { 108 186 super.finish(); … … 112 190 // A changeset does not contain all referred primitives, this is the map of incomplete ones 113 191 // For each incomplete primitive, we'll have to get its state at date it was referred 114 Map<OsmPrimitive, Instant> toLoad = new HashMap<>(); 115 for (OsmPrimitive p : downloadedData.allNonDeletedPrimitives()) { 116 if (p.isIncomplete()) { 117 Instant timestamp = p.getReferrers().stream() 118 .filter(ref -> !ref.isTimestampEmpty()) 119 .findFirst() 120 .map(AbstractPrimitive::getInstant) 121 .orElse(null); 122 toLoad.put(p, timestamp); 123 } 124 } 192 Map<OsmPrimitive, Instant> toLoad = getToLoad(downloadedData); 125 193 if (isCanceled()) return; 126 194 // Let's load all required history … … 131 199 } 132 200 } 201 } 202 203 /** 204 * Get the primitives to load more information 205 * @param ds The dataset to look for incomplete primitives from 206 * @return The objects that still need to be loaded 207 */ 208 private static Map<OsmPrimitive, Instant> getToLoad(DataSet ds) { 209 Map<OsmPrimitive, Instant> toLoad = new HashMap<>(); 210 for (OsmPrimitive p : ds.allNonDeletedPrimitives()) { 211 if (p.isIncomplete()) { 212 Instant timestamp = p.getReferrers().stream() 213 .filter(ref -> !ref.isTimestampEmpty()) 214 .findFirst() 215 .map(AbstractPrimitive::getInstant) 216 .orElse(null); 217 toLoad.put(p, timestamp); 218 } 219 } 220 return toLoad; 133 221 } 134 222
Note:
See TracChangeset
for help on using the changeset viewer.