/* Copyright (c) 2013-2014 Boundless and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Distribution License v1.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/org/documents/edl-v10.html * * Contributors: * Johnathan Garrett (LMN Solutions) - initial implementation */ package org.locationtech.geogig.osm.internal; import java.io.File; import java.io.IOException; import java.util.List; import org.locationtech.geogig.api.AbstractGeoGigOp; import org.locationtech.geogig.api.porcelain.NothingToCommitException; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.io.Files; /** * Downloads data from OSM and commits it to the repository. * */ public class OSMDownloadOp extends AbstractGeoGigOp<Optional<OSMReport>> { private File mappingFile; private File filterFile; private File saveFile; private String osmAPIUrl; private String message; private List<String> bbox; private boolean keepFiles = false; /** * Sets the mapping file to use. * * @param mappingFile the mapping file to use * @return {@code this} */ public OSMDownloadOp setMappingFile(File mappingFile) { this.mappingFile = mappingFile; return this; } /** * Sets the filter file to use. * * @param filterFile the filter file to use * @return {@code this} */ public OSMDownloadOp setFilterFile(File filterFile) { this.filterFile = filterFile; return this; } /** * Sets the save file to use. * * @param saveFile the save file to use * @return {@code this} */ public OSMDownloadOp setSaveFile(File saveFile) { this.saveFile = saveFile; return this; } /** * Sets the URL of the OSM API. * * @param url the url of the OSM API * @return {@code this} */ public OSMDownloadOp setOsmAPIUrl(String url) { this.osmAPIUrl = url; return this; } /** * Sets the commit message to use when committing the updates. * * @param message the commit message to use * @return {@code this} */ public OSMDownloadOp setMessage(String message) { this.message = message; return this; } /** * The bounding box to use as filter (S W N E). * * @param bbox the bounding box coordinates (S W N E) * @return {@code this} */ public OSMDownloadOp setBbox(List<String> bbox) { this.bbox = bbox; return this; } /** * If specified, downloaded files are kept in the `saveFile` folder * * @param keepFiles whether or not to keep the downloaded files * @return {@code this} */ public OSMDownloadOp setKeepFiles(boolean keepFiles) { this.keepFiles = keepFiles; return this; } /** * Executes the {@code OSMDownloadOp} operation. * * @return a {@link OSMDownloadReport} of the operation */ @Override protected Optional<OSMReport> _call() { Mapping mapping = null; if (mappingFile != null) { mapping = Mapping.fromFile(mappingFile.getAbsolutePath()); } message = message == null ? "Updated OSM data" : message; OSMImportOp op = command(OSMImportOp.class).setDataSource(osmAPIUrl) .setDownloadFile(saveFile).setMapping(mapping).setKeepFile(keepFiles) .setMessage(message); String filter = null; if (filterFile != null) { try { filter = readFile(filterFile); } catch (IOException e) { throw new IllegalArgumentException("Error reading filter file:" + e.getMessage(), e); } } else if (bbox != null) { String bboxString = bbox.get(0) + "," + bbox.get(1) + "," + bbox.get(2) + "," + bbox.get(3); filter = "(node(" + bboxString + ");\n" + "way(" + bboxString + "););\n(._;>;);\nout meta;"; } try { Optional<OSMReport> report = op.setFilter(filter) .setProgressListener(getProgressListener()).call(); return report; } catch (EmptyOSMDownloadException e) { throw new IllegalArgumentException("The specified filter did not return any element.\n" + "No changes were made to the repository.\n" + "To check the downloaded elements, use the --saveto and" + " --keep-files options and verify the intermediate file."); } catch (NothingToCommitException alreadyUpToDate) { throw alreadyUpToDate; } catch (RuntimeException e) { throw new IllegalStateException( "Failed to fetch data from overpass server. (Did you try to use a standard OSM server instead?) " + e.getMessage(), e); } } private String readFile(File file) throws IOException { List<String> lines = Files.readLines(file, Charsets.UTF_8); return Joiner.on("\n").join(lines); } }