diff --git a/brouter/src/main/java/slash/navigation/brouter/BRouter.java b/brouter/src/main/java/slash/navigation/brouter/BRouter.java index 842a047de..11ae5436e 100644 --- a/brouter/src/main/java/slash/navigation/brouter/BRouter.java +++ b/brouter/src/main/java/slash/navigation/brouter/BRouter.java @@ -51,6 +51,7 @@ import static slash.navigation.download.Checksum.createChecksum; import static slash.navigation.routing.RoutingResult.Validity.Invalid; import static slash.navigation.routing.RoutingResult.Validity.Valid; +import static slash.navigation.routing.TravelRestrictions.NO_RESTRICTIONS; /** * Encapsulates access to the BRouter. @@ -107,22 +108,6 @@ public boolean isDownload() { return true; } - public boolean isSupportTurnpoints() { - return false; - } - - public boolean isSupportAvoidFerries() { - return false; - } - - public boolean isSupportAvoidHighways() { - return false; - } - - public boolean isSupportAvoidTolls() { - return false; - } - public List getAvailableTravelModes() { List result = new ArrayList<>(); if (getProfiles() != null) { @@ -140,6 +125,10 @@ public TravelMode getPreferredTravelMode() { return MOPED; } + public TravelRestrictions getAvailableTravelRestrictions() { + return NO_RESTRICTIONS; + } + public String getPath() { return preferences.get(DIRECTORY_PREFERENCE, ""); } @@ -209,7 +198,7 @@ Set createFileKeys(double longitude, double latitude) { return result; } - public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode) { + public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode, TravelRestrictions travelRestrictions) { SecondCounter secondCounter = new SecondCounter() { protected void second(int second) { fireRouting(second); diff --git a/brouter/src/test/java/slash/navigation/brouter/BRouterIT.java b/brouter/src/test/java/slash/navigation/brouter/BRouterIT.java index 24509a725..808cb442c 100644 --- a/brouter/src/test/java/slash/navigation/brouter/BRouterIT.java +++ b/brouter/src/test/java/slash/navigation/brouter/BRouterIT.java @@ -43,6 +43,7 @@ import static slash.common.io.Directories.getApplicationDirectory; import static slash.common.io.Externalization.extractFile; import static slash.navigation.routing.RoutingResult.Validity.Valid; +import static slash.navigation.routing.TravelRestrictions.NO_RESTRICTIONS; public class BRouterIT { private static final NavigationPosition FROM = new SimpleNavigationPosition(10.18587, 53.40451); @@ -101,7 +102,7 @@ private TravelMode getTravelMode(String lookupName) { @Test public void testGetRouteBetweenByCar() { - RoutingResult result = router.getRouteBetween(FROM, TO, getTravelMode("car-eco")); + RoutingResult result = router.getRouteBetween(FROM, TO, getTravelMode("car-eco"), NO_RESTRICTIONS); assertEquals(Valid, result.getValidity()); assertEquals(324, result.getPositions().size(), 10); assertEquals(13789, result.getDistanceAndTime().getDistance(), 25.0); @@ -110,7 +111,7 @@ public void testGetRouteBetweenByCar() { @Test public void testGetRouteBetweenByBike() { - RoutingResult result = router.getRouteBetween(FROM, TO, getTravelMode("trekking")); + RoutingResult result = router.getRouteBetween(FROM, TO, getTravelMode("trekking"), NO_RESTRICTIONS); assertEquals(Valid, result.getValidity()); assertEquals(185, result.getPositions().size(), 8); assertEquals(13899.0, result.getDistanceAndTime().getDistance(), 25.0); diff --git a/browser-mapview/src/main/java/slash/navigation/mapview/browser/BrowserMapView.java b/browser-mapview/src/main/java/slash/navigation/mapview/browser/BrowserMapView.java deleted file mode 100644 index 351f327a0..000000000 --- a/browser-mapview/src/main/java/slash/navigation/mapview/browser/BrowserMapView.java +++ /dev/null @@ -1,1984 +0,0 @@ -/* - This file is part of RouteConverter. - - RouteConverter is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - RouteConverter is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with RouteConverter; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright (C) 2007 Christian Pesch. All Rights Reserved. -*/ - -package slash.navigation.mapview.browser; - -import net.andreinc.aleph.AlephFormatter; -import slash.common.helpers.APIKeyRegistry; -import slash.common.io.Externalization; -import slash.common.io.InputOutput; -import slash.common.io.TokenResolver; -import slash.common.type.CompactCalendar; -import slash.navigation.base.*; -import slash.navigation.columbus.ColumbusGpsBinaryFormat; -import slash.navigation.columbus.ColumbusGpsFormat; -import slash.navigation.common.*; -import slash.navigation.converter.gui.models.*; -import slash.navigation.gui.Application; -import slash.navigation.maps.tileserver.TileServer; -import slash.navigation.mapview.BaseMapView; -import slash.navigation.mapview.MapView; -import slash.navigation.mapview.MapViewCallback; -import slash.navigation.nmn.NavigatingPoiWarnerFormat; - -import javax.swing.event.*; -import java.awt.*; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.io.*; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.logging.Logger; -import java.util.prefs.Preferences; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static java.lang.Boolean.parseBoolean; -import static java.lang.Character.isLetterOrDigit; -import static java.lang.Character.isWhitespace; -import static java.lang.Math.max; -import static java.lang.Math.min; -import static java.lang.String.format; -import static java.lang.System.currentTimeMillis; -import static java.lang.Thread.sleep; -import static java.util.Arrays.asList; -import static java.util.Calendar.SECOND; -import static java.util.concurrent.Executors.newCachedThreadPool; -import static javax.swing.JOptionPane.ERROR_MESSAGE; -import static javax.swing.JOptionPane.showMessageDialog; -import static javax.swing.SwingUtilities.invokeLater; -import static javax.swing.event.TableModelEvent.*; -import static org.apache.commons.lang.StringEscapeUtils.escapeHtml; -import static slash.common.helpers.ExceptionHelper.getLocalizedMessage; -import static slash.common.helpers.ExceptionHelper.printStackTrace; -import static slash.common.helpers.ThreadHelper.createSingleThreadExecutor; -import static slash.common.helpers.ThreadHelper.safeJoin; -import static slash.common.io.Externalization.extractFile; -import static slash.common.io.Transfer.*; -import static slash.common.type.CompactCalendar.fromCalendar; -import static slash.navigation.base.RouteCharacteristics.*; -import static slash.navigation.base.WaypointType.*; -import static slash.navigation.common.TransformUtil.delta; -import static slash.navigation.common.TransformUtil.isPositionInChina; -import static slash.navigation.converter.gui.models.FixMapMode.Yes; -import static slash.navigation.converter.gui.models.PositionColumns.*; -import static slash.navigation.gui.events.IgnoreEvent.isIgnoreEvent; -import static slash.navigation.gui.events.Range.asRange; -import static slash.navigation.gui.helpers.JTableHelper.isFirstToLastRow; -import static slash.navigation.mapview.browser.helpers.ColorHelper.asColor; -import static slash.navigation.mapview.browser.helpers.ColorHelper.asOpacity; - -/** - * Base implementation for a browser-based map view. - * - * @author Christian Pesch - */ - -public abstract class BrowserMapView extends BaseMapView { - static final Preferences preferences = Preferences.userNodeForPackage(BrowserMapView.class); - private static final Logger log = Logger.getLogger(MapView.class.getName()); - private static final String RESOURCES_PACKAGE = "slash/navigation/mapview/browser/"; - - private static final String MAP_TYPE_PREFERENCE = "mapType"; - static final String DEBUG_PREFERENCE = "debug"; - private static final String BROWSER_SCALE_FACTOR_PREFERENCE = "browserScaleFactor"; - - private PositionsModel positionsModel; - private MapPreferencesModel preferencesModel; - private List lastSelectedPositions = new ArrayList<>(); - private int[] selectedPositionIndices = new int[0]; - private List selectedPositions = new ArrayList<>(); - private int lastZoom = -1; - - private ServerSocket callbackListenerServerSocket; - private Thread positionListUpdater, selectionUpdater, callbackListener, callbackPoller; - - private final Object notificationMutex = new Object(); - private boolean initialized; - private boolean running = true, haveToInitializeMapOnFirstStart = true, haveToRepaintSelectionImmediately, - haveToRepaintRouteImmediately, haveToRecenterMap, - haveToUpdateRoute, haveToReplaceRoute, - haveToRepaintSelection, ignoreNextZoomCallback; - - private final PositionsModelListener positionsModelListener = new PositionsModelListener(); - private final RoutingPreferencesListener routingPreferencesListener = new RoutingPreferencesListener(); - private final CharacteristicsModelListener characteristicsModelListener = new CharacteristicsModelListener(); - private final UnitSystemListener unitSystemListener = new UnitSystemListener(); - private final ShowCoordinatesListener showCoordinatesListener = new ShowCoordinatesListener(); - private final ShowWaypointDescriptionListener showWaypointDescriptionListener = new ShowWaypointDescriptionListener(); - private final RepaintPositionListListener repaintPositionListListener = new RepaintPositionListListener(); - private final GoogleMapsServerListener googleMapsServerListener = new GoogleMapsServerListener(); - - private String routeUpdateReason = "?", selectionUpdateReason = "?"; - MapViewCallbackGoogle mapViewCallback; - private PositionReducer positionReducer; - private final ExecutorService executor = newCachedThreadPool(); - private int overQueryLimitCount, zeroResultsCount; - - // initialization - - - public void initialize(PositionsModel positionsModel, - MapPreferencesModel preferencesModel, - MapViewCallback mapViewCallback) { - this.positionsModel = positionsModel; - this.preferencesModel = preferencesModel; - this.mapViewCallback = (MapViewCallbackGoogle) mapViewCallback; - - initializeCallbackListener(); - initializeBrowser(); - - positionsModel.addTableModelListener(positionsModelListener); - preferencesModel.getRoutingPreferencesModel().addChangeListener(routingPreferencesListener); - preferencesModel.getCharacteristicsModel().addListDataListener(characteristicsModelListener); - preferencesModel.getUnitSystemModel().addChangeListener(unitSystemListener); - preferencesModel.getShowCoordinatesModel().addChangeListener(showCoordinatesListener); - preferencesModel.getShowWaypointDescriptionModel().addChangeListener(showWaypointDescriptionListener); - preferencesModel.getFixMapModeModel().addChangeListener(repaintPositionListListener); - preferencesModel.getRouteColorModel().addChangeListener(repaintPositionListListener); - preferencesModel.getRouteLineWidthModel().addChangeListener(repaintPositionListListener); - preferencesModel.getTrackColorModel().addChangeListener(repaintPositionListListener); - preferencesModel.getTrackLineWidthModel().addChangeListener(repaintPositionListListener); - getGoogleMapsServerModel().addChangeListener(googleMapsServerListener); - - positionReducer = new PositionReducer(new PositionReducer.Callback() { - public int getZoom() { - return BrowserMapView.this.getZoom(); - } - - public NavigationPosition getNorthEastBounds() { - return BrowserMapView.this.getNorthEastBounds(); - } - - public NavigationPosition getSouthWestBounds() { - return BrowserMapView.this.getSouthWestBounds(); - } - }); - } - - protected abstract void initializeBrowser(); - protected abstract void initializeWebPage(); - - protected double getBrowserScaleFactor() { - return (double) preferences.getInt(BROWSER_SCALE_FACTOR_PREFERENCE, Toolkit.getDefaultToolkit().getScreenResolution()) / 96.0; - } - - protected GoogleMapsServerModel getGoogleMapsServerModel() { - return mapViewCallback.getGoogleMapsServerModel(); - } - - protected String getGoogleMapsServerApiUrl() { - return getGoogleMapsServerModel().getGoogleMapsServer().getApiUrl(); - } - - protected String prepareWebPage() throws IOException { - final String language = Locale.getDefault().getLanguage().toLowerCase(); - final String country = Locale.getDefault().getCountry().toLowerCase(); - File html = extractFile(RESOURCES_PACKAGE + "routeconverter.html", country, new TokenResolver() { - public String resolveToken(String tokenName) { - if (tokenName.equals("port")) - return String.valueOf(getCallbackPort()); - if (tokenName.equals("language")) - return language; - if (tokenName.equals("country")) - return country; - if (tokenName.equals("mapserverapiurl")) - return getGoogleMapsServerApiUrl(); - if (tokenName.equals("mapserverfileurl")) - return getGoogleMapsServerModel().getGoogleMapsServer().getFileUrl(); - if (tokenName.equals("maptype")) - return getMapType(); - if (tokenName.equals("googleapikey")) - return APIKeyRegistry.getInstance().getAPIKey("google", "map"); - if (tokenName.equals("tileservers")) - return registerMaps(mapViewCallback.getTileServerMapManager().getAvailableMapsModel().getItems()); - if (tokenName.equals("menuItems")) - return registerMenuItems(); - if (tokenName.equals("c")) - return "${c}"; - return tokenName; - } - }); - if (html == null) - throw new IllegalArgumentException("Cannot extract routeconverter.html"); - - extractFile(RESOURCES_PACKAGE + "routeconverter.css"); - extractFile(RESOURCES_PACKAGE + "jquery.min.js"); - extractFile(RESOURCES_PACKAGE + "contextmenu.js"); - extractFile(RESOURCES_PACKAGE + "keydragzoom.js"); - extractFile(RESOURCES_PACKAGE + "label.js"); - extractFile(RESOURCES_PACKAGE + "latlngcontrol.js"); - - return html.toURI().toURL().toExternalForm(); - } - - protected void tryToInitialize(int count, long start) { - boolean initialized = getComponent() != null && isMapInitialized(); - synchronized (INITIALIZED_LOCK) { - this.initialized = initialized; - } - log.fine("Initialized map: " + initialized); - - if (isInitialized()) { - runBrowserInteractionCallbacksAndTests(start); - } else { - long end = currentTimeMillis(); - int timeout = count++ * 100; - if (timeout > 3000) - timeout = 3000; - log.info("Failed to initialize map since " + (end - start) + " ms, sleeping for " + timeout + " ms"); - - try { - sleep(timeout); - } catch (InterruptedException e) { - // intentionally left empty - } - tryToInitialize(count, start); - } - } - - protected void runBrowserInteractionCallbacksAndTests(long start) { - long end = currentTimeMillis(); - log.fine("Starting browser interaction, callbacks and tests after " + (end - start) + " ms"); - initializeAfterLoading(); - initializeBrowserInteraction(); - checkLocalhostResolution(); - checkCallback(); - setDegreeFormat(); - setShowCoordinates(); - end = currentTimeMillis(); - log.fine("Browser interaction is running after " + (end - start) + " ms"); - } - - protected abstract boolean isMapInitialized(); - - protected void initializeAfterLoading() { - resize(); - update(true, false); - } - - private Throwable initializationCause; - - public Throwable getInitializationCause() { - return initializationCause; - } - - protected void setInitializationCause(Throwable initializationCause) { - this.initializationCause = initializationCause; - } - - private static final Object INITIALIZED_LOCK = new Object(); - - public boolean isInitialized() { - synchronized (INITIALIZED_LOCK) { - return initialized; - } - } - - public boolean isDownload() { - return false; - } - - public String getMapIdentifier() { - return getMapType(); - } - - public String getMapsPath() { - throw new UnsupportedOperationException(); - } - - public void setMapsPath(String path) { - throw new UnsupportedOperationException(); - } - - public String getThemesPath() { - throw new UnsupportedOperationException(); - } - - public void setThemesPath(String path) { - throw new UnsupportedOperationException(); - } - - protected void initializeBrowserInteraction() { - getComponent().addComponentListener(new ComponentListener() { - public void componentResized(ComponentEvent e) { - resize(); - } - - public void componentMoved(ComponentEvent e) { - } - - public void componentShown(ComponentEvent e) { - } - - public void componentHidden(ComponentEvent e) { - } - }); - - positionListUpdater = new Thread(() -> { - long lastTime = 0; - boolean recenter; - while (true) { - List copiedPositions; - synchronized (notificationMutex) { - try { - notificationMutex.wait(1000); - } catch (InterruptedException e) { - // ignore this - } - - if (!running) - return; - if (!hasPositions()) - continue; - if (!isVisible()) - continue; - - /* - Update conditions: - - - new route was loaded - - clear cache - - center map - - set zoom level according to route bounds - - repaint immediately - - user has moved position - - clear cache - - stay on current zoom level - - center map to position - - repaint - - user has removed position - - clear cache - - stay on current zoom level - - repaint - - user has zoomed map - - repaint if zooming into the map as it reveals more details - - user has moved map - - repaint if moved - */ - long currentTime = currentTimeMillis(); - if (haveToRepaintRouteImmediately || - haveToReplaceRoute || - (haveToUpdateRoute && (currentTime - lastTime > 5 * 1000))) { - log.info("Woke up to update route: " + routeUpdateReason + - " haveToUpdateRoute:" + haveToUpdateRoute + - " haveToReplaceRoute:" + haveToReplaceRoute + - " haveToRepaintRouteImmediately:" + haveToRepaintRouteImmediately); - copiedPositions = new ArrayList<>(positionsModel.getRoute().getPositions()); - recenter = haveToReplaceRoute; - haveToUpdateRoute = false; - haveToReplaceRoute = false; - haveToRepaintRouteImmediately = false; - } else - continue; - } - - setCenterOfMap(copiedPositions, recenter); - RouteCharacteristics characteristics = positionsModel.getRoute().getCharacteristics(); - List render = positionReducer.reducePositions(copiedPositions, characteristics, preferencesModel.getShowWaypointDescriptionModel().getBoolean()); - switch (characteristics) { - case Route -> addDirectionsToMap(render); - case Track -> addPolylinesToMap(render, copiedPositions); - case Waypoints -> addMarkersToMap(render); - } - log.info("Position list updated for " + render.size() + " positions of type " + characteristics + - ", reason: " + routeUpdateReason + ", recentering: " + recenter); - lastTime = currentTimeMillis(); - } - }, "MapViewPositionListUpdater"); - positionListUpdater.start(); - - selectionUpdater = new Thread(() -> { - long lastTime = 0; - while (true) { - int[] copiedSelectedPositionIndices; - List copiedPositions; - boolean recenter; - synchronized (notificationMutex) { - try { - notificationMutex.wait(250); - } catch (InterruptedException e) { - // ignore this - } - - if (!running) - return; - if (!hasPositions()) - continue; - if (!isVisible()) - continue; - - long currentTime = currentTimeMillis(); - if (haveToRecenterMap || haveToRepaintSelectionImmediately || - (haveToRepaintSelection && (currentTime - lastTime > 500))) { - log.fine("Woke up to update selected positions: " + selectionUpdateReason + - " haveToRepaintSelection: " + haveToRepaintSelection + - " haveToRepaintSelectionImmediately: " + haveToRepaintSelectionImmediately + - " haveToRecenterMap: " + haveToRecenterMap); - recenter = haveToRecenterMap; - haveToRecenterMap = false; - haveToRepaintSelectionImmediately = false; - haveToRepaintSelection = false; - copiedSelectedPositionIndices = new int[selectedPositionIndices.length]; - System.arraycopy(selectedPositionIndices, 0, copiedSelectedPositionIndices, 0, copiedSelectedPositionIndices.length); - copiedPositions = new ArrayList(positionsModel.getRoute().getPositions()); - } else - continue; - } - - List render = new ArrayList<>(positionReducer.reduceSelectedPositions(copiedPositions, copiedSelectedPositionIndices)); - render.addAll(selectedPositions); - NavigationPosition centerPosition = !render.isEmpty() ? new BoundingBox(render).getCenter() : null; - selectPositions(render, recenter ? centerPosition : null); - log.info("Selected positions updated for " + render.size() + " positions, reason: " + - selectionUpdateReason + ", recentering: " + recenter + " to: " + centerPosition); - lastTime = currentTimeMillis(); - } - }, "MapViewSelectionUpdater"); - selectionUpdater.start(); - } - - private ServerSocket createCallbackListenerServerSocket() { - try { - ServerSocket serverSocket = new ServerSocket(0, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1})); - serverSocket.setSoTimeout(1000); - int port = serverSocket.getLocalPort(); - log.info("Map listens on port " + port + " for callbacks"); - setCallbackListenerPort(port); - return serverSocket; - } catch (IOException e) { - log.severe("Cannot open callback listener socket: " + e); - return null; - } - } - - protected void initializeCallbackListener() { - callbackListenerServerSocket = createCallbackListenerServerSocket(); - if (callbackListenerServerSocket == null) - return; - - callbackListener = new Thread(() -> { - while (true) { - synchronized (notificationMutex) { - if (!running) { - return; - } - } - - try { - final Socket socket = callbackListenerServerSocket.accept(); - executor.execute(() -> { - try { - processStream(socket); - } catch (IOException e) { - log.severe(format("Cannot process stream from callback listener socket: %s, %s ", e, printStackTrace(e))); - } - }); - } catch (SocketTimeoutException e) { - // intentionally left empty - } catch (IOException e) { - synchronized (notificationMutex) { - //noinspection ConstantConditions - if (running) { - log.severe("Cannot accept callback listener socket: " + e); - } - } - } - } - }, "MapViewCallbackListener"); - callbackListener.start(); - } - - protected void initializeCallbackPoller() { - callbackPoller = new Thread(() -> { - while (true) { - synchronized (notificationMutex) { - if (!running) { - return; - } - } - - String callbacks = trim(getCallbacks()); - if (callbacks != null) { - String[] lines = callbacks.split("--"); - for (String line : lines) { - processCallback(line); - } - } - - try { - sleep(250); - } catch (InterruptedException e) { - // intentionally left empty - } - } - }, "MapViewCallbackPoller"); - callbackPoller.start(); - } - - protected void checkLocalhostResolution() { - try { - InetAddress localhost = InetAddress.getByName("localhost"); - log.info("localhost is resolved to: " + localhost); - String localhostName = localhost.getHostAddress(); - log.info("IP of localhost is: " + localhostName); - if (!localhostName.equals("127.0.0.1")) - throw new Exception("localhost does not resolve to 127.0.0.1"); - - InetAddress ip = InetAddress.getByAddress(new byte[]{127, 0, 0, 1}); - log.info("127.0.0.1 is resolved to: " + ip); - String ipName = localhost.getHostName(); - log.info("Name of 127.0.0.1 is: " + ipName); - if (!ipName.equals("localhost")) - throw new Exception("127.0.0.1 does not resolve to localhost"); - } catch (Exception e) { - final String message = "Probably faulty network setup: " + getLocalizedMessage(e) + ".\nPlease check your network settings."; - log.severe(message); - invokeLater(new Runnable() { - public void run() { - showMessageDialog(getComponent(), message, "Error", ERROR_MESSAGE); - } - }); - } - } - - protected void checkCallback() { - final Boolean[] receivedCallback = new Boolean[1]; - receivedCallback[0] = false; - - final MapViewListener callbackWaiter = new MapViewListener() { - public void receivedCallback(int port) { - synchronized (receivedCallback) { - receivedCallback[0] = true; - receivedCallback.notifyAll(); - } - } - }; - - executor.execute(() -> { - addMapViewListener(callbackWaiter); - try { - executeScript("checkCallbackListenerPort();"); - - long start = currentTimeMillis(); - while (true) { - synchronized (receivedCallback) { - if (receivedCallback[0]) { - long end = currentTimeMillis(); - log.info("Received callback from browser after " + (end - start) + " milliseconds"); - break; - } - } - - if (start + 5000 < currentTimeMillis()) - break; - - try { - sleep(50); - } catch (InterruptedException e) { - // intentionally left empty - } - } - - synchronized (receivedCallback) { - if (!receivedCallback[0]) { - setCallbackListenerPort(-1); - initializeCallbackPoller(); - log.warning("Switched from callback to polling the browser"); - } - } - } finally { - removeMapViewListener(callbackWaiter); - } - }); - } - - // tile servers - - private static final List GOOGLE_MAP_TYPES = asList("ROADMAP", "SATELLITE", "HYBRID", "TERRAIN"); - - private String getMapType() { - return preferences.get(MAP_TYPE_PREFERENCE, "google.maps.MapTypeId.ROADMAP"); - } - - protected boolean isGoogleMap() { - String mapType = getMapType(); - return mapType != null && GOOGLE_MAP_TYPES.contains(mapType.toUpperCase()); - } - - private String registerMaps(List tileServers) { - StringBuilder buffer = new StringBuilder(); - - for (String tileServerId : GOOGLE_MAP_TYPES) - buffer.append("registerMap(google.maps.MapTypeId.").append(tileServerId).append(", \"Google\");\n"); - buffer.append("\n"); - - String apiKey = APIKeyRegistry.getInstance().getAPIKey("thunderforest", "map"); - for (TileServer tileServer : tileServers) { - if (!tileServer.isActive() || tileServer.getHosts().isEmpty()) - continue; - - String copyright = tileServer.getCopyright().toLowerCase(); - // the Google Maps API sets the copyright notice anyway - String copyrightText = copyright.equals("Google") ? "" : tileServer.getCopyrightText(); - buffer.append("registerCustomMap(\"").append(tileServer.getId()).append("\", '"). - append(copyrightText).append("', new google.maps.ImageMapType({\n"). - append(" getTileUrl: function(coordinates, zoom) {\n"). - append(" var tileServers = ["); - for (int i = 0, c = tileServer.getHosts().size(); i < c; i++) { - buffer.append("\"").append(tileServer.getHosts().get(i)).append("\""); - if (i < c - 1) - buffer.append(", "); - } - String url = AlephFormatter.str(tileServer.getUrlPattern()) - .arg("host", "\" + tileServer + \"") - .arg("language", Locale.getDefault().getLanguage()) - .arg("tilex", "\" + coordinates.x + \"") - .arg("tiley", "\" + coordinates.y + \"") - .arg("zoom", "\" + zoom + \"") - .fmt(); - buffer.append("];\n"). - append(" var tileServer = tileServers[Math.floor(Math.random() * tileServers.length)];\n"). - append(" var url = \"").append(url).append("\";\n"); - if (apiKey != null && copyright.contains("thunderforest")) - buffer.append(" url = url.concat(\"?apikey=").append(apiKey).append("\");\n"); - buffer.append(" return url;\n"). - append(" },\n"). - append(" tileSize: DEFAULT_TILE_SIZE,\n"). - append(" minZoom: ").append(tileServer.getMinZoom()).append(",\n"). - append(" maxZoom: ").append(tileServer.getMaxZoom()).append(",\n"). - append(" alt: \"").append(tileServer.getDescription()).append("\",\n"). - append(" name: \"").append(tileServer.getId()).append("\"\n"). - append("}));\n"); - } - - return buffer.toString(); - } - - private static final String[] MENU_ITEM_KEYS = new String[]{ "center-here-action", "delete-action", - "new-position-action", "select-position-action", "zoom-in-action", "zoom-out-action" }; - - private String registerMenuItems() { - StringBuilder buffer = new StringBuilder(); - - ResourceBundle bundle = Application.getInstance().getContext().getBundle(); - for (String menuItemKey : MENU_ITEM_KEYS) - buffer.append("menuItems[\"").append(menuItemKey).append("\"] = "). - append("\"").append(escapeHtml(bundle.getString(menuItemKey))).append("\";\n"); - - return buffer.toString(); - } - - private boolean isColumbusTrack() { - BaseNavigationFormat format = positionsModel.getRoute().getFormat(); - return format instanceof ColumbusGpsFormat || format instanceof ColumbusGpsBinaryFormat; - } - - // resizing - - private boolean hasBeenResizedToInvisible; - - public void resize() { - if (!isInitialized() || !getComponent().isShowing()) - return; - - new Thread(() -> { - synchronized (notificationMutex) { - // if map is not visible remember to update and resize it again - // once the map becomes visible again - if (!isVisible()) { - hasBeenResizedToInvisible = true; - } else if (hasBeenResizedToInvisible) { - hasBeenResizedToInvisible = false; - update(true, false); - } - resizeMap(); - } - }, "BrowserResizer").start(); - } - - private int lastWidth = -1, lastHeight = -1; - - private void resizeMap() { - synchronized (notificationMutex) { - double browserScaleFactor = getBrowserScaleFactor(); - int width = (int) max(getComponent().getWidth() / browserScaleFactor, 0.0); - int height = (int) max(getComponent().getHeight() / browserScaleFactor, 0.0); - if (width != lastWidth || height != lastHeight) { - executeScript("resize(" + width + "," + height + ");"); - } - lastWidth = width; - lastHeight = height; - } - } - - // disposal - - public void dispose() { - if(positionsModel != null) { - positionsModel.removeTableModelListener(positionsModelListener); - preferencesModel.getRoutingPreferencesModel().removeChangeListener(routingPreferencesListener); - preferencesModel.getCharacteristicsModel().removeListDataListener(characteristicsModelListener); - preferencesModel.getUnitSystemModel().removeChangeListener(unitSystemListener); - preferencesModel.getShowCoordinatesModel().removeChangeListener(showCoordinatesListener); - preferencesModel.getShowWaypointDescriptionModel().removeChangeListener(showWaypointDescriptionListener); - preferencesModel.getFixMapModeModel().removeChangeListener(repaintPositionListListener); - preferencesModel.getRouteColorModel().removeChangeListener(repaintPositionListListener); - preferencesModel.getRouteLineWidthModel().removeChangeListener(repaintPositionListListener); - preferencesModel.getTrackColorModel().removeChangeListener(repaintPositionListListener); - preferencesModel.getTrackLineWidthModel().removeChangeListener(repaintPositionListListener); - getGoogleMapsServerModel().removeChangeListener(googleMapsServerListener); - } - - long start = currentTimeMillis(); - synchronized (notificationMutex) { - running = false; - notificationMutex.notifyAll(); - } - - if (selectionUpdater != null) { - try { - safeJoin(selectionUpdater); - } catch (InterruptedException e) { - // intentionally left empty - } - long end = currentTimeMillis(); - log.info("PositionUpdater stopped after " + (end - start) + " ms"); - } - - if (positionListUpdater != null) { - try { - safeJoin(positionListUpdater); - } catch (InterruptedException e) { - // intentionally left empty - } - long end = currentTimeMillis(); - log.info("RouteUpdater stopped after " + (end - start) + " ms"); - } - - if (callbackListenerServerSocket != null) { - try { - callbackListenerServerSocket.close(); - } catch (IOException e) { - log.warning("Cannot close callback listener socket:" + e); - } - long end = currentTimeMillis(); - log.info("CallbackListenerSocket stopped after " + (end - start) + " ms"); - } - - if (callbackListener != null) { - try { - safeJoin(callbackListener); - } catch (InterruptedException e) { - // intentionally left empty - } - long end = currentTimeMillis(); - log.info("CallbackListener stopped after " + (end - start) + " ms"); - } - - if (callbackPoller != null && callbackPoller.isAlive()) { - try { - safeJoin(callbackPoller); - } catch (InterruptedException e) { - // intentionally left empty - } - long end = currentTimeMillis(); - log.info("CallbackPoller stopped after " + (end - start) + " ms"); - } - - executor.shutdownNow(); - insertWaypointsExecutor.shutdownNow(); - long end = currentTimeMillis(); - log.info("Executors stopped after " + (end - start) + " ms"); - } - - // getter and setter - - protected boolean isVisible() { - return getComponent().getWidth() > 0; - } - - private boolean hasPositions() { - synchronized (notificationMutex) { - return isInitialized() && positionsModel.getRoute().getPositions() != null; - } - } - - private void setCallbackListenerPort(int callbackListenerPort) { - synchronized (notificationMutex) { - executeScript("setCallbackListenerPort(" + callbackListenerPort + ")"); - } - } - - public void setSelectedPositions(int[] selectedPositions, boolean replaceSelection) { - synchronized (notificationMutex) { - if (replaceSelection) - this.selectedPositionIndices = selectedPositions; - else { - int[] indices = new int[selectedPositionIndices.length + selectedPositions.length]; - System.arraycopy(selectedPositionIndices, 0, indices, 0, selectedPositionIndices.length); - System.arraycopy(selectedPositions, 0, indices, selectedPositionIndices.length, selectedPositions.length); - this.selectedPositionIndices = indices; - } - this.selectedPositions = new ArrayList<>(); - haveToRecenterMap = selectedPositions.length > 0; - haveToRepaintSelection = true; - selectionUpdateReason = "selected " + selectedPositions.length + " positions; " + - "replacing selection: " + replaceSelection; - notificationMutex.notifyAll(); - } - } - - public void setSelectedPositions(List selectedPositions) { - synchronized (notificationMutex) { - this.selectedPositions = selectedPositions; - this.selectedPositionIndices = new int[0]; - haveToRecenterMap = !selectedPositions.isEmpty(); - haveToRepaintSelection = true; - selectionUpdateReason = "selected " + selectedPositions.size() + " positions without model"; - notificationMutex.notifyAll(); - } - } - - protected void setShowCoordinates() { - executeScript("setShowCoordinates(" + preferencesModel.getShowCoordinatesModel().getBoolean() + ");"); - } - - protected void setDegreeFormat() { - executeScript("setDegreeFormat('" + preferencesModel.getUnitSystemModel().getDegreeFormat() + "');"); - } - - @SuppressWarnings({"unchecked", "Convert2Diamond"}) - public void showAllPositions() { - setCenterOfMap(new ArrayList(positionsModel.getRoute().getPositions()), true); - } - - public void showMapBorder(BoundingBox mapBoundingBox) { - throw new UnsupportedOperationException(); - } - - public void showPositionMagnifier(List positions) { - // not supported for BrowserMapView - } - - public NavigationPosition getCenter() { - if (isInitialized()) - return getCurrentMapCenter(); - else - return getLastMapCenter(); - } - - private int getZoom() { - return preferences.getInt(CENTER_ZOOM_PREFERENCE, 2); - } - - private void setZoom(int zoom) { - preferences.putInt(CENTER_ZOOM_PREFERENCE, zoom); - } - - // bounds and center - - protected abstract NavigationPosition getNorthEastBounds(); - protected abstract NavigationPosition getSouthWestBounds(); - protected abstract NavigationPosition getCurrentMapCenter(); - protected abstract Integer getCurrentZoom(); - protected abstract String getCallbacks(); - - private NavigationPosition getLastMapCenter() { - double latitude = preferences.getDouble(CENTER_LATITUDE_PREFERENCE, 35.0); - double longitude = preferences.getDouble(CENTER_LONGITUDE_PREFERENCE, -25.0); - return new SimpleNavigationPosition(longitude, latitude); - } - - protected NavigationPosition parsePosition(String latLngString) { - String result = executeScriptWithResult(latLngString); - if (result == null) - return null; - - StringTokenizer tokenizer = new StringTokenizer(result, ","); - if (tokenizer.countTokens() != 2) - return null; - - String latitude = tokenizer.nextToken(); - String longitude = tokenizer.nextToken(); - return parsePosition(latitude, longitude); - } - - private boolean isFixMap(Double longitude, Double latitude) { - FixMapMode fixMapMode = preferencesModel.getFixMapModeModel().getFixMapMode(); - return fixMapMode.equals(Yes) && isGoogleMap() && isPositionInChina(longitude, latitude); - } - - private NavigationPosition parsePosition(String latitudeString, String longitudeString) { - Double longitude = parseDouble(longitudeString); - Double latitude = parseDouble(latitudeString); - if (longitude != null && latitude != null && isFixMap(longitude, latitude)) { - double[] delta = delta(latitude, longitude); - longitude += delta[1]; - latitude += delta[0]; - } - return new SimpleNavigationPosition(longitude, latitude); - } - - private String asCoordinates(NavigationPosition position) { - double longitude = position.getLongitude() != null ? position.getLongitude() : 0.0; - double latitude = position.getLatitude() != null ? position.getLatitude() : 0.0; - if (isFixMap(longitude, latitude)) { - double[] delta = delta(latitude, longitude); - longitude += delta[1]; - latitude += delta[0]; - } - return latitude + "," + longitude; - } - - // draw on map - - protected void update(boolean haveToReplaceRoute, boolean clearPositionReducer) { - if (!isInitialized() || !getComponent().isShowing()) - return; - - synchronized (notificationMutex) { - this.haveToUpdateRoute = true; - routeUpdateReason = "update route"; - if (haveToReplaceRoute) { - this.haveToReplaceRoute = true; - routeUpdateReason = "replace route"; - this.haveToRepaintSelection = true; - selectionUpdateReason = "replace route"; - } - if (clearPositionReducer) - positionReducer.clear(); - notificationMutex.notifyAll(); - } - } - - private void updateRouteButDontRecenter() { - // repaint route immediately, simulates update(true) without recentering - synchronized (notificationMutex) { - haveToRepaintRouteImmediately = true; - routeUpdateReason = "update route but don't recenter"; - positionReducer.clear(); - notificationMutex.notifyAll(); - } - } - - private void updateSelection() { - synchronized (notificationMutex) { - haveToRepaintSelection = true; - selectionUpdateReason = "update selection"; - notificationMutex.notifyAll(); - } - } - - private void removeDirections() { - executeScript("removeOverlays();\nremoveDirections();"); - } - - private void addDirectionsToMap(List positions) { - resetDirections(); - - // avoid throwing javascript exceptions if there is nothing to direct - if (positions.size() < 2) { - addMarkersToMap(positions); - return; - } - - generationId++; - directionsPositions.addAll(positions); - executeScript("removeOverlays();"); - - String color = asColor(preferencesModel.getRouteColorModel().getColor()); - float opacity = asOpacity(preferencesModel.getRouteColorModel().getColor()); - int width = preferencesModel.getRouteLineWidthModel().getInteger(); - int maximumRouteSegmentLength = positionReducer.getMaximumSegmentLength(Route); - int directionsCount = ceiling(positions.size(), maximumRouteSegmentLength, false); - for (int j = 0; j < directionsCount; j++) { - StringBuilder waypoints = new StringBuilder(); - int start = max(0, j * maximumRouteSegmentLength - 1); - int end = min(positions.size(), (j + 1) * maximumRouteSegmentLength) - 1; - for (int i = start + 1; i < end; i++) { - NavigationPosition position = positions.get(i); - waypoints.append("{location: new google.maps.LatLng(").append(asCoordinates(position)).append(")}"); - if (i < end - 1) - waypoints.append(","); - } - NavigationPosition origin = positions.get(start); - NavigationPosition destination = positions.get(end); - StringBuilder buffer = new StringBuilder(); - buffer.append("renderDirections({origin: new google.maps.LatLng(").append(asCoordinates(origin)).append("),"); - buffer.append("destination: new google.maps.LatLng(").append(asCoordinates(destination)).append("),"); - buffer.append("waypoints: [").append(waypoints).append("],"). - append("travelMode: google.maps.DirectionsTravelMode.").append(mapViewCallback.getTravelMode().getName().toUpperCase()).append(","); - buffer.append("avoidFerries: ").append(mapViewCallback.isAvoidFerries()).append(","); - buffer.append("avoidHighways: ").append(mapViewCallback.isAvoidHighways()).append(","); - buffer.append("avoidTolls: ").append(mapViewCallback.isAvoidTolls()).append(","); - buffer.append("region: \"").append(Locale.getDefault().getCountry().toLowerCase()).append("\"},"); - buffer.append(generationId).append(","); - buffer.append(start).append(","); - int startIndex = positionsModel.getIndex(origin); - buffer.append(startIndex).append(","); - boolean lastSegment = (j == directionsCount - 1); - buffer.append(lastSegment).append(",\"#").append(color).append("\",").append(opacity).append(",").append(width).append(");\n"); - try { - sleep(preferences.getInt("routeSegmentTimeout", 250)); - } catch (InterruptedException e) { - // intentionally left empty - } - executeScript(buffer.toString()); - } - - try { - sleep(preferences.getInt("routeCompleteTimeout", 1000)); - } catch (InterruptedException e) { - // intentionally left empty - } - } - - private void addPolylinesToMap(final List reducedPositions, List allPositions) { - // display markers if there is no polyline to show - if (reducedPositions.size() < 2) { - addMarkersToMap(reducedPositions); - return; - } - - String color = asColor(preferencesModel.getTrackColorModel().getColor()); - float opacity = asOpacity(preferencesModel.getTrackColorModel().getColor()); - int width = preferencesModel.getTrackLineWidthModel().getInteger(); - int maximumPolylineSegmentLength = positionReducer.getMaximumSegmentLength(Track); - int polylinesCount = ceiling(reducedPositions.size(), maximumPolylineSegmentLength, true); - for (int j = 0; j < polylinesCount; j++) { - StringBuilder latlngs = new StringBuilder(); - int minimum = max(0, j * maximumPolylineSegmentLength - 1); - int maximum = min(reducedPositions.size(), (j + 1) * maximumPolylineSegmentLength); - for (int i = minimum; i < maximum; i++) { - NavigationPosition position = reducedPositions.get(i); - latlngs.append("new google.maps.LatLng(").append(asCoordinates(position)).append(")"); - if (i < maximum - 1) - latlngs.append(","); - } - executeScript("addPolyline([" + latlngs + "],\"#" + color + "\"," + opacity + "," + width + ");"); - } - - addWaypointIconsToMap(allPositions); - - removeDirections(); - - mapViewCallback.getDistanceAndTimeAggregator().clearDistancesAndTimes(); - mapViewCallback.getDistanceAndTimeAggregator().addDistancesAndTimes(calculateDistanceAndTime(allPositions)); - } - - private Map calculateDistanceAndTime(List positions) { - Map result = new HashMap<>(); - NavigationPosition previous = null; - for (int i = 0; i < positions.size(); i++) { - NavigationPosition next = positions.get(i); - if (previous != null) { - Double distance = previous.calculateDistance(next); - Long time = previous.calculateTime(next); - result.put(i, new DistanceAndTime(distance, time)); - } - previous = next; - } - return result; - } - - private void addWaypointIconsToMap(List positions) { - if (!isColumbusTrack()) - return; - - List reducedPositions = positionReducer.filterVisiblePositions(positions, getZoom()); - - StringBuilder icons = new StringBuilder(); - for (int i = 0, c = reducedPositions.size(); i < c; i++) { - NavigationPosition position = reducedPositions.get(i); - Wgs84Position wgs84Position = (Wgs84Position) position; - WaypointType waypointType = wgs84Position.getWaypointType(); - if (i == c - 1) - waypointType = End; - if (i == 0) - waypointType = Start; - - if (waypointType != null && waypointType != Waypoint) - icons.append("addWaypointIcon(new google.maps.LatLng(").append(asCoordinates(position)).append("),\""). - append(waypointType).append("\");\n"); - } - executeScript(icons.toString()); - } - - private void addMarkersToMap(List positions) { - int maximumMarkerSegmentLength = positionReducer.getMaximumSegmentLength(Waypoints); - int markersCount = ceiling(positions.size(), maximumMarkerSegmentLength, false); - for (int j = 0; j < markersCount; j++) { - StringBuilder buffer = new StringBuilder(); - int maximum = min(positions.size(), (j + 1) * maximumMarkerSegmentLength); - for (int i = j * maximumMarkerSegmentLength; i < maximum; i++) { - NavigationPosition position = positions.get(i); - buffer.append("addMarker(new google.maps.LatLng(").append(asCoordinates(position)).append("),"). - append("\"").append(escape(position.getDescription())).append("\","). - append(preferencesModel.getShowWaypointDescriptionModel().getBoolean()).append(");\n"); - } - executeScript(buffer.toString()); - } - removeDirections(); - } - - private void setCenterOfMap(List positions, boolean recenter) { - StringBuilder buffer = new StringBuilder(); - - boolean fitBoundsToPositions = !positions.isEmpty() && recenter; - if (fitBoundsToPositions) { - BoundingBox boundingBox = new BoundingBox(positions); - buffer.append("fitBounds(new google.maps.LatLng(").append(asCoordinates(boundingBox.getSouthWest())).append("),"). - append("new google.maps.LatLng(").append(asCoordinates(boundingBox.getNorthEast())).append("));\n"); - ignoreNextZoomCallback = true; - } - - if (haveToInitializeMapOnFirstStart) { - NavigationPosition center; - // if there are positions right at the start center on them else take the last known center and zoom - if (!positions.isEmpty()) { - center = new BoundingBox(positions).getCenter(); - } else { - int zoom = getZoom(); - buffer.append("setZoom(").append(zoom).append(");\n"); - center = getLastMapCenter(); - } - buffer.append("setCenter(new google.maps.LatLng(").append(asCoordinates(center)).append("));\n"); - } - executeScript(buffer.toString()); - haveToInitializeMapOnFirstStart = false; - - if (fitBoundsToPositions) { - // need to update zoom since fitBounds() changes the zoom level without firing a notification - Integer zoom = getCurrentZoom(); - if (zoom != null) - setZoom(zoom); - } - } - - private void selectPositions(List selectedPositions, NavigationPosition center) { - lastSelectedPositions = new ArrayList<>(selectedPositions); - - StringBuilder buffer = new StringBuilder(); - for (int i = 0; i < selectedPositions.size(); i++) { - NavigationPosition selectedPosition = selectedPositions.get(i); - buffer.append("selectPosition(new google.maps.LatLng(").append(asCoordinates(selectedPosition)).append("),"). - append("\"").append(escape(selectedPosition.getDescription())).append("\","). - append(i).append(");\n"); - } - - if (center != null && center.hasCoordinates()) - buffer.append("panTo(new google.maps.LatLng(").append(asCoordinates(center)).append("));\n"); - buffer.append("removeSelectedPositions();"); - executeScript(buffer.toString()); - } - - private final Map insertWaypointsQueue = new LinkedHashMap<>(); - private final ExecutorService insertWaypointsExecutor = createSingleThreadExecutor("InsertWaypoints"); - - private void insertWaypoints(final String mode, int[] startPositions) { - final Map addToQueue = new LinkedHashMap<>(); - Random random = new Random(); - synchronized (notificationMutex) { - @SuppressWarnings("unchecked") - List positions = positionsModel.getRoute().getPositions(); - for (int i = 0; i < startPositions.length; i++) { - // skip the very last position without successor - if (i == positions.size() - 1 || i == startPositions.length - 1) - continue; - addToQueue.put(random.nextInt(), new PositionPair(positions.get(startPositions[i]), positions.get(startPositions[i] + 1))); - } - } - - synchronized (insertWaypointsQueue) { - insertWaypointsQueue.putAll(addToQueue); - } - - insertWaypointsExecutor.execute(new Runnable() { - public void run() { - for (Map.Entry entry : addToQueue.entrySet()) { - NavigationPosition origin = entry.getValue().getFirst(); - NavigationPosition destination = entry.getValue().getSecond(); - executeScript(mode + - "({" + "origin: new google.maps.LatLng(" + asCoordinates(origin) + ")," + - "destination: new google.maps.LatLng(" + asCoordinates(destination) + ")," + - "travelMode: google.maps.DirectionsTravelMode." + mapViewCallback.getTravelMode().getName().toUpperCase() + "," + - "avoidFerries: " + mapViewCallback.isAvoidFerries() + "," + - "avoidHighways: " + mapViewCallback.isAvoidHighways() + "," + - "avoidTolls: " + mapViewCallback.isAvoidTolls() + "," + - "region: \"" + Locale.getDefault().getCountry().toLowerCase() + "\"}," + entry.getKey() + ");\n"); - try { - sleep(preferences.getInt("insertWaypointsSegmentTimeout", 1000)); - } catch (InterruptedException e) { - // intentionally left empty - } - } - } - }); - } - - private void insertWaypointsCallback(Integer key, List parameters) { - PositionPair pair; - synchronized (insertWaypointsQueue) { - pair = insertWaypointsQueue.remove(key); - } - - if (parameters.size() < 5 || pair == null) - return; - - final NavigationPosition before = pair.getFirst(); - NavigationPosition after = pair.getSecond(); - final BaseRoute route = parseRoute(parameters, before, after); - @SuppressWarnings("unchecked") - final List positions = positionsModel.getRoute().getPositions(); - synchronized (notificationMutex) { - int row = positions.indexOf(before) + 1; - insertPositions(row, route); - } - invokeLater(() -> { - int row; - synchronized (notificationMutex) { - row = positions.indexOf(before) + 1; - } - - int[] rows = asRange(row, row + route.getPositions().size() - 1); - if (preferences.getBoolean(COMPLEMENT_DATA_PREFERENCE, false)) - mapViewCallback.complementData(rows, true, true, true, false, false); - }); - } - - // call Google Maps API functions - - @SuppressWarnings("unused") - public void insertAllWaypoints(int[] startPositions) { - insertWaypoints("insertAllWaypoints", startPositions); - } - - @SuppressWarnings("unused") - public void insertOnlyTurnpoints(int[] startPositions) { - insertWaypoints("insertOnlyTurnpoints", startPositions); - } - - // script execution - - private String escape(String string) { - if (string == null) - return ""; - StringBuilder buffer = new StringBuilder(string); - for (int i = 0; i < buffer.length(); i++) { - char c = buffer.charAt(i); - if (!(isLetterOrDigit(c) || isWhitespace(c) || c == '\'' || c == ',')) { - buffer.deleteCharAt(i); - i--; - } - } - return buffer.toString(); - } - - protected void logJavaScript(String script, Object result) { - log.info("Executed '" + script + (result != null ? "'\nwith result '" + result : "") + "'"); - } - - protected abstract void executeScript(String script); - - protected abstract String executeScriptWithResult(String script); - - // browser callbacks - - private void processStream(Socket socket) throws IOException { - List lines = new ArrayList<>(); - try (socket; BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()), 64 * 1024); - OutputStream outputStream = socket.getOutputStream()) { - boolean processingPost = false, processingBody = false; - while (true) { - try { - String line = trim(reader.readLine()); - if (line == null) { - if (processingPost && !processingBody) { - processingBody = true; - continue; - } else - break; - } - if (line.startsWith("POST")) - processingPost = true; - lines.add(line); - } catch (IOException e) { - log.severe("Cannot read line from callback listener port:" + e); - break; - } - } - - StringBuilder buffer = new StringBuilder(); - for (String line : lines) { - buffer.append(" ").append(line).append("\n"); - } - log.fine("Processing callback @" + currentTimeMillis() + " from port " + socket.getPort() + ": \n" + buffer); - - if (!isAuthenticated(lines)) { - writeStatus("401 Unauthorized", outputStream); - return; - } - - if (processLines(lines, socket.getPort())) - writeStatus("200 OK", outputStream); - else - processDownload(lines, outputStream); - } - } - - private static void writeStatus(String status, OutputStream outputStream) throws IOException { - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream)); - writer.write("HTTP/1.1 " + status + "\n"); - writer.write("Content-Type: text/plain\n"); - } - - private boolean isAuthenticated(List lines) { - Map map = asMap(lines); - String host = trim(map.get("Host")); - return host != null && host.equals("127.0.0.1:" + getCallbackPort()); - } - - int getCallbackPort() { - return callbackListenerServerSocket.getLocalPort(); - } - - private static final Pattern NAME_VALUE_PATTERN = Pattern.compile("^(.+?):(.+)$"); - - private Map asMap(List lines) { - Map map = new HashMap<>(); - for (String line : lines) { - Matcher matcher = NAME_VALUE_PATTERN.matcher(line); - if (matcher.matches()) - map.put(matcher.group(1), matcher.group(2)); - } - return map; - } - - private static final Pattern CALLBACK_REQUEST_PATTERN = Pattern.compile("^(GET|OPTIONS|POST) /(\\d+)/(.*) HTTP.+$"); - private int lastCallbackNumber = -1; - - boolean processLines(List lines, int port) { - boolean hasValidCallbackNumber = false; - for (String line : lines) { - Matcher matcher = CALLBACK_REQUEST_PATTERN.matcher(line); - if (matcher.matches()) { - int callbackNumber = parseInt(matcher.group(2)); - if (lastCallbackNumber >= callbackNumber) { - log.info("Ignoring callback number: " + callbackNumber + " last callback number is: " + lastCallbackNumber + " port is: " + port); - return true; - } - lastCallbackNumber = callbackNumber; - hasValidCallbackNumber = true; - - String callback = matcher.group(3); - if (processCallback(callback)) { - log.info("Processed " + matcher.group(1) + " callback " + callback + " with number: " + callbackNumber + " from port: " + port); - return true; - } - } - - // process body of POST requests - if (hasValidCallbackNumber && processCallback(line)) { - log.info("Processed POST callback " + line + " with number: " + lastCallbackNumber + " from port: " + port); - return true; - } - } - return false; - } - - private static final Pattern DOWNLOAD_REQUEST_PATTERN = Pattern.compile("^GET /(.+) HTTP.+$"); - - boolean processDownload(List lines, OutputStream outputStream) throws IOException { - for (String line : lines) { - Matcher matcher = DOWNLOAD_REQUEST_PATTERN.matcher(line); - if (matcher.matches()) { - String uri = matcher.group(1); - - InputStream inputStream = Externalization.class.getClassLoader().getResourceAsStream(RESOURCES_PACKAGE + uri); - if (inputStream == null) { - writeStatus("404 Not Found", outputStream); - return false; - } - - String mimeType = uri.endsWith("css") ? "text/css" : "text/javascript"; - byte[] bytes = InputOutput.readBytes(inputStream); - - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream)); - writer.write("HTTP/1.1 200 OK\n"); - writer.write("Content-Type: " + mimeType + "\n"); - writer.write("Access-Control-Allow-Origin: *\n"); - writer.write("Content-Length: " + bytes.length + "\n"); - writer.write("\n"); - writer.flush(); - - outputStream.write(bytes); - outputStream.flush(); - return true; - } - } - return false; - } - - private static final Pattern ADD_POSITION_PATTERN = Pattern.compile("^add-position/(.*)/(.*)$"); - private static final Pattern ADD_POSITION_AT_PATTERN = Pattern.compile("^add-position-at/(.*)/(.*)/(.*)$"); - private static final Pattern MOVE_POSITION_PATTERN = Pattern.compile("^move-position/(.*)/(.*)/(.*)$"); - private static final Pattern DELETE_POSITION_PATTERN = Pattern.compile("^delete-position/(.*)/(.*)/(.*)$"); - private static final Pattern SELECT_POSITION_PATTERN = Pattern.compile("^select-position/(.*)/(.*)/(.*)/(.*)$"); - private static final Pattern SELECT_POSITIONS_PATTERN = Pattern.compile("^select-positions/(.*)/(.*)/(.*)/(.*)/(.*)"); - private static final Pattern MAP_TYPE_CHANGED_PATTERN = Pattern.compile("^map-type-changed/(.*)$"); - private static final Pattern ZOOM_CHANGED_PATTERN = Pattern.compile("^zoom-changed/(.*)$"); - private static final Pattern CENTER_CHANGED_PATTERN = Pattern.compile("^center-changed/(.*)/(.*)/(.*)/(.*)/(.*)/(.*)$"); - private static final Pattern CALLBACK_PORT_PATTERN = Pattern.compile("^callback-port/(\\d+)$"); - private static final Pattern OVER_QUERY_LIMIT_PATTERN = Pattern.compile("^over-query-limit$"); - private static final Pattern ZERO_RESULTS_PATTERN = Pattern.compile("^zero-results$"); - private static final Pattern INSERT_WAYPOINTS_PATTERN = Pattern.compile("^(Insert-All-Waypoints|Insert-Only-Turnpoints): (-?\\d+)/(.*)$"); - private static final Pattern DIRECTIONS_LOAD_PATTERN = Pattern.compile("^directions-load/(\\d+)/(\\d+)/(.*)$"); - - boolean processCallback(String callback) { - Matcher insertPositionAtMatcher = ADD_POSITION_AT_PATTERN.matcher(callback); - if (insertPositionAtMatcher.matches()) { - final int row = parseInt(insertPositionAtMatcher.group(1)) + 1; - final NavigationPosition position = parsePosition(insertPositionAtMatcher.group(2), insertPositionAtMatcher.group(3)); - invokeLater(new Runnable() { - public void run() { - insertPosition(row, position.getLongitude(), position.getLatitude()); - } - }); - return true; - } - - Matcher insertPositionMatcher = ADD_POSITION_PATTERN.matcher(callback); - if (insertPositionMatcher.matches()) { - final int row = getAddRow(); - final NavigationPosition position = parsePosition(insertPositionMatcher.group(1), insertPositionMatcher.group(2)); - invokeLater(new Runnable() { - public void run() { - insertPosition(row, position.getLongitude(), position.getLatitude()); - } - }); - return true; - } - - Matcher movePositionMatcher = MOVE_POSITION_PATTERN.matcher(callback); - if (movePositionMatcher.matches()) { - final int row = getMoveRow(parseInt(movePositionMatcher.group(1))); - final NavigationPosition position = parsePosition(movePositionMatcher.group(2), movePositionMatcher.group(3)); - invokeLater(new Runnable() { - public void run() { - movePosition(row, position.getLongitude(), position.getLatitude()); - } - }); - return true; - } - - Matcher deletePositionMatcher = DELETE_POSITION_PATTERN.matcher(callback); - if (deletePositionMatcher.matches()) { - final NavigationPosition position = parsePosition(deletePositionMatcher.group(1), deletePositionMatcher.group(2)); - final Double threshold = parseDouble(deletePositionMatcher.group(3)); - invokeLater(new Runnable() { - public void run() { - deletePosition(position.getLongitude(), position.getLatitude(), threshold); - } - }); - return true; - } - - Matcher selectPositionMatcher = SELECT_POSITION_PATTERN.matcher(callback); - if (selectPositionMatcher.matches()) { - final NavigationPosition position = parsePosition(selectPositionMatcher.group(1), selectPositionMatcher.group(2)); - final Double threshold = parseDouble(selectPositionMatcher.group(3)); - final Boolean replaceSelection = parseBoolean(selectPositionMatcher.group(4)); - invokeLater(new Runnable() { - public void run() { - selectPosition(position.getLongitude(), position.getLatitude(), threshold, replaceSelection); - } - }); - return true; - } - - Matcher selectPositionsMatcher = SELECT_POSITIONS_PATTERN.matcher(callback); - if (selectPositionsMatcher.matches()) { - NavigationPosition northEast = parsePosition(selectPositionsMatcher.group(1), selectPositionsMatcher.group(2)); - NavigationPosition southWest = parsePosition(selectPositionsMatcher.group(3), selectPositionsMatcher.group(4)); - final BoundingBox boundingBox = new BoundingBox(northEast, southWest); - final Boolean replaceSelection = parseBoolean(selectPositionsMatcher.group(5)); - invokeLater(new Runnable() { - public void run() { - selectPositions(boundingBox, replaceSelection); - } - }); - return true; - } - - Matcher mapTypeChangedMatcher = MAP_TYPE_CHANGED_PATTERN.matcher(callback); - if (mapTypeChangedMatcher.matches()) { - String mapType = decodeUri(mapTypeChangedMatcher.group(1)); - mapTypeChanged(mapType); - return true; - } - - Matcher zoomChangedMatcher = ZOOM_CHANGED_PATTERN.matcher(callback); - if (zoomChangedMatcher.matches()) { - Integer zoom = parseInteger(zoomChangedMatcher.group(1)); - zoomChanged(zoom); - return true; - } - - Matcher centerChangedMatcher = CENTER_CHANGED_PATTERN.matcher(callback); - if (centerChangedMatcher.matches()) { - NavigationPosition center = parsePosition(centerChangedMatcher.group(1), centerChangedMatcher.group(2)); - NavigationPosition northEast = parsePosition(centerChangedMatcher.group(3), centerChangedMatcher.group(4)); - NavigationPosition southWest = parsePosition(centerChangedMatcher.group(5), centerChangedMatcher.group(6)); - BoundingBox boundingBox = new BoundingBox(northEast, southWest); - centerChanged(center, boundingBox); - return true; - } - - Matcher callbackPortMatcher = CALLBACK_PORT_PATTERN.matcher(callback); - if (callbackPortMatcher.matches()) { - int port = parseInt(callbackPortMatcher.group(1)); - fireReceivedCallback(port); - return true; - } - - Matcher overQueryLimitMatcher = OVER_QUERY_LIMIT_PATTERN.matcher(callback); - if (overQueryLimitMatcher.matches()) { - overQueryLimitCount++; - log.warning("Google Directions API is over query limit, count: " + overQueryLimitCount); - return true; - } - - Matcher zeroResultsMatcher = ZERO_RESULTS_PATTERN.matcher(callback); - if (zeroResultsMatcher.matches()) { - zeroResultsCount++; - log.warning("Google Directions API returns zero results, count: " + zeroResultsCount); - return true; - } - - Matcher directionsLoadMatcher = DIRECTIONS_LOAD_PATTERN.matcher(callback); - if (directionsLoadMatcher.matches()) { - int generation = parseInt(directionsLoadMatcher.group(1)); - if (generation != generationId) { - log.warning("Got directions load from generation id: " + generation + ", current: " + generationId); - } else { - int generationIndex = parseInt(directionsLoadMatcher.group(2)); - List distanceAndTimes = parseDistanceAndTimeParameters(directionsLoadMatcher.group(3)); - directionsLoadCallback(generationIndex, distanceAndTimes); - } - return true; - } - - Matcher insertWaypointsMatcher = INSERT_WAYPOINTS_PATTERN.matcher(callback); - if (insertWaypointsMatcher.matches()) { - Integer key = parseInteger(insertWaypointsMatcher.group(2)); - List parameters = parsePositionParameters(insertWaypointsMatcher.group(3)); - insertWaypointsCallback(key, parameters); - return true; - } - return false; - } - - private void centerChanged(NavigationPosition center, BoundingBox boundingBox) { - preferences.putDouble(CENTER_LATITUDE_PREFERENCE, center.getLatitude()); - preferences.putDouble(CENTER_LONGITUDE_PREFERENCE, center.getLongitude()); - - if (positionReducer.hasFilteredVisibleArea()) { - if (!positionReducer.isWithinVisibleArea(boundingBox)) { - synchronized (notificationMutex) { - haveToRepaintRouteImmediately = true; - routeUpdateReason = "repaint not visible positions"; - positionReducer.clear(); - notificationMutex.notifyAll(); - } - } - } - } - - private void zoomChanged(Integer zoom) { - setZoom(zoom); - synchronized (notificationMutex) { - // since setCenter() leads to a callback and thus paints the track twice - if (ignoreNextZoomCallback) - ignoreNextZoomCallback = false; - else if (// directions are automatically scaled by the Google Maps API when zooming - !positionsModel.getRoute().getCharacteristics().equals(Route) && - (mapViewCallback.isRecenterAfterZooming() || positionReducer.hasFilteredVisibleArea())) { - haveToRepaintRouteImmediately = true; - // if enabled, recenter map to selected positions after zooming - if (mapViewCallback.isRecenterAfterZooming()) - haveToRecenterMap = true; - haveToRepaintSelectionImmediately = true; - selectionUpdateReason = "zoomed from " + lastZoom + " to " + zoom; - lastZoom = zoom; - notificationMutex.notifyAll(); - } - } - } - - private void mapTypeChanged(String mapType) { - preferences.put(MAP_TYPE_PREFERENCE, mapType); - } - - private boolean isDuplicate(NavigationPosition position, NavigationPosition insert) { - if (position == null) - return false; - Double distance = position.calculateDistance(insert); - return toDouble(distance) < 10.0; - } - - private String trimSpaces(String string) { - if ("-".equals(string)) - return null; - return trim(new String(string.getBytes(), StandardCharsets.UTF_8)); - } - - private List parsePositionParameters(String parameters) { - List result = new ArrayList<>(); - StringTokenizer tokenizer = new StringTokenizer(parameters, "/"); - while (tokenizer.hasMoreTokens()) { - String latitude = trim(tokenizer.nextToken()); - if (tokenizer.hasMoreTokens()) { - String longitude = trim(tokenizer.nextToken()); - if (tokenizer.hasMoreTokens()) { - String meters = trim(tokenizer.nextToken()); - if (tokenizer.hasMoreTokens()) { - String seconds = trim(tokenizer.nextToken()); - if (tokenizer.hasMoreTokens()) { - String instructions = trimSpaces(tokenizer.nextToken()); - result.add(latitude); - result.add(longitude); - result.add(meters); - result.add(seconds); - result.add(instructions); - } - } - } - } - } - return result; - } - - private List parseDistanceAndTimeParameters(String parameters) { - List result = new ArrayList<>(); - StringTokenizer tokenizer = new StringTokenizer(parameters, "/"); - while (tokenizer.hasMoreTokens()) { - String distance = trim(tokenizer.nextToken()); - if (tokenizer.hasMoreTokens()) { - String time = trim(tokenizer.nextToken()); - Long timeInSeconds = parseLong(time); - result.add(new DistanceAndTime(parseDouble(distance), timeInSeconds != null ? timeInSeconds * 1000 : null)); - } - } - return result; - } - - private Double parseSeconds(String string) { - Double result = parseDouble(string); - return !isEmpty(result) ? result : null; - } - - @SuppressWarnings("unchecked") - private BaseRoute parseRoute(List parameters, NavigationPosition before, NavigationPosition after) { - BaseRoute route = new NavigatingPoiWarnerFormat().createRoute(Waypoints, null, new ArrayList<>()); - // count backwards as inserting at position 0 - CompactCalendar time = after.getTime(); - for (int i = parameters.size() - 1; i > 0; i -= 5) { - String instructions = trim(parameters.get(i)); - Double seconds = parseSeconds(parameters.get(i - 1)); - // Double meters = parseDouble(parameters.get(i - 2)); - NavigationPosition coordinates = parsePosition(parameters.get(i - 4), parameters.get(i - 3)); - if (seconds != null && time != null) { - Calendar calendar = time.getCalendar(); - calendar.add(SECOND, -seconds.intValue()); - time = fromCalendar(calendar); - } - BaseNavigationPosition position = route.createPosition(coordinates.getLongitude(), coordinates.getLatitude(), null, null, seconds != null ? time : null, instructions); - if (!isDuplicate(before, position) && !isDuplicate(after, position)) { - route.add(0, position); - } - } - return route; - } - - @SuppressWarnings("unchecked") - private void insertPositions(int row, BaseRoute route) { - try { - positionsModel.add(row, route); - } catch (IOException e) { - log.severe("Cannot insert route: " + e); - } - } - - private void insertPosition(int row, Double longitude, Double latitude) { - positionsModel.add(row, longitude, latitude, null, null, null, mapViewCallback.createDescription(positionsModel.getRowCount() + 1, null)); - int[] rows = new int[]{row}; - mapViewCallback.setSelectedPositions(rows, true); - if (preferences.getBoolean(COMPLEMENT_DATA_PREFERENCE, false)) - mapViewCallback.complementData(rows, true, true, true, true, false); - } - - private int getAddRow() { - NavigationPosition position = !lastSelectedPositions.isEmpty() ? lastSelectedPositions.get(lastSelectedPositions.size() - 1) : null; - // quite crude logic to be as robust as possible on failures - if (position == null && positionsModel.getRowCount() > 0) - position = positionsModel.getPosition(positionsModel.getRowCount() - 1); - return position != null ? positionsModel.getIndex(position) + 1 : 0; - } - - private int getMoveRow(int index) { - NavigationPosition position = lastSelectedPositions.get(index); - final int row; - synchronized (notificationMutex) { - row = positionsModel.getRoute().getPositions().indexOf(position); - } - return row; - } - - private void movePosition(int row, Double longitude, Double latitude) { - NavigationPosition reference = positionsModel.getPosition(row); - Double diffLongitude = reference != null ? longitude - reference.getLongitude() : 0.0; - Double diffLatitude = reference != null ? latitude - reference.getLatitude() : 0.0; - - boolean moveCompleteSelection = preferences.getBoolean(MOVE_COMPLETE_SELECTION_PREFERENCE, true); - boolean cleanElevation = preferences.getBoolean(CLEAN_ELEVATION_ON_MOVE_PREFERENCE, false); - boolean complementElevation = preferences.getBoolean(COMPLEMENT_ELEVATION_ON_MOVE_PREFERENCE, true); - boolean cleanTime = preferences.getBoolean(CLEAN_TIME_ON_MOVE_PREFERENCE, false); - boolean complementTime = preferences.getBoolean(COMPLEMENT_TIME_ON_MOVE_PREFERENCE, true); - - int minimum = row; - for (int index : selectedPositionIndices) { - if (index < minimum) - minimum = index; - - NavigationPosition position = positionsModel.getPosition(index); - if (position == null) - continue; - - if (index != row) { - if (!moveCompleteSelection) - continue; - - positionsModel.edit(index, new PositionColumnValues(asList(LONGITUDE_COLUMN_INDEX, LATITUDE_COLUMN_INDEX), - Arrays.asList(position.getLongitude() + diffLongitude, position.getLatitude() + diffLatitude)), false, true); - } else { - positionsModel.edit(index, new PositionColumnValues(asList(LONGITUDE_COLUMN_INDEX, LATITUDE_COLUMN_INDEX), - Arrays.asList(longitude, latitude)), false, true); - } - - if (cleanTime) - positionsModel.edit(index, new PositionColumnValues(DATE_TIME_COLUMN_INDEX, null), false, false); - if (cleanElevation) - positionsModel.edit(index, new PositionColumnValues(ELEVATION_COLUMN_INDEX, null), false, false); - - if (preferences.getBoolean(COMPLEMENT_DATA_PREFERENCE, false) && (complementTime || complementElevation)) - mapViewCallback.complementData(new int[]{index}, false, complementTime, complementElevation, true, false); - } - - // updating all rows behind the modified is quite expensive, but necessary due to the distance - // calculation - if that didn't exist the single update of row would be sufficient - int size; - synchronized (notificationMutex) { - size = positionsModel.getRoute().getPositions().size() - 1; - haveToRepaintRouteImmediately = true; - routeUpdateReason = "move position"; - positionReducer.clear(); - haveToRepaintSelectionImmediately = true; - selectionUpdateReason = "move position"; - } - positionsModel.fireTableRowsUpdated(minimum, size, ALL_COLUMNS); - - invokeLater(() -> setSelectedPositions(selectedPositionIndices, true)); - } - - private void selectPosition(Double longitude, Double latitude, Double threshold, boolean replaceSelection) { - int row = positionsModel.getClosestPosition(longitude, latitude, threshold); - if (row != -1) - mapViewCallback.setSelectedPositions(new int[]{row}, replaceSelection); - } - - private void selectPositions(BoundingBox boundingBox, boolean replaceSelection) { - int[] rows = positionsModel.getContainedPositions(boundingBox); - if (rows.length > 0) { - mapViewCallback.setSelectedPositions(rows, replaceSelection); - } - } - - private void deletePosition(Double longitude, Double latitude, Double threshold) { - int row = positionsModel.getClosestPosition(longitude, latitude, threshold); - if (row != -1) { - positionsModel.remove(new int[]{row}); - - executor.execute(new Runnable() { - public void run() { - synchronized (notificationMutex) { - haveToRepaintRouteImmediately = true; - routeUpdateReason = "delete position"; - notificationMutex.notifyAll(); - } - } - }); - } - } - - private int generationId; - private final List directionsPositions = new ArrayList<>(); - - private void resetDirections() { - directionsPositions.clear(); - mapViewCallback.getDistanceAndTimeAggregator().clearDistancesAndTimes(); - } - - private void directionsLoadCallback(final int generationIndex, final List distanceAndTimes) { - executor.execute(new Runnable() { - public void run() { - Map result = new HashMap<>(); - for (int i = 0; i < distanceAndTimes.size(); i++) { - // find successor of start position from directions for first DistanceAndTime - NavigationPosition position = directionsPositions.get(generationIndex + i + 1); - int index = positionsModel.getIndex(position); - result.put(index, distanceAndTimes.get(i)); - } - mapViewCallback.getDistanceAndTimeAggregator().updateDistancesAndTimes(result); - } - }); - } - - // listeners - - private class PositionsModelListener implements TableModelListener { - public void tableChanged(TableModelEvent e) { - boolean insertOrDelete = e.getType() == INSERT || e.getType() == DELETE; - boolean allRowsChanged = isFirstToLastRow(e); - // used to be limited to single rows which did work reliably but with usability problems - // if (e.getFirstRow() == e.getLastRow() && insertOrDelete) - if (!allRowsChanged && insertOrDelete) - updateRouteButDontRecenter(); - else { - // ignored updates on columns not displayed - if (e.getType() == UPDATE && - !(e.getColumn() == DESCRIPTION_COLUMN_INDEX || - e.getColumn() == LONGITUDE_COLUMN_INDEX || - e.getColumn() == LATITUDE_COLUMN_INDEX || - e.getColumn() == ALL_COLUMNS)) - return; - - if (mapViewCallback.isShowAllPositionsAfterLoading()) - update(allRowsChanged, true); - else - updateRouteButDontRecenter(); - } - - // update position marker on updates of longitude and latitude - if (e.getType() == UPDATE && - (e.getColumn() == LONGITUDE_COLUMN_INDEX || - e.getColumn() == LATITUDE_COLUMN_INDEX || - e.getColumn() == DESCRIPTION_COLUMN_INDEX || - e.getColumn() == ALL_COLUMNS)) { - for (int selectedPositionIndex : selectedPositionIndices) { - if (selectedPositionIndex >= e.getFirstRow() && selectedPositionIndex <= e.getLastRow()) { - updateSelection(); - break; - } - } - } - } - } - - private class CharacteristicsModelListener implements ListDataListener { - public void intervalAdded(ListDataEvent e) { - } - - public void intervalRemoved(ListDataEvent e) { - } - - public void contentsChanged(ListDataEvent e) { - // ignore events following setRoute() - if (isIgnoreEvent(e)) - return; - updateRouteButDontRecenter(); - } - } - - private class ShowCoordinatesListener implements ChangeListener { - public void stateChanged(ChangeEvent e) { - setShowCoordinates(); - } - } - - private class ShowWaypointDescriptionListener implements ChangeListener { - public void stateChanged(ChangeEvent e) { - if (positionsModel.getRoute().getCharacteristics().equals(Waypoints)) - update(false, false); - } - } - - private class RepaintPositionListListener implements ChangeListener { - public void stateChanged(ChangeEvent e) { - update(true, false); - } - } - - private class RoutingPreferencesListener implements ChangeListener { - public void stateChanged(ChangeEvent e) { - if (positionsModel.getRoute().getCharacteristics().equals(Route)) - update(false, false); - } - } - - private class GoogleMapsServerListener implements ChangeListener { - public void stateChanged(ChangeEvent e) { - initializeWebPage(); - } - } - - private class UnitSystemListener implements ChangeListener { - public void stateChanged(ChangeEvent e) { - setDegreeFormat(); - } - } - - - private final EventListenerList listenerList = new EventListenerList(); - - private void fireReceivedCallback(int port) { - Object[] listeners = listenerList.getListenerList(); - for (int i = listeners.length - 2; i >= 0; i -= 2) { - if (listeners[i] == MapViewListener.class) { - ((MapViewListener) listeners[i + 1]).receivedCallback(port); - } - } - } - - private void addMapViewListener(MapViewListener l) { - listenerList.add(MapViewListener.class, l); - } - - private void removeMapViewListener(MapViewListener l) { - listenerList.remove(MapViewListener.class, l); - } - -} diff --git a/browser-mapview/src/main/java/slash/navigation/mapview/browser/MapViewCallbackGoogle.java b/browser-mapview/src/main/java/slash/navigation/mapview/browser/MapViewCallbackGoogle.java deleted file mode 100644 index aa1676d92..000000000 --- a/browser-mapview/src/main/java/slash/navigation/mapview/browser/MapViewCallbackGoogle.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - This file is part of RouteConverter. - - RouteConverter is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - RouteConverter is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with RouteConverter; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright (C) 2007 Christian Pesch. All Rights Reserved. -*/ - -package slash.navigation.mapview.browser; - -import slash.navigation.converter.gui.models.GoogleMapsServerModel; -import slash.navigation.mapview.MapViewCallback; - -/** - * Interface for callbacks from the {@link BrowserMapView} to the RouteConverterGoogle services. - * - * @author Christian Pesch - */ - -public interface MapViewCallbackGoogle extends MapViewCallback { - GoogleMapsServerModel getGoogleMapsServerModel(); -} diff --git a/feedback/src/test/java/slash/navigation/feedback/domain/RouteFeedbackServiceBase.java b/feedback/src/test/java/slash/navigation/feedback/domain/RouteFeedbackServiceBase.java index 744269d0a..ec7d38b5e 100644 --- a/feedback/src/test/java/slash/navigation/feedback/domain/RouteFeedbackServiceBase.java +++ b/feedback/src/test/java/slash/navigation/feedback/domain/RouteFeedbackServiceBase.java @@ -25,7 +25,7 @@ public abstract class RouteFeedbackServiceBase { protected static final String API = System.getProperty("api", "http://localhost:8000/"); protected static final String USERNAME = "test"; - protected static final char[] PASSWORD = "test".toCharArray(); + protected static final char[] PASSWORD = System.getProperty("password", "test").toCharArray(); protected static final char[] WRONG_PASSWORD = "wrong-password".toCharArray(); protected RouteFeedback routeFeedback; diff --git a/geonames/src/test/java/slash/navigation/geonames/GeoNamesServiceIT.java b/geonames/src/test/java/slash/navigation/geonames/GeoNamesServiceIT.java index f8b517d3b..ff1e21b7b 100644 --- a/geonames/src/test/java/slash/navigation/geonames/GeoNamesServiceIT.java +++ b/geonames/src/test/java/slash/navigation/geonames/GeoNamesServiceIT.java @@ -73,7 +73,7 @@ public void testSrtm3ElevationFor() throws IOException { assertEquals(190, service.getSRTM3ElevationFor(11.2, 60.0), 5); assertNull(service.getSRTM3ElevationFor(11.2, 61.0)); - assertEquals(455, service.getSRTM3ElevationFor(-68.0, -55.0), 5); + assertNull(service.getSRTM3ElevationFor(-68.0, -55.0)); assertNull(service.getSRTM3ElevationFor(-68.0, -56.0)); assertNull(service.getSRTM3ElevationFor(-68.0, -56.1)); assertNull(service.getSRTM3ElevationFor(-68.0, -57.0)); diff --git a/graphhopper/src/main/java/slash/navigation/graphhopper/GraphHopper.java b/graphhopper/src/main/java/slash/navigation/graphhopper/GraphHopper.java index 8a6fa292a..03eeb826d 100644 --- a/graphhopper/src/main/java/slash/navigation/graphhopper/GraphHopper.java +++ b/graphhopper/src/main/java/slash/navigation/graphhopper/GraphHopper.java @@ -23,8 +23,10 @@ import com.graphhopper.GHResponse; import com.graphhopper.ResponsePath; import com.graphhopper.config.Profile; +import com.graphhopper.json.Statement; +import com.graphhopper.util.CustomModel; import com.graphhopper.util.PointList; -import com.graphhopper.util.exceptions.PointNotFoundException; +import com.graphhopper.util.exceptions.DetailedIllegalArgumentException; import com.graphhopper.util.shapes.GHPoint3D; import slash.common.io.Files; import slash.navigation.common.*; @@ -43,6 +45,7 @@ import java.util.logging.Logger; import java.util.prefs.Preferences; +import static com.graphhopper.json.Statement.Op.MULTIPLY; import static java.lang.String.format; import static java.lang.System.currentTimeMillis; import static java.util.Arrays.asList; @@ -97,22 +100,6 @@ public boolean isDownload() { return true; } - public boolean isSupportTurnpoints() { - return false; - } - - public boolean isSupportAvoidFerries() { - return false; - } - - public boolean isSupportAvoidHighways() { - return false; - } - - public boolean isSupportAvoidTolls() { - return false; - } - public List getAvailableTravelModes() { return TRAVEL_MODES; } @@ -121,6 +108,10 @@ public TravelMode getPreferredTravelMode() { return CAR; } + public TravelRestrictions getAvailableTravelRestrictions() { + return new TravelRestrictions(true, true, true, false, true); + } + public String getPath() { return graphManager != null ? graphManager.getPath() : ""; } @@ -150,7 +141,7 @@ private java.io.File createDirectory(Downloadable downloadable) { return ensureDirectory(new java.io.File(getDirectory(downloadable.getDataSource()), removeExtension(downloadable.getUri())).getParentFile()); } - public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode) { + public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode, TravelRestrictions travelRestrictions) { initializeHopper(); if (hopper == null) throw new IllegalStateException("Could not initialize from graph directory of GraphHopper"); @@ -166,12 +157,24 @@ protected void second(int second) { try { GHRequest request = new GHRequest(from.getLatitude(), from.getLongitude(), to.getLatitude(), to.getLongitude()); request.setProfile(travelMode.getName()); + CustomModel customModel = new CustomModel(); + if (travelRestrictions.isAvoidBridges()) + customModel.addToPriority(Statement.If("road_environment == BRIDGE", MULTIPLY, "0")); + if (travelRestrictions.isAvoidFerries()) + customModel.addToPriority(Statement.If("road_environment == FERRY", MULTIPLY, "0")); + if (travelRestrictions.isAvoidMotorways()) + customModel.addToPriority(Statement.If("road_class == MOTORWAY", MULTIPLY, "0")); + // if (travelRestrictions.isAvoidToll()) + // customModel.addToPriority(Statement.If("toll == all", MULTIPLY, "0")); + if (travelRestrictions.isAvoidTunnels()) + customModel.addToPriority(Statement.If("road_environment == TUNNEL", MULTIPLY, "0")); + request.setCustomModel(customModel); GHResponse response = hopper.route(request); if (response.hasErrors()) { String errors = asDialogString(response.getErrors(), false); log.severe(format("Error while routing between %s and %s: %s", from, to, errors)); - boolean pointNotFound = !response.getErrors().isEmpty() && response.getErrors().get(0) instanceof PointNotFoundException; + boolean pointNotFound = !response.getErrors().isEmpty() && response.getErrors().get(0) instanceof DetailedIllegalArgumentException; if (pointNotFound) return new RoutingResult(null, null, PointNotFound); @@ -261,7 +264,7 @@ protected void second(int second) { private com.graphhopper.GraphHopper createHopper() { List profiles = getAvailableTravelModes().stream() .map(mode -> new Profile(mode.getName()) - .setVehicle(mode.getName()) + .setVehicle(mode.getName()) // could set .setTurnCosts(true) ) .toList(); @@ -276,8 +279,7 @@ private com.graphhopper.GraphHopper loadHopper(File graphDirectory) { try { if (result.load()) return result; - } - catch (IllegalStateException e) { + } catch (IllegalStateException e) { log.warning(format("GraphHopper couldn't read %s: %s. Deleting then reimporting.", graphDirectory, e.getLocalizedMessage())); try { @@ -316,9 +318,11 @@ public DownloadFuture downloadRoutingDataFor(String mapIdentifier, List longitudeAndLat private void downloadAndWait(GraphDescriptor graphDescriptor) { Downloadable downloadable = graphDescriptor.getRemoteFile(); - if(downloadable != null) { + if (downloadable != null) { Download download = download(downloadable); downloadManager.waitForCompletion(singletonList(download)); } @@ -405,7 +409,7 @@ private void downloadAndWait(GraphDescriptor graphDescriptor) { private void download(GraphDescriptor graphDescriptor) { Downloadable downloadable = graphDescriptor.getRemoteFile(); - if(downloadable != null) { + if (downloadable != null) { download(downloadable); } } @@ -424,7 +428,7 @@ public long calculateRemainingDownloadSize(List mapDescriptors) { long notExists = 0L; for (GraphDescriptor graphDescriptor : graphDescriptors) { Downloadable downloadable = graphDescriptor.getRemoteFile(); - if(downloadable == null) + if (downloadable == null) continue; Long contentLength = downloadable.getLatestChecksum() != null ? downloadable.getLatestChecksum().getContentLength() : null; diff --git a/graphhopper/src/test/java/slash/navigation/graphhopper/GraphHopperIT.java b/graphhopper/src/test/java/slash/navigation/graphhopper/GraphHopperIT.java index 84171f252..904416940 100644 --- a/graphhopper/src/test/java/slash/navigation/graphhopper/GraphHopperIT.java +++ b/graphhopper/src/test/java/slash/navigation/graphhopper/GraphHopperIT.java @@ -44,6 +44,7 @@ import static org.mockito.Mockito.when; import static slash.common.io.Directories.getApplicationDirectory; import static slash.navigation.routing.RoutingResult.Validity.Valid; +import static slash.navigation.routing.TravelRestrictions.NO_RESTRICTIONS; public class GraphHopperIT { private static final NavigationPosition FROM = new SimpleNavigationPosition(10.18587, 53.40451); @@ -89,7 +90,7 @@ private TravelMode getTravelMode(String lookupName) { @Test public void testGetRouteBetweenByCar() { - RoutingResult result = hopper.getRouteBetween(FROM, TO, getTravelMode("car")); + RoutingResult result = hopper.getRouteBetween(FROM, TO, getTravelMode("car"), NO_RESTRICTIONS); assertEquals(Valid, result.getValidity()); assertEquals(134, result.getPositions().size(), 10); assertEquals(13605.6, result.getDistanceAndTime().getDistance(), 25.0); @@ -98,7 +99,7 @@ public void testGetRouteBetweenByCar() { @Test public void testGetRouteBetweenByBike() { - RoutingResult result = hopper.getRouteBetween(FROM, TO, getTravelMode("bike")); + RoutingResult result = hopper.getRouteBetween(FROM, TO, getTravelMode("bike"), NO_RESTRICTIONS); assertEquals(Valid, result.getValidity()); assertEquals(90, result.getPositions().size(), 10); assertEquals(13658.8, result.getDistanceAndTime().getDistance(), 25.0); diff --git a/mapsforge-mapview/src/main/java/slash/navigation/mapview/mapsforge/renderer/RouteRenderer.java b/mapsforge-mapview/src/main/java/slash/navigation/mapview/mapsforge/renderer/RouteRenderer.java index f9890be51..c433aa146 100644 --- a/mapsforge-mapview/src/main/java/slash/navigation/mapview/mapsforge/renderer/RouteRenderer.java +++ b/mapsforge-mapview/src/main/java/slash/navigation/mapview/mapsforge/renderer/RouteRenderer.java @@ -267,7 +267,7 @@ private RoutingResult calculateResult(RoutingService routingService, DownloadFut } try { - result = routingService.getRouteBetween(pairWithLayer.getFirst(), pairWithLayer.getSecond(), mapViewCallback.getTravelMode()); + result = routingService.getRouteBetween(pairWithLayer.getFirst(), pairWithLayer.getSecond(), mapViewCallback.getTravelMode(), mapViewCallback.getTravelRestrictions()); if (result.getValidity().equals(PointNotFound)) { // special treatment for GraphHopper: try the next download diff --git a/mapview/src/main/java/slash/navigation/mapview/MapViewCallback.java b/mapview/src/main/java/slash/navigation/mapview/MapViewCallback.java index 1bf547936..3acff4977 100644 --- a/mapview/src/main/java/slash/navigation/mapview/MapViewCallback.java +++ b/mapview/src/main/java/slash/navigation/mapview/MapViewCallback.java @@ -24,6 +24,7 @@ import slash.navigation.maps.tileserver.TileServerMapManager; import slash.navigation.routing.RoutingService; import slash.navigation.routing.TravelMode; +import slash.navigation.routing.TravelRestrictions; /** * Interface for callbacks from the {@link MapView} to the other RouteConverter services. @@ -40,9 +41,7 @@ public interface MapViewCallback { RoutingService getRoutingService(); TravelMode getTravelMode(); - boolean isAvoidFerries(); - boolean isAvoidHighways(); - boolean isAvoidTolls(); + TravelRestrictions getTravelRestrictions(); boolean isShowAllPositionsAfterLoading(); boolean isRecenterAfterZooming(); diff --git a/rest/src/main/java/slash/navigation/rest/HttpRequest.java b/rest/src/main/java/slash/navigation/rest/HttpRequest.java index 075303c69..757c0334d 100644 --- a/rest/src/main/java/slash/navigation/rest/HttpRequest.java +++ b/rest/src/main/java/slash/navigation/rest/HttpRequest.java @@ -64,7 +64,7 @@ public abstract class HttpRequest { private final HttpClientBuilder clientBuilder = HttpClientBuilder.create(); private final HttpUriRequestBase method; private ClassicHttpResponse response; - private HttpClientContext context; + private HttpClientContext context = HttpClientContext.create(); private final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); HttpRequest(HttpUriRequestBase method) { @@ -87,14 +87,13 @@ HttpUriRequestBase getMethod() { } private void setAuthentication(String userName, char[] password, URI uri) { - HttpHost httpHost = new HttpHost( uri.getScheme(), uri.getHost(), uri.getPort()); + HttpHost httpHost = new HttpHost(uri.getScheme(), uri.getHost(), uri.getPort()); AuthScope authScope = new AuthScope(httpHost, "api", null); BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(authScope, new UsernamePasswordCredentials(userName, password)); AuthCache authCache = new BasicAuthCache(); BasicScheme basicAuth = new BasicScheme(); authCache.put(httpHost, basicAuth); - context = HttpClientContext.create(); context.setAuthCache(authCache); context.setCredentialsProvider(credentialsProvider); } diff --git a/route-converter-build/buildNumber.properties b/route-converter-build/buildNumber.properties index 3f348bdc8..ff2189f05 100644 --- a/route-converter-build/buildNumber.properties +++ b/route-converter-build/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Tue Jan 23 18:07:06 CET 2024 -buildNumber0=380 +#Thu Jan 25 16:01:46 CET 2024 +buildNumber0=383 diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.form b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.form index b8db77e67..0cdda7278 100644 --- a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.form +++ b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.form @@ -3,7 +3,7 @@ - + @@ -86,7 +86,7 @@ - + @@ -94,30 +94,22 @@ - + - + - - - - - + + - + - + - - - - - - + diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.java b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.java index a9a43e500..ec63068a5 100644 --- a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.java +++ b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/InsertPositionsDialog.java @@ -31,8 +31,6 @@ import slash.navigation.gui.actions.DialogAction; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; @@ -58,7 +56,6 @@ public class InsertPositionsDialog extends SimpleDialog { private JButton buttonSelectAll; private JButton buttonClearSelection; private JButton buttonInsertAllWaypoints; - private JButton buttonInsertOnlyTurnpoints; public InsertPositionsDialog() { super(RouteConverter.getInstance().getFrame(), "insert-positions"); @@ -88,13 +85,6 @@ public void run() { } }); - setMnemonic(buttonInsertOnlyTurnpoints, "insert-only-turnpoints-mnemonic"); - buttonInsertOnlyTurnpoints.addActionListener(new DialogAction(this) { - public void run() { - insertOnlyTurnpoints(); - } - }); - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { @@ -133,7 +123,6 @@ private void handlePositionsUpdate() { boolean existsSelectedPosition = selectedRowCount > 0; buttonInsertAllWaypoints.setEnabled(existsSelectedPosition); - buttonInsertOnlyTurnpoints.setEnabled(existsSelectedPosition && r.getRoutingServiceFacade().getRoutingPreferencesModel().getRoutingService().isSupportTurnpoints()); buttonClearSelection.setEnabled(existsSelectedPosition); boolean notAllPositionsSelected = r.getConvertPanel().getPositionsView().getRowCount() > selectedRowCount; @@ -156,10 +145,6 @@ private void insertAllWaypoints() { RouteConverter.getInstance().getInsertPositionFacade().insertAllWaypoints(); } - private void insertOnlyTurnpoints() { - RouteConverter.getInstance().getInsertPositionFacade().insertOnlyTurnpoints(); - } - private void close() { dispose(); } @@ -208,19 +193,16 @@ private void close() { panel4.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1)); panel1.add(panel4, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, new Dimension(-1, 10), null, null, 0, false)); final JPanel panel5 = new JPanel(); - panel5.setLayout(new GridLayoutManager(2, 3, new Insets(0, 0, 0, 0), -1, -1)); + panel5.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), -1, -1)); panel1.add(panel5, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + final Spacer spacer2 = new Spacer(); + panel5.add(spacer2, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); buttonInsertAllWaypoints = new JButton(); this.$$$loadButtonText$$$(buttonInsertAllWaypoints, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "insert-all-waypoints")); - panel5.add(buttonInsertAllWaypoints, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - buttonInsertOnlyTurnpoints = new JButton(); - this.$$$loadButtonText$$$(buttonInsertOnlyTurnpoints, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "insert-only-turnpoints")); - panel5.add(buttonInsertOnlyTurnpoints, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final Spacer spacer2 = new Spacer(); - panel5.add(spacer2, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); + panel5.add(buttonInsertAllWaypoints, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label2 = new JLabel(); this.$$$loadLabelText$$$(label2, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "insert-positions")); - panel5.add(label2, new GridConstraints(0, 0, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel5.add(label2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); } private static Method $$$cachedGetBundleMethod$$$ = null; diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.form b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.form index 0d69569c6..76040e5aa 100644 --- a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.form +++ b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.form @@ -785,7 +785,7 @@ - + @@ -823,21 +823,21 @@ - + - + - + - + - + @@ -845,33 +845,61 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.java b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.java index 9b88ac31b..2c7ec5cbf 100644 --- a/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.java +++ b/route-converter/src/main/java/slash/navigation/converter/gui/dialogs/OptionsDialog.java @@ -108,9 +108,11 @@ public class OptionsDialog extends SimpleDialog { private JTextField textFieldBabelPath; private JButton buttonChooseBabelPath; private JCheckBox checkBoxAutomaticUpdateCheck; + private JCheckBox checkBoxAvoidBridges; private JCheckBox checkBoxAvoidFerries; - private JCheckBox checkBoxAvoidHighways; + private JCheckBox checkBoxAvoidMotorways; private JCheckBox checkBoxAvoidTolls; + private JCheckBox checkBoxAvoidTunnels; private JCheckBox checkBoxShowAllPositionsAfterLoading; private JCheckBox checkBoxRecenterAfterZooming; private JCheckBox checkBoxShowCoordinates; @@ -143,6 +145,7 @@ public class OptionsDialog extends SimpleDialog { private JLabel labelThunderforestApiKey; private JLabel labelGeonamesUserName; + public OptionsDialog() { super(RouteConverter.getInstance().getFrame(), "options"); setTitle(getBundle().getString("options-title")); @@ -420,30 +423,18 @@ public void run() { handleRoutingServiceUpdate(); comboboxTravelMode.setRenderer(new TravelModeListCellRenderer()); - comboboxTravelMode.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() != SELECTED) { - return; - } - TravelMode travelMode = (TravelMode) e.getItem(); - r.getRoutingServiceFacade().getRoutingPreferencesModel().setTravelMode(travelMode); - } - }); - checkBoxAvoidFerries.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidFerries(checkBoxAvoidFerries.isSelected()); - } - }); - checkBoxAvoidHighways.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidHighways(checkBoxAvoidHighways.isSelected()); - } - }); - checkBoxAvoidTolls.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidTolls(checkBoxAvoidTolls.isSelected()); + comboboxTravelMode.addItemListener(e -> { + if (e.getStateChange() != SELECTED) { + return; } + TravelMode travelMode = (TravelMode) e.getItem(); + r.getRoutingServiceFacade().getRoutingPreferencesModel().setTravelMode(travelMode); }); + checkBoxAvoidBridges.addItemListener(e -> r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidBridges(checkBoxAvoidBridges.isSelected())); + checkBoxAvoidFerries.addItemListener(e -> r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidFerries(checkBoxAvoidFerries.isSelected())); + checkBoxAvoidMotorways.addItemListener(e -> r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidMotorways(checkBoxAvoidMotorways.isSelected())); + checkBoxAvoidTolls.addItemListener(e -> r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidTolls(checkBoxAvoidTolls.isSelected())); + checkBoxAvoidTunnels.addItemListener(e -> r.getRoutingServiceFacade().getRoutingPreferencesModel().setAvoidTunnels(checkBoxAvoidTunnels.isSelected())); ComboBoxModel numberPatternModel = new DefaultComboBoxModel<>(new NumberPattern[]{ Description_Only, Number_Only, Number_Directly_Followed_By_Description, Number_Space_Then_Description @@ -674,12 +665,16 @@ private void handleRoutingServiceUpdate() { textFieldRoutingServicePath.setEnabled(service.isDownload()); textFieldRoutingServicePath.setText(service.isDownload() ? service.getPath() : ""); buttonChooseRoutingServicePath.setEnabled(service.isDownload()); - checkBoxAvoidFerries.setEnabled(service.isSupportAvoidFerries()); - checkBoxAvoidFerries.setSelected(preferences.isAvoidFerries()); - checkBoxAvoidHighways.setEnabled(service.isSupportAvoidHighways()); - checkBoxAvoidHighways.setSelected(preferences.isAvoidHighways()); - checkBoxAvoidTolls.setEnabled(service.isSupportAvoidTolls()); - checkBoxAvoidTolls.setSelected(preferences.isAvoidTolls()); + checkBoxAvoidBridges.setEnabled(service.getAvailableTravelRestrictions().isAvoidBridges()); + checkBoxAvoidBridges.setSelected(preferences.getTravelRestrictions().isAvoidBridges()); + checkBoxAvoidFerries.setEnabled(service.getAvailableTravelRestrictions().isAvoidFerries()); + checkBoxAvoidFerries.setSelected(preferences.getTravelRestrictions().isAvoidFerries()); + checkBoxAvoidMotorways.setEnabled(service.getAvailableTravelRestrictions().isAvoidMotorways()); + checkBoxAvoidMotorways.setSelected(preferences.getTravelRestrictions().isAvoidMotorways()); + checkBoxAvoidTolls.setEnabled(service.getAvailableTravelRestrictions().isAvoidTolls()); + checkBoxAvoidTolls.setSelected(preferences.getTravelRestrictions().isAvoidTolls()); + checkBoxAvoidTunnels.setEnabled(service.getAvailableTravelRestrictions().isAvoidTunnels()); + checkBoxAvoidTunnels.setSelected(preferences.getTravelRestrictions().isAvoidTunnels()); updateTravelModes(); } @@ -1095,7 +1090,7 @@ private void close() { final Spacer spacer9 = new Spacer(); panel21.add(spacer9, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); final JPanel panel24 = new JPanel(); - panel24.setLayout(new GridLayoutManager(7, 2, new Insets(3, 3, 3, 3), -1, -1)); + panel24.setLayout(new GridLayoutManager(9, 2, new Insets(3, 3, 3, 3), -1, -1)); panel21.add(panel24, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); final JLabel label32 = new JLabel(); this.$$$loadLabelText$$$(label32, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "routing-options")); @@ -1108,42 +1103,52 @@ private void close() { comboboxTravelMode = new JComboBox(); panel24.add(comboboxTravelMode, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label34 = new JLabel(); - this.$$$loadLabelText$$$(label34, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-highways")); - panel24.add(label34, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - checkBoxAvoidHighways = new JCheckBox(); - panel24.add(checkBoxAvoidHighways, new GridConstraints(4, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + this.$$$loadLabelText$$$(label34, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-motorways")); + panel24.add(label34, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + checkBoxAvoidMotorways = new JCheckBox(); + panel24.add(checkBoxAvoidMotorways, new GridConstraints(5, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label35 = new JLabel(); this.$$$loadLabelText$$$(label35, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-tolls")); - panel24.add(label35, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel24.add(label35, new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); checkBoxAvoidTolls = new JCheckBox(); - panel24.add(checkBoxAvoidTolls, new GridConstraints(5, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel24.add(checkBoxAvoidTolls, new GridConstraints(6, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel25 = new JPanel(); panel25.setLayout(new GridLayoutManager(1, 1, new Insets(6, 0, 0, 0), -1, -1)); - panel24.add(panel25, new GridConstraints(6, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + panel24.add(panel25, new GridConstraints(8, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); final JLabel label36 = new JLabel(); - this.$$$loadLabelText$$$(label36, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-ferries")); - panel24.add(label36, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + this.$$$loadLabelText$$$(label36, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-tunnels")); + panel24.add(label36, new GridConstraints(7, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + checkBoxAvoidTunnels = new JCheckBox(); + panel24.add(checkBoxAvoidTunnels, new GridConstraints(7, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label37 = new JLabel(); + this.$$$loadLabelText$$$(label37, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-ferries")); + panel24.add(label37, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label38 = new JLabel(); + this.$$$loadLabelText$$$(label38, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "avoid-bridges")); + panel24.add(label38, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + checkBoxAvoidBridges = new JCheckBox(); + panel24.add(checkBoxAvoidBridges, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); checkBoxAvoidFerries = new JCheckBox(); - panel24.add(checkBoxAvoidFerries, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel24.add(checkBoxAvoidFerries, new GridConstraints(4, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel26 = new JPanel(); panel26.setLayout(new GridLayoutManager(5, 1, new Insets(5, 0, 0, 0), -1, -1)); tabbedPane1.addTab(this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "paths-services-options-tab"), panel26); final JPanel panel27 = new JPanel(); panel27.setLayout(new GridLayoutManager(5, 3, new Insets(3, 3, 3, 3), -1, -1)); panel26.add(panel27, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - final JLabel label37 = new JLabel(); - this.$$$loadLabelText$$$(label37, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "elevation-options")); - panel27.add(label37, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label39 = new JLabel(); + this.$$$loadLabelText$$$(label39, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "elevation-options")); + panel27.add(label39, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JSeparator separator9 = new JSeparator(); panel27.add(separator9, new GridConstraints(1, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - final JLabel label38 = new JLabel(); - this.$$$loadLabelText$$$(label38, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "elevation-service")); - panel27.add(label38, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label40 = new JLabel(); + this.$$$loadLabelText$$$(label40, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "elevation-service")); + panel27.add(label40, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); comboBoxElevationService = new JComboBox(); panel27.add(comboBoxElevationService, new GridConstraints(2, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final JLabel label39 = new JLabel(); - this.$$$loadLabelText$$$(label39, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "elevation-service-path")); - panel27.add(label39, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label41 = new JLabel(); + this.$$$loadLabelText$$$(label41, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "elevation-service-path")); + panel27.add(label41, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); textFieldElevationServicePath = new JTextField(); panel27.add(textFieldElevationServicePath, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); buttonChooseElevationServicePath = new JButton(); @@ -1160,14 +1165,14 @@ private void close() { final JPanel panel30 = new JPanel(); panel30.setLayout(new GridLayoutManager(4, 3, new Insets(3, 3, 3, 3), -1, -1)); panel26.add(panel30, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - final JLabel label40 = new JLabel(); - this.$$$loadLabelText$$$(label40, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "gpsbabel-options")); - panel30.add(label40, new GridConstraints(0, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label42 = new JLabel(); + this.$$$loadLabelText$$$(label42, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "gpsbabel-options")); + panel30.add(label42, new GridConstraints(0, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JSeparator separator10 = new JSeparator(); panel30.add(separator10, new GridConstraints(1, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - final JLabel label41 = new JLabel(); - this.$$$loadLabelText$$$(label41, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "gpsbabel-path")); - panel30.add(label41, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label43 = new JLabel(); + this.$$$loadLabelText$$$(label43, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "gpsbabel-path")); + panel30.add(label43, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); textFieldBabelPath = new JTextField(); panel30.add(textFieldBabelPath, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); buttonChooseBabelPath = new JButton(); @@ -1181,14 +1186,14 @@ private void close() { final JPanel panel32 = new JPanel(); panel32.setLayout(new GridLayoutManager(4, 3, new Insets(3, 3, 3, 3), -1, -1)); panel26.add(panel32, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - final JLabel label42 = new JLabel(); - this.$$$loadLabelText$$$(label42, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "geocoding-options")); - panel32.add(label42, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label44 = new JLabel(); + this.$$$loadLabelText$$$(label44, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "geocoding-options")); + panel32.add(label44, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JSeparator separator11 = new JSeparator(); panel32.add(separator11, new GridConstraints(1, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - final JLabel label43 = new JLabel(); - this.$$$loadLabelText$$$(label43, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "geocoding-service")); - panel32.add(label43, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label45 = new JLabel(); + this.$$$loadLabelText$$$(label45, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "geocoding-service")); + panel32.add(label45, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); comboBoxGeocodingService = new JComboBox(); panel32.add(comboBoxGeocodingService, new GridConstraints(2, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel33 = new JPanel(); @@ -1214,9 +1219,9 @@ private void close() { panel34.add(textFieldGeonamesUserName, new GridConstraints(4, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); final JSeparator separator12 = new JSeparator(); panel34.add(separator12, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - final JLabel label44 = new JLabel(); - this.$$$loadLabelText$$$(label44, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "api-key-options")); - panel34.add(label44, new GridConstraints(0, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label46 = new JLabel(); + this.$$$loadLabelText$$$(label46, this.$$$getMessageFromBundle$$$("slash/navigation/converter/gui/RouteConverter", "api-key-options")); + panel34.add(label46, new GridConstraints(0, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); } private static Method $$$cachedGetBundleMethod$$$ = null; diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/helpers/GoogleDirections.java b/route-converter/src/main/java/slash/navigation/converter/gui/helpers/GoogleDirections.java deleted file mode 100644 index be86fc0d2..000000000 --- a/route-converter/src/main/java/slash/navigation/converter/gui/helpers/GoogleDirections.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - This file is part of RouteConverter. - - RouteConverter is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - RouteConverter is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with RouteConverter; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Copyright (C) 2007 Christian Pesch. All Rights Reserved. -*/ -package slash.navigation.converter.gui.helpers; - -import slash.navigation.common.LongitudeAndLatitude; -import slash.navigation.common.MapDescriptor; -import slash.navigation.common.NavigationPosition; -import slash.navigation.converter.gui.RouteConverter; -import slash.navigation.mapview.MapView; -import slash.navigation.routing.BaseRoutingService; -import slash.navigation.routing.DownloadFuture; -import slash.navigation.routing.RoutingResult; -import slash.navigation.routing.TravelMode; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; -import java.util.logging.Logger; - -import static java.util.Arrays.asList; -import static slash.common.helpers.ExceptionHelper.getLocalizedMessage; - -/** - * Encapsulates access to Google Directions service. - * - * @author Christian Pesch - */ - -public class GoogleDirections extends BaseRoutingService { - private static final Logger log = Logger.getLogger(GoogleDirections.class.getName()); - private static final TravelMode DRIVING = new TravelMode("Driving"); - private static final List TRAVEL_MODES = asList(new TravelMode("Bicycling"), DRIVING, new TravelMode("Walking")); - - public String getName() { - return "Google Directions"; - } - - public boolean isInitialized() { - return true; - } - - public boolean isDownload() { - return false; - } - - public boolean isSupportTurnpoints() { - return true; - } - - public boolean isSupportAvoidFerries() { - return true; - } - - public boolean isSupportAvoidHighways() { - return true; - } - - public boolean isSupportAvoidTolls() { - return true; - } - - public List getAvailableTravelModes() { - return TRAVEL_MODES; - } - - public TravelMode getPreferredTravelMode() { - return DRIVING; - } - - public String getPath() { - throw new UnsupportedOperationException(); - } - - public void setPath(String path) { - throw new UnsupportedOperationException(); - } - - public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode) { - throw new UnsupportedOperationException(); - } - - public DownloadFuture downloadRoutingDataFor(String mapIdentifier, List longitudeAndLatitudes) { - throw new UnsupportedOperationException(); - } - - public long calculateRemainingDownloadSize(List mapDescriptors) { - throw new UnsupportedOperationException(); - } - - public void downloadRoutingData(List mapDescriptors) { - throw new UnsupportedOperationException(); - } - - private Method findMethod(Class clazz, String name) { - try { - return clazz.getDeclaredMethod(name, int[].class); - } catch (NoSuchMethodException e) { - Class superclass = clazz.getSuperclass(); - if(superclass != null) - return findMethod(superclass, name); - } - return null; - } - - private void insertWaypoints(String mode, int[] selectedRows) { - MapView mapView = RouteConverter.getInstance().getMapView(); - try { - Method method = findMethod(mapView.getClass(), mode); - if (method != null) - method.invoke(mapView, new Object[]{selectedRows}); - } catch (InvocationTargetException | IllegalAccessException e) { - log.severe("Failed to " + mode + ": " + getLocalizedMessage(e)); - } - } - - public void insertAllWaypoints(int[] selectedRows) { - insertWaypoints("insertAllWaypoints", selectedRows); - } - - public void insertOnlyTurnpoints(int[] selectedRows) { - insertWaypoints("insertOnlyTurnpoints", selectedRows); - } -} diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/helpers/InsertPositionFacade.java b/route-converter/src/main/java/slash/navigation/converter/gui/helpers/InsertPositionFacade.java index 80aeb937b..9f88b6e07 100644 --- a/route-converter/src/main/java/slash/navigation/converter/gui/helpers/InsertPositionFacade.java +++ b/route-converter/src/main/java/slash/navigation/converter/gui/helpers/InsertPositionFacade.java @@ -25,10 +25,7 @@ import slash.navigation.converter.gui.RouteConverter; import slash.navigation.converter.gui.models.PositionsModel; import slash.navigation.gui.Application; -import slash.navigation.routing.DownloadFuture; -import slash.navigation.routing.RoutingResult; -import slash.navigation.routing.RoutingService; -import slash.navigation.routing.TravelMode; +import slash.navigation.routing.*; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -46,7 +43,7 @@ import static slash.common.helpers.ThreadHelper.createSingleThreadExecutor; import static slash.common.io.Transfer.toArray; import static slash.navigation.gui.helpers.WindowHelper.getFrame; -import static slash.navigation.routing.RoutingResult.Validity.*; +import static slash.navigation.routing.RoutingResult.Validity.Valid; /** * Helps to insert positions. @@ -63,22 +60,7 @@ public void insertAllWaypoints() { r.clearSelection(); RoutingService service = r.getRoutingServiceFacade().getRoutingService(); - if (service instanceof GoogleDirections) { - ((GoogleDirections) service).insertAllWaypoints(selectedRows); - } else - insertWithRoutingService(service, selectedRows); - } - - public void insertOnlyTurnpoints() { - RouteConverter r = RouteConverter.getInstance(); - int[] selectedRows = r.getConvertPanel().getPositionsView().getSelectedRows(); - r.clearSelection(); - - RoutingService service = r.getRoutingServiceFacade().getRoutingService(); - if (service instanceof GoogleDirections) { - ((GoogleDirections) service).insertOnlyTurnpoints(selectedRows); - } else - throw new UnsupportedOperationException(); + insertWithRoutingService(service, selectedRows); } private final ExecutorService executor = createSingleThreadExecutor("InsertPositions"); @@ -103,22 +85,25 @@ private void doInsertWithRoutingService(RoutingService routingService, int[] sel for (int selectedRow : selectedRows) selectedPositions.add(positionsModel.getPosition(selectedRow)); - DownloadFuture future = null; if (routingService.isDownload()) { List longitudeAndLatitudes = new ArrayList<>(); for (NavigationPosition position : selectedPositions) { longitudeAndLatitudes.add(new LongitudeAndLatitude(position.getLongitude(), position.getLatitude())); } - future = routingService.downloadRoutingDataFor(r.getMapView().getMapIdentifier(), longitudeAndLatitudes); + DownloadFuture future = routingService.downloadRoutingDataFor(r.getMapView().getMapIdentifier(), longitudeAndLatitudes); + if(future.isRequiresDownload()) + future.download(); } TravelMode travelMode = r.getRoutingServiceFacade().getRoutingPreferencesModel().getTravelMode(); - List positions = insertPositions(routingService, future, travelMode, selectedPositions); + TravelRestrictions travelRestrictions = r.getRoutingServiceFacade().getRoutingPreferencesModel().getTravelRestrictions(); + List positions = insertPositions(routingService, travelMode, travelRestrictions, selectedPositions); if (!positions.isEmpty()) invokeLater(() -> r.getPositionAugmenter().addData(toArray(positions), false, true, true, false, false)); } - private List insertPositions(RoutingService routingService, DownloadFuture future, TravelMode travelMode, List selectedPositions) throws InterruptedException, InvocationTargetException { + private List insertPositions(RoutingService routingService, TravelMode travelMode, TravelRestrictions travelRestrictions, + List selectedPositions) throws InterruptedException, InvocationTargetException { PositionsModel positionsModel = RouteConverter.getInstance().getConvertPanel().getPositionsModel(); List insertedPositions = new ArrayList<>(); @@ -127,7 +112,7 @@ private List insertPositions(RoutingService routingService, DownloadFut if (i == positionsModel.getRowCount() - 1 || i == selectedPositions.size() - 1) continue; - RoutingResult result = routingService.getRouteBetween(selectedPositions.get(i), selectedPositions.get(i + 1), travelMode); + RoutingResult result = routingService.getRouteBetween(selectedPositions.get(i), selectedPositions.get(i + 1), travelMode, travelRestrictions); if (result.getValidity().equals(Valid)) { final List positions = new ArrayList<>(); for (NavigationPosition position : result.getPositions()) { diff --git a/route-converter/src/main/java/slash/navigation/converter/gui/helpers/MapViewCallbackImpl.java b/route-converter/src/main/java/slash/navigation/converter/gui/helpers/MapViewCallbackImpl.java index 11349e270..3ec744d92 100644 --- a/route-converter/src/main/java/slash/navigation/converter/gui/helpers/MapViewCallbackImpl.java +++ b/route-converter/src/main/java/slash/navigation/converter/gui/helpers/MapViewCallbackImpl.java @@ -27,6 +27,7 @@ import slash.navigation.mapview.MapViewCallback; import slash.navigation.routing.RoutingService; import slash.navigation.routing.TravelMode; +import slash.navigation.routing.TravelRestrictions; import static slash.navigation.converter.gui.helpers.PositionHelper.formatLatitude; import static slash.navigation.converter.gui.helpers.PositionHelper.formatLongitude; @@ -67,16 +68,8 @@ public TravelMode getTravelMode() { return RouteConverter.getInstance().getRoutingServiceFacade().getRoutingPreferencesModel().getTravelMode(); } - public boolean isAvoidFerries() { - return RouteConverter.getInstance().getRoutingServiceFacade().getRoutingPreferencesModel().isAvoidFerries(); - } - - public boolean isAvoidHighways() { - return RouteConverter.getInstance().getRoutingServiceFacade().getRoutingPreferencesModel().isAvoidHighways(); - } - - public boolean isAvoidTolls() { - return RouteConverter.getInstance().getRoutingServiceFacade().getRoutingPreferencesModel().isAvoidTolls(); + public TravelRestrictions getTravelRestrictions() { + return RouteConverter.getInstance().getRoutingServiceFacade().getRoutingPreferencesModel().getTravelRestrictions(); } public boolean isShowAllPositionsAfterLoading() { diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ca.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ca.properties index ae892e3ad..861cd41e4 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ca.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ca.properties @@ -310,7 +310,7 @@ travel-mode-bicycling=Amb bicicleta travel-mode-driving=Amb vehicle travel-mode-walking=A peu avoid-ferries=Evita els ferris per a les rutes: -avoid-highways=Evita les autovies per a les rutes: +avoid-motorways=Evita les autovies per a les rutes: avoid-tolls=Evita els peatges per a les rutes: number-pattern-description_only=Descripció solament number-pattern-number_only=Número solament diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_cs.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_cs.properties index ac0cc9cfb..cb207f36b 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_cs.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_cs.properties @@ -260,7 +260,7 @@ travel-mode-bicycling=Kolo travel-mode-driving=Automobil travel-mode-walking=Chodce avoid-ferries=Zamezit routování přes trajekty: -avoid-highways=Zakázat dálnice pro návrh cest: +avoid-motorways=Zakázat dálnice pro návrh cest: avoid-tolls=Vyhnout se placeným úsekům při návrhu cest: number-pattern=Číslovat pozice podle vzoru: number-pattern-description_only=Jen popis diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_da.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_da.properties index 8d5a2ec33..39a97c124 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_da.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_da.properties @@ -180,7 +180,7 @@ travel-mode-bicycling=Cykling travel-mode-driving=Bil travel-mode-walking=Fodgænger avoid-ferries=Undgå færger: -avoid-highways=Undgå motorveje: +avoid-motorways=Undgå motorveje: avoid-tolls=Undgå vejafgifter: number-pattern-description_only=Kun beskrivelse number-pattern-number_only=Kun tal diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_de.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_de.properties index e38138892..45a24ade2 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_de.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_de.properties @@ -490,9 +490,11 @@ travel-mode=Plane Routen: travel-mode-bicycling=Mit dem Fahrrad travel-mode-driving=Mit dem Auto travel-mode-walking=Zu Fuß +avoid-bridges=Vermeide Brücken für Routen: avoid-ferries=Vermeide Fähren für Routen: -avoid-highways=Vermeide Autobahnen für Routen: +avoid-motorways=Vermeide Autobahnen für Routen: avoid-tolls=Vermeide Maut für Routen: +avoid-tunnels=Vermeide Tunnel für Routen: number-pattern=Nummeriere Positionen mit dem Muster: number-pattern-description_only=Nur Beschreibung number-pattern-number_only=Nur Nummern diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_en.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_en.properties index 67d76b5af..f0d3182cc 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_en.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_en.properties @@ -438,9 +438,11 @@ travel-mode=Plan routes for: travel-mode-bicycling=Bicycling travel-mode-driving=Driving travel-mode-walking=Walking +avoid-bridges=Avoid bridges for routes: avoid-ferries=Avoid ferries for routes: -avoid-highways=Avoid highways for routes: +avoid-motorways=Avoid motorways for routes: avoid-tolls=Avoid tolls for routes: +avoid-tunnels=Avoid tunnels for routes: number-pattern=Number positions with pattern: number-pattern-description_only=Description only number-pattern-number_only=Number only diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_es.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_es.properties index 0cd3e46a7..23f182678 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_es.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_es.properties @@ -224,7 +224,7 @@ travel-mode-bicycling=Bicicleta travel-mode-driving=Coche travel-mode-walking=Caminando avoid-ferries=Evitar ferris en las rutas: -avoid-highways=Evitar autopistas para las rutas: +avoid-motorways=Evitar autopistas para las rutas: avoid-tolls=Evitar peajes en rutas: number-pattern=Número de posición con patrón: number-pattern-description_only=Descripción únicamente diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fi.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fi.properties index 020429015..5a2185b66 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fi.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fi.properties @@ -27,3 +27,4 @@ add=Lisää save-action=Tallenna comment-colon=Kommentti: description-colon=Kuvaus: +avoid-tolls=[avoid-tolls / slash/navigation/converter/gui/RouteConverter] diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fr.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fr.properties index 63a58ea0d..e1d895f50 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fr.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_fr.properties @@ -217,7 +217,7 @@ travel-mode-bicycling=Vélo travel-mode-driving=Voiture travel-mode-walking=Piéton avoid-ferries=Eviter les ferries pour les itinéraires: -avoid-highways=Eviter les autoroutes pour les itinéraires: +avoid-motorways=Eviter les autoroutes pour les itinéraires: avoid-tolls=Eviter les péages pour les itinéraires: number-pattern=Nombre de points formatés: number-pattern-description_only=Description seulement diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_hr.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_hr.properties index cb735890e..1bbac7923 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_hr.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_hr.properties @@ -227,7 +227,7 @@ travel-mode-bicycling=Biciklizam travel-mode-driving=Vožnja travel-mode-walking=Pješačenje avoid-ferries=Izbjegni trajekte na rutama: -avoid-highways=Izbjegni autoceste na rutama: +avoid-motorways=Izbjegni autoceste na rutama: avoid-tolls=Izbjegni cestarine na rutama: number-pattern=Broj pozicija sa šemom: number-pattern-description_only=Samo opis diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_it.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_it.properties index 87e7f8057..7b069c5c5 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_it.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_it.properties @@ -176,7 +176,7 @@ travel-mode-bicycling=Bici travel-mode-driving=Auto travel-mode-walking=Andare a piedi avoid-ferries=Evitare traghetti: -avoid-highways=Evita autostrade: +avoid-motorways=Evita autostrade: avoid-tolls=Evita pedaggi: number-pattern=Numerazione e nome punto come modello: number-pattern-description_only=Solo descrizione diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ja.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ja.properties index 4ae771368..8b568409a 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ja.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ja.properties @@ -201,7 +201,7 @@ travel-mode-bicycling=自転車 travel-mode-driving=車 travel-mode-walking=徒歩 avoid-ferries=フェリーを使わない: -avoid-highways=高速道路を使わない: +avoid-motorways=高速道路を使わない: avoid-tolls=有料道路を使わない: number-pattern-description_only=説明のみ number-pattern-number_only=番号のみ diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nb_NO.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nb_NO.properties index e72a5b96b..1983ed4dc 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nb_NO.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nb_NO.properties @@ -360,7 +360,7 @@ travel-mode-bicycling=Sykling travel-mode-driving=Kjøring travel-mode-walking=Gåing avoid-ferries=Unngå ferger for ruter: -avoid-highways=Unngå motorveier for ruter: +avoid-motorways=Unngå motorveier for ruter: number-pattern-description_only=Kun beskrivelse number-pattern-number_only=Kun tall number-pattern-number_directly_followed_by_description=Nummer direkte etterfulgt av beskrivelse diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nl.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nl.properties index dfba2961a..72ac0a53d 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nl.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_nl.properties @@ -218,7 +218,7 @@ travel-mode-bicycling=fietser travel-mode-driving=auto/motor travel-mode-walking=voetganger avoid-ferries=Vermijd veerdiensten in routes: -avoid-highways=Vermijd snelwegen voor routes: +avoid-motorways=Vermijd snelwegen voor routes: avoid-tolls=Vermijd tolwegen op de route: number-pattern=Nummer posities met patroon: number-pattern-description_only=Alleen de beschrijving diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pl.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pl.properties index a8c09269b..1b1fea02e 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pl.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pl.properties @@ -224,7 +224,7 @@ travel-mode-bicycling=Rowerów travel-mode-driving=Samochodów travel-mode-walking=Pieszych avoid-ferries=Unikaj promów: -avoid-highways=Unikaj autostrad: +avoid-motorways=Unikaj autostrad: avoid-tolls=Unikaj opłat: number-pattern=Pozycje numerów z wzorem: number-pattern-description_only=Tylko opis diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt.properties index 9952840ca..1bfcef69f 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt.properties @@ -225,7 +225,7 @@ travel-mode-bicycling=Bicicleta travel-mode-driving=Carro travel-mode-walking=Caminhada avoid-ferries=Evitar ferries: -avoid-highways=Evitar autoestradas: +avoid-motorways=Evitar autoestradas: avoid-tolls=Evitar portagens: number-pattern=Numerar posições com padrão: number-pattern-description_only=Apenas descrição diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt_BR.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt_BR.properties index f323b17e2..fb4c23753 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt_BR.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_pt_BR.properties @@ -422,7 +422,7 @@ travel-mode-bicycling=Bicicleta travel-mode-driving=Carro travel-mode-walking=Caminhada avoid-ferries=Evitar ferries: -avoid-highways=Evitar autoestradas: +avoid-motorways=Evitar autoestradas: avoid-tolls=Evitar portagens: number-pattern=Numerar posições com padrão: number-pattern-description_only=Apenas descrição diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ru.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ru.properties index f914c7101..e87a976a1 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ru.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_ru.properties @@ -241,7 +241,7 @@ travel-mode=Планировать маршруты для: travel-mode-bicycling=Велосипед travel-mode-driving=Машина travel-mode-walking=Пешеход -avoid-highways=Избегать трасс для маршрутов: +avoid-motorways=Избегать трасс для маршрутов: avoid-tolls=Избегать платных дорог для маршрутов: number-pattern=Шаблон нумерации позиций: number-pattern-description_only=Только описание diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sk.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sk.properties index bd486146f..bb2d2a308 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sk.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sk.properties @@ -263,7 +263,7 @@ travel-mode-bicycling=Bicykel travel-mode-driving=Automobil travel-mode-walking=Peších avoid-ferries=Zamedziť routovaniu cez trajekty: -avoid-highways=Zakáž diaľnice pre návrh ciest: +avoid-motorways=Zakáž diaľnice pre návrh ciest: avoid-tolls=Vyhni sa plateným úsekom pri návrhu ciest: number-pattern=Čísluj pozície podľa vzoru: number-pattern-description_only=Iba popis diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sr.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sr.properties index 0022f4166..1a11876d2 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sr.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_sr.properties @@ -231,7 +231,7 @@ travel-mode-bicycling=Biciklizam travel-mode-driving=Vožnju travel-mode-walking=Pešačenje avoid-ferries=Izbegni trajekte na ruti: -avoid-highways=Izbegavanje auto-puteva kod ruta: +avoid-motorways=Izbegavanje auto-puteva kod ruta: avoid-tolls=Izbegni putarine na rutama: number-pattern=Broj pozicija sa šemom: number-pattern-description_only=Samo opis diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_uk.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_uk.properties index c2a477ff6..83f9868d0 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_uk.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_uk.properties @@ -403,7 +403,7 @@ travel-mode-bicycling=Велосипед travel-mode-driving=Машина travel-mode-walking=Пішохід avoid-ferries=Уникати поромів для маршрутів: -avoid-highways=Уникати автомагістралей для маршрутів: +avoid-motorways=Уникати автомагістралей для маршрутів: avoid-tolls=Уникати плати за маршрути: number-pattern=Номер позиції з шаблону: number-pattern-description_only=Тільки опис diff --git a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_zh.properties b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_zh.properties index 451236d81..0a88b5ece 100644 --- a/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_zh.properties +++ b/route-converter/src/main/resources/slash/navigation/converter/gui/RouteConverter_zh.properties @@ -150,7 +150,7 @@ travel-mode-bicycling=自行车 travel-mode-driving=驾驶 travel-mode-walking=步行 avoid-ferries=避开轮渡: -avoid-highways=航线避开高速公路: +avoid-motorways=航线避开高速公路: avoid-tolls=避免收费路段: number-pattern=轨迹点的描述方式: number-pattern-description_only=仅说明 diff --git a/routing-service/src/main/java/slash/navigation/routing/Beeline.java b/routing-service/src/main/java/slash/navigation/routing/Beeline.java index f70340fb3..8928106ca 100644 --- a/routing-service/src/main/java/slash/navigation/routing/Beeline.java +++ b/routing-service/src/main/java/slash/navigation/routing/Beeline.java @@ -20,7 +20,10 @@ package slash.navigation.routing; -import slash.navigation.common.*; +import slash.navigation.common.DistanceAndTime; +import slash.navigation.common.LongitudeAndLatitude; +import slash.navigation.common.MapDescriptor; +import slash.navigation.common.NavigationPosition; import java.util.List; @@ -28,6 +31,7 @@ import static java.util.Collections.singletonList; import static slash.navigation.common.Bearing.calculateBearing; import static slash.navigation.routing.RoutingResult.Validity.Invalid; +import static slash.navigation.routing.TravelRestrictions.NO_RESTRICTIONS; /** * A routing service that does no routing, i.e. returns beelines. @@ -50,26 +54,14 @@ public boolean isDownload() { return false; } - public boolean isSupportTurnpoints() { - return false; - } - - public boolean isSupportAvoidFerries() { - return false; - } - - public boolean isSupportAvoidHighways() { - return false; - } - - public boolean isSupportAvoidTolls() { - return false; - } - public List getAvailableTravelModes() { return singletonList(BEELINE); } + public TravelRestrictions getAvailableTravelRestrictions() { + return NO_RESTRICTIONS; + } + public TravelMode getPreferredTravelMode() { return BEELINE; } @@ -87,7 +79,7 @@ public static RoutingResult getRouteBetween(NavigationPosition from, NavigationP return new RoutingResult(asList(from, to), new DistanceAndTime(distance, null), Invalid); } - public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode) { + public RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode, TravelRestrictions travelRestrictions) { return getRouteBetween(from, to); } diff --git a/routing-service/src/main/java/slash/navigation/routing/RoutingPreferencesModel.java b/routing-service/src/main/java/slash/navigation/routing/RoutingPreferencesModel.java index 99ada52ec..e00b7bfc2 100644 --- a/routing-service/src/main/java/slash/navigation/routing/RoutingPreferencesModel.java +++ b/routing-service/src/main/java/slash/navigation/routing/RoutingPreferencesModel.java @@ -20,9 +20,11 @@ public class RoutingPreferencesModel { private static final String ROUTING_SERVICE_PREFERENCE = "routingService"; private static final String TRAVEL_MODE_PREFERENCE = "travelMode"; + private static final String AVOID_BRIDGES_PREFERENCE = "avoidBridges"; private static final String AVOID_FERRIES_PREFERENCE = "avoidFerries"; - private static final String AVOID_HIGHWAYS_PREFERENCE = "avoidHighways"; + private static final String AVOID_MOTORWAYS_PREFERENCE = "avoidMotorways"; private static final String AVOID_TOLLS_PREFERENCE = "avoidTolls"; + private static final String AVOID_TUNNELS_PREFERENCE = "avoidTunnels"; private final EventListenerList listenerList = new EventListenerList(); @@ -84,31 +86,39 @@ public void setTravelMode(TravelMode travelMode) { fireChanged(); } - public boolean isAvoidFerries() { - return preferences.getBoolean(AVOID_FERRIES_PREFERENCE + getRoutingService().getName(), false); + public TravelRestrictions getTravelRestrictions() { + return new TravelRestrictions(getAvoidPreference(AVOID_BRIDGES_PREFERENCE), + getAvoidPreference(AVOID_FERRIES_PREFERENCE), getAvoidPreference(AVOID_MOTORWAYS_PREFERENCE), + getAvoidPreference(AVOID_TOLLS_PREFERENCE), getAvoidPreference(AVOID_TUNNELS_PREFERENCE)); } - public void setAvoidFerries(boolean avoidFerries) { - preferences.putBoolean(AVOID_FERRIES_PREFERENCE + getRoutingService().getName(), avoidFerries); + private boolean getAvoidPreference(String key) { + return preferences.getBoolean(key + getRoutingService().getName(), false); + } + + private void setAvoidPreference(String key, boolean avoidPreference) { + preferences.putBoolean(key + getRoutingService().getName(), avoidPreference); fireChanged(); } - public boolean isAvoidHighways() { - return preferences.getBoolean(AVOID_HIGHWAYS_PREFERENCE + getRoutingService().getName(), false); + public void setAvoidBridges(boolean avoidBridges) { + setAvoidPreference(AVOID_BRIDGES_PREFERENCE, avoidBridges); } - public void setAvoidHighways(boolean avoidHighways) { - preferences.putBoolean(AVOID_HIGHWAYS_PREFERENCE + getRoutingService().getName(), avoidHighways); - fireChanged(); + public void setAvoidFerries(boolean avoidFerries) { + setAvoidPreference(AVOID_FERRIES_PREFERENCE, avoidFerries); } - public boolean isAvoidTolls() { - return preferences.getBoolean(AVOID_TOLLS_PREFERENCE + getRoutingService().getName(), false); + public void setAvoidMotorways(boolean avoidMotorways) { + setAvoidPreference(AVOID_MOTORWAYS_PREFERENCE, avoidMotorways); } public void setAvoidTolls(boolean avoidTolls) { - preferences.putBoolean(AVOID_TOLLS_PREFERENCE + getRoutingService().getName(), avoidTolls); - fireChanged(); + setAvoidPreference(AVOID_TOLLS_PREFERENCE, avoidTolls); + } + + public void setAvoidTunnels(boolean avoidTunnels) { + setAvoidPreference(AVOID_TUNNELS_PREFERENCE, avoidTunnels); } protected void fireChanged() { diff --git a/routing-service/src/main/java/slash/navigation/routing/RoutingService.java b/routing-service/src/main/java/slash/navigation/routing/RoutingService.java index d1dd46402..72fece1b3 100644 --- a/routing-service/src/main/java/slash/navigation/routing/RoutingService.java +++ b/routing-service/src/main/java/slash/navigation/routing/RoutingService.java @@ -36,16 +36,13 @@ public interface RoutingService { String getName(); boolean isInitialized(); boolean isDownload(); - boolean isSupportTurnpoints(); - boolean isSupportAvoidFerries(); - boolean isSupportAvoidHighways(); - boolean isSupportAvoidTolls(); List getAvailableTravelModes(); + TravelRestrictions getAvailableTravelRestrictions(); TravelMode getPreferredTravelMode(); String getPath(); void setPath(String path); - RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode); + RoutingResult getRouteBetween(NavigationPosition from, NavigationPosition to, TravelMode travelMode, TravelRestrictions travelRestrictions); DownloadFuture downloadRoutingDataFor(String mapIdentifier, List longitudeAndLatitudes); long calculateRemainingDownloadSize(List mapDescriptors); diff --git a/routing-service/src/main/java/slash/navigation/routing/TravelRestrictions.java b/routing-service/src/main/java/slash/navigation/routing/TravelRestrictions.java new file mode 100644 index 000000000..cf8c307e3 --- /dev/null +++ b/routing-service/src/main/java/slash/navigation/routing/TravelRestrictions.java @@ -0,0 +1,44 @@ +package slash.navigation.routing; + +/** + * Travel restrictions for a routing service. + * + * @author Christian Pesch + */ +public class TravelRestrictions { + public static final TravelRestrictions NO_RESTRICTIONS = new TravelRestrictions(false, false, false, false, false); + + private boolean avoidBridges; + private boolean avoidFerries; + private boolean avoidMotorways; + private boolean avoidTolls; + private boolean avoidTunnels; + + public TravelRestrictions(boolean avoidBridges, boolean avoidFerries, boolean avoidMotorways, boolean avoidTolls, boolean avoidTunnels) { + this.avoidBridges = avoidBridges; + this.avoidFerries = avoidFerries; + this.avoidMotorways = avoidMotorways; + this.avoidTolls = avoidTolls; + this.avoidTunnels = avoidTunnels; + } + + public boolean isAvoidBridges() { + return avoidBridges; + } + + public boolean isAvoidFerries() { + return avoidFerries; + } + + public boolean isAvoidMotorways() { + return avoidMotorways; + } + + public boolean isAvoidTolls() { + return avoidTolls; + } + + public boolean isAvoidTunnels() { + return avoidTunnels; + } +} \ No newline at end of file