source: josm/trunk/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java@ 9325

Last change on this file since 9325 was 9325, checked in by simon04, 8 years ago

see #7670 fix #7647 - Fetching objects via Overpass API recurses down

Thus, there is no need for separately querying way nodes, or relation members.

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.io.IOException;
8import java.util.Collection;
9import java.util.Collections;
10
11import org.openstreetmap.josm.data.osm.DataSet;
12import org.openstreetmap.josm.data.osm.DataSetMerger;
13import org.openstreetmap.josm.data.osm.Node;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
16import org.openstreetmap.josm.data.osm.Relation;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.gui.ExceptionDialogUtil;
19import org.openstreetmap.josm.gui.PleaseWaitRunnable;
20import org.openstreetmap.josm.gui.layer.OsmDataLayer;
21import org.openstreetmap.josm.gui.progress.ProgressMonitor;
22import org.openstreetmap.josm.gui.util.GuiHelper;
23import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
24import org.openstreetmap.josm.io.OsmServerObjectReader;
25import org.openstreetmap.josm.io.OsmTransferException;
26import org.xml.sax.SAXException;
27
28/**
29 * The asynchronous task for updating a collection of objects using multi fetch.
30 *
31 */
32public class UpdatePrimitivesTask extends PleaseWaitRunnable {
33 private DataSet ds;
34 private boolean canceled;
35 private Exception lastException;
36 private final Collection<? extends OsmPrimitive> toUpdate;
37 private final OsmDataLayer layer;
38 private MultiFetchServerObjectReader multiObjectReader;
39 private OsmServerObjectReader objectReader;
40
41 /**
42 * Creates the task
43 *
44 * @param layer the layer in which primitives are updated. Must not be null.
45 * @param toUpdate a collection of primitives to update from the server. Set to
46 * the empty collection if null.
47 * @throws IllegalArgumentException if layer is null.
48 */
49 public UpdatePrimitivesTask(OsmDataLayer layer, Collection<? extends OsmPrimitive> toUpdate) {
50 super(tr("Update objects"), false /* don't ignore exception */);
51 ensureParameterNotNull(layer, "layer");
52 if (toUpdate == null) {
53 toUpdate = Collections.emptyList();
54 }
55 this.layer = layer;
56 this.toUpdate = toUpdate;
57 }
58
59 @Override
60 protected void cancel() {
61 canceled = true;
62 synchronized (this) {
63 if (multiObjectReader != null) {
64 multiObjectReader.cancel();
65 }
66 if (objectReader != null) {
67 objectReader.cancel();
68 }
69 }
70 }
71
72 @Override
73 protected void finish() {
74 if (canceled)
75 return;
76 if (lastException != null) {
77 ExceptionDialogUtil.explainException(lastException);
78 return;
79 }
80 GuiHelper.runInEDTAndWait(new Runnable() {
81 @Override
82 public void run() {
83 layer.mergeFrom(ds);
84 layer.onPostDownloadFromServer();
85 }
86 });
87 }
88
89 protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) {
90 getProgressMonitor().indeterminateSubTask(tr("Initializing nodes to update ..."));
91 for (OsmPrimitive primitive : toUpdate) {
92 if (primitive instanceof Node && !primitive.isNew()) {
93 reader.append(primitive);
94 }
95 }
96 }
97
98 protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) {
99 getProgressMonitor().indeterminateSubTask(tr("Initializing ways to update ..."));
100 for (OsmPrimitive primitive : toUpdate) {
101 if (primitive instanceof Way && !primitive.isNew()) {
102 // this also adds way nodes
103 reader.append(primitive);
104 }
105 }
106 }
107
108 protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) {
109 getProgressMonitor().indeterminateSubTask(tr("Initializing relations to update ..."));
110 for (OsmPrimitive primitive : toUpdate) {
111 if (primitive instanceof Relation && !primitive.isNew()) {
112 // this also adds relation members
113 reader.append(primitive);
114 }
115 }
116 }
117
118 @Override
119 protected void realRun() throws SAXException, IOException, OsmTransferException {
120 this.ds = new DataSet();
121 DataSet theirDataSet;
122 try {
123 synchronized (this) {
124 if (canceled) return;
125 multiObjectReader = MultiFetchServerObjectReader.create();
126 }
127 initMultiFetchReaderWithNodes(multiObjectReader);
128 initMultiFetchReaderWithWays(multiObjectReader);
129 initMultiFetchReaderWithRelations(multiObjectReader);
130 theirDataSet = multiObjectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
131 synchronized (this) {
132 multiObjectReader = null;
133 }
134 DataSetMerger merger = new DataSetMerger(ds, theirDataSet);
135 merger.merge();
136 // a way loaded with MultiFetch may have incomplete nodes because at least one of its
137 // nodes isn't present in the local data set. We therefore fully load all
138 // ways with incomplete nodes.
139 //
140 for (Way w : ds.getWays()) {
141 if (canceled) return;
142 if (w.hasIncompleteNodes()) {
143 synchronized (this) {
144 if (canceled) return;
145 objectReader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */);
146 }
147 theirDataSet = objectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
148 synchronized (this) {
149 objectReader = null;
150 }
151 merger = new DataSetMerger(ds, theirDataSet);
152 merger.merge();
153 }
154 }
155 } catch (Exception e) {
156 if (canceled)
157 return;
158 lastException = e;
159 }
160 }
161}
Note: See TracBrowser for help on using the repository browser.