/** * H2GIS is a library that brings spatial support to the H2 Database Engine * <http://www.h2database.com>. H2GIS is developed by CNRS * <http://www.cnrs.fr/>. * * This code is part of the H2GIS project. H2GIS 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; * version 3.0 of the License. * * H2GIS 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 Lesser General Public License * for more details <http://www.gnu.org/licenses/>. * * * For more information, please consult: <http://www.h2gis.org/> * or contact directly: info_at_h2gis.org */ package org.h2gis.functions.io.osm; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.sql.Connection; import java.sql.SQLException; import org.h2gis.api.AbstractFunction; import org.h2gis.api.ScalarFunction; import org.h2gis.functions.spatial.crs.ST_Transform; import org.h2gis.utilities.URIUtilities; /** * This function is used to download data from the osm api using a bounding box. * * @author Erwan Bocher */ public class ST_OSMDownloader extends AbstractFunction implements ScalarFunction { private static final String OSM_API_URL = "http://api.openstreetmap.org/api/0.6/"; public ST_OSMDownloader() { addProperty(PROP_REMARKS, "Extract an OSM XML file from the OSM api server using a the bounding box of a given geometry.\n" + "A path must be set to specified where the OSM file will be stored./n" + "Set true to delete the XML file if exists. Default behaviour is false."); } @Override public String getJavaStaticMethod() { return "downloadData"; } /** * * @param con the database connection * @param area The geometry used to compute the area set to the OSM server * @param fileName The path to save the osm file * @throws FileNotFoundException * @throws IOException */ public static void downloadData(Connection con, Geometry area, String fileName) throws FileNotFoundException, IOException, SQLException { downloadData(con,area, fileName, false); } /** * * @param con the database connection * @param area The geometry used to compute the area set to the OSM server * @param fileName The path to save the osm file * @param deleteFile True to delete the file if exists * @throws FileNotFoundException * @throws IOException */ public static void downloadData(Connection con,Geometry area, String fileName, boolean deleteFile) throws FileNotFoundException, IOException, SQLException { File file = URIUtilities.fileFromString(fileName); if (file.exists()) { if(deleteFile){ file.delete(); } else{ throw new FileNotFoundException("The following file already exists:\n" + fileName); } } if (file.getName().toLowerCase().endsWith(".osm")) { if (area != null) { int srid = area.getSRID(); if (srid != 4326) { downloadOSMFile(file, ST_Transform.ST_Transform(con, area, 4326).getEnvelopeInternal()); } else { downloadOSMFile(file, area.getEnvelopeInternal()); } } } else { throw new SQLException("Supported format is .osm"); } } /** * Download OSM file from the official server * * @param file * @param geometryEnvelope * @throws IOException */ public static void downloadOSMFile(File file, Envelope geometryEnvelope) throws IOException { InputStream in = createOsmUrl(geometryEnvelope).openStream(); OutputStream out = new FileOutputStream(file); try { byte[] data = new byte[4096]; while (true) { int numBytes = in.read(data); if (numBytes == -1) { break; } out.write(data, 0, numBytes); } } finally { out.close(); in.close(); } } /** * Build the OSM URL based on a given envelope * * @param geometryEnvelope * @return */ private static URL createOsmUrl(Envelope geometryEnvelope) { try { return new URL(OSM_API_URL + "map?bbox=" + geometryEnvelope.getMinX() + "," + geometryEnvelope.getMinY() + "," + geometryEnvelope.getMaxX() + "," + geometryEnvelope.getMaxY()); } catch (MalformedURLException e) { throw new IllegalStateException(e); } } }