Search in sources :

Example 1 with TransportSchedule

use of net.osmand.data.TransportSchedule in project OsmAnd-tools by osmandapp.

the class IndexTransportCreator method readSchedule.

private TransportSchedule readSchedule(String ref, List<TransportStop> directStops) throws SQLException {
    if (!Algorithms.isEmpty(ref) && gtfsConnection != null && directStops.size() > 0) {
        if (gtfsSelectRoute == null) {
            // new String[] { "firstStopLat", "firstStopLon", "minLat", "maxLat", "minLon", "maxLon" }
            gtfsSelectRoute = gtfsConnection.prepareStatement("SELECT r.route_id, r.route_short_name, r.route_long_name, " + " t.trip_id, t.shape_id, t.service_id, t.firstStopLat, t.firstStopLon from routes r join " + " trips t on t.route_id = r.route_id where route_short_name = ? order by r.route_id asc, t.trip_id asc ");
        }
        if (gtfsSelectStopTimes == null) {
            gtfsSelectStopTimes = gtfsConnection.prepareStatement("SELECT arrival_time, departure_time, stop_id, stop_sequence" + " from stop_times where trip_id = ? order by stop_sequence ");
        }
        gtfsSelectRoute.setString(1, ref);
        ResultSet rs = gtfsSelectRoute.executeQuery();
        String routeId = null, routeShortName = null, routeLongName = null;
        TransportSchedule schedule = new TransportSchedule();
        TIntArrayList timeDeparturesFirst = new TIntArrayList();
        while (rs.next()) {
            String nrouteId = rs.getString(1);
            if (!Algorithms.objectEquals(routeId, nrouteId)) {
                routeId = nrouteId;
                routeShortName = rs.getString(2);
                routeLongName = rs.getString(3);
            }
            String tripId = rs.getString(4);
            // String shapeId = rs.getString(5);
            // String serviceId = rs.getString(6);
            double firstLat = rs.getDouble(7);
            double firstLon = rs.getDouble(8);
            double dist = MapUtils.getDistance(directStops.get(0).getLocation(), firstLat, firstLon);
            if (dist < DISTANCE_THRESHOLD) {
                gtfsSelectStopTimes.setString(1, tripId);
                ResultSet nrs = gtfsSelectStopTimes.executeQuery();
                TIntArrayList stopIntervals = new TIntArrayList(directStops.size());
                TIntArrayList waitIntervals = new TIntArrayList(directStops.size());
                int ftime = 0, ptime = 0;
                while (nrs.next()) {
                    int arrivalTime = parseTime(nrs.getString(1));
                    int depTime = parseTime(nrs.getString(2));
                    if (arrivalTime == -1 || depTime == -1) {
                        gtfsStats.errorsTimeParsing++;
                        continue;
                    }
                    if (ftime == 0) {
                        ftime = ptime = depTime;
                    } else {
                        stopIntervals.add(arrivalTime - ptime);
                    }
                    waitIntervals.add(depTime - arrivalTime);
                    ptime = arrivalTime;
                }
                if (waitIntervals.size() != directStops.size()) {
                    gtfsStats.errorsTripsStopCounts++;
                // failed = true;
                } else {
                    gtfsStats.successTripsParsing++;
                    if (schedule.avgWaitIntervals.isEmpty()) {
                        schedule.avgWaitIntervals.addAll(waitIntervals);
                    } else {
                        // check wait intervals different
                        for (int j = 0; j < waitIntervals.size(); j++) {
                            if (Math.abs(schedule.avgWaitIntervals.getQuick(j) - waitIntervals.getQuick(j)) > 3) {
                                gtfsStats.avgWaitDiff30Sec++;
                                break;
                            }
                        }
                    }
                    if (schedule.avgStopIntervals.isEmpty()) {
                        schedule.avgStopIntervals.addAll(stopIntervals);
                    } else {
                        for (int j = 0; j < stopIntervals.size(); j++) {
                            if (Math.abs(schedule.avgStopIntervals.getQuick(j) - stopIntervals.getQuick(j)) > 3) {
                                gtfsStats.avgStopDiff30Sec++;
                                break;
                            }
                        }
                    }
                    timeDeparturesFirst.add(ftime);
                }
                nrs.close();
            }
        }
        if (timeDeparturesFirst.size() > 0) {
            timeDeparturesFirst.sort();
            int p = 0;
            for (int i = 0; i < timeDeparturesFirst.size(); i++) {
                int x = timeDeparturesFirst.get(i) - p;
                // this is a wrong check cause there should be a check for calendar
                if (x > 0) {
                    schedule.tripIntervals.add(x);
                    p = timeDeparturesFirst.get(i);
                }
            }
            boolean allZeros = true;
            for (int i = 0; i < schedule.avgWaitIntervals.size(); i++) {
                if (schedule.avgWaitIntervals.getQuick(i) != 0) {
                    allZeros = false;
                    break;
                }
            }
            if (allZeros) {
                schedule.avgWaitIntervals.clear();
            }
            return schedule;
        }
    }
    return null;
}
Also used : TransportSchedule(net.osmand.data.TransportSchedule) ResultSet(java.sql.ResultSet) TIntArrayList(gnu.trove.list.array.TIntArrayList)

Example 2 with TransportSchedule

use of net.osmand.data.TransportSchedule in project OsmAnd-tools by osmandapp.

the class IndexTransportCreator method writeBinaryTransportIndex.

public void writeBinaryTransportIndex(BinaryMapIndexWriter writer, String regionName, Connection mapConnection) throws IOException, SQLException {
    try {
        closePreparedStatements(transRouteStat, transRouteStopsStat, transStopsStat, transRouteGeometryStat);
        mapConnection.commit();
        transportStopsTree.flush();
        // allow gc to collect it
        visitedStops = null;
        PreparedStatement selectTransportRouteData = mapConnection.prepareStatement(// $NON-NLS-1$
        "SELECT id, dist, name, name_en, ref, operator, type, color FROM transport_route");
        PreparedStatement selectTransportData = mapConnection.prepareStatement(// $NON-NLS-1$
        "SELECT S.stop, " + // $NON-NLS-1$
        "  A.latitude,  A.longitude, A.name, A.name_en, A.names, A.deleted_routes " + // $NON-NLS-1$
        "FROM transport_route_stop S INNER JOIN transport_stop A ON A.id = S.stop WHERE S.route = ? ORDER BY S.ord asc");
        PreparedStatement selectTransportRouteGeometry = mapConnection.prepareStatement("SELECT S.geometry " + // $NON-NLS-1$
        "FROM transport_route_geometry S WHERE S.route = ? order by S.ind");
        long transportIndexOffset = writer.startWriteTransportIndex(regionName);
        writer.startWriteTransportRoutes();
        // expect that memory would be enough
        Map<String, Integer> stringTable = createStringTableForTransport();
        Map<Long, Long> transportRoutes = new LinkedHashMap<>();
        ResultSet rs = selectTransportRouteData.executeQuery();
        List<TransportStop> directStops = new ArrayList<>();
        List<TransportStop> reverseStops = new ArrayList<>();
        List<byte[]> directGeometry = new ArrayList<>();
        while (rs.next()) {
            long idRoute = rs.getLong(1);
            int dist = rs.getInt(2);
            String routeName = rs.getString(3);
            String routeEnName = rs.getString(4);
            if (routeEnName != null && routeEnName.equals(Junidecode.unidecode(routeName))) {
                routeEnName = null;
            }
            String ref = rs.getString(5);
            String operator = rs.getString(6);
            String type = rs.getString(7);
            String color = rs.getString(8);
            selectTransportData.setLong(1, idRoute);
            ResultSet rset = selectTransportData.executeQuery();
            reverseStops.clear();
            directStops.clear();
            directGeometry.clear();
            while (rset.next()) {
                long idStop = rset.getLong(1);
                String stopName = rset.getString(4);
                String stopEnName = rset.getString(5);
                Gson gson = new Gson();
                String names = rset.getString(6);
                Type t = new TypeToken<Map<String, String>>() {
                }.getType();
                Map<String, String> map = gson.fromJson(names, t);
                if (stopEnName != null && stopEnName.equals(Junidecode.unidecode(stopName))) {
                    stopEnName = null;
                }
                TransportStop st = new TransportStop();
                st.setNames(map);
                st.setId(idStop);
                st.setName(stopName);
                st.setLocation(rset.getDouble(2), rset.getDouble(3));
                if (stopEnName != null) {
                    st.setEnName(stopEnName);
                }
                directStops.add(st);
            }
            selectTransportRouteGeometry.setLong(1, idRoute);
            rset = selectTransportRouteGeometry.executeQuery();
            while (rset.next()) {
                byte[] bytes = rset.getBytes(1);
                directGeometry.add(bytes);
            }
            TransportSchedule schedule = readSchedule(ref, directStops);
            long ptr = writer.writeTransportRoute(idRoute, routeName, routeEnName, ref, operator, type, dist, color, directStops, directGeometry, stringTable, transportRoutes, schedule, transportRouteTagValues);
            if (isRouteIncomplete(idRoute)) {
                incompleteRoutesMap.get(idRoute).setFileOffset((int) ptr);
            }
        }
        rs.close();
        selectTransportRouteData.close();
        selectTransportData.close();
        writer.endWriteTransportRoutes();
        PreparedStatement selectTransportStop = mapConnection.prepareStatement(// $NON-NLS-1$
        "SELECT A.id,  A.latitude,  A.longitude, A.name, A.name_en, A.names, A.deleted_routes FROM transport_stop A where A.id = ?");
        PreparedStatement selectTransportRouteStop = mapConnection.prepareStatement(// $NON-NLS-1$
        "SELECT DISTINCT S.route FROM transport_route_stop S join transport_route R  on R.id = S.route WHERE S.stop = ? ORDER BY R.type, R.ref ");
        long rootIndex = transportStopsTree.getFileHdr().getRootIndex();
        rtree.Node root = transportStopsTree.getReadNode(rootIndex);
        Rect rootBounds = calcBounds(root);
        if (rootBounds != null) {
            writer.startTransportTreeElement(rootBounds.getMinX(), rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY());
            writeBinaryTransportTree(root, transportStopsTree, writer, selectTransportStop, selectTransportRouteStop, transportRoutes, stringTable);
            writer.endWriteTransportTreeElement();
        }
        selectTransportStop.close();
        selectTransportRouteStop.close();
        writer.writeIncompleteTransportRoutes(incompleteRoutesMap.valueCollection(), stringTable, transportIndexOffset);
        writer.writeTransportStringTable(stringTable);
        writer.endWriteTransportIndex();
        writer.flush();
        log.info(gtfsStats);
    } catch (RTreeException e) {
        throw new IllegalStateException(e);
    }
}
Also used : RTreeException(rtree.RTreeException) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) TLongArrayList(gnu.trove.list.array.TLongArrayList) Gson(com.google.gson.Gson) LinkedHashMap(java.util.LinkedHashMap) TransportSchedule(net.osmand.data.TransportSchedule) ResultSet(java.sql.ResultSet) TransportStop(net.osmand.data.TransportStop) QuadRect(net.osmand.data.QuadRect) Rect(rtree.Rect) PreparedStatement(java.sql.PreparedStatement) Type(java.lang.reflect.Type) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TLongObjectHashMap(gnu.trove.map.hash.TLongObjectHashMap)

Example 3 with TransportSchedule

use of net.osmand.data.TransportSchedule in project Osmand by osmandapp.

the class TransportRouteResult method getTravelTime.

public double getTravelTime() {
    double t = 0;
    for (TransportRoutePlanner.TransportRouteResultSegment s : segments) {
        if (cfg.useSchedule) {
            TransportSchedule sts = s.route.getSchedule();
            for (int k = s.start; k < s.end; k++) {
                t += sts.getAvgStopIntervals()[k] * 10;
            }
        } else {
            t += cfg.getBoardingTime();
            t += s.getTravelTime();
        }
    }
    return t;
}
Also used : TransportSchedule(net.osmand.data.TransportSchedule)

Example 4 with TransportSchedule

use of net.osmand.data.TransportSchedule in project Osmand by osmandapp.

the class TransportRoutePlanner method convertTransportRoute.

private static TransportRoute convertTransportRoute(NativeTransportRoute nr, TLongObjectHashMap<TransportRoute> convertedRoutesCache, TLongObjectHashMap<TransportStop> convertedStopsCache) {
    TransportRoute r = new TransportRoute();
    r.setId(nr.id);
    r.setLocation(nr.routeLat, nr.routeLon);
    r.setName(nr.name);
    r.setEnName(nr.enName);
    if (nr.namesLng.length > 0 && nr.namesLng.length == nr.namesNames.length) {
        for (int i = 0; i < nr.namesLng.length; i++) {
            r.setName(nr.namesLng[i], nr.namesNames[i]);
        }
    }
    r.setFileOffset(nr.fileOffset);
    r.setForwardStops(convertTransportStops(nr.forwardStops, convertedStopsCache));
    r.setRef(nr.ref);
    r.setOperator(nr.routeOperator);
    r.setType(nr.type);
    r.setDist(nr.dist);
    r.setColor(nr.color);
    if (nr.intervals != null && nr.intervals.length > 0 && nr.avgStopIntervals != null && nr.avgStopIntervals.length > 0 && nr.avgWaitIntervals != null && nr.avgWaitIntervals.length > 0) {
        r.setSchedule(new TransportSchedule(new TIntArrayList(nr.intervals), new TIntArrayList(nr.avgStopIntervals), new TIntArrayList(nr.avgWaitIntervals)));
    }
    for (int i = 0; i < nr.waysIds.length; i++) {
        List<Node> wnodes = new ArrayList<>();
        for (int j = 0; j < nr.waysNodesLats[i].length; j++) {
            wnodes.add(new Node(nr.waysNodesLats[i][j], nr.waysNodesLons[i][j], -1));
        }
        r.addWay(new Way(nr.waysIds[i], wnodes));
    }
    if (convertedRoutesCache.get(r.getId()) == null) {
        convertedRoutesCache.put(r.getId(), r);
    }
    return r;
}
Also used : TransportRoute(net.osmand.data.TransportRoute) TransportSchedule(net.osmand.data.TransportSchedule) Node(net.osmand.osm.edit.Node) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) TIntArrayList(gnu.trove.list.array.TIntArrayList) Way(net.osmand.osm.edit.Way)

Example 5 with TransportSchedule

use of net.osmand.data.TransportSchedule in project Osmand by osmandapp.

the class TransportRoutePlanner method buildRoute.

public List<TransportRouteResult> buildRoute(TransportRoutingContext ctx, LatLon start, LatLon end) throws IOException, InterruptedException {
    ctx.startCalcTime = System.currentTimeMillis();
    double totalDistance = MapUtils.getDistance(start, end);
    List<TransportRouteSegment> startStops = ctx.getTransportStops(start);
    List<TransportRouteSegment> endStops = ctx.getTransportStops(end);
    TLongObjectHashMap<TransportRouteSegment> endSegments = new TLongObjectHashMap<TransportRouteSegment>();
    for (TransportRouteSegment s : endStops) {
        endSegments.put(s.getId(), s);
    }
    if (startStops.size() == 0) {
        return Collections.emptyList();
    }
    PriorityQueue<TransportRouteSegment> queue = new PriorityQueue<TransportRouteSegment>(startStops.size(), new SegmentsComparator(ctx));
    for (TransportRouteSegment r : startStops) {
        r.walkDist = (float) MapUtils.getDistance(r.getLocation(), start);
        r.distFromStart = r.walkDist / ctx.cfg.walkSpeed;
        queue.add(r);
    }
    double finishTime = ctx.cfg.maxRouteTime;
    ctx.finishTimeSeconds = ctx.cfg.finishTimeSeconds;
    if (totalDistance > ctx.cfg.maxRouteDistance && ctx.cfg.maxRouteIncreaseSpeed > 0) {
        int increaseTime = (int) ((totalDistance - ctx.cfg.maxRouteDistance) * 3.6 / ctx.cfg.maxRouteIncreaseSpeed);
        finishTime += increaseTime;
        ctx.finishTimeSeconds += increaseTime / 6;
    }
    double maxTravelTimeCmpToWalk = totalDistance / ctx.cfg.walkSpeed - ctx.cfg.changeTime / 2;
    List<TransportRouteSegment> results = new ArrayList<TransportRouteSegment>();
    initProgressBar(ctx, start, end);
    while (!queue.isEmpty()) {
        long beginMs = MEASURE_TIME ? System.currentTimeMillis() : 0;
        if (ctx.calculationProgress != null && ctx.calculationProgress.isCancelled) {
            return null;
        }
        TransportRouteSegment segment = queue.poll();
        TransportRouteSegment ex = ctx.visitedSegments.get(segment.getId());
        if (ex != null) {
            if (ex.distFromStart > segment.distFromStart) {
                System.err.println(String.format("%.1f (%s) > %.1f (%s)", ex.distFromStart, ex, segment.distFromStart, segment));
            }
            continue;
        }
        ctx.visitedRoutesCount++;
        ctx.visitedSegments.put(segment.getId(), segment);
        if (segment.getDepth() > ctx.cfg.maxNumberOfChanges + 1) {
            continue;
        }
        if (segment.distFromStart > finishTime + ctx.finishTimeSeconds || segment.distFromStart > maxTravelTimeCmpToWalk) {
            break;
        }
        long segmentId = segment.getId();
        TransportRouteSegment finish = null;
        double minDist = 0;
        double travelDist = 0;
        double travelTime = 0;
        final float routeTravelSpeed = ctx.cfg.getSpeedByRouteType(segment.road.getType());
        if (routeTravelSpeed == 0) {
            continue;
        }
        TransportStop prevStop = segment.getStop(segment.segStart);
        List<TransportRouteSegment> sgms = new ArrayList<TransportRouteSegment>();
        for (int ind = 1 + segment.segStart; ind < segment.getLength(); ind++) {
            if (ctx.calculationProgress != null && ctx.calculationProgress.isCancelled) {
                return null;
            }
            segmentId++;
            ctx.visitedSegments.put(segmentId, segment);
            TransportStop stop = segment.getStop(ind);
            // could be geometry size
            double segmentDist = MapUtils.getDistance(prevStop.getLocation(), stop.getLocation());
            travelDist += segmentDist;
            if (ctx.cfg.useSchedule) {
                TransportSchedule sc = segment.road.getSchedule();
                int interval = sc.avgStopIntervals.get(ind - 1);
                travelTime += interval * 10;
            } else {
                travelTime += ctx.cfg.stopTime + segmentDist / routeTravelSpeed;
            }
            if (segment.distFromStart + travelTime > finishTime + ctx.finishTimeSeconds) {
                break;
            }
            sgms.clear();
            sgms = ctx.getTransportStops(stop.x31, stop.y31, true, sgms);
            ctx.visitedStops++;
            for (TransportRouteSegment sgm : sgms) {
                if (ctx.calculationProgress != null && ctx.calculationProgress.isCancelled) {
                    return null;
                }
                if (segment.wasVisited(sgm)) {
                    continue;
                }
                TransportRouteSegment nextSegment = new TransportRouteSegment(sgm);
                nextSegment.parentRoute = segment;
                nextSegment.parentStop = ind;
                nextSegment.walkDist = MapUtils.getDistance(nextSegment.getLocation(), stop.getLocation());
                nextSegment.parentTravelTime = travelTime;
                nextSegment.parentTravelDist = travelDist;
                double walkTime = nextSegment.walkDist / ctx.cfg.walkSpeed + ctx.cfg.getChangeTime() + ctx.cfg.getBoardingTime();
                nextSegment.distFromStart = segment.distFromStart + travelTime + walkTime;
                if (ctx.cfg.useSchedule) {
                    int tm = (sgm.departureTime - ctx.cfg.scheduleTimeOfDay) * 10;
                    if (tm >= nextSegment.distFromStart) {
                        nextSegment.distFromStart = tm;
                        queue.add(nextSegment);
                    }
                } else {
                    queue.add(nextSegment);
                }
            }
            TransportRouteSegment finalSegment = endSegments.get(segmentId);
            double distToEnd = MapUtils.getDistance(stop.getLocation(), end);
            if (finalSegment != null && distToEnd < ctx.cfg.walkRadius) {
                if (finish == null || minDist > distToEnd) {
                    minDist = distToEnd;
                    finish = new TransportRouteSegment(finalSegment);
                    finish.parentRoute = segment;
                    finish.parentStop = ind;
                    finish.walkDist = distToEnd;
                    finish.parentTravelTime = travelTime;
                    finish.parentTravelDist = travelDist;
                    double walkTime = distToEnd / ctx.cfg.walkSpeed;
                    finish.distFromStart = segment.distFromStart + travelTime + walkTime;
                }
            }
            prevStop = stop;
        }
        if (finish != null) {
            if (finishTime > finish.distFromStart) {
                finishTime = finish.distFromStart;
            }
            if (finish.distFromStart < finishTime + ctx.finishTimeSeconds && (finish.distFromStart < maxTravelTimeCmpToWalk || results.size() == 0)) {
                results.add(finish);
            }
        }
        if (ctx.calculationProgress != null && ctx.calculationProgress.isCancelled) {
            throw new InterruptedException("Route calculation interrupted");
        }
        if (MEASURE_TIME) {
            long time = System.currentTimeMillis() - beginMs;
            if (time > 10) {
                System.out.println(String.format("%d ms ref - %s id - %d", time, segment.road.getRef(), segment.road.getId()));
            }
        }
        updateCalculationProgress(ctx, queue);
    }
    return prepareResults(ctx, results);
}
Also used : TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) TLongObjectHashMap(gnu.trove.map.hash.TLongObjectHashMap) PriorityQueue(java.util.PriorityQueue) TransportSchedule(net.osmand.data.TransportSchedule) TransportStop(net.osmand.data.TransportStop)

Aggregations

TransportSchedule (net.osmand.data.TransportSchedule)9 TIntArrayList (gnu.trove.list.array.TIntArrayList)7 ArrayList (java.util.ArrayList)6 TransportStop (net.osmand.data.TransportStop)4 TLongObjectHashMap (gnu.trove.map.hash.TLongObjectHashMap)3 TransportRoute (net.osmand.data.TransportRoute)3 TLongArrayList (gnu.trove.list.array.TLongArrayList)2 ResultSet (java.sql.ResultSet)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 PriorityQueue (java.util.PriorityQueue)2 Node (net.osmand.osm.edit.Node)2 Way (net.osmand.osm.edit.Way)2 Gson (com.google.gson.Gson)1 TIntObjectHashMap (gnu.trove.map.hash.TIntObjectHashMap)1 Type (java.lang.reflect.Type)1 PreparedStatement (java.sql.PreparedStatement)1 QuadRect (net.osmand.data.QuadRect)1 RTreeException (rtree.RTreeException)1