Search in sources :

Example 1 with Node

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");
        }
    }
}
Also used : Node(uk.me.parabola.mkgmap.reader.osm.Node) CoordNode(uk.me.parabola.imgfmt.app.CoordNode) Way(uk.me.parabola.mkgmap.reader.osm.Way) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) MapExitPoint(uk.me.parabola.mkgmap.general.MapExitPoint) LinkedHashMap(java.util.LinkedHashMap) Coord(uk.me.parabola.imgfmt.app.Coord) Entry(java.util.Map.Entry) GeneralRouteRestriction(uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction) List(java.util.List) ArrayList(java.util.ArrayList) CoordNode(uk.me.parabola.imgfmt.app.CoordNode) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) MultiHashMap(uk.me.parabola.util.MultiHashMap)

Example 2 with Node

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);
            }
        }
    }
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) CoordPOI(uk.me.parabola.mkgmap.reader.osm.CoordPOI) Node(uk.me.parabola.mkgmap.reader.osm.Node) CoordNode(uk.me.parabola.imgfmt.app.CoordNode) Way(uk.me.parabola.mkgmap.reader.osm.Way) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) MapExitPoint(uk.me.parabola.mkgmap.general.MapExitPoint)

Example 3 with Node

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);
    }
}
Also used : Node(uk.me.parabola.mkgmap.reader.osm.Node) CoordNode(uk.me.parabola.imgfmt.app.CoordNode) Way(uk.me.parabola.mkgmap.reader.osm.Way) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) MapExitPoint(uk.me.parabola.mkgmap.general.MapExitPoint) Coord(uk.me.parabola.imgfmt.app.Coord) CoordPOI(uk.me.parabola.mkgmap.reader.osm.CoordPOI) List(java.util.List) ArrayList(java.util.ArrayList)

Example 4 with Node

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;
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) CityInfo(uk.me.parabola.mkgmap.general.CityInfo) ZipCodeInfo(uk.me.parabola.mkgmap.general.ZipCodeInfo) Node(uk.me.parabola.mkgmap.reader.osm.Node) ArrayList(java.util.ArrayList)

Example 5 with Node

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);
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) GeneralRelation(uk.me.parabola.mkgmap.reader.osm.GeneralRelation) Element(uk.me.parabola.mkgmap.reader.osm.Element) Node(uk.me.parabola.mkgmap.reader.osm.Node)

Aggregations

Node (uk.me.parabola.mkgmap.reader.osm.Node)15 Coord (uk.me.parabola.imgfmt.app.Coord)13 Way (uk.me.parabola.mkgmap.reader.osm.Way)8 ArrayList (java.util.ArrayList)7 Element (uk.me.parabola.mkgmap.reader.osm.Element)7 Map (java.util.Map)5 HashMap (java.util.HashMap)4 List (java.util.List)4 CoordNode (uk.me.parabola.imgfmt.app.CoordNode)4 IdentityHashMap (java.util.IdentityHashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)3 MapPoint (uk.me.parabola.mkgmap.general.MapPoint)3 CoordPOI (uk.me.parabola.mkgmap.reader.osm.CoordPOI)3 MultiHashMap (uk.me.parabola.util.MultiHashMap)3 Area (uk.me.parabola.imgfmt.app.Area)2 Relation (uk.me.parabola.mkgmap.reader.osm.Relation)2 RestrictionRelation (uk.me.parabola.mkgmap.reader.osm.RestrictionRelation)2 Int2IntOpenHashMap (it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap)1 Int2ObjectOpenHashMap (it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap)1