/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.graph_builder.impl.ned; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.jets3t.service.S3Service; import org.jets3t.service.S3ServiceException; import org.jets3t.service.ServiceException; import org.jets3t.service.impl.rest.httpclient.RestS3Service; import org.jets3t.service.model.S3Object; import org.jets3t.service.security.AWSCredentials; import org.opentripplanner.common.model.P2; import org.opentripplanner.graph_builder.services.ned.NEDTileSource; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graph.Vertex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.vividsolutions.jts.geom.Coordinate; /** * Download one-degree-wide, 1/3 arcsecond NED tiles from S3 (or get them from a directory of files * organized as USGS organizes them when you ship them a hard drive). * * @author novalis * */ public class DegreeGridNEDTileSource implements NEDTileSource { private static Logger log = LoggerFactory.getLogger(DegreeGridNEDTileSource.class); private Graph graph; private File cacheDirectory; private String awsAccessKey; private String awsSecretKey; @Override public void setGraph(Graph graph) { this.graph = graph; } @Override public void setCacheDirectory(File cacheDirectory) { this.cacheDirectory = cacheDirectory; } @Override public List<File> getNEDTiles() { HashSet<P2<Integer>> tiles = new HashSet<P2<Integer>>(); for (Vertex v : graph.getVertices()) { Coordinate coord = v.getCoordinate(); tiles.add(new P2<Integer>((int) coord.x, (int) coord.y)); } List<File> paths = new ArrayList<File>(); for (P2<Integer> tile : tiles) { int x = tile.getFirst() - 1; int y = tile.getSecond() + 1; paths.add(getPathToTile(x, y)); } return paths; } private String formatLatLon(int x, int y) { String northSouth, eastWest; if (y < 0) { northSouth = "s"; y = -y; } else { northSouth = "n"; } if (x < 0) { eastWest = "w"; x = -x; } else { eastWest = "e"; } return String.format("%s%d%s%03d", northSouth, y, eastWest, x); } private File getPathToTile(int x, int y) { File path = new File(cacheDirectory, formatLatLon(x, y) + ".tiff"); if (path.exists()) { return path; } else { path.getParentFile().mkdirs(); if (awsAccessKey == null || awsSecretKey == null) { throw new RuntimeException("Cannot download NED tiles from S3: awsAccessKey or awsSecretKey properties are not set"); } log.debug("Downloading NED degree tile " + path); // download the file from S3. AWSCredentials awsCredentials = new AWSCredentials(awsAccessKey, awsSecretKey); try { S3Service s3Service = new RestS3Service(awsCredentials); String key = formatLatLon(x, y) + ".tiff"; S3Object object = s3Service.getObject("ned13", key); InputStream istream = object.getDataInputStream(); FileOutputStream ostream = new FileOutputStream(path); byte[] buffer = new byte[4096]; while (true) { int read = istream.read(buffer); if (read == -1) { break; } ostream.write(buffer, 0, read); } ostream.close(); istream.close(); } catch (S3ServiceException e) { path.deleteOnExit(); throw new RuntimeException(e); } catch (ServiceException e) { path.deleteOnExit(); throw new RuntimeException(e); } catch (FileNotFoundException e) { path.deleteOnExit(); throw new RuntimeException(e); } catch (IOException e) { path.deleteOnExit(); throw new RuntimeException(e); } return path; } } public String getAwsAccessKey() { return awsAccessKey; } public void setAwsAccessKey(String awsAccessKey) { this.awsAccessKey = awsAccessKey; } public String getAwsSecretKey() { return awsSecretKey; } public void setAwsSecretKey(String awsSecretKey) { this.awsSecretKey = awsSecretKey; } }