/* 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.BoundingBox; import slash.navigation.common.LongitudeAndLatitude; import slash.navigation.elevation.ElevationService; import java.io.IOException; import java.util.*; import java.util.logging.Logger; import static java.util.Arrays.sort; /** * An elevation service that tries to find the best available elevation service. * * @author Christian Pesch */ public class AutomaticElevationService implements ElevationService { private static final Logger log = Logger.getLogger(AutomaticElevationService.class.getName()); private static final String AUTOMATIC_ELEVATION_SERVICE_NAME = "Automatic"; private static final String JONATHAN_DE_FERRANTI_DEM_3 = "Jonathan de Ferranti DEM 3"; private final ElevationServiceFacade elevationServiceFacade; public AutomaticElevationService(ElevationServiceFacade elevationServiceFacade) { this.elevationServiceFacade = elevationServiceFacade; } public String getName() { return AUTOMATIC_ELEVATION_SERVICE_NAME; } public boolean isDownload() { return true; } public boolean isOverQueryLimit() { return false; } public boolean isSupportsPath() { return false; } public String getPath() { throw new UnsupportedOperationException(); } public void setPath(String path) { throw new UnsupportedOperationException(); } public Double getElevationFor(double longitude, double latitude) throws IOException { IOException lastException = null; for (ElevationService service : sortByBestEffort(elevationServiceFacade.getElevationServices())) { try { if(service.isOverQueryLimit()) continue; Double elevation = service.getElevationFor(longitude, latitude); if (elevation != null) { log.info("Used " + service.getName() + " to retrieve elevation " + elevation + " for " + longitude + "/" + latitude); return elevation; } } catch (IOException e) { lastException = e; } } if(lastException != null) throw lastException; else return null; } private ElevationService[] sortByBestEffort(List<ElevationService> elevationServices) { List<ElevationService> toSort = new ArrayList<>(elevationServices); toSort.remove(this); ElevationService[] result = toSort.toArray(new ElevationService[toSort.size()]); sort(result, new ElevationServicePriorityComparator()); return result; } public String getPreferredDownloadName() { return JONATHAN_DE_FERRANTI_DEM_3; } public void downloadElevationDataFor(List<LongitudeAndLatitude> longitudeAndLatitudes, boolean waitForDownload) { ElevationService service = elevationServiceFacade.findElevationService(getPreferredDownloadName()); if (service != null) service.downloadElevationDataFor(longitudeAndLatitudes, false); } public long calculateRemainingDownloadSize(List<BoundingBox> boundingBoxes) { ElevationService service = elevationServiceFacade.findElevationService(getPreferredDownloadName()); return service != null ? service.calculateRemainingDownloadSize(boundingBoxes) : 0L; } public void downloadElevationData(List<BoundingBox> boundingBoxes) { ElevationService service = elevationServiceFacade.findElevationService(getPreferredDownloadName()); if (service != null) service.downloadElevationData(boundingBoxes); } private static class ElevationServicePriorityComparator implements Comparator<ElevationService> { private static final Map<String, Integer> PRIORITY = new HashMap<>(); static { PRIORITY.put("Jonathan de Ferranti DEM 1", 1); PRIORITY.put("NASA SRTM 1", 2); PRIORITY.put(JONATHAN_DE_FERRANTI_DEM_3, 3); PRIORITY.put("NASA SRTM 3", 4); PRIORITY.put("GeoNames", 5); PRIORITY.put("Google Maps", 6); } private int getPriority(ElevationService elevationService) { Integer priority = PRIORITY.get(elevationService.getName()); return priority == null ? 10 : priority; } public int compare(ElevationService e1, ElevationService e2) { return getPriority(e1) - getPriority(e2); } } }