[mkgmap-splitter] 01/04: Imported Upstream version 0.0.0+svn437
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Fri Apr 1 23:17:46 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository mkgmap-splitter.
commit 100c99de7d048f491146d5f921e2031887f8f64b
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Apr 2 01:08:02 2016 +0200
Imported Upstream version 0.0.0+svn437
---
resources/splitter-version.properties | 4 +-
src/uk/me/parabola/splitter/AbstractOSMWriter.java | 21 +++-
src/uk/me/parabola/splitter/BinaryMapParser.java | 7 ++
src/uk/me/parabola/splitter/BinaryMapWriter.java | 15 ++-
.../me/parabola/splitter/DensityMapCollector.java | 14 ++-
src/uk/me/parabola/splitter/Element.java | 10 +-
.../me/parabola/splitter/EnhancedDensityMap.java | 41 ++++++--
src/uk/me/parabola/splitter/Main.java | 25 ++++-
src/uk/me/parabola/splitter/O5mMapParser.java | 12 ++-
src/uk/me/parabola/splitter/O5mMapWriter.java | 21 +++-
src/uk/me/parabola/splitter/OSMParser.java | 12 ++-
src/uk/me/parabola/splitter/OSMXMLWriter.java | 11 +-
.../parabola/splitter/SplittableDensityArea.java | 24 +++--
src/uk/me/parabola/splitter/Tile.java | 114 +++++++++++++++++++--
.../me/parabola/splitter/args/SplitterParams.java | 6 ++
15 files changed, 294 insertions(+), 43 deletions(-)
diff --git a/resources/splitter-version.properties b/resources/splitter-version.properties
index c670dbc..1d21a42 100644
--- a/resources/splitter-version.properties
+++ b/resources/splitter-version.properties
@@ -1,2 +1,2 @@
-svn.version: 429
-build.timestamp: 2016-03-02T07:39:57+0000
+svn.version: 437
+build.timestamp: 2016-03-26T09:10:19+0000
diff --git a/src/uk/me/parabola/splitter/AbstractOSMWriter.java b/src/uk/me/parabola/splitter/AbstractOSMWriter.java
index e969d03..66023b6 100644
--- a/src/uk/me/parabola/splitter/AbstractOSMWriter.java
+++ b/src/uk/me/parabola/splitter/AbstractOSMWriter.java
@@ -17,12 +17,15 @@ import java.awt.Rectangle;
import java.io.File;
public abstract class AbstractOSMWriter implements OSMWriter{
-
+ final static int REMOVE_VERSION = 1;
+ final static int FAKE_VERSION = 2;
+ final static int KEEP_VERSION = 3;
protected final Area bounds;
protected final Area extendedBounds;
protected final File outputDir;
protected final int mapId;
- protected final Rectangle bbox;
+ protected final Rectangle bbox;
+ protected int versionMethod;
public AbstractOSMWriter(Area bounds, File outputDir, int mapId, int extra) {
@@ -36,6 +39,20 @@ public abstract class AbstractOSMWriter implements OSMWriter{
this.bbox = Utils.area2Rectangle(bounds, 1);
}
+ public void setVersionMethod (int versionMethod){
+ this.versionMethod = versionMethod;
+ }
+
+ protected int getWriteVersion (Element el){
+ if (versionMethod == REMOVE_VERSION)
+ return 0;
+ if (versionMethod == FAKE_VERSION)
+ return 1;
+ // XXX maybe return 1 if no version was read ?
+ return el.getVersion();
+
+ }
+
public Area getBounds() {
return bounds;
}
diff --git a/src/uk/me/parabola/splitter/BinaryMapParser.java b/src/uk/me/parabola/splitter/BinaryMapParser.java
index 4563de1..0b6c2a8 100644
--- a/src/uk/me/parabola/splitter/BinaryMapParser.java
+++ b/src/uk/me/parabola/splitter/BinaryMapParser.java
@@ -111,6 +111,8 @@ public class BinaryMapParser extends BinaryParser implements MapReader {
tmp = new Node();
tmp.set(id, latf, lonf);
+ if (nodes.hasDenseinfo())
+ tmp.setVersion(nodes.getDenseinfo().getVersion(i));
if (!skipTags) {
if (nodes.getKeysValsCount() > 0) {
@@ -143,6 +145,8 @@ public class BinaryMapParser extends BinaryParser implements MapReader {
double latf = parseLat(i.getLat()), lonf = parseLon(i.getLon());
tmp.set(id, latf, lonf);
+ if (i.hasInfo())
+ tmp.setVersion(i.getInfo().getVersion());
processor.processNode(tmp);
elemCounter.countNode(tmp.getId());
@@ -172,6 +176,8 @@ public class BinaryMapParser extends BinaryParser implements MapReader {
long id = i.getId();
tmp.setId(id);
+ if (i.hasInfo())
+ tmp.setVersion(i.getInfo().getVersion());
processor.processWay(tmp);
elemCounter.countWay(i.getId());
@@ -195,6 +201,7 @@ public class BinaryMapParser extends BinaryParser implements MapReader {
}
long id = i.getId();
tmp.setId(id);
+ tmp.setVersion(i.getInfo().getVersion());
long last_mid=0;
for (int j =0; j < i.getMemidsCount() ; j++) {
diff --git a/src/uk/me/parabola/splitter/BinaryMapWriter.java b/src/uk/me/parabola/splitter/BinaryMapWriter.java
index 649590c..8c44a81 100644
--- a/src/uk/me/parabola/splitter/BinaryMapWriter.java
+++ b/src/uk/me/parabola/splitter/BinaryMapWriter.java
@@ -115,7 +115,10 @@ public class BinaryMapWriter extends AbstractOSMWriter {
// }
for(Element e : entities) {
- b.addVersion(1);
+ int version = getWriteVersion(e);
+ if (versionMethod != KEEP_VERSION || version == 0)
+ version = 1; // JOSM requires a fake version
+ b.addVersion(version);
b.addTimestamp(0);
b.addChangeset(0);
b.addUid(0);
@@ -127,7 +130,7 @@ public class BinaryMapWriter extends AbstractOSMWriter {
{
// StringTable stable = serializer.getStringTable();
Osmformat.Info.Builder b = Osmformat.Info.newBuilder();
- if(!omit_metadata) {
+// if(!omit_metadata) {
// if(e.getUser() == OsmUser.NONE && warncount < MAXWARN) {
// LOG
// .warning("Attention: Data being output lacks metadata. Please use omitmetadata=true");
@@ -140,6 +143,14 @@ public class BinaryMapWriter extends AbstractOSMWriter {
// b.setTimestamp((int)(e.getTimestamp().getTime() / date_granularity));
// b.setVersion(e.getVersion());
// b.setChangeset(e.getChangesetId());
+// }
+ if (versionMethod != REMOVE_VERSION){
+ int version = getWriteVersion(e);
+ b.setVersion(version);
+ b.setTimestamp(0);
+ b.setChangeset(0);
+ b.setUid(0);
+ b.setUserSid(0);
}
return b;
}
diff --git a/src/uk/me/parabola/splitter/DensityMapCollector.java b/src/uk/me/parabola/splitter/DensityMapCollector.java
index cc71e54..367a505 100644
--- a/src/uk/me/parabola/splitter/DensityMapCollector.java
+++ b/src/uk/me/parabola/splitter/DensityMapCollector.java
@@ -19,11 +19,18 @@ package uk.me.parabola.splitter;
class DensityMapCollector extends AbstractMapProcessor{
private final DensityMap densityMap;
private final MapDetails details = new MapDetails();
+ private final boolean ignoreBoundsTags;
private Area bounds;
+
- DensityMapCollector(int resolution) {
+ /**
+ * @param resolution gives the granularity of the grid
+ * @param ignoreBoundsTags true means ignore bounds found in the input file(s)
+ */
+ DensityMapCollector(int resolution, boolean ignoreBoundsTags) {
Area densityBounds = new Area(-0x400000, -0x800000, 0x400000, 0x800000);
densityMap = new DensityMap(densityBounds, resolution);
+ this.ignoreBoundsTags = ignoreBoundsTags;
}
@Override
@@ -45,8 +52,11 @@ class DensityMapCollector extends AbstractMapProcessor{
@Override
public void boundTag(Area fileBbox) {
- if (this.bounds == null)
+ if (ignoreBoundsTags)
+ return;
+ if (this.bounds == null){
this.bounds = fileBbox;
+ }
else
this.bounds = this.bounds.add(fileBbox);
}
diff --git a/src/uk/me/parabola/splitter/Element.java b/src/uk/me/parabola/splitter/Element.java
index 7fb1358..dd8fccb 100644
--- a/src/uk/me/parabola/splitter/Element.java
+++ b/src/uk/me/parabola/splitter/Element.java
@@ -22,7 +22,7 @@ import java.util.Iterator;
public abstract class Element {
protected ArrayList<Tag> tags;
private long id;
-
+ private int version;
public void setId(long id) {
this.id = id;
@@ -32,6 +32,14 @@ public abstract class Element {
return id;
}
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
class Tag {
public Tag(String key,String value) {
this.key = key;
diff --git a/src/uk/me/parabola/splitter/EnhancedDensityMap.java b/src/uk/me/parabola/splitter/EnhancedDensityMap.java
index 5c42cec..90ef497 100644
--- a/src/uk/me/parabola/splitter/EnhancedDensityMap.java
+++ b/src/uk/me/parabola/splitter/EnhancedDensityMap.java
@@ -13,6 +13,7 @@
package uk.me.parabola.splitter;
import java.awt.Rectangle;
+import java.util.BitSet;
/**
* Contains info that is needed by the {@link Tile} class. For a given
@@ -26,13 +27,17 @@ public class EnhancedDensityMap {
private final DensityMap densityMap;
private int[][] xyMap;
private int[][] yxMap;
+ private BitSet xyInPolygon;
private double[] aspectRatioFactor;
private int minAspectRatioFactorPos;
private int maxNodesInDensityMapGridElement = Integer.MIN_VALUE;
+ private int maxNodesInDensityMapGridElementInPoly = Integer.MIN_VALUE;
+ private java.awt.geom.Area polygonArea;
public EnhancedDensityMap(DensityMap densities, java.awt.geom.Area polygonArea) {
this.densityMap = densities;
- prepare(polygonArea);
+ this.polygonArea = polygonArea;
+ prepare();
}
@@ -40,12 +45,8 @@ public class EnhancedDensityMap {
* If a polygon is given, filter the density data Compute once complex
* trigonometric results for needed for proper aspect ratio calculations.
*
- * @param polygonArea
- * if not null, this is used to filter the data in the density
- * map so that grid elements outside of the polygon are
- * reduced
*/
- private void prepare(java.awt.geom.Area polygonArea){
+ private void prepare(){
// performance: calculate only once the needed complex math results
aspectRatioFactor = new double[densityMap.getHeight()+1];
int minLat = densityMap.getBounds().getMinLat();
@@ -69,6 +70,8 @@ public class EnhancedDensityMap {
int width = densityMap.getWidth();
int height = densityMap.getHeight();
xyMap = new int [width][height];
+ if (polygonArea != null)
+ xyInPolygon = new BitSet(width * height);
int shift = densityMap.getShift();
for (int x = 0; x < width; x++){
int polyXPos = densityMap.getBounds().getMinLong() + (x << shift);
@@ -77,14 +80,17 @@ public class EnhancedDensityMap {
int count = densityMap.getNodeCount(x, y);
if (polygonArea != null){
int polyYPos = densityMap.getBounds().getMinLat() + (y << shift);
- if (polygonArea.intersects(polyXPos, polyYPos, 1<<shift, 1<<shift))
- count = Math.max(1, count);
- else
- count = 0;
+ if (polygonArea.intersects(polyXPos, polyYPos, 1<<shift, 1<<shift)){
+ xyInPolygon.set(x * height + y);
+ if (count > maxNodesInDensityMapGridElementInPoly){
+ maxNodesInDensityMapGridElementInPoly = count;
+ }
+ }
}
if (count > 0){
if (count > maxNodesInDensityMapGridElement)
maxNodesInDensityMapGridElement = count;
+
xCol[y] = count;
}
}
@@ -99,6 +105,12 @@ public class EnhancedDensityMap {
}
}
+ public boolean isGridElemInPolygon (int x, int y){
+ if (polygonArea == null)
+ return true;
+ return xyInPolygon.get(x* densityMap.getHeight() + y);
+ }
+
// calculate aspect ratio of a tile which is a view on the densityMap
public double getAspectRatio(Rectangle r) {
double ratio;
@@ -140,4 +152,13 @@ public class EnhancedDensityMap {
public int getMaxNodesInDensityMapGridElement() {
return maxNodesInDensityMapGridElement;
}
+
+ public int getMaxNodesInDensityMapGridElementInPoly() {
+ return maxNodesInDensityMapGridElementInPoly;
+ }
+
+ public java.awt.geom.Area getPolygonArea() {
+ return polygonArea;
+ }
+
}
diff --git a/src/uk/me/parabola/splitter/Main.java b/src/uk/me/parabola/splitter/Main.java
index 0e983dc..3a2c9a6 100644
--- a/src/uk/me/parabola/splitter/Main.java
+++ b/src/uk/me/parabola/splitter/Main.java
@@ -149,6 +149,10 @@ public class Main {
private int searchLimit;
+ private String handleElementVersion;
+
+ private boolean ignoreBoundsTags;
+
public static void main(String[] args) {
Main m = new Main();
try{
@@ -577,6 +581,11 @@ public class Main {
searchLimit = 1000;
System.err.println("The --search-limit parameter must be 1000 or higher. Resetting to 1000.");
}
+ handleElementVersion = params.getHandleElementVersion();
+ if (Arrays.asList("remove", "fake" , "keep").contains(handleElementVersion) == false){
+ throw new IllegalArgumentException("the --handle-element-version parameter must be either remove, fake, or keep.");
+ }
+ ignoreBoundsTags = params.getIgnoreOsmBounds();
}
/**
@@ -585,7 +594,7 @@ public class Main {
*/
private AreaList calculateAreas() throws XmlPullParserException {
- DensityMapCollector pass1Collector = new DensityMapCollector(resolution);
+ DensityMapCollector pass1Collector = new DensityMapCollector(resolution, ignoreBoundsTags);
MapProcessor processor = pass1Collector;
File densityData = new File("densities.txt");
@@ -613,7 +622,7 @@ public class Main {
if (precompSeaDir != null){
System.out.println("Counting nodes of precompiled sea data ...");
long startSea = System.currentTimeMillis();
- DensityMapCollector seaCollector = new DensityMapCollector(resolution);
+ DensityMapCollector seaCollector = new DensityMapCollector(resolution, true);
PrecompSeaReader precompSeaReader = new PrecompSeaReader(exactArea, new File(precompSeaDir));
precompSeaReader.processMap(seaCollector);
pass1Collector.mergeSeaData(seaCollector, trim, resolution);
@@ -825,7 +834,7 @@ public class Main {
for (int j = 0; j < allWriters.length; j++) {
Area area = areas.get(j);
- OSMWriter w;
+ AbstractOSMWriter w;
if ("pbf".equals(outputType))
w = new BinaryMapWriter(area, fileOutputDir, area.getMapId(), overlapAmount );
else if ("o5m".equals(outputType))
@@ -834,6 +843,16 @@ public class Main {
w = new PseudoOSMWriter(area, area.getMapId(), false, overlapAmount);
else
w = new OSMXMLWriter(area, fileOutputDir, area.getMapId(), overlapAmount );
+ switch (handleElementVersion) {
+ case "keep":
+ w.setVersionMethod(AbstractOSMWriter.KEEP_VERSION);
+ break;
+ case "remove":
+ w.setVersionMethod(AbstractOSMWriter.REMOVE_VERSION);
+ break;
+ default:
+ w.setVersionMethod(AbstractOSMWriter.FAKE_VERSION);
+ }
allWriters[j] = w;
}
diff --git a/src/uk/me/parabola/splitter/O5mMapParser.java b/src/uk/me/parabola/splitter/O5mMapParser.java
index 14a1793..6dedf04 100644
--- a/src/uk/me/parabola/splitter/O5mMapParser.java
+++ b/src/uk/me/parabola/splitter/O5mMapParser.java
@@ -248,7 +248,8 @@ public class O5mMapParser implements MapReader{
lastNodeId += readSignedNum64();
if (bytesToRead == 0)
return; // only nodeId: this is a delete action, we ignore it
- readVersionTsAuthor();
+ int version = readVersionTsAuthor();
+ node.setVersion(version);
if (bytesToRead == 0)
return; // only nodeId+version: this is a delete action, we ignore it
int lon = readSignedNum32() + lastLon; lastLon = lon;
@@ -274,11 +275,12 @@ public class O5mMapParser implements MapReader{
if (bytesToRead == 0)
return; // only wayId: this is a delete action, we ignore it
- readVersionTsAuthor();
+ int version = readVersionTsAuthor();
if (bytesToRead == 0)
return; // only wayId + version: this is a delete action, we ignore it
Way way = new Way();
way.setId(lastWayId);
+ way.setVersion(version);
long refSize = readUnsignedNum32();
long stop = bytesToRead - refSize;
@@ -301,12 +303,13 @@ public class O5mMapParser implements MapReader{
lastRelId += readSignedNum64();
if (bytesToRead == 0)
return; // only relId: this is a delete action, we ignore it
- readVersionTsAuthor();
+ int version = readVersionTsAuthor();
if (bytesToRead == 0)
return; // only relId + version: this is a delete action, we ignore it
Relation rel = new Relation();
rel.setId(lastRelId);
+ rel.setVersion(version);
long refSize = readUnsignedNum32();
long stop = bytesToRead - refSize;
while(bytesToRead > stop){
@@ -365,7 +368,7 @@ public class O5mMapParser implements MapReader{
* @throws IOException
*/
- private void readVersionTsAuthor() throws IOException {
+ private int readVersionTsAuthor() throws IOException {
int version = readUnsignedNum32();
if (version != 0){
// version info
@@ -375,6 +378,7 @@ public class O5mMapParser implements MapReader{
readAuthor();
}
}
+ return version;
}
/**
* Read author .
diff --git a/src/uk/me/parabola/splitter/O5mMapWriter.java b/src/uk/me/parabola/splitter/O5mMapWriter.java
index 478b43c..e684fde 100644
--- a/src/uk/me/parabola/splitter/O5mMapWriter.java
+++ b/src/uk/me/parabola/splitter/O5mMapWriter.java
@@ -189,7 +189,8 @@ public class O5mMapWriter extends AbstractOSMWriter{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
long delta = node.getId() - lastNodeId; lastNodeId = node.getId();
writeSignedNum(delta, stream);
- stream.write(0x00); // no version info
+ writeVersion(node, stream);
+ //TODO : write version
int o5Lon = (int)(node.getLon() * FACTOR);
int o5Lat = (int)(node.getLat() * FACTOR);
int deltaLon = o5Lon - lastLon; lastLon = o5Lon;
@@ -207,7 +208,7 @@ public class O5mMapWriter extends AbstractOSMWriter{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
long delta = way.getId() - lastWayId; lastWayId = way.getId();
writeSignedNum(delta, stream);
- stream.write(0x00); // no version info
+ writeVersion(way, stream);
ByteArrayOutputStream refStream = new ByteArrayOutputStream();
LongArrayList refs = way.getRefs();
int numRefs = refs.size();
@@ -229,7 +230,7 @@ public class O5mMapWriter extends AbstractOSMWriter{
ByteArrayOutputStream stream = new ByteArrayOutputStream(256);
long delta = rel.getId() - lastRelId; lastRelId = rel.getId();
writeSignedNum(delta, stream);
- stream.write(0x00); // no version info
+ writeVersion(rel, stream);
ByteArrayOutputStream memStream = new ByteArrayOutputStream(256);
for (Member mem: rel.getMembers()){
writeRelRef(mem, memStream);
@@ -257,6 +258,20 @@ public class O5mMapWriter extends AbstractOSMWriter{
stw_write(REL_REF_TYPES[refType] + mem.getRole(), null, memStream);
}
+ private void writeVersion (Element element, OutputStream stream) throws IOException {
+ if (versionMethod == REMOVE_VERSION){
+ stream.write(0x00); // no version
+ return;
+ }
+ int version = 1;
+ if (versionMethod == KEEP_VERSION)
+ version = element.getVersion();
+ if (version != 0){
+ writeUnsignedNum(version, stream);
+ }
+ stream.write(0x00); // no author or time-stamp info
+ }
+
private void writeTags(Element element, OutputStream stream) throws IOException {
if (!element.hasTags())
return;
diff --git a/src/uk/me/parabola/splitter/OSMParser.java b/src/uk/me/parabola/splitter/OSMParser.java
index a2dec98..230b038 100644
--- a/src/uk/me/parabola/splitter/OSMParser.java
+++ b/src/uk/me/parabola/splitter/OSMParser.java
@@ -104,28 +104,38 @@ class OSMParser extends AbstractXppParser implements MapReader {
System.err.println("Node encountered with missing data. Bad/corrupt osm file? id=" + idStr + ", lat=" + latStr + ", lon=" + lonStr + ". Ignoring this node");
return;
}
-
long id = Long.parseLong(idStr);
double lat = Convert.parseDouble(latStr);
double lon = Convert.parseDouble(lonStr);
currentNode = new Node();
currentNode.set(id, lat, lon);
+ currentNode.setVersion(parseVersion());
+
state = State.Node;
}
private void startWay() {
currentWay = new Way();
currentWay.setId(getLongAttr("id"));
+ currentWay.setVersion(parseVersion());
state = State.Way;
}
private void startRelation() {
currentRelation = new Relation();
currentRelation.setId(getLongAttr("id"));
+ currentRelation.setVersion(parseVersion());
state = State.Relation;
}
+ private int parseVersion () {
+ String versionStr = getAttr("version");
+ if (versionStr == null)
+ return 0;
+ return Integer.parseInt(versionStr);
+
+ }
private void processNode(CharSequence name) {
if (name.equals("tag")) {
if (!skipTags)
diff --git a/src/uk/me/parabola/splitter/OSMXMLWriter.java b/src/uk/me/parabola/splitter/OSMXMLWriter.java
index 854cf7e..3d7d45c 100644
--- a/src/uk/me/parabola/splitter/OSMXMLWriter.java
+++ b/src/uk/me/parabola/splitter/OSMXMLWriter.java
@@ -57,7 +57,9 @@ public class OSMXMLWriter extends AbstractOSMWriter{
private void writeHeader() throws IOException {
writeString("<?xml version='1.0' encoding='UTF-8'?>\n");
- writeString("<osm version='0.5' generator='splitter' upload='false'>\n");
+ String apiVersion = (versionMethod == REMOVE_VERSION) ? "version='0.5'" : "version='0.6'";
+
+ writeString("<osm " + apiVersion + " generator='splitter' upload='false'>\n");
writeString("<bounds minlat='");
writeLongDouble(Utils.toDegrees(bounds.getMinLat()));
@@ -88,6 +90,8 @@ public class OSMXMLWriter extends AbstractOSMWriter{
writeDouble(node.getLat());
writeString("' lon='");
writeDouble(node.getLon());
+ if (versionMethod != REMOVE_VERSION)
+ writeString("' version='" + getWriteVersion(node));
if (node.hasTags()) {
writeString("'>\n");
writeTags(node);
@@ -95,11 +99,14 @@ public class OSMXMLWriter extends AbstractOSMWriter{
} else {
writeString("'/>\n");
}
+
}
public void write(Way way) throws IOException {
writeString("<way id='");
writeLong(way.getId());
+ if (versionMethod != REMOVE_VERSION)
+ writeString("' version='" + getWriteVersion(way));
writeString("'>\n");
LongArrayList refs = way.getRefs();
for (int i = 0; i < refs.size(); i++) {
@@ -115,6 +122,8 @@ public class OSMXMLWriter extends AbstractOSMWriter{
public void write(Relation rel) throws IOException {
writeString("<relation id='");
writeLong(rel.getId());
+ if (versionMethod != REMOVE_VERSION)
+ writeString("' version='" + getWriteVersion(rel));
writeString("'>\n");
List<Relation.Member> memlist = rel.getMembers();
for (Relation.Member m : memlist) {
diff --git a/src/uk/me/parabola/splitter/SplittableDensityArea.java b/src/uk/me/parabola/splitter/SplittableDensityArea.java
index 1428322..6c0fca1 100644
--- a/src/uk/me/parabola/splitter/SplittableDensityArea.java
+++ b/src/uk/me/parabola/splitter/SplittableDensityArea.java
@@ -46,6 +46,7 @@ public class SplittableDensityArea {
private long minNodes;
private final int startSearchLimit;
private int searchLimit;
+ private double maxOutsidePolygonRatio = 0.5; // TODO: maybe reduce it when a good solution was found
private final DensityMap allDensities;
private EnhancedDensityMap extraDensityInfo;
@@ -330,9 +331,13 @@ public class SplittableDensityArea {
*/
private void prepare(java.awt.geom.Area polygonArea){
extraDensityInfo = new EnhancedDensityMap(allDensities, polygonArea);
- if (!beQuiet)
+ if (!beQuiet){
System.out.println("Highest node count in a single grid element is "
- + Utils.format(extraDensityInfo.getMaxNodesInDensityMapGridElement()));
+ + Utils.format(extraDensityInfo.getMaxNodesInDensityMapGridElement()));
+ if (polygonArea != null)
+ System.out.println("Highest node count in a single grid element within the bounding polygon is "
+ + Utils.format(extraDensityInfo.getMaxNodesInDensityMapGridElementInPoly()));
+ }
if (polygonArea != null)
trimTiles = true;
@@ -611,7 +616,14 @@ public class SplittableDensityArea {
} else if (tile.width < 2 && tile.height < 2) {
return null;
}
+ if (tile.outsidePolygon()){
+ return new Solution(maxNodes);
+ }
if (addAndReturn){
+ double outsidePolygonRatio = tile.calcOutsidePolygonRatio();
+ if (outsidePolygonRatio > maxOutsidePolygonRatio ){
+ return null;
+ }
Solution solution = new Solution(maxNodes);
solution.add(tile); // can't split further
return solution;
@@ -678,16 +690,16 @@ public class SplittableDensityArea {
continue;
Tile[] parts = smi.getParts();
+ if (trimTiles){
+ parts[0] = parts[0].trim();
+ parts[1] = parts[1].trim();
+ }
if (parts[0].count > parts[1].count){
// first try the less populated part
Tile help = parts[0];
parts[0] = parts[1];
parts[1] = help;
}
- if (trimTiles){
- parts[0] = parts[0].trim();
- parts[1] = parts[1].trim();
- }
Solution [] sols = new Solution[2];
int countOK = 0;
for (int i = 0; i < 2; i++){
diff --git a/src/uk/me/parabola/splitter/Tile.java b/src/uk/me/parabola/splitter/Tile.java
index c6048c8..71efebc 100644
--- a/src/uk/me/parabola/splitter/Tile.java
+++ b/src/uk/me/parabola/splitter/Tile.java
@@ -468,40 +468,142 @@ import java.awt.Rectangle;
* @return the trimmed version of the tile.
*/
public Tile trim() {
+ long sumRemovedColCounts = 0;
+ long sumRemovedRowCounts = 0;
int minX = -1;
for (int i = 0; i < width; i++) {
- if (getColSum(i) > 0){
+ long colSum = getColSum(i) ;
+ boolean needed = (densityInfo.getPolygonArea() == null) ? colSum > 0 : (colOutsidePolygon(i) == false);
+ if (needed){
minX = x + i;
break;
}
+ sumRemovedColCounts += colSum;
}
int maxX = -1;
for (int i = width - 1; i >= 0; i--) {
- if (getColSum(i) > 0){
+ long colSum = getColSum(i) ;
+ boolean needed = (densityInfo.getPolygonArea() == null) ? colSum > 0 : (colOutsidePolygon(i) == false);
+ if (needed){
maxX = x + i;
break;
}
+ sumRemovedColCounts += colSum;
}
int minY = -1;
for (int i = 0; i < height; i++) {
- if (getRowSum(i) > 0){
+ long rowSum = getRowSum(i);
+ boolean needed = (densityInfo.getPolygonArea() == null) ? rowSum > 0 : (rowOutsidePolygon(i) == false);
+ if (needed){
minY = y + i;
break;
}
+ sumRemovedRowCounts += rowSum;
}
int maxY = -1;
for (int i = height - 1; i >= 0; i--) {
- if (getRowSum(i) > 0){
+ long rowSum = getRowSum(i);
+ boolean needed = (densityInfo.getPolygonArea() == null) ? rowSum > 0 : (rowOutsidePolygon(i) == false);
+ if (needed){
maxY = y + i;
break;
}
+ sumRemovedRowCounts += rowSum;
}
-
assert minX <= maxX;
assert minY <= maxY;
- return new Tile(densityInfo, minX, minY, maxX - minX + 1, maxY - minY + 1, count);
+ assert maxX >= 0;
+ assert maxY >= 0;
+ long newCount = count;
+ int modWidth = maxX - minX + 1;
+ int modHeight = maxY - minY + 1;
+ if (densityInfo.getPolygonArea() != null){
+ if (modWidth != width || modHeight != height){
+ // tile was trimmed, try hard to avoid a new costly calculation of the count value
+ if (width == modWidth){
+ newCount = count - sumRemovedRowCounts;
+ } else if (height == modHeight){
+ newCount = count - sumRemovedColCounts;
+ } else {
+// System.out.printf("ouch: %d %d %d %d (%d) -> %d %d %d %d\n",x,y,width,height,count,minX,minY, maxX - minX + 1, maxY - minY + 1 );
+ return new Tile (densityInfo, new Rectangle(minX, minY, modWidth, modHeight));
+ }
+ }
+ }
+ return new Tile(densityInfo, minX, minY, modWidth, modHeight, newCount);
+ }
+
+ private boolean rowOutsidePolygon(int row) {
+ if (densityInfo.getPolygonArea() == null)
+ return false;
+ // performance critical part, check corners first
+ if (densityInfo.isGridElemInPolygon(x, y + row) || densityInfo.isGridElemInPolygon(x + width-1, y + row))
+ return false;
+ // check rest of row
+ for (int i = 1; i < width-1; i++) {
+ if (densityInfo.isGridElemInPolygon(x + i, y + row))
+ return false;
+ }
+ return true;
+ }
+
+ private boolean colOutsidePolygon(int col) {
+ if (densityInfo.getPolygonArea() == null)
+ return false;
+ // performance critical part, check corners first
+ if (densityInfo.isGridElemInPolygon(x + col, y) || densityInfo.isGridElemInPolygon(x + col, y + height - 1))
+ return false;
+ // check rest of column
+ for (int i = 1; i < height - 1; i++) {
+ if (densityInfo.isGridElemInPolygon(x + col, y + i))
+ return false;
+ }
+ return true;
+ }
+
+ public boolean outsidePolygon(){
+ java.awt.geom.Area polygonArea = densityInfo.getPolygonArea();
+ if (polygonArea == null)
+ return false;
+ if (polygonArea.intersects(getRealBBox()))
+ return false;
+ return true;
+ }
+
+ /**
+ * Count the number of grid elements which are outside of the polygon area,
+ * divide it by the total number of grid elements covered by this tile to
+ * get a value between 0 and 1 (including).
+ * @return
+ */
+ public double calcOutsidePolygonRatio (){
+ if (densityInfo.getPolygonArea() == null)
+ return 0;
+ Rectangle realBBox = getRealBBox();
+// if (densityInfo.getPolygonArea().contains(realBBox) )
+// return 0;
+ // check special case: tile may contain the polygon
+ Rectangle polyBBox = densityInfo.getPolygonArea().getBounds();
+ if (realBBox.contains(polyBBox)){
+ return 0;
+ }
+ int countOutside = 0;
+ for (int i = x; i < x+width; i++){
+ for (int j = y; j < y+height; j++){
+ if (densityInfo.isGridElemInPolygon(i,j) == false)
+ countOutside++;
+ }
+ }
+ double ratio = (double) countOutside / (width * height) ;
+ return ratio;
}
+ public Rectangle getRealBBox(){
+ int shift = densityInfo.getDensityMap().getShift();
+ int polyYPos = densityInfo.getDensityMap().getBounds().getMinLat() + (y << shift);
+ int polyXPos = densityInfo.getDensityMap().getBounds().getMinLong() + (x << shift);
+ return new Rectangle(polyXPos, polyYPos, width<<shift, height<<shift);
+ }
@Override
public String toString(){
diff --git a/src/uk/me/parabola/splitter/args/SplitterParams.java b/src/uk/me/parabola/splitter/args/SplitterParams.java
index c17bc8d..987ca31 100644
--- a/src/uk/me/parabola/splitter/args/SplitterParams.java
+++ b/src/uk/me/parabola/splitter/args/SplitterParams.java
@@ -115,4 +115,10 @@ public interface SplitterParams {
@Option(defaultValue = "200000", description = "Search limit in split algo. Higher values may find better splits, but will take longer.")
int getSearchLimit();
+ @Option(defaultValue = "remove", description = "Define how splitter treats version info in the osm data. Can be remove, fake, or keep")
+ String getHandleElementVersion();
+
+ @Option(defaultValue = "false", description = "Specify if splitter should ignore bounds tags in input files")
+ boolean getIgnoreOsmBounds();
+
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mkgmap-splitter.git
More information about the Pkg-grass-devel
mailing list