| 153 | | progressMonitor.setTicksCount(children.size()); |
| 154 | | int i = 1; |
| 155 | | for (PrimitiveId p : children) { |
| 156 | | if (canceled) |
| 157 | | return; |
| 158 | | String msg; |
| 159 | | String id = Long.toString(p.getUniqueId()); |
| 160 | | switch(p.getType()) { |
| 161 | | case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i, children.size(), id); break; |
| 162 | | case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i, children.size(), id); break; |
| 163 | | case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i, children.size(), id); break; |
| 164 | | default: throw new AssertionError(); |
| | 159 | if (Boolean.TRUE.equals(OverpassDownloadReader.FOR_MULTI_FETCH.get())) { |
| | 160 | String request = genOverpassQuery(); |
| | 161 | OverpassDownloadReader reader = new OverpassDownloadReader(new Bounds(0, 0, 0, 0), |
| | 162 | OverpassDownloadReader.OVERPASS_SERVER.get(), request); |
| | 163 | DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false)); |
| | 164 | new DataSetMerger(parents, ds).merge(); |
| | 165 | } else { |
| | 166 | progressMonitor.setTicksCount(children.size()); |
| | 167 | int i = 1; |
| | 168 | for (PrimitiveId p : children) { |
| | 169 | if (canceled) |
| | 170 | return; |
| | 171 | String msg; |
| | 172 | String id = Long.toString(p.getUniqueId()); |
| | 173 | switch(p.getType()) { |
| | 174 | case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i, children.size(), id); break; |
| | 175 | case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i, children.size(), id); break; |
| | 176 | case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i, children.size(), id); break; |
| | 177 | default: throw new AssertionError(); |
| | 178 | } |
| | 179 | progressMonitor.subTask(msg); |
| | 180 | downloadParents(p.getUniqueId(), p.getType(), progressMonitor); |
| | 181 | i++; |
| 172 | | if (!ways.isEmpty()) { |
| 173 | | // Collect incomplete nodes of parent ways |
| 174 | | Set<Node> nodes = ways.stream().flatMap(w -> w.getNodes().stream().filter(OsmPrimitive::isIncomplete)) |
| 175 | | .collect(Collectors.toSet()); |
| 176 | | if (!nodes.isEmpty()) { |
| 177 | | reader = MultiFetchServerObjectReader.create(); |
| 178 | | ((MultiFetchServerObjectReader) reader).append(nodes); |
| 179 | | DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false)); |
| 180 | | synchronized (this) { // avoid race condition in cancel() |
| 181 | | reader = null; |
| | 185 | if (!ways.isEmpty()) { |
| | 186 | // Collect incomplete nodes of parent ways |
| | 187 | Set<Node> nodes = ways.stream().flatMap(w -> w.getNodes().stream().filter(OsmPrimitive::isIncomplete)) |
| | 188 | .collect(Collectors.toSet()); |
| | 189 | if (!nodes.isEmpty()) { |
| | 190 | reader = MultiFetchServerObjectReader.create(); |
| | 191 | ((MultiFetchServerObjectReader) reader).append(nodes); |
| | 192 | DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false)); |
| | 193 | synchronized (this) { // avoid race condition in cancel() |
| | 194 | reader = null; |
| | 195 | } |
| | 196 | new DataSetMerger(parents, wayNodes).merge(); |
| | 206 | |
| | 207 | private String genOverpassQuery() { |
| | 208 | Map<OsmPrimitiveType, Set<Long>> primitivesMap = new LinkedHashMap<>(); |
| | 209 | primitivesMap.put(OsmPrimitiveType.NODE, new LinkedHashSet<>()); |
| | 210 | primitivesMap.put(OsmPrimitiveType.WAY, new LinkedHashSet<>()); |
| | 211 | primitivesMap.put(OsmPrimitiveType.RELATION, new LinkedHashSet<>()); |
| | 212 | for (PrimitiveId p : children) { |
| | 213 | primitivesMap.get(p.getType()).add(p.getUniqueId()); |
| | 214 | } |
| | 215 | boolean getWays = false; |
| | 216 | StringBuilder sb = new StringBuilder(); |
| | 217 | StringBuilder sets = new StringBuilder(); |
| | 218 | for (Entry<OsmPrimitiveType, Set<Long>> e : primitivesMap.entrySet()) { |
| | 219 | if (!e.getValue().isEmpty()) { |
| | 220 | String list = getPackageString(e.getKey(), e.getValue()); |
| | 221 | switch (e.getKey()) { |
| | 222 | case NODE: |
| | 223 | sb.append('(').append(list).append("->.n;.n;rel(bn);.n;way(bn);)->.pn;"); |
| | 224 | sets.append(".pn;"); |
| | 225 | getWays = true; |
| | 226 | break; |
| | 227 | case CLOSEDWAY: |
| | 228 | case WAY: |
| | 229 | sb.append(list).append(";rel(bw)->.pw;"); |
| | 230 | sets.append(".pw;"); |
| | 231 | break; |
| | 232 | case MULTIPOLYGON: |
| | 233 | case RELATION: |
| | 234 | sb.append(list).append(";rel(br)->.pr;"); |
| | 235 | sets.append(".pr;"); |
| | 236 | break; |
| | 237 | } |
| | 238 | } |
| | 239 | } |
| | 240 | // retrieve all incomplete nodes for union of parents |
| | 241 | if (getWays) |
| | 242 | sb.append("((").append(sets).append(");node(w);node(r););"); |
| | 243 | else |
| | 244 | sb.append("((").append(sets).append(");node(r););"); |
| | 245 | sb.append("out meta;"); |
| | 246 | String query = sb.toString(); |
| | 247 | Logging.debug("{0} {1}", "Generated Overpass query:", query); |
| | 248 | return query; |
| | 249 | |
| | 250 | } |
| | 251 | |
| | 252 | private static String getPackageString(final OsmPrimitiveType type, Set<Long> idPackage) { |
| | 253 | return idPackage.stream().map(String::valueOf) |
| | 254 | .collect(Collectors.joining(",", type.getAPIName() + (idPackage.size() == 1 ? "(" : "(id:"), ")")); |
| | 255 | } |
| | 256 | |