Rev 2272 |
View as "text/plain" |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* 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.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
/**
* The class merges two directories with precompiled bounds files. Both directory may contain files covering
* the same area. These files are merged so that the resulting file contains all boundaries of both
* files. Boundaries with the same OSM-id that are contained in both files are merged with a union of its covered area.
* <br/><br/>
* Using this merger it is possible to create several smaller bounds compilations (e.g. one country only) and merge
* these compilations together afterwards.
*
* @author WanMil
*/
public class BoundaryMerger
{
public BoundaryMerger
() {
}
private void copy
(File file,
File to
) {
String filename = file.
getName();
try {
FileChannel in =
(new FileInputStream(file
)).
getChannel();
FileChannel out =
(new FileOutputStream(new File(to,filename
))).
getChannel();
in.
transferTo(0, file.
length(), out
);
in.
close();
out.
close();
} catch (IOException exp
) {
System.
err.
println(exp
);
}
}
public void merge
(File dir1,
File dir2,
File targetDir
) throws IOException {
List<String> fl1 = BoundaryUtil.
getBoundaryDirContent(dir1.
getAbsolutePath());
List<String> fl2 = BoundaryUtil.
getBoundaryDirContent(dir2.
getAbsolutePath());
Collections.
sort(fl1
);
Collections.
sort(fl2
);
ListIterator<String> fl1Iter = fl1.
listIterator();
ListIterator<String> fl2Iter = fl2.
listIterator();
BoundarySaver bSave =
new BoundarySaver
(targetDir, BoundarySaver.
QUADTREE_DATA_FORMAT);
bSave.
setCreateEmptyFiles(false);
List<File> copy =
new ArrayList<File>();
int processed =
0;
int all = fl1.
size()+fl2.
size();
while (fl1Iter.
hasNext() || fl2Iter.
hasNext()) {
String f1 =
(fl1Iter.
hasNext() ? fl1Iter.
next():
null);
String f2 =
(fl2Iter.
hasNext() ? fl2Iter.
next():
null);
if (f1 ==
null) {
copy.
add(new File(dir2,f2
));
} else if (f2 ==
null) {
copy.
add(new File(dir1,f1
));
} else {
int cmp = f1.
compareTo(f2
);
if (cmp
< 0) {
copy.
add(new File(dir1,f1
));
fl2Iter.
previous();
} else if (cmp
> 0) {
copy.
add(new File(dir2,f2
));
fl1Iter.
previous();
} else {
BoundaryQuadTree bqt1 = BoundaryUtil.
loadQuadTree(dir1.
getAbsolutePath(), f1
);
if (bqt1 ==
null){
System.
err.
println("Failed to load quadtree for " + dir1.
getAbsolutePath() + f1
);
System.
exit(-
1);
}
BoundaryQuadTree bqt2 = BoundaryUtil.
loadQuadTree(dir2.
getAbsolutePath(), f2
);
if (bqt2 ==
null){
System.
err.
println("Failed to load quadtree for " + dir2.
getAbsolutePath() + f2
);
System.
exit(-
1);
}
bqt1.
merge(bqt2
);
bSave.
saveQuadTree(bqt1, f1
);
processed +=
2;
System.
out.
println(processed+
"/"+all+
" processed");
}
}
}
bSave.
end();
for (File f: copy
) {
copy
(f, targetDir
);
processed++
;
System.
out.
println(processed+
"/"+all+
" processed");
}
}
/**
* @param args
* @throws IOException
*/
public static void main
(String[] args
) throws IOException {
if (args.
length !=
3) {
System.
err.
println("java uk.me.parabola.mkgmap.reader.osm.boundary.BoundaryMerger <bounds1> <bounds2> <merge>");
System.
err.
println("<bounds1> <bounds2> : directories with *.bnd files to merge");
System.
err.
println("<merge> target directory, is created if it doesn't exist");
return;
}
File b1 =
new File(args
[0]);
File b2 =
new File(args
[1]);
File merge =
new File(args
[2]);
// TODO: maybe allow zip as input
if (b1.
exists() ==
false || b1.
isDirectory() ==
false) {
System.
err.
println(b1 +
" does not exist or is not a directory");
return;
}
if (b2.
exists() ==
false || b2.
isDirectory() ==
false) {
System.
err.
println(b2 +
" does not exist or is not a directory");
return;
}
if (merge.
exists() && merge.
isDirectory() ==
false) {
System.
err.
println(merge +
" is not a directory");
}
if (merge.
exists() ==
false) {
merge.
mkdirs();
}
BoundaryMerger merger =
new BoundaryMerger
();
merger.
merge(b1, b2, merge
);
}
}