use of uk.me.parabola.mkgmap.reader.osm.Relation in project mkgmap by openstreetmap.
the class StyledConverter method end.
public void end() {
pointMap.clear();
style.reportStats();
driveOnLeft = calcDrivingSide();
setHighwayCounts();
findUnconnectedRoads();
rotateClosedWaysToFirstNode();
filterCoordPOI();
WrongAngleFixer wrongAngleFixer = new WrongAngleFixer(bbox);
wrongAngleFixer.optimizeWays(roads, lines, modifiedRoads, deletedRoads, restrictions);
// make sure that copies of modified roads have equal points
for (ConvertedWay line : lines) {
if (!line.isValid())
continue;
Way way = line.getWay();
if (deletedRoads.contains(way.getId())) {
line.getPoints().clear();
continue;
}
if (!line.isOverlay())
continue;
ConvertedWay modWay = modifiedRoads.get(way.getId());
if (modWay != null) {
List<Coord> points = line.getPoints();
points.clear();
points.addAll(modWay.getPoints());
if (modWay.isReversed() != line.isReversed())
Collections.reverse(points);
}
}
for (Long wayId : deletedRoads) {
if (wayRelMap.containsKey(wayId)) {
// may happen e.g. when very short way is leading to nowhere
log.warn("Way that is used in valid restriction relation was removed, id:", wayId);
}
}
deletedRoads = null;
modifiedRoads = null;
mergeRoads();
resetHighwayCounts();
setHighwayCounts();
for (ConvertedWay cw : lines) {
if (cw.isValid())
addLine(cw.getWay(), cw.getGType());
}
lines = null;
if (roadLog.isInfoEnabled()) {
roadLog.info("Flags: oneway,no-emergency, no-delivery, no-throughroute, no-truck, no-bike, no-foot, carpool, no-taxi, no-bus, no-car");
roadLog.info(String.format("%19s %4s %11s %6s %6s %6s %s", "Road-OSM-Id", "Type", "Flags", "Class", "Speed", "Points", "Labels"));
}
// add the roads after the other lines
for (ConvertedWay cw : roads) {
if (cw.isValid())
addRoad(cw);
}
housenumberGenerator.generate(lineAdder, nextNodeId);
housenumberGenerator = null;
if (routable)
createRouteRestrictionsFromPOI();
poiRestrictions = null;
if (routable) {
for (RestrictionRelation rr : restrictions) {
rr.addRestriction(collector, nodeIdMap);
}
}
roads = null;
if (routable) {
for (Relation relation : throughRouteRelations) {
Node node = null;
Way w1 = null;
Way w2 = null;
for (Map.Entry<String, Element> member : relation.getElements()) {
if (member.getValue() instanceof Node) {
if (node == null)
node = (Node) member.getValue();
else
log.warn("Through route relation", relation.toBrowseURL(), "has more than 1 node");
} else if (member.getValue() instanceof Way) {
Way w = (Way) member.getValue();
if (w1 == null)
w1 = w;
else if (w2 == null)
w2 = w;
else
log.warn("Through route relation", relation.toBrowseURL(), "has more than 2 ways");
}
}
CoordNode coordNode = null;
if (node == null)
log.warn("Through route relation", relation.toBrowseURL(), "is missing the junction node");
else {
Coord junctionPoint = node.getLocation();
if (bbox != null && !bbox.contains(junctionPoint)) {
// junction is outside of the tile - ignore it
continue;
}
coordNode = nodeIdMap.get(junctionPoint);
if (coordNode == null)
log.warn("Through route relation", relation.toBrowseURL(), "junction node at", junctionPoint.toOSMURL(), "is not a routing node");
}
if (w1 == null || w2 == null)
log.warn("Through route relation", relation.toBrowseURL(), "should reference 2 ways that meet at the junction node");
if (coordNode != null && w1 != null && w2 != null)
collector.addThroughRoute(coordNode.getId(), w1.getId(), w2.getId());
}
}
// return memory to GC
nodeIdMap = null;
throughRouteRelations.clear();
restrictions.clear();
}
use of uk.me.parabola.mkgmap.reader.osm.Relation in project mkgmap by openstreetmap.
the class ActionRule method resolveType.
public int resolveType(int cacheId, Element el, TypeResult result) {
Element element = el;
if (expression != null) {
numEval++;
if (!expression.eval(cacheId, element))
return cacheId;
numTrue++;
// There is another reason we need to copy: since there will be
if (type != null && !type.isPropogateActions() && !(element instanceof Relation)) {
element = element.copy();
}
}
// an action will be performed, so we may have to invalidate the cache
boolean invalidate_cache = false;
for (Action a : actions) {
if (a.perform(element)) {
invalidate_cache = true;
}
}
if (invalidate_cache)
cacheId++;
if (type != null && finalizeRule != null) {
if (el == element && type.isContinueSearch())
// if there is a continue statement changes performed in
// the finalize block must not be persistent
element = element.copy();
// there is a type so first execute the finalize rules
if (type.getDefaultName() != null)
element.addTag("mkgmap:default_name", type.getDefaultName());
cacheId = finalizeRule.resolveType(cacheId, element, finalizeTypeResult);
}
result.add(element, type);
return cacheId;
}
use of uk.me.parabola.mkgmap.reader.osm.Relation in project mkgmap by openstreetmap.
the class ActionRule method resolveType.
public void resolveType(Element el, TypeResult result) {
Element element = el;
if (expression != null) {
numEval++;
if (!expression.eval(element))
return;
numTrue++;
// There is another reason we need to copy: since there will be
if (type != null && !type.isPropogateActions() && !(element instanceof Relation)) {
element = element.copy();
}
}
for (Action a : actions) a.perform(element);
if (type != null && finalizeRule != null) {
if (el == element && type.isContinueSearch())
// if there is a continue statement changes performed in
// the finalize block must not be persistent
element = element.copy();
// there is a type so first execute the finalize rules
if (type.getDefaultName() != null)
element.addTag("mkgmap:default_name", type.getDefaultName());
finalizeRule.resolveType(element, finalizeTypeResult);
}
result.add(element, type);
}
use of uk.me.parabola.mkgmap.reader.osm.Relation in project mkgmap by openstreetmap.
the class RoadMerger method workoutThroughRoutes.
private void workoutThroughRoutes(List<Relation> throughRouteRelations) {
for (Relation relation : throughRouteRelations) {
Node node = null;
Way w1 = null;
Way w2 = null;
for (Map.Entry<String, Element> member : relation.getElements()) {
if (member.getValue() instanceof Node) {
if (node == null)
node = (Node) member.getValue();
else
log.warn("Through route relation " + relation.toBrowseURL() + " has more than 1 node");
} else if (member.getValue() instanceof Way) {
Way w = (Way) member.getValue();
if (w1 == null)
w1 = w;
else if (w2 == null)
w2 = w;
else
log.warn("Through route relation " + relation.toBrowseURL() + " has more than 2 ways");
}
}
if (node == null)
log.warn("Through route relation " + relation.toBrowseURL() + " is missing the junction node");
if (w1 == null || w2 == null)
log.warn("Through route relation " + relation.toBrowseURL() + " should reference 2 ways that meet at the junction node");
if (node != null && w1 != null && w2 != null) {
restrictions.add(node.getLocation(), w1.getId());
restrictions.add(node.getLocation(), w2.getId());
}
}
}
use of uk.me.parabola.mkgmap.reader.osm.Relation in project mkgmap by openstreetmap.
the class PrecompSeaMerger method run.
public void run() {
Area merge = null;
try {
merge = mergeData.toMerge.poll(5, TimeUnit.MILLISECONDS);
} catch (InterruptedException exp) {
exp.printStackTrace();
}
int merges = 0;
while (merge != null) {
Area landClipped = new Area(mergeData.bounds);
landClipped.intersect(merge);
mergeData.tmpLandPath.append(landClipped, false);
merges++;
if (merges % 500 == 0) {
// store each 500 polygons into a temporary area
// and merge them after that. That seems to be quicker
// than adding lots of very small areas to a highly
// scattered area
Area tmpLandArea = new Area(mergeData.tmpLandPath);
mergeData.landArea.add(tmpLandArea);
mergeData.tmpLandPath.reset();
}
if (merges % 500 == 0) {
break;
}
merge = mergeData.toMerge.poll();
}
if (mergeData.ready.get() == false || mergeData.toMerge.isEmpty() == false) {
// repost the merge thread
service.execute(this);
return;
}
if (mergeData.landArea.isEmpty())
mergeData.landArea = new Area(mergeData.tmpLandPath);
else
mergeData.landArea.add(new Area(mergeData.tmpLandPath));
mergeData.tmpLandPath = null;
// post processing //
// convert the land area to a list of ways
List<Way> ways = convertToWays(mergeData.landArea, "land");
if (ways.isEmpty()) {
// no land in this tile => create a sea way only
ways.addAll(convertToWays(new Area(mergeData.bounds), "sea"));
} else {
Map<Long, Way> landWays = new HashMap<Long, Way>();
List<List<Coord>> landParts = Java2DConverter.areaToShapes(mergeData.landArea);
for (List<Coord> landPoints : landParts) {
Way landWay = new Way(FakeIdGenerator.makeFakeId(), landPoints);
landWays.put(landWay.getId(), landWay);
}
Way seaWay = new Way(FakeIdGenerator.makeFakeId());
seaWay.addPoint(new Coord(-90.0d, -180.0d));
seaWay.addPoint(new Coord(90.0d, -180.0d));
seaWay.addPoint(new Coord(90.0d, 180.0d));
seaWay.addPoint(new Coord(-90.0d, 180.0d));
// close shape
seaWay.addPoint(seaWay.getPoints().get(0));
seaWay.setClosedInOSM(true);
landWays.put(seaWay.getId(), seaWay);
Relation rel = new GeneralRelation(FakeIdGenerator.makeFakeId());
for (Way w : landWays.values()) {
rel.addElement((w == seaWay ? "outer" : "inner"), w);
}
// process the tile as sea multipolygon to create simple polygons only
MultiPolygonRelation mpr = new MultiPolygonRelation(rel, landWays, Java2DConverter.createBbox(new Area(mergeData.bounds))) {
// do not calculate the area size => it is not required and adds
// a superfluous tag
protected boolean isAreaSizeCalculated() {
return false;
}
};
mpr.addTag("type", "multipolygon");
mpr.addTag("natural", "sea");
mpr.processElements();
for (Way w : landWays.values()) {
// be ignored here
if (MultiPolygonRelation.STYLE_FILTER_POLYGON.equals(w.getTag(MultiPolygonRelation.STYLE_FILTER_TAG))) {
String tag = w.getTag("natural");
if ("sea".equals(tag) == false) {
// ignore the land polygons - we already have them in our list
continue;
}
w.deleteTag(MultiPolygonRelation.STYLE_FILTER_TAG);
w.deleteTag(MultiPolygonRelation.MP_CREATED_TAG);
ways.add(w);
}
}
}
try {
// forward the ways to the queue of the saver thread
saveQueue.put(new SimpleEntry<String, List<Way>>(mergeData.getKey(), ways));
} catch (InterruptedException exp) {
exp.printStackTrace();
}
// signal that this tile is finished
signal.countDown();
}
Aggregations