/* * Copyright (C) 2006, 2011. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 or * version 2 as published by the Free Software Foundation. * * 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. */ package uk.me.parabola.mkgmap.reader.osm.boundary; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import uk.me.parabola.imgfmt.app.Coord; import uk.me.parabola.mkgmap.reader.osm.Tags; import uk.me.parabola.mkgmap.reader.osm.Way; import uk.me.parabola.util.GpxCreator; import uk.me.parabola.util.Java2DConverter; public class BoundaryFile2Gpx { private final String boundaryFileName; private final BoundaryQuadTree bqt; public BoundaryFile2Gpx(String boundaryDirName, String boundaryFileName) { this.boundaryFileName = boundaryFileName; bqt = BoundaryUtil.loadQuadTree(boundaryDirName, boundaryFileName); } /** * Create gpx files for areas which contain no information for a given * admin level. * @param admLevel reasonable values are 2..11 */ public void saveEmptyAreas(int admLevel) { Area tileArea = Java2DConverter.createBoundsArea(BoundaryUtil .getBbox(boundaryFileName)); Area coveredArea = bqt.getCoveredArea(admLevel); tileArea.subtract(coveredArea); String levelId = "admin_level" ; if (admLevel < 12) levelId += admLevel; else levelId += "notset"; if (tileArea.isEmpty()) { System.out.println(levelId + " is covered completely."); } else { String gpxBasename = "gpx/" + boundaryFileName + "/uncovered/" + levelId + "/"; List<List<Coord>> emptyPolys = Java2DConverter .areaToShapes(tileArea); Collections.reverse(emptyPolys); int i = 0; for (List<Coord> emptyPart : emptyPolys) { String attr = Way.clockwise(emptyPart) ? "o" : "i"; GpxCreator.createGpx(gpxBasename + i + "_" + attr, emptyPart); i++; } } } /** * create gpx files for all boundaries contained in one *.bnd file */ public void saveAsGpx() { System.out.println("Start converting " + boundaryFileName); Map<String, Tags> bTags = bqt.getTagsMap(); Map<String, List<Area>> areas = bqt.getAreas(); // verify data: remove boundary ids that have no related areas Iterator<Entry<String, Tags>> tagIter = bTags.entrySet().iterator(); while (tagIter.hasNext()) { Entry<String, Tags> entry = tagIter.next(); List<Area> aList = areas.get(entry.getKey()); if (aList == null || aList.isEmpty()){ System.err.println("no area info for "+ entry.getKey()); tagIter.remove(); continue; } } for (int adminlevel = 2; adminlevel < 12; adminlevel++) { boolean found = false; for (Entry<String, Tags> entry: bTags.entrySet()){ String admLevel = entry.getValue().get("admin_level"); if (admLevel != null && admLevel.equals(String.valueOf(adminlevel))){ found = true; break; } } if (found == false){ System.out.println("No boundary with admin_level=" + adminlevel + " found."); continue; } for (Entry<String, Tags> entry: bTags.entrySet()){ // get the admin_level tag String admLevel = entry.getValue().get("admin_level"); if (admLevel == null) { admLevel = "notset"; } String bId = entry.getKey(); String gpxBasename = "gpx/" + boundaryFileName + "/covered/admin_level=" + admLevel + "/" + admLevel + "_" + bId + "_"; Path2D.Double path = new Path2D.Double(); List<Area> aList = areas.get(bId); for (Area area : aList){ path.append(area, false); } int i = 0; List<BoundaryElement> bElements = BoundaryUtil.splitToElements(new Area(path),bId); for (BoundaryElement be : bElements){ String gpxFile = gpxBasename; if (be.isOuter()) { gpxFile += "o_" + i; } else { gpxFile = "i_" + i; } GpxCreator.createGpx(gpxFile, be.getPoints()); i++; } } saveEmptyAreas(adminlevel); } System.out.println("Finished " + boundaryFileName); } /** * @param args */ public static void main(String[] args) { String boundaryDirName = args[0]; System.out.println(boundaryDirName); File boundaryDir = new File(boundaryDirName); List<String> boundaryFileNames; if (boundaryDir.isFile() && boundaryDir.getName().endsWith(".bnd")) { boundaryDirName = boundaryDir.getParent(); if (boundaryDirName == null) boundaryDirName = "."; boundaryFileNames = new ArrayList<String>(); boundaryFileNames.add(boundaryDir.getName()); } else { boundaryFileNames = BoundaryUtil.getBoundaryDirContent(boundaryDirName); } for (String boundaryFileName : boundaryFileNames) { BoundaryFile2Gpx converter = new BoundaryFile2Gpx(boundaryDirName,boundaryFileName); converter.saveAsGpx(); } } }