[8684] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[8744] | 2 | package org.openstreetmap.josm.tools;
|
---|
[8684] | 3 |
|
---|
| 4 | import java.io.IOException;
|
---|
| 5 | import java.io.Reader;
|
---|
| 6 |
|
---|
[8685] | 7 | import javax.script.Invocable;
|
---|
| 8 | import javax.script.ScriptEngine;
|
---|
| 9 | import javax.script.ScriptEngineManager;
|
---|
| 10 | import javax.script.ScriptException;
|
---|
| 11 |
|
---|
[9856] | 12 | import org.openstreetmap.josm.io.CachedFile;
|
---|
[9717] | 13 |
|
---|
[8684] | 14 | /**
|
---|
[9704] | 15 | * Uses <a href="https://github.com/tyrasd/overpass-wizard/">Overpass Turbo query wizard</a> code (MIT Licensed)
|
---|
[8684] | 16 | * to build an Overpass QL from a {@link org.openstreetmap.josm.actions.search.SearchAction} like query.
|
---|
| 17 | *
|
---|
| 18 | * Requires a JavaScript {@link ScriptEngine}.
|
---|
[8744] | 19 | * @since 8744
|
---|
[8684] | 20 | */
|
---|
[8685] | 21 | public final class OverpassTurboQueryWizard {
|
---|
[8684] | 22 |
|
---|
| 23 | private static OverpassTurboQueryWizard instance;
|
---|
| 24 | private final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
|
---|
| 25 |
|
---|
| 26 | /**
|
---|
| 27 | * Replies the unique instance of this class.
|
---|
| 28 | *
|
---|
| 29 | * @return the unique instance of this class
|
---|
| 30 | */
|
---|
| 31 | public static synchronized OverpassTurboQueryWizard getInstance() {
|
---|
| 32 | if (instance == null) {
|
---|
| 33 | instance = new OverpassTurboQueryWizard();
|
---|
| 34 | }
|
---|
| 35 | return instance;
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | private OverpassTurboQueryWizard() {
|
---|
[10802] | 39 | if (engine == null) {
|
---|
| 40 | throw new IllegalStateException("Failed to retrieve JavaScript engine");
|
---|
| 41 | }
|
---|
[10733] | 42 | try (CachedFile file = new CachedFile("resource://data/overpass-wizard.js");
|
---|
| 43 | Reader reader = file.getContentReader()) {
|
---|
[12627] | 44 | engine.eval("var console = {error: " + Logging.class.getCanonicalName() + ".warn};");
|
---|
[9704] | 45 | engine.eval("var global = {};");
|
---|
[8684] | 46 | engine.eval(reader);
|
---|
[9856] | 47 | engine.eval("var overpassWizard = function(query) {" +
|
---|
| 48 | " return global.overpassWizard(query, {" +
|
---|
| 49 | " comment: false," +
|
---|
| 50 | " outputFormat: 'xml'," +
|
---|
| 51 | " outputMode: 'recursive_meta'" +
|
---|
| 52 | " });" +
|
---|
| 53 | "}");
|
---|
[8684] | 54 | } catch (ScriptException | IOException ex) {
|
---|
[10235] | 55 | throw new IllegalStateException("Failed to initialize OverpassTurboQueryWizard", ex);
|
---|
[8684] | 56 | }
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | /**
|
---|
| 60 | * Builds an Overpass QL from a {@link org.openstreetmap.josm.actions.search.SearchAction} like query.
|
---|
| 61 | * @param search the {@link org.openstreetmap.josm.actions.search.SearchAction} like query
|
---|
| 62 | * @return an Overpass QL query
|
---|
[9385] | 63 | * @throws UncheckedParseException when the parsing fails
|
---|
[8684] | 64 | */
|
---|
[10101] | 65 | public String constructQuery(String search) {
|
---|
[8684] | 66 | try {
|
---|
[9856] | 67 | final Object result = ((Invocable) engine).invokeFunction("overpassWizard", search);
|
---|
[9850] | 68 | if (Boolean.FALSE.equals(result)) {
|
---|
[9385] | 69 | throw new UncheckedParseException();
|
---|
[8684] | 70 | }
|
---|
[11003] | 71 | return (String) result;
|
---|
[8684] | 72 | } catch (NoSuchMethodException e) {
|
---|
[9997] | 73 | throw new IllegalStateException(e);
|
---|
[8684] | 74 | } catch (ScriptException e) {
|
---|
[10101] | 75 | throw new UncheckedParseException("Failed to execute OverpassTurboQueryWizard", e);
|
---|
[8684] | 76 | }
|
---|
| 77 | }
|
---|
| 78 | }
|
---|