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

Last change on this file since 19050 was 19050, checked in by taylor.smock, 6 weeks ago

Revert most var changes from r19048, fix most new compile warnings and checkstyle issues

Also, document why various ErrorProne checks were originally disabled and fix
generic SonarLint issues.

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