use of uk.me.parabola.mkgmap.reader.osm.Way in project mkgmap by openstreetmap.
the class BoundaryRelation method processElements.
/**
* Process the ways in this relation. Joins way with the role "outer" Adds
* ways with the role "inner" to the way with the role "outer"
*/
public void processElements() {
log.info("Processing multipolygon", toBrowseURL());
List<Way> allWays = getSourceWays();
// join all single ways to polygons, try to close ways and remove non closed ways
polygons = joinWays(allWays);
outerWaysForLineTagging = new HashSet<>();
outerTags = new HashMap<>();
removeOutOfBbox(polygons);
do {
closeWays(polygons, getMaxCloseDist());
} while (connectUnclosedWays(polygons));
removeUnclosedWays(polygons);
// now only closed ways are left => polygons only
// check if we have at least one polygon left
boolean hasPolygons = !polygons.isEmpty();
removeWaysOutsideBbox(polygons);
if (polygons.isEmpty()) {
// do nothing
if (log.isInfoEnabled()) {
if (hasPolygons)
log.info("Multipolygon", toBrowseURL(), "is completely outside the bounding box. It is not processed.");
else
log.info("Multipolygon " + toBrowseURL() + " does not contain a closed polygon.");
}
tagOuterWays();
cleanup();
return;
}
// the intersectingPolygons marks all intersecting/overlapping polygons
intersectingPolygons = new HashSet<>();
// check which polygons lie inside which other polygon
createContainsMatrix(polygons);
// unfinishedPolygons marks which polygons are not yet processed
unfinishedPolygons = new BitSet(polygons.size());
unfinishedPolygons.set(0, polygons.size());
// create bitsets which polygons belong to the outer and to the inner role
innerPolygons = new BitSet();
taggedInnerPolygons = new BitSet();
outerPolygons = new BitSet();
taggedOuterPolygons = new BitSet();
int wi = 0;
for (Way w : polygons) {
String role = getRole(w);
if ("inner".equals(role)) {
innerPolygons.set(wi);
taggedInnerPolygons.set(wi);
} else if ("outer".equals(role)) {
outerPolygons.set(wi);
taggedOuterPolygons.set(wi);
} else {
// unknown role => it could be both
innerPolygons.set(wi);
outerPolygons.set(wi);
}
wi++;
}
if (outerPolygons.isEmpty()) {
log.warn("Multipolygon", toBrowseURL(), "does not contain any way tagged with role=outer or empty role.");
cleanup();
return;
}
Queue<PolygonStatus> polygonWorkingQueue = new LinkedBlockingQueue<PolygonStatus>();
BitSet nestedOuterPolygons = new BitSet();
BitSet nestedInnerPolygons = new BitSet();
BitSet outmostPolygons;
BitSet outmostInnerPolygons = new BitSet();
boolean outmostInnerFound;
do {
outmostInnerFound = false;
outmostPolygons = findOutmostPolygons(unfinishedPolygons);
if (outmostPolygons.intersects(taggedInnerPolygons)) {
outmostInnerPolygons.or(outmostPolygons);
outmostInnerPolygons.and(taggedInnerPolygons);
if (log.isDebugEnabled())
log.debug("wrong inner polygons: " + outmostInnerPolygons);
// do not process polygons tagged with role=inner but which are
// not contained by any other polygon
unfinishedPolygons.andNot(outmostInnerPolygons);
outmostPolygons.andNot(outmostInnerPolygons);
outmostInnerFound = true;
}
} while (outmostInnerFound);
if (!outmostPolygons.isEmpty()) {
polygonWorkingQueue.addAll(getPolygonStatus(outmostPolygons, "outer"));
}
boolean outmostPolygonProcessing = true;
outerResultArea = new java.awt.geom.Area();
while (!polygonWorkingQueue.isEmpty()) {
// the polygon is not contained by any other unfinished polygon
PolygonStatus currentPolygon = polygonWorkingQueue.poll();
// this polygon is now processed and should not be used by any
// further step
unfinishedPolygons.clear(currentPolygon.index);
BitSet polygonContains = new BitSet();
polygonContains.or(containsMatrix.get(currentPolygon.index));
// use only polygon that are contained by the polygon
polygonContains.and(unfinishedPolygons);
// polygonContains is the intersection of the unfinished and
// the contained polygons
// get the holes
// these are all polygons that are in the main polygon
// and that are not contained by any other polygon
boolean holesOk;
BitSet holeIndexes;
do {
holeIndexes = findOutmostPolygons(polygonContains);
holesOk = true;
if (currentPolygon.outer) {
// for role=outer only role=inner is allowed
if (holeIndexes.intersects(taggedOuterPolygons)) {
BitSet addOuterNestedPolygons = new BitSet();
addOuterNestedPolygons.or(holeIndexes);
addOuterNestedPolygons.and(taggedOuterPolygons);
nestedOuterPolygons.or(addOuterNestedPolygons);
holeIndexes.andNot(addOuterNestedPolygons);
// do not process them
unfinishedPolygons.andNot(addOuterNestedPolygons);
polygonContains.andNot(addOuterNestedPolygons);
// recalculate the holes again to get all inner polygons
// in the nested outer polygons
holesOk = false;
}
} else {
// although inner in inner is not officially allowed
if (holeIndexes.intersects(taggedInnerPolygons)) {
// process inner in inner but issue a warning later
BitSet addInnerNestedPolygons = new BitSet();
addInnerNestedPolygons.or(holeIndexes);
addInnerNestedPolygons.and(taggedInnerPolygons);
nestedInnerPolygons.or(addInnerNestedPolygons);
}
}
} while (!holesOk);
ArrayList<PolygonStatus> holes = getPolygonStatus(holeIndexes, (currentPolygon.outer ? "inner" : "outer"));
// these polygons must all be checked for holes
polygonWorkingQueue.addAll(holes);
if (currentPolygon.outer) {
// add the original ways to the list of ways that get the line tags of the mp
// the joined ways may be changed by the auto closing algorithm
outerWaysForLineTagging.addAll(currentPolygon.polygon.getOriginalWays());
}
if (currentPolygon.outer) {
java.awt.geom.Area toAdd = Java2DConverter.createArea(currentPolygon.polygon.getPoints());
if (outerResultArea.isEmpty())
outerResultArea = toAdd;
else
outerResultArea.add(toAdd);
for (Way outerWay : currentPolygon.polygon.getOriginalWays()) {
if (outmostPolygonProcessing) {
for (Entry<String, String> tag : outerWay.getTagEntryIterator()) {
outerTags.put(tag.getKey(), tag.getValue());
}
outmostPolygonProcessing = false;
} else {
for (String tag : new ArrayList<String>(outerTags.keySet())) {
if (outerTags.get(tag).equals(outerWay.getTag(tag)) == false) {
outerTags.remove(tag);
}
}
}
}
} else {
outerResultArea.subtract(Java2DConverter.createArea(currentPolygon.polygon.getPoints()));
}
}
if (hasStyleRelevantTags(this)) {
outerTags.clear();
for (Entry<String, String> mpTags : getTagEntryIterator()) {
if ("type".equals(mpTags.getKey()) == false) {
outerTags.put(mpTags.getKey(), mpTags.getValue());
}
}
} else {
for (Entry<String, String> mpTags : outerTags.entrySet()) {
addTag(mpTags.getKey(), mpTags.getValue());
}
}
// the simple line information should be used.
for (Way orgOuterWay : outerWaysForLineTagging) {
// lineTagWay.addTag(STYLE_FILTER_TAG, STYLE_FILTER_LINE);
for (Entry<String, String> tag : outerTags.entrySet()) {
// remove the tag from the original way if it has the same value
if (tag.getValue().equals(orgOuterWay.getTag(tag.getKey()))) {
removeTagsInOrgWays(orgOuterWay, tag.getKey());
}
}
// if (log.isDebugEnabled())
// log.debug("Add line way", lineTagWay.getId(), lineTagWay.toTagString());
// tileWayMap.put(lineTagWay.getId(), lineTagWay);
}
postProcessing();
cleanup();
}
use of uk.me.parabola.mkgmap.reader.osm.Way in project mkgmap by openstreetmap.
the class PrecompSeaMerger method convertToWays.
private List<Way> convertToWays(Area a, String naturalTag) {
List<List<Coord>> pointLists = Java2DConverter.areaToShapes(a);
List<Way> ways = new ArrayList<Way>(pointLists.size());
for (List<Coord> points : pointLists) {
Way w = new Way(FakeIdGenerator.makeFakeId(), points);
w.addTag("natural", naturalTag);
w.setClosedInOSM(true);
ways.add(w);
}
return ways;
}
use of uk.me.parabola.mkgmap.reader.osm.Way in project mkgmap by openstreetmap.
the class RuleFileReaderTest method testComplexExpressions.
/**
* Try out arithmetic comparisons and mixtures of 'and' and 'or'.
*/
@Test
public void testComplexExpressions() {
String str = "a=b & (c=d | e=f) & x>10 [0x1]\n";
RuleSet rs = makeRuleSet(str);
Element el = new Way(1);
el.addTag("a", "b");
el.addTag("c", "d");
el.addTag("x", "11");
GType type = getFirstType(rs, el);
assertNotNull(type);
assertEquals("expression ok", 1, type.getType());
// fails with x less than 10
el.addTag("x", "9");
type = getFirstType(rs, el);
assertNull("x too low", type);
// also fails with x equal to 10
el.addTag("x", "10");
type = getFirstType(rs, el);
assertNull("x too low", type);
// OK with x > 10
el.addTag("x", "100");
el.addTag("e", "f");
type = getFirstType(rs, el);
assertNotNull(type);
assertEquals("c and e set", 1, type.getType());
el.addTag("c", "");
el.addTag("e", "");
type = getFirstType(rs, el);
assertNull("none of c and e set", type);
el.addTag("e", "f");
type = getFirstType(rs, el);
assertNotNull(type);
assertEquals("e is set to f", 1, type.getType());
}
use of uk.me.parabola.mkgmap.reader.osm.Way in project mkgmap by openstreetmap.
the class RuleFileReaderTest method testValueTagValue.
@Test
public void testValueTagValue() {
RuleSet rs = makeRuleSet("a=$b [0x5]");
Way w = new Way(1);
w.addTag("a", "2");
w.addTag("b", "2");
GType type = getFirstType(rs, w);
assertNotNull(type);
assertEquals(5, type.getType());
}
use of uk.me.parabola.mkgmap.reader.osm.Way in project mkgmap by openstreetmap.
the class RuleFileReaderTest method testLoad.
/**
* Test of a file containing a number of different rules, with varying
* formatting and including comments.
*/
@Test
public void testLoad() {
RuleSet rs = makeRuleSet("highway=footway & type=rough [0x2 level 2]\n" + "highway=footway | highway = path\n" + " [0x3]\n# comment here\n" + "foo=\nbar & bar=two [0x4]\n" + "highway=* & oneway=true [0x6 level 1]\n" + "");
Element el = new Way(1);
el.addTag("highway", "footway");
GType type = getFirstType(rs, el);
assertNotNull(type);
assertEquals("plain footway", "[0x3 level 0]", type.toString());
el.addTag("type", "rough");
type = getFirstType(rs, el);
assertNotNull(type);
assertEquals("rough footway", "[0x2 level 2]", type.toString());
}
Aggregations