source: josm/trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java

Last change on this file was 16613, checked in by GerdP, 4 years ago

fix @since xxx

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import java.util.Arrays;
5import java.util.Collection;
6import java.util.LinkedHashMap;
7import java.util.List;
8import java.util.Map;
9import java.util.Set;
10import java.util.TreeSet;
11import java.util.stream.Collectors;
12
13import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
14import org.openstreetmap.josm.data.osm.PrimitiveId;
15import org.openstreetmap.josm.tools.Logging;
16
17/**
18 * Retrieves a set of {@link org.openstreetmap.josm.data.osm.OsmPrimitive}s from an Overpass API server.
19 *
20 * @since 9241
21 */
22public class MultiFetchOverpassObjectReader extends MultiFetchServerObjectReader {
23 private static final List<OsmPrimitiveType> wantedOrder = Arrays.asList(OsmPrimitiveType.RELATION,
24 OsmPrimitiveType.WAY, OsmPrimitiveType.NODE);
25
26 private static String getPackageString(final OsmPrimitiveType type, Set<Long> idPackage) {
27 return idPackage.stream().map(String::valueOf)
28 .collect(Collectors.joining(",", type.getAPIName() + (idPackage.size() == 1 ? "(" : "(id:"), ")"));
29 }
30
31 /**
32 * Generate single overpass query to retrieve multiple primitives. Can be used to download parents,
33 * children, the objects, or any combination of them.
34 * @param ids the collection of ids
35 * @param includeObjects if false, don't retrieve the primitives (e.g. only the referrers)
36 * @param recurseUp if true, referrers (parents) of the objects are downloaded and all nodes of parent ways
37 * @param recurseDownRelations true: yes, recurse down to retrieve complete relations
38 * @return the overpass query
39 * @since 16611
40 */
41 public static String genOverpassQuery(Collection<? extends PrimitiveId> ids, boolean includeObjects, boolean recurseUp,
42 boolean recurseDownRelations) {
43 Map<OsmPrimitiveType, Set<Long>> primitivesMap = new LinkedHashMap<>();
44 Arrays.asList(OsmPrimitiveType.RELATION, OsmPrimitiveType.WAY, OsmPrimitiveType.NODE)
45 .forEach(type -> primitivesMap.put(type, new TreeSet<>()));
46 for (PrimitiveId p : ids) {
47 primitivesMap.get(p.getType()).add(p.getUniqueId());
48 }
49 return genOverpassQuery(primitivesMap, includeObjects, recurseUp, recurseDownRelations);
50 }
51
52 /**
53 * Generate single overpass query to retrieve multiple primitives. Can be used to download parents,
54 * children, the objects, or any combination of them.
55 * @param primitivesMap map containing the primitives
56 * @param includeObjects if false, don't retrieve the primitives (e.g. only the referrers)
57 * @param recurseUp if true, referrers (parents) of the objects are downloaded and all nodes of parent ways
58 * @param recurseDownRelations true: yes, recurse down to retrieve complete relations
59 * @return the overpass query
60 */
61 protected static String genOverpassQuery(Map<OsmPrimitiveType, Set<Long>> primitivesMap, boolean includeObjects,
62 boolean recurseUp, boolean recurseDownRelations) {
63 if (!(includeObjects || recurseUp || recurseDownRelations))
64 throw new IllegalArgumentException("At least one options must be true");
65 StringBuilder sb = new StringBuilder(128);
66 StringBuilder setsToInclude = new StringBuilder();
67 StringBuilder up = new StringBuilder();
68 String down = null;
69 for (OsmPrimitiveType type : wantedOrder) {
70 Set<Long> set = primitivesMap.get(type);
71 if (!set.isEmpty()) {
72 sb.append(getPackageString(type, set));
73 if (type == OsmPrimitiveType.NODE) {
74 sb.append("->.n;");
75 if (includeObjects) {
76 setsToInclude.append(".n;");
77 }
78 if (recurseUp) {
79 up.append(".n;way(bn)->.wn;.n;rel(bn)->.rn;");
80 setsToInclude.append(".wn;node(w);.rn;");
81 }
82 } else if (type == OsmPrimitiveType.WAY) {
83 sb.append("->.w;");
84 if (includeObjects) {
85 setsToInclude.append(".w;>;");
86 }
87 if (recurseUp) {
88 up.append(".w;rel(bw)->.pw;");
89 setsToInclude.append(".pw;");
90 }
91 } else {
92 sb.append("->.r;");
93 if (includeObjects) {
94 setsToInclude.append(".r;");
95 }
96 if (recurseUp) {
97 up.append(".r;rel(br)->.pr;");
98 setsToInclude.append(".pr;");
99 }
100 if (recurseDownRelations) {
101 // get complete ways and nodes of the relation and next level of sub relations
102 down = ".r;rel(r)->.rm;";
103 setsToInclude.append(".r;>;.rm;");
104 }
105 }
106 }
107 }
108 if (up.length() > 0) {
109 sb.append(up);
110 }
111 if (down != null) {
112 sb.append(down);
113 }
114 sb.append('(').append(setsToInclude).append(");out meta;");
115
116 String query = sb.toString();
117 Logging.debug("{0} {1}", "Generated Overpass query:", query);
118 return query;
119 }
120
121 @Override
122 protected String getBaseUrl() {
123 return OverpassDownloadReader.OVERPASS_SERVER.get();
124 }
125}
Note: See TracBrowser for help on using the repository browser.