Changeset 16611 in josm for trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java
- Timestamp:
- 2020-06-13T06:35:37+02:00 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/io/MultiFetchOverpassObjectReader.java
r16008 r16611 2 2 package org.openstreetmap.josm.io; 3 3 4 import java.util.Map.Entry; 4 import java.util.Arrays; 5 import java.util.Collection; 6 import java.util.LinkedHashMap; 7 import java.util.List; 8 import java.util.Map; 5 9 import java.util.Set; 10 import java.util.TreeSet; 6 11 import java.util.stream.Collectors; 7 12 8 13 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 14 import org.openstreetmap.josm.data.osm.PrimitiveId; 9 15 import org.openstreetmap.josm.tools.Logging; 10 16 … … 15 21 */ 16 22 public class MultiFetchOverpassObjectReader extends MultiFetchServerObjectReader { 23 private static final List<OsmPrimitiveType> wantedOrder = Arrays.asList(OsmPrimitiveType.RELATION, 24 OsmPrimitiveType.WAY, OsmPrimitiveType.NODE); 17 25 18 26 private static String getPackageString(final OsmPrimitiveType type, Set<Long> idPackage) { 19 27 return idPackage.stream().map(String::valueOf) 20 .collect(Collectors.joining(",", type.getAPIName() + (idPackage.size() == 1 ? "(" : "(id:"), ") ;"));28 .collect(Collectors.joining(",", type.getAPIName() + (idPackage.size() == 1 ? "(" : "(id:"), ")")); 21 29 } 22 30 23 31 /** 24 * Create a single query for all elements 25 * @return the request string 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 xxx 26 40 */ 27 protected String buildComplexRequestString() { 28 StringBuilder sb = new StringBuilder(); 29 int countTypes = 0; 30 for (Entry<OsmPrimitiveType, Set<Long>> e : primitivesMap.entrySet()) { 31 if (!e.getValue().isEmpty()) { 32 countTypes++; 33 String list = getPackageString(e.getKey(), e.getValue()); 34 switch (e.getKey()) { 35 case MULTIPOLYGON: 36 case RELATION: 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 } 37 100 if (recurseDownRelations) { 38 sb.append('(').append(list); 39 sb.setLength(sb.length()-1); // remove semicolon 40 //recurse down only one level, see #18835 41 sb.append("->.r;.r;rel(r);.r;way(r);>;.r;node(r););"); 42 } else { 43 sb.append(list); 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;"); 44 104 } 45 break;46 case CLOSEDWAY:47 case WAY:48 sb.append('(').append(list).append(">;);");49 break;50 case NODE:51 sb.append(list);52 105 } 53 106 } 54 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(");"); 115 116 sb.append("out meta;"); 55 117 String query = sb.toString(); 56 if (countTypes > 1) {57 query = "(" + query + ");";58 }59 query += "out meta;";60 118 Logging.debug("{0} {1}", "Generated Overpass query:", query); 61 119 return query;
Note:
See TracChangeset
for help on using the changeset viewer.