org.servalproject.maps.osmbboxsplit.BBoxSplit.java Source code

Java tutorial

Introduction

Here is the source code for org.servalproject.maps.osmbboxsplit.BBoxSplit.java

Source

/*
 * Copyright (C) 2012 The Serval Project
 *
 * This file is part of the Serval Maps OSM Bounding Box Split Software
 *
 * Serval Maps OSM PBF Metadata Reader Software 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 3 of the License, or (at your option) any later version.
 *
 * This source code 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 source code; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.servalproject.maps.osmbboxsplit;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.servalproject.maps.osmbboxsplit.utils.FileUtils;

import crosby.binary.file.BlockInputStream;

/**
 * class used to calculate the bounding box split and optionally write an
 * osmosis script based on the supplied template
 */
public class BBoxSplit {

    /**
     * read an OSM PBF file and optionally write an osmosis script using the supplied template
     * 
     * @param inputFile path to the input file
     * @param outputDir path to the output directory
     * @param template the contents of the template file
     * @param minFileSize the minimum file size, in MB, of files to process
     * @throws IOException if the specified file cannot be read
     */
    public static void readFile(File inputFile, File outputDir, String template, int minFileSize)
            throws IOException {

        // check the parameters
        try {
            if (FileUtils.isFileAccessible(inputFile.getCanonicalPath()) == false) {
                throw new IOException("unable to access the required file");
            }

            System.out.println("Processing file: " + inputFile.getCanonicalPath());

        } catch (IOException e) {
            throw new IOException("unable to access the required file", e);
        }

        // check to see if this file should be ignored
        if (OsmBBoxSplit.ignoreList.size() > 0) {
            if (OsmBBoxSplit.ignoreList.contains(inputFile.getCanonicalPath())) {
                System.out.println("WARNING: File specified in the ignore list, skipping...");
                return;
            }
        }

        // read the data in the file
        BlockInputStream blockinput;
        BinaryDataParser dataParser = new BinaryDataParser();
        try {
            blockinput = (new BlockInputStream(new FileInputStream(inputFile), dataParser));
        } catch (FileNotFoundException e) {
            throw new IOException("unable to access the required file", e);
        }

        // output some information
        try {
            blockinput.process();

            System.out.println("File Size: " + FileUtils.humanReadableByteCount(inputFile.length(), true));
        } catch (IOException e) {
            throw new IOException("unable to process the required file", e);
        } finally {
            blockinput.close();
        }

        // determine if we need to split the file
        if (inputFile.length() >= (minFileSize * 1000 * 1000)) {
            // file is over the minimum file size so try to split

            double minLat = dataParser.getGeoCoordinates()[0];
            double minLng = dataParser.getGeoCoordinates()[1];
            double maxLat = dataParser.getGeoCoordinates()[2];
            double maxLng = dataParser.getGeoCoordinates()[3];

            //         boolean latOk = false;
            //         boolean lngOk = false;
            //         
            //         // check to make sure that the all of the lats and longs are of the same size
            //         if((minLat < 0 && maxLat < 0) || (minLat > 0 && maxLat > 0)) {
            //            latOk = true;
            //         }
            //         
            //         if((minLng < 0 && maxLng < 0) || (minLng > 0 && maxLng > 0)) {
            //            lngOk = true;
            //         }
            //         
            //         if(!latOk || !lngOk) {
            //            System.out.println("Error: bounding box spans equator or prime meridian, can't split");
            //            return;
            //         }
            //         
            //         // calculate the differences
            //         double diffLat = (maxLat - minLat) / 2;
            //         double diffLng = (maxLng - minLng) / 2;
            //         
            //         // calculate the new bounding boxes
            //         double newLat = minLat + diffLat;
            //         double newLng = minLng + diffLng;

            // calculate the new latitude and longitude
            double newLat = (minLat + maxLat) / 2;
            double newLng = (minLng + maxLng) / 2;

            // output the new definitions
            System.out.println("BBox A lat/lng: " + newLat + ", " + minLng + " - " + maxLat + ", " + newLng);
            System.out
                    .println("URL: " + String.format(BinaryDataParser.URL_FORMAT, minLng, newLat, newLng, maxLat));

            System.out.println("BBox B lat/lng: " + newLat + ", " + newLng + " - " + maxLat + ", " + maxLng);
            System.out
                    .println("URL: " + String.format(BinaryDataParser.URL_FORMAT, newLng, newLat, maxLng, maxLat));

            System.out.println("BBox C lat/lng: " + minLat + ", " + minLng + " - " + newLat + ", " + newLng);
            System.out
                    .println("URL: " + String.format(BinaryDataParser.URL_FORMAT, minLng, minLat, newLng, newLat));

            System.out.println("BBox D lat/lng: " + minLat + ", " + newLng + " - " + newLat + ", " + maxLng);
            System.out
                    .println("URL: " + String.format(BinaryDataParser.URL_FORMAT, newLng, minLat, maxLng, newLat));

            // create a new script
            if (template != null) {

                String scriptContents = new String(template);

                // add missing information
                scriptContents = scriptContents.replace("{{INPUT_PATH}}", inputFile.getCanonicalPath());
                scriptContents = scriptContents.replace("{{OUTPUT_PATH}}",
                        inputFile.getCanonicalFile().getParent());

                //replace all of the a quadrant variables
                scriptContents = scriptContents.replace("{{BBOX_A_BOTTOM}}", Double.toString(newLat));
                scriptContents = scriptContents.replace("{{BBOX_A_LEFT}}", Double.toString(minLng));
                scriptContents = scriptContents.replace("{{BBOX_A_TOP}}", Double.toString(maxLat));
                scriptContents = scriptContents.replace("{{BBOX_A_RIGHT}}", Double.toString(newLng));
                scriptContents = scriptContents.replace("{{BBOX_A_FILE}}",
                        inputFile.getName().replace(".osm.pbf", "_a.osm.pbf"));

                scriptContents = scriptContents.replace("{{BBOX_B_BOTTOM}}", Double.toString(newLat));
                scriptContents = scriptContents.replace("{{BBOX_B_LEFT}}", Double.toString(newLng));
                scriptContents = scriptContents.replace("{{BBOX_B_TOP}}", Double.toString(maxLat));
                scriptContents = scriptContents.replace("{{BBOX_B_RIGHT}}", Double.toString(maxLng));
                scriptContents = scriptContents.replace("{{BBOX_B_FILE}}",
                        inputFile.getName().replace(".osm.pbf", "_b.osm.pbf"));

                scriptContents = scriptContents.replace("{{BBOX_C_BOTTOM}}", Double.toString(minLat));
                scriptContents = scriptContents.replace("{{BBOX_C_LEFT}}", Double.toString(minLng));
                scriptContents = scriptContents.replace("{{BBOX_C_TOP}}", Double.toString(newLat));
                scriptContents = scriptContents.replace("{{BBOX_C_RIGHT}}", Double.toString(newLng));
                scriptContents = scriptContents.replace("{{BBOX_C_FILE}}",
                        inputFile.getName().replace(".osm.pbf", "_c.osm.pbf"));

                scriptContents = scriptContents.replace("{{BBOX_D_BOTTOM}}", Double.toString(minLat));
                scriptContents = scriptContents.replace("{{BBOX_D_LEFT}}", Double.toString(newLng));
                scriptContents = scriptContents.replace("{{BBOX_D_TOP}}", Double.toString(newLat));
                scriptContents = scriptContents.replace("{{BBOX_D_RIGHT}}", Double.toString(maxLng));
                scriptContents = scriptContents.replace("{{BBOX_D_FILE}}",
                        inputFile.getName().replace(".osm.pbf", "_d.osm.pbf"));

                // write the file
                try {

                    File newFile = new File(
                            outputDir.getCanonicalPath() + File.separator + inputFile.getName() + ".sh");

                    System.out.println("writing script file:\n" + newFile.getCanonicalPath());

                    org.apache.commons.io.FileUtils.writeStringToFile(newFile, scriptContents);

                    newFile.setExecutable(true);

                } catch (IOException e) {
                    throw new IOException("unable to write the script file.", e);
                }
            }

        }

    }

    /**
     * read a directory looking for OSM PBF files to process
     * 
     * @param inputDir path to the parent directory
     * @param outputDir path to the output directory
     * @param template the contents of the template file
     * @param minFileSize the minimum file size, in MB, of files to process
     * @throws IOException if a file / directory cannot be accessed
     */
    public static void readFilesInDir(File inputDir, File outputDir, String template, int minFileSize)
            throws IOException {

        // check the parameters
        try {
            if (FileUtils.isDirectoryAccessible(inputDir.getCanonicalPath()) == false) {
                throw new IOException("unable to access the required file");
            }
        } catch (IOException e) {
            throw new IOException("unable to access the required file", e);
        }

        // get a list of map files in the directory
        File[] fileList = FileUtils.getFileListWithDirs(inputDir, ".osm.pbf");

        // test each of the files in turn
        for (File file : fileList) {

            // check to see if this is a subdirectory
            if (file.isDirectory()) {
                readFilesInDir(file, outputDir, template, minFileSize);
            } else {
                readFile(file, outputDir, template, minFileSize);
            }
        }

    }

}