source: josm/trunk/scripts/TagInfoExtract.java@ 18783

Last change on this file since 18783 was 18760, checked in by taylor.smock, 21 months ago

Indicate that JOSM presets are also used by Vespucci to TagInfo (patch by simonpoole)

Also remove an unneeded import in SplitMode.

File size: 27.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2import java.awt.Graphics2D;
3import java.awt.image.BufferedImage;
4import java.io.BufferedReader;
5import java.io.IOException;
6import java.io.OutputStream;
7import java.io.StringWriter;
8import java.io.UncheckedIOException;
9import java.io.Writer;
10import java.nio.file.Files;
11import java.nio.file.Path;
12import java.nio.file.Paths;
13import java.time.Instant;
14import java.time.ZoneId;
15import java.time.format.DateTimeFormatter;
16import java.util.ArrayList;
17import java.util.Arrays;
18import java.util.Collection;
19import java.util.Collections;
20import java.util.EnumSet;
21import java.util.HashSet;
22import java.util.LinkedHashMap;
23import java.util.List;
24import java.util.Locale;
25import java.util.Map;
26import java.util.Optional;
27import java.util.Set;
28import java.util.regex.Matcher;
29import java.util.regex.Pattern;
30import java.util.stream.Collectors;
31import java.util.stream.Stream;
32
33import javax.imageio.ImageIO;
34import jakarta.json.Json;
35import jakarta.json.JsonArrayBuilder;
36import jakarta.json.JsonObjectBuilder;
37import jakarta.json.JsonWriter;
38import jakarta.json.stream.JsonGenerator;
39
40import org.openstreetmap.josm.actions.DeleteAction;
41import org.openstreetmap.josm.command.DeleteCommand;
42import org.openstreetmap.josm.data.Preferences;
43import org.openstreetmap.josm.data.Version;
44import org.openstreetmap.josm.data.coor.LatLon;
45import org.openstreetmap.josm.data.osm.Node;
46import org.openstreetmap.josm.data.osm.OsmPrimitive;
47import org.openstreetmap.josm.data.osm.Tag;
48import org.openstreetmap.josm.data.osm.Way;
49import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
50import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer;
51import org.openstreetmap.josm.data.preferences.JosmBaseDirectories;
52import org.openstreetmap.josm.data.preferences.JosmUrls;
53import org.openstreetmap.josm.data.preferences.sources.ExtendedSourceEntry;
54import org.openstreetmap.josm.data.preferences.sources.SourceEntry;
55import org.openstreetmap.josm.data.projection.ProjectionRegistry;
56import org.openstreetmap.josm.data.projection.Projections;
57import org.openstreetmap.josm.gui.NavigatableComponent;
58import org.openstreetmap.josm.gui.mappaint.Cascade;
59import org.openstreetmap.josm.gui.mappaint.Environment;
60import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
61import org.openstreetmap.josm.gui.mappaint.MultiCascade;
62import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory;
63import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule;
64import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
65import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser;
66import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
67import org.openstreetmap.josm.gui.mappaint.styleelement.AreaElement;
68import org.openstreetmap.josm.gui.mappaint.styleelement.LineElement;
69import org.openstreetmap.josm.gui.mappaint.styleelement.StyleElement;
70import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
71import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
72import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetReader;
73import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetType;
74import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
75import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem;
76import org.openstreetmap.josm.io.CachedFile;
77import org.openstreetmap.josm.io.OsmTransferException;
78import org.openstreetmap.josm.spi.preferences.Config;
79import org.openstreetmap.josm.tools.Http1Client;
80import org.openstreetmap.josm.tools.HttpClient;
81import org.openstreetmap.josm.tools.Logging;
82import org.openstreetmap.josm.tools.OptionParser;
83import org.openstreetmap.josm.tools.Territories;
84import org.openstreetmap.josm.tools.Utils;
85import org.xml.sax.SAXException;
86
87/**
88 * Extracts tag information for the taginfo project.
89 * <p>
90 * Run from the base directory of a JOSM checkout:
91 * <p>
92 * java -cp dist/josm-custom.jar TagInfoExtract --type mappaint
93 * java -cp dist/josm-custom.jar TagInfoExtract --type presets
94 * java -cp dist/josm-custom.jar TagInfoExtract --type external_presets
95 */
96public class TagInfoExtract {
97
98 /**
99 * Main method.
100 * @param args Main program arguments
101 * @throws Exception if any error occurs
102 */
103 public static void main(String[] args) throws Exception {
104 HttpClient.setFactory(Http1Client::new);
105 TagInfoExtract script = new TagInfoExtract();
106 script.parseCommandLineArguments(args);
107 script.init();
108 switch (script.options.mode) {
109 case MAPPAINT:
110 script.new StyleSheet().run();
111 break;
112 case PRESETS:
113 script.new Presets().run();
114 break;
115 case EXTERNAL_PRESETS:
116 script.new ExternalPresets().run();
117 break;
118 default:
119 throw new IllegalStateException("Invalid type " + script.options.mode);
120 }
121 if (!script.options.noexit) {
122 System.exit(0);
123 }
124 }
125
126 enum Mode {
127 MAPPAINT, PRESETS, EXTERNAL_PRESETS
128 }
129
130 private final Options options = new Options();
131
132 /**
133 * Parse command line arguments.
134 * @param args command line arguments
135 */
136 private void parseCommandLineArguments(String[] args) {
137 if (args.length == 1 && "--help".equals(args[0])) {
138 this.usage();
139 }
140 final OptionParser parser = new OptionParser(getClass().getName());
141 parser.addArgumentParameter("type", OptionParser.OptionCount.REQUIRED, options::setMode);
142 parser.addArgumentParameter("input", OptionParser.OptionCount.OPTIONAL, options::setInputFile);
143 parser.addArgumentParameter("output", OptionParser.OptionCount.OPTIONAL, options::setOutputFile);
144 parser.addArgumentParameter("imgdir", OptionParser.OptionCount.OPTIONAL, options::setImageDir);
145 parser.addArgumentParameter("imgurlprefix", OptionParser.OptionCount.OPTIONAL, options::setImageUrlPrefix);
146 parser.addFlagParameter("noexit", options::setNoExit);
147 parser.addFlagParameter("help", this::usage);
148 parser.parseOptionsOrExit(Arrays.asList(args));
149 }
150
151 private void usage() {
152 System.out.println("java " + getClass().getName());
153 System.out.println(" --type TYPE\tthe project type to be generated: " + Arrays.toString(Mode.values()));
154 System.out.println(" --input FILE\tthe input file to use (overrides defaults for types mappaint, presets)");
155 System.out.println(" --output FILE\tthe output file to use (defaults to STDOUT)");
156 System.out.println(" --imgdir DIRECTORY\tthe directory to put the generated images in (default: " + options.imageDir + ")");
157 System.out.println(" --imgurlprefix STRING\timage URLs prefix for generated image files (public path on webserver)");
158 System.out.println(" --noexit\tdo not call System.exit(), for use from Ant script");
159 System.out.println(" --help\tshow this help");
160 System.exit(0);
161 }
162
163 private static class Options {
164 Mode mode;
165 int josmSvnRevision = Version.getInstance().getVersion();
166 Path baseDir = Paths.get("");
167 Path imageDir = Paths.get("taginfo-img");
168 String imageUrlPrefix;
169 CachedFile inputFile;
170 Path outputFile;
171 boolean noexit;
172
173 void setMode(String value) {
174 mode = Mode.valueOf(value.toUpperCase(Locale.ENGLISH));
175 switch (mode) {
176 case MAPPAINT:
177 inputFile = new CachedFile("resource://styles/standard/elemstyles.mapcss");
178 break;
179 case PRESETS:
180 inputFile = new CachedFile("resource://data/defaultpresets.xml");
181 break;
182 default:
183 inputFile = null;
184 }
185 }
186
187 void setInputFile(String value) {
188 inputFile = new CachedFile(value);
189 }
190
191 void setOutputFile(String value) {
192 outputFile = Paths.get(value);
193 }
194
195 void setImageDir(String value) {
196 imageDir = Paths.get(value);
197 }
198
199 void setImageUrlPrefix(String value) {
200 imageUrlPrefix = value;
201 }
202
203 void setNoExit() {
204 noexit = true;
205 }
206
207 /**
208 * Determine full image url (can refer to JOSM or OSM repository).
209 * @param path the image path
210 * @return full image url
211 */
212 private String findImageUrl(String path) {
213 final Path f = baseDir.resolve("resources").resolve("images").resolve(path);
214 if (Files.exists(f)) {
215 return "https://josm.openstreetmap.de/export/" + josmSvnRevision + "/josm/trunk/resources/images/" + path;
216 }
217 throw new IllegalStateException("Cannot find image url for " + path);
218 }
219 }
220
221 private abstract class Extractor {
222 abstract void run() throws Exception;
223
224 void writeJson(String name, String description, Iterable<TagInfoTag> tags) throws IOException {
225 try (Writer writer = options.outputFile != null ? Files.newBufferedWriter(options.outputFile) : new StringWriter();
226 JsonWriter json = Json
227 .createWriterFactory(Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true))
228 .createWriter(writer)) {
229 JsonObjectBuilder project = Json.createObjectBuilder()
230 .add("name", name)
231 .add("description", description)
232 .add("project_url", JosmUrls.getInstance().getJOSMWebsite())
233 .add("icon_url", options.findImageUrl("logo_16x16x8.png"))
234 .add("contact_name", "JOSM developer team")
235 .add("contact_email", "josm-dev@openstreetmap.org");
236 final JsonArrayBuilder jsonTags = Json.createArrayBuilder();
237 for (TagInfoTag t : tags) {
238 jsonTags.add(t.toJson());
239 }
240 json.writeObject(Json.createObjectBuilder()
241 .add("data_format", 1)
242 .add("data_updated", DateTimeFormatter.ofPattern("yyyyMMdd'T'hhmmss'Z'").withZone(ZoneId.of("Z")).format(Instant.now()))
243 .add("project", project)
244 .add("tags", jsonTags)
245 .build());
246 if (options.outputFile == null) {
247 System.out.println(writer.toString());
248 }
249 }
250 }
251 }
252
253 private class Presets extends Extractor {
254
255 @Override
256 void run() throws IOException, OsmTransferException, SAXException {
257 try (BufferedReader reader = options.inputFile.getContentReader()) {
258 Collection<TaggingPreset> presets = TaggingPresetReader.readAll(reader, true);
259 List<TagInfoTag> tags = convertPresets(presets, "", true);
260 Logging.info("Converting {0} internal presets", tags.size());
261 writeJson("JOSM main presets", "Tags supported by the default presets in the OSM editor JOSM", tags);
262 }
263 }
264
265 List<TagInfoTag> convertPresets(Iterable<TaggingPreset> presets, String descriptionPrefix, boolean addImages) {
266 final List<TagInfoTag> tags = new ArrayList<>();
267 final Map<Tag, TagInfoTag> requiredTags = new LinkedHashMap<>();
268 final Map<Tag, TagInfoTag> optionalTags = new LinkedHashMap<>();
269 for (TaggingPreset preset : presets) {
270 preset.data.stream()
271 .flatMap(item -> item instanceof KeyedItem
272 ? Stream.of(((KeyedItem) item))
273 : item instanceof CheckGroup
274 ? ((CheckGroup) item).checks.stream()
275 : Stream.empty())
276 .forEach(item -> {
277 for (String value : values(item)) {
278 Set<TagInfoTag.Type> types = TagInfoTag.Type.forPresetTypes(preset.types);
279 if (item.isKeyRequired()) {
280 fillTagsMap(requiredTags, item, value, preset.getName(), types,
281 descriptionPrefix + TagInfoTag.REQUIRED_FOR_COUNT + ": ",
282 addImages && preset.iconName != null ? options.findImageUrl(preset.iconName) : null);
283 } else {
284 fillTagsMap(optionalTags, item, value, preset.getName(), types,
285 descriptionPrefix + TagInfoTag.OPTIONAL_FOR_COUNT + ": ", null);
286 }
287 }
288 });
289 }
290 tags.addAll(requiredTags.values());
291 tags.addAll(optionalTags.values());
292 return tags;
293 }
294
295 private void fillTagsMap(Map<Tag, TagInfoTag> optionalTags, KeyedItem item, String value,
296 String presetName, Set<TagInfoTag.Type> types, String descriptionPrefix, String iconUrl) {
297 optionalTags.compute(new Tag(item.key, value), (osmTag, tagInfoTag) -> {
298 if (tagInfoTag == null) {
299 return new TagInfoTag(descriptionPrefix + presetName, item.key, value, types, iconUrl);
300 } else {
301 tagInfoTag.descriptions.add(presetName);
302 tagInfoTag.objectTypes.addAll(types);
303 return tagInfoTag;
304 }
305 });
306 }
307
308 private Collection<String> values(KeyedItem item) {
309 final Collection<String> values = item.getValues();
310 return values.isEmpty() || values.size() > 50 ? Collections.singleton(null) : values;
311 }
312 }
313
314 private class ExternalPresets extends Presets {
315
316 @Override
317 void run() throws IOException, OsmTransferException, SAXException {
318 TaggingPresetReader.setLoadIcons(false);
319 final Collection<ExtendedSourceEntry> sources = new TaggingPresetPreference.TaggingPresetSourceEditor().loadAndGetAvailableSources();
320 final List<TagInfoTag> tags = new ArrayList<>();
321 for (SourceEntry source : sources) {
322 if (source.url.startsWith("resource")) {
323 // default presets
324 continue;
325 }
326 try {
327 Logging.info("Loading {0}", source.url);
328 Collection<TaggingPreset> presets = TaggingPresetReader.readAll(source.url, false);
329 final List<TagInfoTag> t = convertPresets(presets, source.title + " ", false);
330 Logging.info("Converted {0} presets of {1} to {2} tags", presets.size(), source.title, t.size());
331 tags.addAll(t);
332 } catch (Exception ex) {
333 Logging.warn("Skipping {0} due to error", source.url);
334 Logging.warn(ex);
335 }
336 }
337 writeJson("JOSM user presets", "Tags supported by the user contributed presets to the OSM editors JOSM and Vespucci", tags);
338 }
339 }
340
341 private class StyleSheet extends Extractor {
342 private MapCSSStyleSource styleSource;
343
344 @Override
345 void run() throws IOException, ParseException {
346 init();
347 parseStyleSheet();
348 final List<TagInfoTag> tags = convertStyleSheet();
349 writeJson("JOSM main mappaint style", "Tags supported by the main mappaint style in the OSM editor JOSM", tags);
350 }
351
352 /**
353 * Read the style sheet file and parse the MapCSS code.
354 * @throws IOException if any I/O error occurs
355 * @throws ParseException in case of parsing error
356 */
357 private void parseStyleSheet() throws IOException, ParseException {
358 try (BufferedReader reader = options.inputFile.getContentReader()) {
359 MapCSSParser parser = new MapCSSParser(reader, MapCSSParser.LexicalState.DEFAULT);
360 styleSource = new MapCSSStyleSource("");
361 styleSource.url = "";
362 parser.sheet(styleSource);
363 }
364 }
365
366 /**
367 * Collect all the tag from the style sheet.
368 * @return list of taginfo tags
369 */
370 private List<TagInfoTag> convertStyleSheet() {
371 return styleSource.rules.stream()
372 .flatMap(rule -> rule.selectors.stream())
373 .flatMap(selector -> selector.getConditions().stream())
374 .filter(ConditionFactory.SimpleKeyValueCondition.class::isInstance)
375 .map(ConditionFactory.SimpleKeyValueCondition.class::cast)
376 .map(condition -> condition.asTag(null))
377 .distinct()
378 .map(tag -> {
379 String iconUrl = null;
380 final EnumSet<TagInfoTag.Type> types = EnumSet.noneOf(TagInfoTag.Type.class);
381 Optional<String> nodeUrl = new NodeChecker(tag).findUrl(true);
382 if (nodeUrl.isPresent()) {
383 iconUrl = nodeUrl.get();
384 types.add(TagInfoTag.Type.NODE);
385 }
386 Optional<String> wayUrl = new WayChecker(tag).findUrl(iconUrl == null);
387 if (wayUrl.isPresent()) {
388 if (iconUrl == null) {
389 iconUrl = wayUrl.get();
390 }
391 types.add(TagInfoTag.Type.WAY);
392 }
393 Optional<String> areaUrl = new AreaChecker(tag).findUrl(iconUrl == null);
394 if (areaUrl.isPresent()) {
395 if (iconUrl == null) {
396 iconUrl = areaUrl.get();
397 }
398 types.add(TagInfoTag.Type.AREA);
399 }
400 return new TagInfoTag(null, tag.getKey(), tag.getValue(), types, iconUrl);
401 })
402 .collect(Collectors.toList());
403 }
404
405 /**
406 * Check if a certain tag is supported by the style as node / way / area.
407 */
408 private abstract class Checker {
409 private final Pattern reservedChars = Pattern.compile("[<>:\"|\\?\\*]");
410
411 Checker(Tag tag) {
412 this.tag = tag;
413 }
414
415 Environment applyStylesheet(OsmPrimitive osm) {
416 osm.put(tag);
417 MultiCascade mc = new MultiCascade();
418
419 Environment env = new Environment(osm, mc, null, styleSource);
420 for (MapCSSRule r : styleSource.rules) {
421 env.clearSelectorMatchingInformation();
422 if (r.matches(env)) {
423 // ignore selector range
424 if (env.layer == null) {
425 env.layer = "default";
426 }
427 r.execute(env);
428 }
429 }
430 env.layer = "default";
431 return env;
432 }
433
434 /**
435 * Create image file from StyleElement.
436 * @param element style element
437 * @param type object type
438 * @param nc navigable component
439 *
440 * @return the URL
441 */
442 String createImage(StyleElement element, final String type, NavigatableComponent nc) {
443 BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
444 Graphics2D g = img.createGraphics();
445 g.setClip(0, 0, 16, 16);
446 StyledMapRenderer renderer = new StyledMapRenderer(g, nc, false);
447 renderer.getSettings(false);
448 element.paintPrimitive(osm, MapPaintSettings.INSTANCE, renderer, false, false, false);
449 final String imageName = type + "_" + normalize(tag.toString()) + ".png";
450 try (OutputStream out = Files.newOutputStream(options.imageDir.resolve(imageName))) {
451 ImageIO.write(img, "png", out);
452 } catch (IOException e) {
453 throw new UncheckedIOException(e);
454 }
455 final String baseUrl = options.imageUrlPrefix != null ? options.imageUrlPrefix : options.imageDir.toString();
456 return baseUrl + "/" + imageName;
457 }
458
459 /**
460 * Normalizes tag so that it can used as a filename on all platforms, including Windows.
461 * @param tag OSM tag, that can contain illegal path characters
462 * @return OSM tag with all illegal path characters replaced by underscore ('_')
463 */
464 String normalize(String tag) {
465 Matcher m = reservedChars.matcher(tag);
466 return m.find() ? m.replaceAll("_") : tag;
467 }
468
469 /**
470 * Checks, if tag is supported and find URL for image icon in this case.
471 *
472 * @param generateImage if true, create or find a suitable image icon and return URL,
473 * if false, just check if tag is supported and return true or false
474 * @return URL for image icon if tag is supported
475 */
476 abstract Optional<String> findUrl(boolean generateImage);
477
478 protected Tag tag;
479 protected OsmPrimitive osm;
480 }
481
482 private class NodeChecker extends Checker {
483 NodeChecker(Tag tag) {
484 super(tag);
485 }
486
487 @Override
488 Optional<String> findUrl(boolean generateImage) {
489 this.osm = new Node(LatLon.ZERO);
490 Environment env = applyStylesheet(osm);
491 Cascade c = env.getCascade("default");
492 Object image = c.get("icon-image");
493 if (image instanceof MapPaintStyles.IconReference && !((MapPaintStyles.IconReference) image).isDeprecatedIcon()) {
494 return Optional.of(options.findImageUrl(((MapPaintStyles.IconReference) image).iconName));
495 }
496 return Optional.empty();
497 }
498 }
499
500 private class WayChecker extends Checker {
501 WayChecker(Tag tag) {
502 super(tag);
503 }
504
505 @Override
506 Optional<String> findUrl(boolean generateImage) {
507 this.osm = new Way();
508 NavigatableComponent nc = new NavigatableComponent();
509 Node n1 = new Node(nc.getLatLon(2, 8));
510 Node n2 = new Node(nc.getLatLon(14, 8));
511 ((Way) osm).addNode(n1);
512 ((Way) osm).addNode(n2);
513 Environment env = applyStylesheet(osm);
514 LineElement les = LineElement.createLine(env);
515 if (les != null) {
516 return Optional.of(generateImage ? createImage(les, "way", nc) : "");
517 }
518 return Optional.empty();
519 }
520 }
521
522 private class AreaChecker extends Checker {
523 AreaChecker(Tag tag) {
524 super(tag);
525 }
526
527 @Override
528 Optional<String> findUrl(boolean generateImage) {
529 this.osm = new Way();
530 NavigatableComponent nc = new NavigatableComponent();
531 Node n1 = new Node(nc.getLatLon(2, 2));
532 Node n2 = new Node(nc.getLatLon(14, 2));
533 Node n3 = new Node(nc.getLatLon(14, 14));
534 Node n4 = new Node(nc.getLatLon(2, 14));
535 ((Way) osm).addNode(n1);
536 ((Way) osm).addNode(n2);
537 ((Way) osm).addNode(n3);
538 ((Way) osm).addNode(n4);
539 ((Way) osm).addNode(n1);
540 Environment env = applyStylesheet(osm);
541 AreaElement aes = AreaElement.create(env);
542 if (aes != null) {
543 if (!generateImage) return Optional.of("");
544 return Optional.of(createImage(aes, "area", nc));
545 }
546 return Optional.empty();
547 }
548 }
549 }
550
551 /**
552 * POJO representing a <a href="https://wiki.openstreetmap.org/wiki/Taginfo/Projects">Taginfo tag</a>.
553 */
554 private static class TagInfoTag {
555 static final String REQUIRED_FOR_COUNT = "Required for {count}";
556 static final String OPTIONAL_FOR_COUNT = "Optional for {count}";
557 final Collection<String> descriptions = new ArrayList<>();
558 final String key;
559 final String value;
560 final Set<Type> objectTypes;
561 final String iconURL;
562
563 TagInfoTag(String description, String key, String value, Set<Type> objectTypes, String iconURL) {
564 if (description != null) {
565 this.descriptions.add(description);
566 }
567 this.key = key;
568 this.value = value;
569 this.objectTypes = objectTypes;
570 this.iconURL = iconURL;
571 }
572
573 JsonObjectBuilder toJson() {
574 final JsonObjectBuilder object = Json.createObjectBuilder();
575 if (!descriptions.isEmpty()) {
576 final int size = descriptions.size();
577 object.add("description", String.join(", ", Utils.limit(descriptions, 8, "..."))
578 .replace(REQUIRED_FOR_COUNT, size > 3 ? "Required for " + size : "Required for")
579 .replace(OPTIONAL_FOR_COUNT, size > 3 ? "Optional for " + size : "Optional for"));
580 }
581 object.add("key", key);
582 if (value != null) {
583 object.add("value", value);
584 }
585 if ((!objectTypes.isEmpty())) {
586 final JsonArrayBuilder types = Json.createArrayBuilder();
587 objectTypes.stream().map(Enum::name).map(String::toLowerCase).forEach(types::add);
588 object.add("object_types", types);
589 }
590 if (iconURL != null) {
591 object.add("icon_url", iconURL);
592 }
593 return object;
594 }
595
596 enum Type {
597 NODE, WAY, AREA, RELATION;
598
599 static TagInfoTag.Type forPresetType(TaggingPresetType type) {
600 switch (type) {
601 case CLOSEDWAY:
602 return AREA;
603 case MULTIPOLYGON:
604 return RELATION;
605 default:
606 return valueOf(type.toString());
607 }
608 }
609
610 static Set<TagInfoTag.Type> forPresetTypes(Set<TaggingPresetType> types) {
611 return types == null ? new HashSet<>() : types.stream()
612 .map(Type::forPresetType)
613 .collect(Collectors.toCollection(() -> EnumSet.noneOf(Type.class)));
614 }
615 }
616 }
617
618 /**
619 * Initialize the script.
620 * @throws IOException if any I/O error occurs
621 */
622 private void init() throws IOException {
623 Logging.setLogLevel(Logging.LEVEL_INFO);
624 Preferences.main().enableSaveOnPut(false);
625 Config.setPreferencesInstance(Preferences.main());
626 Config.setBaseDirectoriesProvider(JosmBaseDirectories.getInstance());
627 Config.setUrlsProvider(JosmUrls.getInstance());
628 ProjectionRegistry.setProjection(Projections.getProjectionByCode("EPSG:3857"));
629 Path tmpdir = Files.createTempDirectory(options.baseDir, "pref");
630 tmpdir.toFile().deleteOnExit();
631 System.setProperty("josm.home", tmpdir.toString());
632 DeleteCommand.setDeletionCallback(DeleteAction.defaultDeletionCallback);
633 Territories.initializeInternalData();
634 Files.createDirectories(options.imageDir);
635 }
636}
Note: See TracBrowser for help on using the repository browser.