use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class ElementQuadTreeNode method split.
/**
* Splits this quadtree node into 4 subnodes.
*/
private void split() {
if (bounds.getHeight() <= 5 || bounds.getWidth() <= 5) {
log.error("Do not split more due to too small bounds: " + bounds);
return;
}
int halfLat = (bounds.getMinLat() + bounds.getMaxLat()) / 2;
int halfLong = (bounds.getMinLong() + bounds.getMaxLong()) / 2;
children = new ElementQuadTreeNode[4];
Area[] childBounds = new Area[4];
childBounds[0] = new Area(bounds.getMinLat(), bounds.getMinLong(), halfLat, halfLong);
childBounds[1] = new Area(halfLat, bounds.getMinLong(), bounds.getMaxLat(), halfLong);
childBounds[2] = new Area(bounds.getMinLat(), halfLong, halfLat, bounds.getMaxLong());
childBounds[3] = new Area(halfLat, halfLong, bounds.getMaxLat(), bounds.getMaxLong());
List<Map<Element, List<Coord>>> childElems = new ArrayList<Map<Element, List<Coord>>>(4);
for (int i = 0; i < 4; i++) {
childElems.add(new HashMap<Element, List<Coord>>());
}
for (Entry<Element, List<Coord>> elem : elementMap.entrySet()) {
if (elem.getKey() instanceof Node) {
Node node = (Node) elem.getKey();
for (int i = 0; i < childBounds.length; i++) {
if (childBounds[i].contains(node.getLocation())) {
childElems.get(i).put(node, EMPTY_LIST);
break;
}
}
} else if (elem.getKey() instanceof Way) {
List<List<Coord>> points = new ArrayList<List<Coord>>(4);
for (int i = 0; i < 4; i++) {
// usually ways are quite local
// therefore there is a high probability that only one child is covered
// dim the new list as the old list
points.add(new ArrayList<Coord>(elem.getValue().size()));
}
for (Coord c : elem.getValue()) {
for (int i = 0; i < childBounds.length; i++) {
if (childBounds[i].contains(c)) {
points.get(i).add(c);
break;
}
}
}
for (int i = 0; i < 4; i++) {
if (points.get(i).isEmpty() == false) {
childElems.get(i).put(elem.getKey(), points.get(i));
}
}
}
}
for (int i = 0; i < 4; i++) {
children[i] = new ElementQuadTreeNode(childBounds[i], childElems.get(i));
}
elementMap = null;
}
use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class ElementQuadTreeNode method get.
/**
* Retrieves all elements that intersects the given polygon.
* @param polygon the polygon
* @param resultList results are stored in this collection
* @return the resultList
*/
public Set<Element> get(ElementQuadTreePolygon polygon, Set<Element> resultList) {
if (isEmpty()) {
return resultList;
}
if (polygon.getBbox().intersects(getBounds())) {
if (isLeaf()) {
for (Entry<Element, List<Coord>> elem : elementMap.entrySet()) {
if (resultList.contains(elem.getKey())) {
continue;
}
if (elem.getKey() instanceof Node) {
Node n = (Node) elem.getKey();
Coord c = n.getLocation();
if (polygon.getArea().contains(c.getLongitude(), c.getLatitude())) {
resultList.add(n);
}
} else if (elem.getKey() instanceof Way) {
for (Coord c : elem.getValue()) {
if (polygon.getArea().contains(c.getLongitude(), c.getLatitude())) {
resultList.add(elem.getKey());
break;
}
}
}
}
} else {
for (ElementQuadTreeNode child : children) {
if (child.isEmpty() == false && polygon.getArea().intersects(child.getBoundsAsRectangle())) {
java.awt.geom.Area subArea = (java.awt.geom.Area) polygon.getArea().clone();
subArea.intersect(Java2DConverter.createBoundsArea(new Area(child.getBounds().getMinLat() - 1, child.getBounds().getMinLong() - 1, child.getBounds().getMaxLat() + 1, child.getBounds().getMaxLong() + 1)));
child.get(new ElementQuadTreePolygon(subArea), resultList);
}
}
}
}
return resultList;
}
use of uk.me.parabola.mkgmap.reader.osm.Node 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.Node in project mkgmap by openstreetmap.
the class WrongAngleFixer method getReplacement.
/**
* Common code to handle replacements of points in ways. Checks for special
* cases regarding CoordPOI.
*
* @param p point to replace
* @param way way that contains p
* @param replacements the Map containing the replaced points
* @return the replacement
*/
private static Coord getReplacement(Coord p, Way way, Map<Coord, Coord> replacements) {
// it was previously merged into another point
if (p.isReplaced()) {
Coord replacement = null;
Coord r = p;
while ((r = replacements.get(r)) != null) {
replacement = r;
}
if (replacement != null) {
if (p instanceof CoordPOI) {
CoordPOI cp = (CoordPOI) p;
Node node = cp.getNode();
if (cp.isUsed() && way != null && way.getId() != 0) {
String wayPOI = way.getTag(StyledConverter.WAY_POI_NODE_IDS);
if (wayPOI != null && wayPOI.contains("[" + node.getId() + "]")) {
if (replacement instanceof CoordPOI) {
Node rNode = ((CoordPOI) replacement).getNode();
if (rNode.getId() != node.getId()) {
if (wayPOI.contains("[" + rNode.getId() + "]")) {
log.warn("CoordPOI", node.getId(), "replaced by CoordPOI", rNode.getId(), "in way", way.toBrowseURL());
} else
log.warn("CoordPOI", node.getId(), "replaced by ignored CoordPOI", rNode.getId(), "in way", way.toBrowseURL());
}
} else
log.warn("CoordPOI", node.getId(), "replaced by simple coord in way", way.toBrowseURL());
}
}
}
return replacement;
}
log.error("replacement not found for point " + p.toOSMURL());
}
return p;
}
use of uk.me.parabola.mkgmap.reader.osm.Node 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());
}
}
}
Aggregations