use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class StyledConverter method createRouteRestrictionsFromPOI.
/**
* If POI changes access restrictions (e.g. bollards), create corresponding
* route restrictions so that only allowed vehicles/pedestrians are routed
* through this point.
*/
private void createRouteRestrictionsFromPOI() {
Iterator<Map.Entry<Node, List<Way>>> iter = poiRestrictions.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Node, List<Way>> entry = iter.next();
Node node = entry.getKey();
Coord p = node.getLocation();
// list of ways that are connected to the poi
List<Way> wayList = entry.getValue();
byte exceptMask = AccessTagsAndBits.evalAccessTags(node);
Map<Integer, CoordNode> otherNodeIds = new LinkedHashMap<>();
CoordNode viaNode = null;
boolean viaIsUnique = true;
for (Way way : wayList) {
CoordNode lastNode = null;
for (Coord co : way.getPoints()) {
// not 100% fail safe: points may have been replaced before
if (co instanceof CoordNode == false)
continue;
CoordNode cn = (CoordNode) co;
if (p.highPrecEquals(cn)) {
if (viaNode == null)
viaNode = cn;
else if (viaNode != cn) {
log.error("Found multiple points with equal coords as CoordPOI at " + p.toOSMURL());
// if we ever get here we can add code to identify the exact node
viaIsUnique = false;
}
if (lastNode != null)
otherNodeIds.put(lastNode.getId(), lastNode);
} else {
if (p.highPrecEquals(lastNode))
otherNodeIds.put(cn.getId(), cn);
}
lastNode = cn;
}
}
if (viaNode == null) {
log.error("Did not find CoordPOI node at " + p.toOSMURL() + " in ways " + wayList);
continue;
}
if (viaIsUnique == false) {
log.error("Found multiple points with equal coords as CoordPOI at " + p.toOSMURL());
continue;
}
if (otherNodeIds.size() < 2) {
log.info("Access restriction in POI node " + node.toBrowseURL() + " was ignored, has no effect on any connected way");
continue;
}
GeneralRouteRestriction rr = new GeneralRouteRestriction("no_through", exceptMask, "CoordPOI at " + p.toOSMURL());
rr.setViaNodes(Arrays.asList(viaNode));
int added = collector.addRestriction(rr);
if (added == 0) {
log.info("Access restriction in POI node " + node.toBrowseURL() + " was ignored, has no effect on any connected way");
} else {
log.info("Access restriction in POI node", node.toBrowseURL(), "was translated to", added, "route restriction(s)");
}
if (wayList.size() > 1 && added > 2) {
log.warn("Access restriction in POI node", node.toBrowseURL(), "affects routing on multiple ways");
}
}
}
use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class StyledConverter method filterCoordPOI.
/**
* Make sure that only CoordPOI which affect routing will be treated as
* nodes in the following routines.
*/
private void filterCoordPOI() {
if (!linkPOIsToWays)
return;
log.info("translating CoordPOI");
for (ConvertedWay cw : roads) {
if (!cw.isValid())
continue;
Way way = cw.getWay();
if ("true".equals(way.getTag("mkgmap:way-has-pois"))) {
String wayPOI = "";
List<Coord> points = way.getPoints();
int numPoints = points.size();
for (int i = 0; i < numPoints; i++) {
Coord p = points.get(i);
if (p instanceof CoordPOI) {
CoordPOI cp = (CoordPOI) p;
Node node = cp.getNode();
boolean usedInThisWay = false;
byte wayAccess = cw.getAccess();
if (node.getTag("mkgmap:road-class") != null || node.getTag("mkgmap:road-speed") != null) {
if (wayAccess != AccessTagsAndBits.FOOT)
usedInThisWay = true;
}
byte nodeAccess = AccessTagsAndBits.evalAccessTags(node);
if (nodeAccess != (byte) 0xff) {
// barriers etc.
if ((wayAccess & nodeAccess) != wayAccess) {
// node is more restrictive
if (p.getHighwayCount() >= 2 || (i != 0 && i != numPoints - 1)) {
usedInThisWay = true;
cp.setConvertToViaInRouteRestriction(true);
} else {
log.info("POI node", node.getId(), "with access restriction is ignored, it is not connected to other routable ways");
}
} else
log.info("Access restriction in POI node", node.toBrowseURL(), "was ignored for way", way.toBrowseURL());
}
if (usedInThisWay) {
cp.setUsed(true);
wayPOI += "[" + node.getId() + "]";
}
}
}
if (wayPOI.isEmpty()) {
way.deleteTag("mkgmap:way-has-pois");
log.info("ignoring CoordPOI(s) for way", way.toBrowseURL(), "because routing is not affected.");
} else {
way.addTag(WAY_POI_NODE_IDS, wayPOI);
}
}
}
}
use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class StyledConverter method addRoad.
/**
* Add a way to the road network. May call itself recursively and
* might truncate the way if splitting is required.
* @param way the way
* @param gt the type assigned by the style
*/
private void addRoad(ConvertedWay cw) {
Way way = cw.getWay();
if (way.getPoints().size() < 2) {
log.warn("road has < 2 points", way.getId(), "(discarding)");
return;
}
checkRoundabout(cw);
// process any Coords that have a POI associated with them
// metres
final double stubSegmentLength = 25;
String wayPOI = way.getTag(WAY_POI_NODE_IDS);
if (wayPOI != null) {
List<Coord> points = way.getPoints();
// or a barrier
for (int i = 0; i < points.size(); ++i) {
Coord p = points.get(i);
if (p instanceof CoordPOI && ((CoordPOI) p).isUsed()) {
CoordPOI cp = (CoordPOI) p;
Node node = cp.getNode();
if (wayPOI.contains("[" + node.getId() + "]")) {
log.debug("POI", node.getId(), "changes way", way.getId());
// are converted to RouteRestrictions
if (p.getHighwayCount() < 2 && cp.getConvertToViaInRouteRestriction() && (i != 0 && i != points.size() - 1))
p.incHighwayCount();
String roadClass = node.getTag("mkgmap:road-class");
String roadSpeed = node.getTag("mkgmap:road-speed");
if (roadClass != null || roadSpeed != null) {
// find good split point after POI
Coord splitPoint;
double segmentLength = 0;
int splitPos = i + 1;
while (splitPos + 1 < points.size()) {
splitPoint = points.get(splitPos);
segmentLength += splitPoint.distance(points.get(splitPos - 1));
if (splitPoint.getHighwayCount() > 1 || segmentLength > stubSegmentLength - 5)
break;
splitPos++;
}
if (segmentLength > stubSegmentLength + 10) {
// insert a new point after the POI to
// make a short stub segment
splitPoint = points.get(splitPos);
Coord prev = points.get(splitPos - 1);
double dist = splitPoint.distance(prev);
double neededLength = stubSegmentLength - (segmentLength - dist);
splitPoint = prev.makeBetweenPoint(splitPoint, neededLength / dist);
double newDist = splitPoint.distance(prev);
segmentLength += newDist - dist;
splitPoint.incHighwayCount();
points.add(splitPos, splitPoint);
}
if ((splitPos + 1) < points.size() && way.isViaWay() == false && safeToSplitWay(points, splitPos, i, points.size() - 1)) {
Way tail = splitWayAt(way, splitPos);
// recursively process tail of way
addRoad(new ConvertedWay(cw, tail));
}
boolean classChanged = cw.recalcRoadClass(node);
if (classChanged && log.isInfoEnabled()) {
log.info("POI changing road class of", way.toBrowseURL(), "to", cw.getRoadClass(), "at", points.get(0).toOSMURL());
}
boolean speedChanged = cw.recalcRoadSpeed(node);
if (speedChanged && log.isInfoEnabled()) {
log.info("POI changing road speed of", way.toBrowseURL(), "to", cw.getRoadSpeed(), "at", points.get(0).toOSMURL());
}
}
}
}
// the affected region
if (i + 1 < points.size() && points.get(i + 1) instanceof CoordPOI) {
CoordPOI cp = (CoordPOI) points.get(i + 1);
Node node = cp.getNode();
if (cp.isUsed() && wayPOI.contains("[" + node.getId() + "]")) {
if (node.getTag("mkgmap:road-class") != null || node.getTag("mkgmap:road-speed") != null) {
// find good split point before POI
double segmentLength = 0;
int splitPos = i;
Coord splitPoint;
while (splitPos >= 0) {
splitPoint = points.get(splitPos);
segmentLength += splitPoint.distance(points.get(splitPos + 1));
if (splitPoint.getHighwayCount() >= 2 || segmentLength > stubSegmentLength - 5)
break;
--splitPos;
}
if (segmentLength > stubSegmentLength + 10) {
// insert a new point before the POI to
// make a short stub segment
splitPoint = points.get(splitPos);
Coord prev = points.get(splitPos + 1);
double dist = splitPoint.distance(prev);
double neededLength = stubSegmentLength - (segmentLength - dist);
splitPoint = prev.makeBetweenPoint(splitPoint, neededLength / dist);
segmentLength += splitPoint.distance(prev) - dist;
splitPoint.incHighwayCount();
splitPos++;
points.add(splitPos, splitPoint);
}
if (splitPos > 0 && safeToSplitWay(points, splitPos, 0, points.size() - 1)) {
Way tail = splitWayAt(way, splitPos);
// recursively process tail of way
addRoad(new ConvertedWay(cw, tail));
}
}
}
}
}
}
// if there is a bounding box, clip the way with it
List<Way> clippedWays = null;
if (bbox != null) {
List<List<Coord>> lineSegs = LineClipper.clip(bbox, way.getPoints());
if (lineSegs != null) {
if (lineSegs.isEmpty()) {
removeRestrictionsWithWay(Level.WARNING, way, "ends on tile boundary, restriction is ignored");
}
clippedWays = new ArrayList<>();
for (List<Coord> lco : lineSegs) {
Way nWay = new Way(way.getId());
nWay.copyTags(way);
for (Coord co : lco) {
nWay.addPoint(co);
if (co.getOnBoundary()) {
// this point lies on a boundary
// make sure it becomes a node
co.incHighwayCount();
}
}
clippedWays.add(nWay);
}
}
}
if (clippedWays != null) {
for (Way clippedWay : clippedWays) {
addRoadAfterSplittingLoops(new ConvertedWay(cw, clippedWay));
}
} else {
// no bounding box or way was not clipped
addRoadAfterSplittingLoops(cw);
}
}
use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class HousenumberIvl method getInterpolatedHouses.
public List<HousenumberMatch> getInterpolatedHouses() {
List<HousenumberMatch> houses = new ArrayList<>();
if (ignoreForInterpolation || start == end || steps <= 0)
return houses;
List<Coord> interpolatedPoints = getInterpolatedPoints();
int usedStep = (start < end) ? step : -step;
int hn = start;
boolean distanceWarningIssued = false;
CityInfo ci = knownHouses[0].getCityInfo();
ZipCodeInfo zip = knownHouses[0].getZipCode();
if (ci != null && ci.equals(knownHouses[1].getCityInfo()) == false)
log.warn("addr:interpolation way connects houses in different cities", streetName, this, "using city", ci, "for all interpolated adresses");
if (zip != null && zip.equals(knownHouses[1].getZipCode()) == false)
log.warn("addr:interpolation way connects houses with differnt zip codes", streetName, this, "using zip code", zip, "for all interpolated adresses");
for (Coord co : interpolatedPoints) {
hn += usedStep;
Node generated = new Node(interpolationWay.getId(), co);
generated.setFakeId();
generated.addTag(streetTagKey, streetName);
String number = String.valueOf(hn);
generated.addTag(housenumberTagKey, number);
// TODO: maybe add check that city info and zip code of both houses is equal ?
// what if not ?
HousenumberElem houseElem = new HousenumberElem(generated, ci);
houseElem.setHousenumber(hn);
houseElem.setZipCode(zip);
houseElem.setStreet(streetName);
houseElem.setSign(number);
HousenumberMatch house = new HousenumberMatch(houseElem);
if (roadForInterpolatedHouses != null) {
HousenumberGenerator.findClosestRoadSegment(house, roadForInterpolatedHouses);
if (house.getRoad() == null || house.getDistance() > MAX_INTERPOLATION_DISTANCE_TO_ROAD) {
if (distanceWarningIssued == false) {
log.warn("interpolated house is not close to expected road", this, house);
distanceWarningIssued = true;
}
continue;
}
house.calcRoadSide();
}
house.setInterpolated(true);
houses.add(house);
}
if (log.isDebugEnabled()) {
String addrInterpolationMethod = interpolationWay.getTag(addrInterpolationTagKey);
if (hasMultipleRoads == false)
log.debug(this, "generated", addrInterpolationMethod, "interpolated number(s) for", knownHouses[0].getRoad());
else
log.debug(this, "generated", addrInterpolationMethod, "interpolated number(s) for", streetName);
}
return houses;
}
use of uk.me.parabola.mkgmap.reader.osm.Node in project mkgmap by openstreetmap.
the class O5mBinHandler method readRel.
/**
* read a relation data set
* @throws IOException
*/
private void readRel() throws IOException {
lastRelId += readSignedNum64();
if (bytesToRead == 0)
// only relId: this is a delete action, we ignore it
return;
readVersionTsAuthor();
if (bytesToRead == 0)
// only relId + version: this is a delete action, we ignore it
return;
GeneralRelation rel = new GeneralRelation(lastRelId);
long refSize = readUnsignedNum32();
long stop = bytesToRead - refSize;
while (bytesToRead > stop) {
Element el = null;
long deltaRef = readSignedNum64();
int refType = readRelRef();
String role = stringPair[1];
lastRef[refType] += deltaRef;
long memId = lastRef[refType];
if (refType == 0) {
el = saver.getNode(memId);
if (el == null) {
// we didn't make a node for this point earlier,
// do it now (if it exists)
Coord co = saver.getCoord(memId);
if (co != null) {
el = new Node(memId, co);
saver.addNode((Node) el);
}
}
} else if (refType == 1) {
el = saver.getWay(memId);
} else if (refType == 2) {
el = saver.getRelation(memId);
if (el == null) {
saver.deferRelation(memId, rel, role);
}
} else {
assert false;
}
if (// ignore non existing ways caused by splitting files
el != null)
rel.addElement(role, el);
}
boolean tagsIncomplete = readTags(rel);
rel.setTagsIncomplete(tagsIncomplete);
saver.addRelation(rel);
}
Aggregations