/*
* 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();
}
}
}