From a753dc75ae640fe96ea05bfbb7f14c6ec4fa9c94 Mon Sep 17 00:00:00 2001 From: amartinelli Date: Mon, 30 Nov 2015 12:08:56 +0100 Subject: [PATCH] Fix io.opentraffic.traffic-engine 0.3 dependency --- pom.xml | 2 +- .../traffic/app/TrafficEngineApp.java | 609 ++++++++++-------- .../traffic/app/data/TrafficPath.java | 14 +- .../traffic/app/data/TrafficPathEdge.java | 31 +- .../traffic/app/data/WeeklyStatsObject.java | 112 ++-- .../conveyal/traffic/app/engine/Engine.java | 122 ++-- .../conveyal/traffic/app/routing/Routing.java | 338 +++++----- .../traffic/app/tiles/TrafficTileRequest.java | 428 ++++++------ 8 files changed, 904 insertions(+), 752 deletions(-) diff --git a/pom.xml b/pom.xml index 838acdb..4e21b8e 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ 12.2 - com.conveyal + io.opentraffic traffic-engine 0.3 diff --git a/src/main/java/com/conveyal/traffic/app/TrafficEngineApp.java b/src/main/java/com/conveyal/traffic/app/TrafficEngineApp.java index d8e3eb7..bf53a50 100644 --- a/src/main/java/com/conveyal/traffic/app/TrafficEngineApp.java +++ b/src/main/java/com/conveyal/traffic/app/TrafficEngineApp.java @@ -1,5 +1,16 @@ package com.conveyal.traffic.app; +import static spark.Spark.get; +import static spark.Spark.post; +import static spark.SparkBase.staticFileLocation; +import io.opentraffic.engine.data.SpatialDataItem; +import io.opentraffic.engine.data.pbf.ExchangeFormat; +import io.opentraffic.engine.data.stats.SegmentStatistics; +import io.opentraffic.engine.data.stats.SummaryStatistics; +import io.opentraffic.engine.data.stats.SummaryStatisticsComparison; +import io.opentraffic.engine.geom.GPSPoint; +import io.opentraffic.engine.geom.StreetSegment; + import java.awt.Rectangle; import java.io.FileInputStream; import java.io.IOException; @@ -9,338 +20,404 @@ import java.time.LocalDateTime; import java.time.OffsetDateTime; import java.time.ZoneOffset; -import java.time.temporal.ChronoField; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import com.conveyal.traffic.app.data.TrafficPath; -import com.conveyal.traffic.app.data.WeekObject; -import com.conveyal.traffic.app.data.WeeklyStatsObject; -import com.conveyal.traffic.app.engine.Engine; -import com.conveyal.traffic.data.SpatialDataItem; -import com.conveyal.traffic.data.stats.SummaryStatistics; -import com.conveyal.traffic.data.stats.SummaryStatisticsComparison; -import com.conveyal.traffic.geom.StreetSegment; -import com.conveyal.traffic.data.stats.SegmentStatistics; -import com.vividsolutions.jts.geom.Envelope; import org.mapdb.Fun; import org.opentripplanner.common.model.GenericLocation; import org.opentripplanner.routing.core.RoutingRequest; import org.opentripplanner.routing.core.TraverseMode; import org.opentripplanner.routing.core.TraverseModeSet; -import com.conveyal.traffic.data.pbf.ExchangeFormat; -import com.conveyal.traffic.geom.GPSPoint; import com.conveyal.traffic.app.data.StatsObject; +import com.conveyal.traffic.app.data.TrafficPath; +import com.conveyal.traffic.app.data.WeekObject; +import com.conveyal.traffic.app.data.WeeklyStatsObject; +import com.conveyal.traffic.app.engine.Engine; import com.conveyal.traffic.app.routing.Routing; import com.conveyal.traffic.app.tiles.TrafficTileRequest.DataTile; import com.conveyal.traffic.app.tiles.TrafficTileRequest.SegmentTile; import com.fasterxml.jackson.databind.ObjectMapper; - -import static spark.Spark.*; +import com.vividsolutions.jts.geom.Envelope; public class TrafficEngineApp { - - private static final Logger log = Logger.getLogger( TrafficEngineApp.class.getName()); - - private static final ObjectMapper mapper = new ObjectMapper(); - - private static Routing routing = new Routing(new Rectangle(-180, -90, 360, 180)); - - public static Properties appProps = new Properties(); - - public static Engine engine; - - public static HashMap vehicleIdMap = new HashMap<>(); - - public static void main(String[] args) { - - // load settings file - loadSettings(); - - // setup public folder - staticFileLocation("/public"); - - engine = new Engine(); - - get("/writeTrafficTiles", (request, response) -> { - engine.collectStatistics(); - return "Traffic tiles written."; - }); - get("/stats", (request, response) -> new StatsObject(), mapper::writeValueAsString); + private static final Logger log = Logger.getLogger(TrafficEngineApp.class + .getName()); - get("/weeks", (request, response) -> { + private static final ObjectMapper mapper = new ObjectMapper(); - List weeks = engine.getTrafficEngine().osmData.statsDataStore.getWeekList(); - List weekObjects = new ArrayList(); - for(Integer week : weeks) { - WeekObject weekObj = new WeekObject(); - weekObj.weekId = week; - weekObj.weekStartTime = SegmentStatistics.getTimeForWeek(week); - weekObjects.add(weekObj); - } - return weekObjects; - }, mapper::writeValueAsString); + private static Routing routing = new Routing(new Rectangle(-180, -90, 360, + 180)); - get("/weeklyStats", (request, response) -> { + public static Properties appProps = new Properties(); - response.header("Access-Control-Allow-Origin", "*"); - response.header("Access-Control-Request-Method", "*"); - response.header("Access-Control-Allow-Headers", "*"); + public static Engine engine; - double x1 = request.queryMap("x1").doubleValue(); - double x2 = request.queryMap("x2").doubleValue(); - double y1 = request.queryMap("y1").doubleValue(); - double y2 = request.queryMap("y2").doubleValue(); + public static HashMap vehicleIdMap = new HashMap<>(); - Set weeks1 = new HashSet<>(); - Set weeks2 = new HashSet<>(); + public static void main(String[] args) { - boolean normalizeByTime = request.queryMap("normalizeByTime").booleanValue(); - int confidenceInterval = request.queryMap("confidenceInterval").integerValue(); + // load settings file + loadSettings(); - if(request.queryMap("w1").value() != null && !request.queryMap("w1").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("w1").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> weeks1.add(Integer.parseInt(v.trim()))); - } + // setup public folder + staticFileLocation("/public"); - if(request.queryMap("w2").value() != null && !request.queryMap("w2").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("w2").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> weeks2.add(Integer.parseInt(v.trim()))); - } + engine = new Engine(); - Envelope env1 = new Envelope(x1, x2, y1, y2); + get("/writeTrafficTiles", (request, response) -> { + engine.collectStatistics(); + return "Traffic tiles written."; + }); - Set segmentIds = TrafficEngineApp.engine.getTrafficEngine().getStreetSegmentIds(env1) - .stream().collect(Collectors.toSet()); + get("/stats", (request, response) -> new StatsObject(), + mapper::writeValueAsString); - SummaryStatistics summaryStats1 = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(segmentIds,normalizeByTime, weeks1, null); + get("/weeks", + (request, response) -> { - if (weeks2.size() > 0) { - SummaryStatistics summaryStats2 = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(segmentIds,normalizeByTime, weeks2, null); - SummaryStatisticsComparison summaryStatisticsComparison = new SummaryStatisticsComparison(SummaryStatisticsComparison.PValue.values()[confidenceInterval], summaryStats1, summaryStats2); + List weeks = engine.getTrafficEngine().osmData.statsDataStore + .getWeekList(); + List weekObjects = new ArrayList(); + for (Integer week : weeks) { + WeekObject weekObj = new WeekObject(); + weekObj.weekId = week; + weekObj.weekStartTime = SegmentStatistics + .getTimeForWeek(week); + weekObjects.add(weekObj); + } + return weekObjects; + }, mapper::writeValueAsString); - return new WeeklyStatsObject(summaryStatisticsComparison); - } - else - return new WeeklyStatsObject(summaryStats1); + get("/weeklyStats", + (request, response) -> { + + response.header("Access-Control-Allow-Origin", "*"); + response.header("Access-Control-Request-Method", "*"); + response.header("Access-Control-Allow-Headers", "*"); + + double x1 = request.queryMap("x1").doubleValue(); + double x2 = request.queryMap("x2").doubleValue(); + double y1 = request.queryMap("y1").doubleValue(); + double y2 = request.queryMap("y2").doubleValue(); + + Set weeks1 = new HashSet<>(); + Set weeks2 = new HashSet<>(); + + boolean normalizeByTime = request.queryMap( + "normalizeByTime").booleanValue(); + int confidenceInterval = request.queryMap( + "confidenceInterval").integerValue(); + + if (request.queryMap("w1").value() != null + && !request.queryMap("w1").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("w1").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> weeks1.add(Integer.parseInt(v + .trim()))); + } + + if (request.queryMap("w2").value() != null + && !request.queryMap("w2").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("w2").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> weeks2.add(Integer.parseInt(v + .trim()))); + } + + Envelope env1 = new Envelope(x1, x2, y1, y2); + + Set segmentIds = TrafficEngineApp.engine + .getTrafficEngine().getStreetSegmentIds(env1) + .stream().collect(Collectors.toSet()); + + SummaryStatistics summaryStats1 = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(segmentIds, + normalizeByTime, weeks1, null); + + if (weeks2.size() > 0) { + SummaryStatistics summaryStats2 = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(segmentIds, + normalizeByTime, weeks2, null); + SummaryStatisticsComparison summaryStatisticsComparison = new SummaryStatisticsComparison( + SummaryStatisticsComparison.PValue.values()[confidenceInterval], + summaryStats1, summaryStats2); + + return new WeeklyStatsObject( + summaryStatisticsComparison); + } else + return new WeeklyStatsObject(summaryStats1); }, mapper::writeValueAsString); - - post("/locationUpdate", (request, response) -> { - ExchangeFormat.VehicleMessageEnvelope vmEnvelope = ExchangeFormat.VehicleMessageEnvelope.parseFrom(request.bodyAsBytes()); + post("/locationUpdate", + (request, response) -> { - long sourceId = vmEnvelope.getSourceId(); + ExchangeFormat.VehicleMessageEnvelope vmEnvelope = ExchangeFormat.VehicleMessageEnvelope + .parseFrom(request.bodyAsBytes()); - for(ExchangeFormat.VehicleMessage vm : vmEnvelope.getMessagesList()) { + long sourceId = vmEnvelope.getSourceId(); - long vehicleId = getUniqueIdFromString(sourceId + "_" + vm.getVehicleId()); + for (ExchangeFormat.VehicleMessage vm : vmEnvelope + .getMessagesList()) { - for (ExchangeFormat.VehicleLocation location : vm.getLocationsList()) { + long vehicleId = getUniqueIdFromString(sourceId + "_" + + vm.getVehicleId()); - GPSPoint gpsPoint = new GPSPoint(location.getTimestamp(), vehicleId, location.getLon(), location.getLat()); + for (ExchangeFormat.VehicleLocation location : vm + .getLocationsList()) { - if(gpsPoint.lat != 0.0 && gpsPoint.lon != 0.0) - TrafficEngineApp.engine.locationUpdate(gpsPoint); - } + GPSPoint gpsPoint = new GPSPoint(location + .getTimestamp(), vehicleId, location + .getLon(), location.getLat()); + + if (gpsPoint.lat != 0.0 && gpsPoint.lon != 0.0) + TrafficEngineApp.engine + .locationUpdate(gpsPoint); } - return response; + } + return response; }); - - // routing requests - - get("/route", (request, response) -> { - - response.header("Access-Control-Allow-Origin", "*"); - - double fromLat = request.queryMap("fromLat").doubleValue(); - double fromLon = request.queryMap("fromLon").doubleValue(); - double toLat = request.queryMap("toLat").doubleValue(); - double toLon = request.queryMap("toLon").doubleValue(); - boolean useTraffic = false; - boolean normalizeByTime = true; - - - Set hours = new HashSet<>(); - - if(request.queryMap("h").value() != null && !request.queryMap("h").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("h").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> hours.add(Integer.parseInt(v.trim()))); - } - - Set w1 = new HashSet<>(); - Set w2 = new HashSet<>(); - if(request.queryMap("w1").value() != null && !request.queryMap("w1").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("w1").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> w1.add(Integer.parseInt(v.trim()))); + // routing requests + + get("/route", + (request, response) -> { + + response.header("Access-Control-Allow-Origin", "*"); + + double fromLat = request.queryMap("fromLat").doubleValue(); + double fromLon = request.queryMap("fromLon").doubleValue(); + double toLat = request.queryMap("toLat").doubleValue(); + double toLon = request.queryMap("toLon").doubleValue(); + boolean useTraffic = false; + boolean normalizeByTime = true; + + Set hours = new HashSet<>(); + + if (request.queryMap("h").value() != null + && !request.queryMap("h").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("h").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> hours.add(Integer.parseInt(v.trim()))); + } + + Set w1 = new HashSet<>(); + Set w2 = new HashSet<>(); + + if (request.queryMap("w1").value() != null + && !request.queryMap("w1").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("w1").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> w1.add(Integer.parseInt(v.trim()))); + } + + if (request.queryMap("w2").value() != null + && !request.queryMap("w2").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("w2").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> w2.add(Integer.parseInt(v.trim()))); + } + + routing.buildIfUnbuilt(); + + RoutingRequest rr = new RoutingRequest(); + + rr.useTraffic = useTraffic; + rr.from = new GenericLocation(fromLat, fromLon); + rr.to = new GenericLocation(toLat, toLon); + rr.modes = new TraverseModeSet(TraverseMode.CAR); + + // figure out the time + LocalDateTime dt = LocalDateTime.now(); + rr.dateTime = OffsetDateTime.of(dt, ZoneOffset.UTC) + .toEpochSecond(); + + List> edges = new ArrayList<>( + routing.route(rr)); + + TrafficPath trafficPath = new TrafficPath(); + + Set edgeIds = new HashSet<>(); + + Fun.Tuple3 lastUnmatchedEdgeId = null; + for (Fun.Tuple3 edgeId : edges) { + List streetSegments = engine + .getTrafficEngine() + .getStreetSegmentsBySegmentId(edgeId); + if (streetSegments.size() == 0) { + if (lastUnmatchedEdgeId != null + && lastUnmatchedEdgeId.a.equals(edgeId.a)) { + edgeId = new Fun.Tuple3<>(edgeId.a, + lastUnmatchedEdgeId.b, edgeId.c); + } + streetSegments = engine.getTrafficEngine() + .getStreetSegmentsBySegmentId(edgeId); } - - if(request.queryMap("w2").value() != null && !request.queryMap("w2").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("w2").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> w2.add(Integer.parseInt(v.trim()))); + if (streetSegments.size() != 0) { + for (SpatialDataItem sdi : streetSegments) { + StreetSegment streetSegment = (StreetSegment) sdi; + if (streetSegment != null) { + lastUnmatchedEdgeId = null; + edgeIds.add(streetSegment.id); + SummaryStatistics summaryStatistics = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics( + streetSegment.id, true, w1, + hours); + if (summaryStatistics != null) + trafficPath.addSegment(streetSegment, + summaryStatistics); + } else { + lastUnmatchedEdgeId = edgeId; + } + } + } else { + lastUnmatchedEdgeId = edgeId; } - routing.buildIfUnbuilt(); - - RoutingRequest rr = new RoutingRequest(); - - rr.useTraffic = useTraffic; - rr.from = new GenericLocation(fromLat, fromLon); - rr.to = new GenericLocation(toLat, toLon); - rr.modes = new TraverseModeSet(TraverseMode.CAR); + } - // figure out the time - LocalDateTime dt = LocalDateTime.now(); - rr.dateTime = OffsetDateTime.of(dt, ZoneOffset.UTC).toEpochSecond(); + SummaryStatistics summaryStatistics = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(edgeIds, true, w1, null); + trafficPath.setWeeklyStats(summaryStatistics); - List> edges = new ArrayList<>(routing.route(rr)); + return mapper.writeValueAsString(trafficPath); + }); - TrafficPath trafficPath =new TrafficPath(); + get("/tile/data", + (request, response) -> { - Set edgeIds = new HashSet<>(); + int x = request.queryMap("x").integerValue(); + int y = request.queryMap("y").integerValue(); + int z = request.queryMap("z").integerValue(); - Fun.Tuple3 lastUnmatchedEdgeId = null; - for(Fun.Tuple3 edgeId : edges) { - List streetSegments = engine.getTrafficEngine().getStreetSegmentsBySegmentId(edgeId); - if(streetSegments.size() == 0) { - if(lastUnmatchedEdgeId != null && lastUnmatchedEdgeId.a.equals(edgeId.a)) { - edgeId = new Fun.Tuple3<>(edgeId.a, lastUnmatchedEdgeId.b, edgeId.c); - } - streetSegments = engine.getTrafficEngine().getStreetSegmentsBySegmentId(edgeId); - } - if(streetSegments.size() != 0) { - for(SpatialDataItem sdi : streetSegments) { - StreetSegment streetSegment = (StreetSegment)sdi; - if(streetSegment != null) { - lastUnmatchedEdgeId = null; - edgeIds.add(streetSegment.id); - SummaryStatistics summaryStatistics = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(streetSegment.id, true, w1, hours); - if(summaryStatistics != null) - trafficPath.addSegment(streetSegment, summaryStatistics); - } - else { - lastUnmatchedEdgeId = edgeId; - } - } - } - else { - lastUnmatchedEdgeId = edgeId; - } + response.raw().setHeader("CACHE_CONTROL", + "no-cache, no-store, must-revalidate"); + response.raw().setHeader("PRAGMA", "no-cache"); + response.raw().setHeader("EXPIRES", "0"); + response.raw().setContentType("image/png"); - } + DataTile dataTile = new DataTile(x, y, z); - SummaryStatistics summaryStatistics = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(edgeIds, true, w1, null); - trafficPath.setWeeklyStats(summaryStatistics); + byte[] imageData = dataTile.render(); - return mapper.writeValueAsString(trafficPath); + response.raw().getOutputStream().write(imageData); + return response; }); - - get("/tile/data", (request, response) -> { - - int x = request.queryMap("x").integerValue(); - int y = request.queryMap("y").integerValue(); - int z = request.queryMap("z").integerValue(); - - response.raw().setHeader("CACHE_CONTROL", "no-cache, no-store, must-revalidate"); - response.raw().setHeader("PRAGMA", "no-cache"); - response.raw().setHeader("EXPIRES", "0"); - response.raw().setContentType("image/png"); - - DataTile dataTile = new DataTile(x, y, z); - - byte[] imageData = dataTile.render(); - - response.raw().getOutputStream().write(imageData); - return response; + + get("/tile/traffic", + (request, response) -> { + + int x = request.queryMap("x").integerValue(); + int y = request.queryMap("y").integerValue(); + int z = request.queryMap("z").integerValue(); + + boolean normalizeByTime = request.queryMap( + "normalizeByTime").booleanValue(); + int confidenceInterval = request.queryMap( + "confidenceInterval").integerValue(); + + List hours = new ArrayList<>(); + + if (request.queryMap("h").value() != null + && !request.queryMap("h").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("h").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> hours.add(Integer.parseInt(v.trim()))); + } + + List w1 = new ArrayList<>(); + List w2 = new ArrayList<>(); + + if (request.queryMap("w1").value() != null + && !request.queryMap("w1").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("w1").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> w1.add(Integer.parseInt(v.trim()))); + } + + if (request.queryMap("w2").value() != null + && !request.queryMap("w2").value().trim().isEmpty()) { + String valueStr[] = request.queryMap("w2").value() + .trim().split(","); + List values = new ArrayList(Arrays + .asList(valueStr)); + values.forEach(v -> w2.add(Integer.parseInt(v.trim()))); + } + + response.raw().setHeader("CACHE_CONTROL", + "no-cache, no-store, must-revalidate"); + response.raw().setHeader("PRAGMA", "no-cache"); + response.raw().setHeader("EXPIRES", "0"); + response.raw().setContentType("image/png"); + + SegmentTile dataTile = new SegmentTile(x, y, z, + normalizeByTime, confidenceInterval, w1, w2, hours); + + byte[] imageData = dataTile.render(); + + response.raw().getOutputStream().write(imageData); + return response; }); - - get("/tile/traffic", (request, response) -> { - - int x = request.queryMap("x").integerValue(); - int y = request.queryMap("y").integerValue(); - int z = request.queryMap("z").integerValue(); - - boolean normalizeByTime = request.queryMap("normalizeByTime").booleanValue(); - int confidenceInterval = request.queryMap("confidenceInterval").integerValue(); - - List hours = new ArrayList<>(); - - if(request.queryMap("h").value() != null && !request.queryMap("h").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("h").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> hours.add(Integer.parseInt(v.trim()))); - } + } - List w1 = new ArrayList<>(); - List w2 = new ArrayList<>(); + static Long getUniqueIdFromString(String data) + throws NoSuchAlgorithmException { - if(request.queryMap("w1").value() != null && !request.queryMap("w1").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("w1").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> w1.add(Integer.parseInt(v.trim()))); - } + if (vehicleIdMap.containsKey(data)) + return vehicleIdMap.get(data); - if(request.queryMap("w2").value() != null && !request.queryMap("w2").value().trim().isEmpty()) { - String valueStr[] = request.queryMap("w2").value().trim().split(","); - List values = new ArrayList(Arrays.asList(valueStr)); - values.forEach(v -> w2.add(Integer.parseInt(v.trim()))); - } + MessageDigest md = MessageDigest.getInstance("MD5"); - response.raw().setHeader("CACHE_CONTROL", "no-cache, no-store, must-revalidate"); - response.raw().setHeader("PRAGMA", "no-cache"); - response.raw().setHeader("EXPIRES", "0"); - response.raw().setContentType("image/png"); - - SegmentTile dataTile = new SegmentTile(x, y, z, normalizeByTime, confidenceInterval, w1, w2, hours); - - byte[] imageData = dataTile.render(); - - response.raw().getOutputStream().write(imageData); - return response; - }); - } + md.update(data.getBytes()); + ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / 8); - - static Long getUniqueIdFromString(String data) throws NoSuchAlgorithmException { + buffer.put(md.digest(), 0, Long.SIZE / 8); + buffer.flip();// need flip - if(vehicleIdMap.containsKey(data)) - return vehicleIdMap.get(data); + vehicleIdMap.put(data, buffer.getLong()); + return vehicleIdMap.get(data); - MessageDigest md = MessageDigest.getInstance("MD5"); - - md.update(data.getBytes()); - ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / 8); - - buffer.put(md.digest(), 0, Long.SIZE / 8); - buffer.flip();//need flip + } - vehicleIdMap.put(data, buffer.getLong()); - return vehicleIdMap.get(data); + public static void loadSettings() { + try { + FileInputStream in = new FileInputStream("application.conf"); + appProps.load(in); + in.close(); + } catch (IOException e) { + log.log(Level.WARNING, "Unable to load application.conf file: {0}", + e.getMessage()); + e.printStackTrace(); } - - public static void loadSettings() { - try { - FileInputStream in = new FileInputStream("application.conf"); - appProps.load(in); - in.close(); - - } catch (IOException e) { - log.log(Level.WARNING, "Unable to load application.conf file: {0}", e.getMessage()); - e.printStackTrace(); - } - } - - + } } diff --git a/src/main/java/com/conveyal/traffic/app/data/TrafficPath.java b/src/main/java/com/conveyal/traffic/app/data/TrafficPath.java index 1fd27a6..3312c49 100644 --- a/src/main/java/com/conveyal/traffic/app/data/TrafficPath.java +++ b/src/main/java/com/conveyal/traffic/app/data/TrafficPath.java @@ -1,7 +1,7 @@ package com.conveyal.traffic.app.data; -import com.conveyal.traffic.data.stats.SummaryStatistics; -import com.conveyal.traffic.geom.StreetSegment; +import io.opentraffic.engine.data.stats.SummaryStatistics; +import io.opentraffic.engine.geom.StreetSegment; import java.util.ArrayList; import java.util.List; @@ -16,12 +16,14 @@ public class TrafficPath { public WeeklyStatsObject weeklyStats; public void setWeeklyStats(SummaryStatistics stats) { - weeklyStats = new WeeklyStatsObject(stats); + weeklyStats = new WeeklyStatsObject(stats); } - public void addSegment(StreetSegment streetSegment, SummaryStatistics summaryStatistics) { + public void addSegment(StreetSegment streetSegment, + SummaryStatistics summaryStatistics) { - TrafficPathEdge pathEdge = new TrafficPathEdge(streetSegment, summaryStatistics); - pathEdges.add(pathEdge); + TrafficPathEdge pathEdge = new TrafficPathEdge(streetSegment, + summaryStatistics); + pathEdges.add(pathEdge); } } diff --git a/src/main/java/com/conveyal/traffic/app/data/TrafficPathEdge.java b/src/main/java/com/conveyal/traffic/app/data/TrafficPathEdge.java index 9fd43d5..2525527 100644 --- a/src/main/java/com/conveyal/traffic/app/data/TrafficPathEdge.java +++ b/src/main/java/com/conveyal/traffic/app/data/TrafficPathEdge.java @@ -1,13 +1,14 @@ package com.conveyal.traffic.app.data; -import com.conveyal.traffic.data.stats.SummaryStatistics; -import com.conveyal.traffic.geom.StreetSegment; +import io.opentraffic.engine.data.stats.SummaryStatistics; +import io.opentraffic.engine.geom.StreetSegment; + +import java.awt.Color; + import org.jcolorbrewer.ColorBrewer; import org.opentripplanner.util.PolylineEncoder; import org.opentripplanner.util.model.EncodedPolylineBean; -import java.awt.*; - /** * Created by kpw on 7/19/15. */ @@ -20,19 +21,21 @@ public class TrafficPathEdge { public double length; public double speed; - public TrafficPathEdge(StreetSegment streetSegment, SummaryStatistics summaryStatistics) { - + public TrafficPathEdge(StreetSegment streetSegment, + SummaryStatistics summaryStatistics) { - EncodedPolylineBean encodedPolyline = PolylineEncoder.createEncodings(streetSegment.getGeometry()); - geometry = encodedPolyline.getPoints(); + EncodedPolylineBean encodedPolyline = PolylineEncoder + .createEncodings(streetSegment.getGeometry()); + geometry = encodedPolyline.getPoints(); - int colorNum = (int) (10 / (50.0 / (summaryStatistics.getMean() * 3.6))); - if(colorNum > 10) - colorNum = 10; + int colorNum = (int) (10 / (50.0 / (summaryStatistics.getMean() * 3.6))); + if (colorNum > 10) + colorNum = 10; - color = String.format("#%02x%02x%02x", colors[colorNum].getRed(), colors[colorNum].getGreen(), colors[colorNum].getBlue()); + color = String.format("#%02x%02x%02x", colors[colorNum].getRed(), + colors[colorNum].getGreen(), colors[colorNum].getBlue()); - length = streetSegment.length; - speed = summaryStatistics.getMean(); + length = streetSegment.length; + speed = summaryStatistics.getMean(); } } diff --git a/src/main/java/com/conveyal/traffic/app/data/WeeklyStatsObject.java b/src/main/java/com/conveyal/traffic/app/data/WeeklyStatsObject.java index fb5094d..1544b04 100644 --- a/src/main/java/com/conveyal/traffic/app/data/WeeklyStatsObject.java +++ b/src/main/java/com/conveyal/traffic/app/data/WeeklyStatsObject.java @@ -1,70 +1,68 @@ package com.conveyal.traffic.app.data; -import com.conveyal.traffic.data.stats.SummaryStatistics; -import com.conveyal.traffic.data.stats.SummaryStatisticsComparison; +import io.opentraffic.engine.data.stats.SummaryStatistics; +import io.opentraffic.engine.data.stats.SummaryStatisticsComparison; public class WeeklyStatsObject { - public static double MS_TO_KMH = 3.6d; - public static int HOURS_IN_WEEK = 24 * 7; + public static double MS_TO_KMH = 3.6d; + public static int HOURS_IN_WEEK = 24 * 7; - public HourStats[] hours = new HourStats[HOURS_IN_WEEK]; + public HourStats[] hours = new HourStats[HOURS_IN_WEEK]; - public WeeklyStatsObject(SummaryStatistics stats) { + public WeeklyStatsObject(SummaryStatistics stats) { - for(int hour = 0; hour < (HOURS_IN_WEEK); hour++) { + for (int hour = 0; hour < (HOURS_IN_WEEK); hour++) { - HourStats hourStats = new HourStats(); - hourStats.h = hour; - double sum =stats.hourSum.get(hour); - double count = stats.hourCount.get(hour); - double std = stats.getStdDev(hour); - if(!Double.isNaN(sum) && !Double.isNaN(count) && !Double.isNaN(std)){ - hourStats.s = sum; - hourStats.c = count; - hourStats.std = std; - } else { - hourStats.s = 0; - hourStats.c = 0; - hourStats.std = 0; - } + HourStats hourStats = new HourStats(); + hourStats.h = hour; + double sum = stats.hourSum.get(hour); + double count = stats.hourCount.get(hour); + double std = stats.getStdDev(hour); + if (!Double.isNaN(sum) && !Double.isNaN(count) + && !Double.isNaN(std)) { + hourStats.s = sum; + hourStats.c = count; + hourStats.std = std; + } else { + hourStats.s = 0; + hourStats.c = 0; + hourStats.std = 0; + } - hours[hour] = hourStats; - } + hours[hour] = hourStats; } - - public WeeklyStatsObject(SummaryStatisticsComparison stats) { - - for(int hour = 0; hour < (HOURS_IN_WEEK); hour++) { - - HourStats hourStats = new HourStats(); - hourStats.h = hour; - double diff = stats.differenceAsPercent(hour); - double meanSize = stats.getMeanSize(hour); - double std = stats.combinedStdDev(hour); - if(stats.tTest(hour) && !Double.isNaN(diff) && !Double.isNaN(meanSize) && !Double.isNaN(meanSize)) { - hourStats.s = diff * meanSize; - hourStats.c = meanSize; - hourStats.std = std; - } - else { - hourStats.s = 0; - hourStats.c = stats.getMeanSize(hour); - hourStats.std = stats.combinedStdDev(hour); - } - - - - - hours[hour] = hourStats; - } - } - - private static class HourStats { - public int h; - public double s; - public double c; - public double std; - public boolean t; + } + + public WeeklyStatsObject(SummaryStatisticsComparison stats) { + + for (int hour = 0; hour < (HOURS_IN_WEEK); hour++) { + + HourStats hourStats = new HourStats(); + hourStats.h = hour; + double diff = stats.differenceAsPercent(hour); + double meanSize = stats.getMeanSize(hour); + double std = stats.combinedStdDev(hour); + if (stats.tTest(hour) && !Double.isNaN(diff) + && !Double.isNaN(meanSize) && !Double.isNaN(meanSize)) { + hourStats.s = diff * meanSize; + hourStats.c = meanSize; + hourStats.std = std; + } else { + hourStats.s = 0; + hourStats.c = stats.getMeanSize(hour); + hourStats.std = stats.combinedStdDev(hour); + } + + hours[hour] = hourStats; } + } + + private static class HourStats { + public int h; + public double s; + public double c; + public double std; + public boolean t; + } } \ No newline at end of file diff --git a/src/main/java/com/conveyal/traffic/app/engine/Engine.java b/src/main/java/com/conveyal/traffic/app/engine/Engine.java index 5663162..7bc22ba 100644 --- a/src/main/java/com/conveyal/traffic/app/engine/Engine.java +++ b/src/main/java/com/conveyal/traffic/app/engine/Engine.java @@ -1,82 +1,94 @@ package com.conveyal.traffic.app.engine; +import io.opentraffic.engine.TrafficEngine; +import io.opentraffic.engine.geom.GPSPoint; +import io.opentraffic.engine.osm.OSMArea; + import java.io.File; -import java.util.*; +import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; -import com.conveyal.traffic.TrafficEngine; import com.conveyal.traffic.app.TrafficEngineApp; -import com.conveyal.traffic.geom.GPSPoint; -import com.conveyal.traffic.osm.OSMArea; import com.vividsolutions.jts.geom.Point; - public class Engine { - - private static final Logger log = Logger.getLogger( Engine.class.getName()); - - private TrafficEngine te; - private HashMap locationMap = new HashMap<>(); + private static final Logger log = Logger.getLogger(Engine.class.getName()); - - public Engine() { + private TrafficEngine te; - String cacheDirectory =TrafficEngineApp.appProps.getProperty("application.data.cacheDirectory"); - String osmDirectory = TrafficEngineApp.appProps.getProperty("application.data.osmDirectory"); - String osmServer = TrafficEngineApp.appProps.getProperty("application.vex"); + private HashMap locationMap = new HashMap<>(); - Boolean enableTimeZoneConversion; - try { - enableTimeZoneConversion = Boolean.parseBoolean(TrafficEngineApp.appProps.getProperty("application.enableTimeZoneConversion")); - } catch(Exception e) { - enableTimeZoneConversion = true; - log.log(Level.INFO, "Property enableTimeZoneConversion not set, defaulting to enabled"); + public Engine() { - } + String cacheDirectory = TrafficEngineApp.appProps + .getProperty("application.data.cacheDirectory"); + String osmDirectory = TrafficEngineApp.appProps + .getProperty("application.data.osmDirectory"); + String osmServer = TrafficEngineApp.appProps + .getProperty("application.vex"); + + Boolean enableTimeZoneConversion; + try { + enableTimeZoneConversion = Boolean + .parseBoolean(TrafficEngineApp.appProps + .getProperty("application.enableTimeZoneConversion")); + } catch (Exception e) { + enableTimeZoneConversion = true; + log.log(Level.INFO, + "Property enableTimeZoneConversion not set, defaulting to enabled"); + + } + + Integer numberOfWorkerCores; + try { + numberOfWorkerCores = Integer.parseInt(TrafficEngineApp.appProps + .getProperty("writeStatistics")); + } catch (Exception e) { + numberOfWorkerCores = Runtime.getRuntime().availableProcessors() / 2; + log.log(Level.INFO, + "Property numberOfWorkerCores not set, defaulting to " + + numberOfWorkerCores + " cores."); + + } + + Integer osmCacheSize; + try { + osmCacheSize = Integer.parseInt(TrafficEngineApp.appProps + .getProperty("application.osmCacheSize")); + } catch (Exception e) { + log.log(Level.INFO, + "Property application.osmCacheSize not set, defaulting to cache size of 1,000,000"); + osmCacheSize = 1_000_000; + } + + te = new TrafficEngine(numberOfWorkerCores, new File(cacheDirectory), + new File(osmDirectory), osmServer, osmCacheSize, + enableTimeZoneConversion); - Integer numberOfWorkerCores; - try { - numberOfWorkerCores = Integer.parseInt(TrafficEngineApp.appProps.getProperty("writeStatistics")); - } catch(Exception e) { - numberOfWorkerCores = Runtime.getRuntime().availableProcessors() / 2; - log.log(Level.INFO, "Property numberOfWorkerCores not set, defaulting to " + numberOfWorkerCores + " cores."); + } - } + public TrafficEngine getTrafficEngine() { + return te; + } - Integer osmCacheSize; - try { - osmCacheSize = Integer.parseInt(TrafficEngineApp.appProps.getProperty("application.osmCacheSize")); - } catch(Exception e) { - log.log(Level.INFO, "Property application.osmCacheSize not set, defaulting to cache size of 1,000,000"); - osmCacheSize = 1_000_000; - } + public void collectStatistics() { + String trafficTilePath = TrafficEngineApp.appProps + .getProperty("application.data.trafficTileDirectory"); - te = new TrafficEngine(numberOfWorkerCores, new File(cacheDirectory), new File(osmDirectory), osmServer, osmCacheSize, enableTimeZoneConversion); + File dataCache = new File(trafficTilePath); + dataCache.mkdirs(); + for (OSMArea osmArea : te.getOsmAreas()) { + te.writeStatistics(new File(dataCache, osmArea.z + "_" + osmArea.x + + "_" + osmArea.y + ".traffic.protobuf"), osmArea.env); + } } - - public TrafficEngine getTrafficEngine() { - return te; - } - - - public void collectStatistics() { - String trafficTilePath = TrafficEngineApp.appProps.getProperty("application.data.trafficTileDirectory"); - - File dataCache = new File(trafficTilePath); - dataCache.mkdirs(); - - for(OSMArea osmArea : te.getOsmAreas()) { - te.writeStatistics(new File(dataCache, osmArea.z + "_" + osmArea.x + "_" + osmArea.y + ".traffic.protobuf"), osmArea.env); - } - } - public void locationUpdate(GPSPoint gpsPoint) { - te.enqeueGPSPoint(gpsPoint); + te.enqeueGPSPoint(gpsPoint); } diff --git a/src/main/java/com/conveyal/traffic/app/routing/Routing.java b/src/main/java/com/conveyal/traffic/app/routing/Routing.java index 23df380..80890dd 100644 --- a/src/main/java/com/conveyal/traffic/app/routing/Routing.java +++ b/src/main/java/com/conveyal/traffic/app/routing/Routing.java @@ -1,13 +1,19 @@ package com.conveyal.traffic.app.routing; +import io.opentraffic.engine.data.SpatialDataItem; +import io.opentraffic.engine.data.stats.SummaryStatistics; +import io.opentraffic.engine.geom.StreetSegment; -import com.beust.jcommander.internal.Maps; -import com.conveyal.traffic.data.SpatialDataItem; -import com.conveyal.traffic.geom.StreetSegment; -import com.conveyal.traffic.data.stats.SummaryStatistics; -import com.conveyal.traffic.app.TrafficEngineApp; -import com.google.common.collect.Lists; -import com.vividsolutions.jts.geom.Envelope; +import java.awt.Rectangle; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; import org.mapdb.Fun; import org.opentripplanner.analyst.core.SlippyTile; @@ -27,24 +33,18 @@ import org.opentripplanner.traffic.StreetSpeedSnapshot; import org.opentripplanner.traffic.StreetSpeedSnapshotSource; -import java.awt.*; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; +import com.beust.jcommander.internal.Maps; +import com.conveyal.traffic.app.TrafficEngineApp; +import com.google.common.collect.Lists; +import com.vividsolutions.jts.geom.Envelope; /** * Routing with OpenTraffic data in a single area of the world. */ public class Routing { - private static final Logger log = Logger.getLogger( Routing.class.getName()); - - /** The graph to use for routing. */ + private static final Logger log = Logger.getLogger(Routing.class.getName()); + + /** The graph to use for routing. */ private Router graph; /** The graph path finder for the above graph */ @@ -54,8 +54,8 @@ public class Routing { private Rectangle boundingBox; /** Create a new router with the given bounding box */ - public Routing (Rectangle boundingBox) { - this.boundingBox = boundingBox; + public Routing(Rectangle boundingBox) { + this.boundingBox = boundingBox; } private boolean unbuilt = true; @@ -63,164 +63,184 @@ public Routing (Rectangle boundingBox) { /** Get a trip plan, or null if the graph is not yet built */ public List> route(RoutingRequest request) { - if (graph == null) - return null; + if (graph == null) + return null; - Envelope env = new Envelope(); - env.expandToInclude(request.to.lng, request.to.lat); - env.expandToInclude(request.from.lng, request.from.lat); + Envelope env = new Envelope(); + env.expandToInclude(request.to.lng, request.to.lat); + env.expandToInclude(request.from.lng, request.from.lat); - //if(!updated) - // update(env); + // if(!updated) + // update(env); - List paths = gpf.graphPathFinderEntryPoint(request); + List paths = gpf.graphPathFinderEntryPoint(request); - List> edges = new ArrayList<>(); + List> edges = new ArrayList<>(); - if(paths.size() > 0) { - for(Edge edge : paths.get(0).edges) { - if(edge instanceof StreetEdge) { + if (paths.size() > 0) { + for (Edge edge : paths.get(0).edges) { + if (edge instanceof StreetEdge) { - StreetEdge streetEdge = (StreetEdge)edge; - if(streetEdge.wayId > 0) { - Fun.Tuple3 streetEdgeId = new Fun.Tuple3<>(streetEdge.wayId, streetEdge.getStartOsmNodeId(), streetEdge.getEndOsmNodeId()); - edges.add(streetEdgeId); - } + StreetEdge streetEdge = (StreetEdge) edge; + if (streetEdge.wayId > 0) { + Fun.Tuple3 streetEdgeId = new Fun.Tuple3<>( + streetEdge.wayId, + streetEdge.getStartOsmNodeId(), + streetEdge.getEndOsmNodeId()); + edges.add(streetEdgeId); + } - } + } - } - } + } + } - return edges; + return edges; } /** Update the traffic data in the graph */ private void update(Envelope env) { - Map samples = Maps.newHashMap(); - - // not using an updater here as that requires dumping/loading PBFs. - for (SpatialDataItem sdi : TrafficEngineApp.engine.getTrafficEngine().getStreetSegments(env)) { - StreetSegment ss = (StreetSegment) sdi; - SummaryStatistics stats = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(ss.id, null, null); - - if (stats == null || Double.isNaN(stats.getMean())) - continue; - - SegmentSpeedSample samp; - try { - samp = new SegmentSpeedSample(stats); - } catch (Exception e) { - e.printStackTrace(); - continue; - } - - Segment seg = new Segment(ss.wayId, ss.startNodeId, ss.endNodeId); - samples.put(seg, samp); - } - - if (!samples.isEmpty()) { - log.log(Level.INFO, "Applying " + samples.size() + " speed samples to graph"); - - if (graph.graph.streetSpeedSource == null) - graph.graph.streetSpeedSource = new StreetSpeedSnapshotSource(); - - graph.graph.streetSpeedSource.setSnapshot(new StreetSpeedSnapshot(samples)); - } - else { - log.log(Level.INFO, "Found no samples to apply to graph."); - - // clear existing samples - graph.graph.streetSpeedSource = null; - } - - updated = true; + Map samples = Maps.newHashMap(); + + // not using an updater here as that requires dumping/loading PBFs. + for (SpatialDataItem sdi : TrafficEngineApp.engine.getTrafficEngine() + .getStreetSegments(env)) { + StreetSegment ss = (StreetSegment) sdi; + SummaryStatistics stats = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(ss.id, null, null); + + if (stats == null || Double.isNaN(stats.getMean())) + continue; + + SegmentSpeedSample samp; + try { + samp = new SegmentSpeedSample(stats); + } catch (Exception e) { + e.printStackTrace(); + continue; + } + + Segment seg = new Segment(ss.wayId, ss.startNodeId, ss.endNodeId); + samples.put(seg, samp); + } + + if (!samples.isEmpty()) { + log.log(Level.INFO, "Applying " + samples.size() + + " speed samples to graph"); + + if (graph.graph.streetSpeedSource == null) + graph.graph.streetSpeedSource = new StreetSpeedSnapshotSource(); + + graph.graph.streetSpeedSource.setSnapshot(new StreetSpeedSnapshot( + samples)); + } else { + log.log(Level.INFO, "Found no samples to apply to graph."); + + // clear existing samples + graph.graph.streetSpeedSource = null; + } + + updated = true; } - public void buildIfUnbuilt () { - if (unbuilt) build(); + public void buildIfUnbuilt() { + if (unbuilt) + build(); } /** (Re)-build the graph (async method) */ - public void build () { - unbuilt = false; - ExecutorService es = Executors.newCachedThreadPool(); - es.execute( new BuildGraphs(this)); + public void build() { + unbuilt = false; + ExecutorService es = Executors.newCachedThreadPool(); + es.execute(new BuildGraphs(this)); } /** Build graphs so we can do routing with traffic data */ public static class BuildGraphs implements Runnable { - private final Routing routing; - - public BuildGraphs (Routing routing) { - this.routing = routing; - } - - @Override - public void run() { - // gather input files - List infiles = Lists.newArrayList(); - - // find all the OSM files we need - File cacheDir = new File(TrafficEngineApp.appProps.getProperty("application.data.osmDirectory")); - - Z: for (File zfile : cacheDir.listFiles()) { - int z = Integer.parseInt(zfile.getName()); - X: for (File xfile : zfile.listFiles()) { - int x = Integer.parseInt(xfile.getName()); - - log.log(Level.INFO, "x: " + x); - - double west = SlippyTile.tile2lon(x, z); - double east = SlippyTile.tile2lon(x + 1, z); - - // check if this could possibly contain the right file - if (east < routing.boundingBox.getMinX() || west > routing.boundingBox.getMaxX()) - continue X; - - Y: for (File yfile : xfile.listFiles()) { - int y = Integer.parseInt(yfile.getName().replace(".osm.pbf", "")); - - double north = SlippyTile.tile2lat(y, z); - double south = SlippyTile.tile2lat(y + 1, z); - - log.log(Level.INFO, "y: " + y + ", n: " + north + ", s: " + south); - - log.log(Level.INFO, "min: " + routing.boundingBox.getMinY() + ", max: " + routing.boundingBox.getMaxY()); - - if (north < routing.boundingBox.getMinY() || south > routing.boundingBox.getMaxY()) - continue Y; - - infiles.add(yfile); - } - } - } - - log.log(Level.INFO, "Using " + infiles.size() + " tiles for graph"); - - // phew. having figured out what tiles we need now build an OTP graph. - // note we do not configure an updater: we don't need one, as we do the updates - // ourselves. - GraphBuilder gb = new GraphBuilder(); - OpenStreetMapModule osm = new OpenStreetMapModule(); - osm.setProviders(infiles.stream() - .map(osmFile -> new AnyFileBasedOpenStreetMapProviderImpl(osmFile)) - .collect(Collectors.toList())); - gb.addModule(osm); - gb.serializeGraph = false; - gb.run(); - Graph g = gb.getGraph(); - Router r = new Router("default", g); - GraphPathFinder gpf = new GraphPathFinder(r); - - g.index(new DefaultStreetVertexIndexFactory()); - - synchronized (routing) { - routing.graph = r; - routing.gpf = gpf; - } - - log.log(Level.INFO, "graph built"); - } + private final Routing routing; + + public BuildGraphs(Routing routing) { + this.routing = routing; + } + + @Override + public void run() { + // gather input files + List infiles = Lists.newArrayList(); + + // find all the OSM files we need + File cacheDir = new File( + TrafficEngineApp.appProps + .getProperty("application.data.osmDirectory")); + + Z: for (File zfile : cacheDir.listFiles()) { + int z = Integer.parseInt(zfile.getName()); + X: for (File xfile : zfile.listFiles()) { + int x = Integer.parseInt(xfile.getName()); + + log.log(Level.INFO, "x: " + x); + + double west = SlippyTile.tile2lon(x, z); + double east = SlippyTile.tile2lon(x + 1, z); + + // check if this could possibly contain the right file + if (east < routing.boundingBox.getMinX() + || west > routing.boundingBox.getMaxX()) + continue X; + + Y: for (File yfile : xfile.listFiles()) { + int y = Integer.parseInt(yfile.getName().replace( + ".osm.pbf", "")); + + double north = SlippyTile.tile2lat(y, z); + double south = SlippyTile.tile2lat(y + 1, z); + + log.log(Level.INFO, "y: " + y + ", n: " + north + + ", s: " + south); + + log.log(Level.INFO, + "min: " + routing.boundingBox.getMinY() + + ", max: " + + routing.boundingBox.getMaxY()); + + if (north < routing.boundingBox.getMinY() + || south > routing.boundingBox.getMaxY()) + continue Y; + + infiles.add(yfile); + } + } + } + + log.log(Level.INFO, "Using " + infiles.size() + " tiles for graph"); + + // phew. having figured out what tiles we need now build an OTP + // graph. + // note we do not configure an updater: we don't need one, as we do + // the updates + // ourselves. + GraphBuilder gb = new GraphBuilder(); + OpenStreetMapModule osm = new OpenStreetMapModule(); + osm.setProviders(infiles + .stream() + .map(osmFile -> new AnyFileBasedOpenStreetMapProviderImpl( + osmFile)).collect(Collectors.toList())); + gb.addModule(osm); + gb.serializeGraph = false; + gb.run(); + Graph g = gb.getGraph(); + Router r = new Router("default", g); + GraphPathFinder gpf = new GraphPathFinder(r); + + g.index(new DefaultStreetVertexIndexFactory()); + + synchronized (routing) { + routing.graph = r; + routing.gpf = gpf; + } + + log.log(Level.INFO, "graph built"); + } } } diff --git a/src/main/java/com/conveyal/traffic/app/tiles/TrafficTileRequest.java b/src/main/java/com/conveyal/traffic/app/tiles/TrafficTileRequest.java index a5c7acb..f429df8 100644 --- a/src/main/java/com/conveyal/traffic/app/tiles/TrafficTileRequest.java +++ b/src/main/java/com/conveyal/traffic/app/tiles/TrafficTileRequest.java @@ -1,9 +1,22 @@ package com.conveyal.traffic.app.tiles; -import com.conveyal.traffic.data.SpatialDataItem; -import com.conveyal.traffic.data.stats.SummaryStatisticsComparison; -import com.conveyal.traffic.geom.StreetSegment; -import com.conveyal.traffic.data.stats.SummaryStatistics; +import io.opentraffic.engine.data.SpatialDataItem; +import io.opentraffic.engine.data.stats.SummaryStatistics; +import io.opentraffic.engine.data.stats.SummaryStatisticsComparison; +import io.opentraffic.engine.geom.StreetSegment; + +import java.awt.Color; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.imaging.ImageWriteException; +import org.jcolorbrewer.ColorBrewer; +import org.opengis.geometry.MismatchedDimensionException; +import org.opengis.referencing.operation.TransformException; + import com.conveyal.traffic.app.TrafficEngineApp; import com.google.common.base.Charsets; import com.google.common.hash.HashCode; @@ -11,247 +24,274 @@ import com.google.common.hash.Hashing; import com.vividsolutions.jts.geom.GeometryFactory; -import org.apache.commons.imaging.ImageWriteException; -import org.jcolorbrewer.ColorBrewer; -import org.opengis.geometry.MismatchedDimensionException; -import org.opengis.referencing.operation.TransformException; +public abstract class TrafficTileRequest { -import java.awt.*; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; + public static final double MS_TO_KMS = 3.6d; -public abstract class TrafficTileRequest { + final public String type; + final public Integer x, y, z; + + public TrafficTileRequest(Integer x, Integer y, Integer z, String type) { + this.x = x; + this.y = y; + this.z = z; + + this.type = type; + } + + public String getId() { + return type + "_" + x + "_" + y + "_" + z; + } + + public boolean equals(TrafficTileRequest tr) { + return this.getId().equals(tr.getId()); + } + + @Override + public int hashCode() { + HashFunction hashFunction = Hashing.md5(); + HashCode hashCode = hashFunction.newHasher() + .putString(this.getId(), Charsets.UTF_8).hash(); + + return hashCode.asInt(); + } + + abstract byte[] render(); - public static final double MS_TO_KMS = 3.6d; - - final public String type; - final public Integer x, y, z; - - public TrafficTileRequest(Integer x, Integer y, Integer z, String type) { - this.x = x; - this.y = y; - this.z = z; - - this.type = type; + public static class SegmentTile extends TrafficTileRequest { + Set hours; + Set w1, w2; + + Boolean normalizeByTime; + Integer confidenceInterval; + + public SegmentTile(Integer x, Integer y, Integer z, + Boolean normalizeByTime, Integer confidenceInterval, + List w1, List w2, List hours) { + super(x, y, z, "segment"); + + this.hours = new HashSet<>(hours); + this.w1 = new HashSet<>(w1); + this.w2 = new HashSet<>(w2); + this.normalizeByTime = normalizeByTime; + this.confidenceInterval = confidenceInterval; } + @Override public String getId() { - return type + "_" + x + "_" + y + "_" + z; - } - - public boolean equals(TrafficTileRequest tr) { - return this.getId().equals(tr.getId()); + return super.getId(); } - - public int hashCode() { - HashFunction hashFunction = Hashing.md5(); - HashCode hashCode = hashFunction.newHasher().putString(this.getId(), Charsets.UTF_8).hash(); - - return hashCode.asInt(); + + @Override + public byte[] render() { + if (this.w2 != null && this.w2.size() > 0) + return renderPercentChange(); + else + return renderSpeed(); } - - abstract byte[] render(); - public static class SegmentTile extends TrafficTileRequest { - Set hours; - Set w1, w2; + public byte[] renderPercentChange() { - Boolean normalizeByTime; - Integer confidenceInterval; + Tile tile = new Tile(this); - public SegmentTile(Integer x, Integer y, Integer z, Boolean normalizeByTime, Integer confidenceInterval, List w1, List w2, List hours) { - super(x, y, z, "segment"); + List segmentIds = TrafficEngineApp.engine.getTrafficEngine() + .getStreetSegmentIds(tile.envelope); - this.hours = new HashSet<>(hours); - this.w1 = new HashSet<>(w1); - this.w2 = new HashSet<>(w2); - this.normalizeByTime = normalizeByTime; - this.confidenceInterval =confidenceInterval; - } - - public String getId() { - return super.getId(); - } + for (Long id : segmentIds) { - public byte[] render() { - if(this.w2 != null && this.w2.size() > 0) - return renderPercentChange(); - else - return renderSpeed(); - } + try { - public byte[] renderPercentChange() { + double averageSpeed = 0.0; - Tile tile = new Tile(this); + int streetType = TrafficEngineApp.engine.getTrafficEngine() + .getStreetTypeById(id); - List segmentIds = TrafficEngineApp.engine.getTrafficEngine().getStreetSegmentIds(tile.envelope); + if (streetType == StreetSegment.TYPE_PRIMARY && z < 11) + continue; + else if (streetType == StreetSegment.TYPE_SECONDARY + && z < 14) + continue; + else if ((streetType == StreetSegment.TYPE_TERTIARY) + && z < 15) + continue; + else if ((streetType == StreetSegment.TYPE_RESIDENTIAL) + && z < 17) + continue; + else if (streetType == StreetSegment.TYPE_OTHER + || streetType == StreetSegment.TYPE_NON_ROADWAY) + continue; - for(Long id : segmentIds) { + Color color; - try { + SummaryStatistics stats1 = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(id, normalizeByTime, w1, + hours); + SummaryStatistics stats2 = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(id, normalizeByTime, w2, + hours); - double averageSpeed = 0.0; + SummaryStatisticsComparison statsComparison = new SummaryStatisticsComparison( + SummaryStatisticsComparison.PValue.values()[confidenceInterval], + stats1, stats2); - int streetType = TrafficEngineApp.engine.getTrafficEngine().getStreetTypeById(id); + Color[] colors; - if(streetType== StreetSegment.TYPE_PRIMARY && z < 11) - continue; - else if(streetType == StreetSegment.TYPE_SECONDARY && z < 14) - continue; - else if((streetType == StreetSegment.TYPE_TERTIARY) && z < 15) - continue; - else if((streetType == StreetSegment.TYPE_RESIDENTIAL) && z < 17) - continue; - else if(streetType == StreetSegment.TYPE_OTHER || streetType == StreetSegment.TYPE_NON_ROADWAY) - continue; + if (statsComparison.tTest()) { - Color color; + double speedPercentChange = statsComparison + .differenceAsPercent(); - SummaryStatistics stats1 = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(id, normalizeByTime, w1, hours); - SummaryStatistics stats2 = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(id, normalizeByTime, w2, hours); + if (speedPercentChange < 0) + colors = ColorBrewer.Reds.getColorPalette(5); + else + colors = ColorBrewer.Blues.getColorPalette(5); - SummaryStatisticsComparison statsComparison = new SummaryStatisticsComparison(SummaryStatisticsComparison.PValue.values()[confidenceInterval], stats1, stats2); + int colorNum; - Color[] colors; + if (Math.abs(speedPercentChange) > .5) + colorNum = 4; + else { + speedPercentChange = Math.abs(speedPercentChange) / 0.5; + colorNum = (int) Math.round(4 * speedPercentChange); + } - if(statsComparison.tTest()) { + tile.renderLineString(TrafficEngineApp.engine + .getTrafficEngine().getGeometryById(id), + colors[colorNum], 2); - double speedPercentChange = statsComparison.differenceAsPercent(); + } + // else + // tile.renderLineString(TrafficEngineApp.engine.getTrafficEngine().getGeometryById(id), + // Color.GREEN, 2); - if(speedPercentChange < 0) - colors = ColorBrewer.Reds.getColorPalette(5); - else - colors = ColorBrewer.Blues.getColorPalette(5); + } catch (MismatchedDimensionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (TransformException e) { + e.printStackTrace(); + } + } + + try { + return tile.generateImage(); + } catch (IOException | ImageWriteException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } - int colorNum; + public byte[] renderSpeed() { - if(Math.abs(speedPercentChange) > .5) - colorNum = 4; - else { - speedPercentChange = Math.abs(speedPercentChange) / 0.5 ; - colorNum = (int)Math.round(4 * speedPercentChange); - } + Tile tile = new Tile(this); - tile.renderLineString(TrafficEngineApp.engine.getTrafficEngine().getGeometryById(id), colors[colorNum], 2); + List segmentIds = TrafficEngineApp.engine.getTrafficEngine() + .getStreetSegmentIds(tile.envelope); - } - //else - // tile.renderLineString(TrafficEngineApp.engine.getTrafficEngine().getGeometryById(id), Color.GREEN, 2); + Color[] colors = ColorBrewer.RdYlBu.getColorPalette(11); - } catch (MismatchedDimensionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (TransformException e) { - e.printStackTrace(); - } - } - - try { - return tile.generateImage(); - } catch (IOException | ImageWriteException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } - } + for (Long id : segmentIds) { - public byte[] renderSpeed(){ + try { - Tile tile = new Tile(this); + double averageSpeed = 0.0; - List segmentIds = TrafficEngineApp.engine.getTrafficEngine().getStreetSegmentIds(tile.envelope); + int streetType = TrafficEngineApp.engine.getTrafficEngine() + .getStreetTypeById(id); - Color[] colors = ColorBrewer.RdYlBu.getColorPalette(11); + if (streetType == StreetSegment.TYPE_PRIMARY && z < 11) + continue; + else if (streetType == StreetSegment.TYPE_SECONDARY + && z < 14) + continue; + else if ((streetType == StreetSegment.TYPE_TERTIARY) + && z < 15) + continue; + else if ((streetType == StreetSegment.TYPE_RESIDENTIAL) + && z < 17) + continue; + else if (streetType == StreetSegment.TYPE_OTHER + || streetType == StreetSegment.TYPE_NON_ROADWAY) + continue; - for(Long id : segmentIds) { + int colorNum; - try { + SummaryStatistics baselineStats = TrafficEngineApp.engine + .getTrafficEngine().osmData.statsDataStore + .collectSummaryStatistics(id, normalizeByTime, w1, + hours); - double averageSpeed = 0.0; + if (baselineStats.getMean() > 0) { + averageSpeed = baselineStats.getMean() * MS_TO_KMS; + colorNum = (int) (10 / (50.0 / averageSpeed)); + if (colorNum > 10) + colorNum = 10; - int streetType = TrafficEngineApp.engine.getTrafficEngine().getStreetTypeById(id); + tile.renderLineString(TrafficEngineApp.engine + .getTrafficEngine().getGeometryById(id), + colors[colorNum], 2); + } - if(streetType== StreetSegment.TYPE_PRIMARY && z < 11) - continue; - else if(streetType == StreetSegment.TYPE_SECONDARY && z < 14) - continue; - else if((streetType == StreetSegment.TYPE_TERTIARY) && z < 15) - continue; - else if((streetType == StreetSegment.TYPE_RESIDENTIAL) && z < 17) - continue; - else if(streetType == StreetSegment.TYPE_OTHER || streetType == StreetSegment.TYPE_NON_ROADWAY) - continue; + } catch (MismatchedDimensionException | TransformException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + try { + return tile.generateImage(); + } catch (IOException | ImageWriteException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + } - int colorNum; + public static class DataTile extends TrafficTileRequest { - SummaryStatistics baselineStats = TrafficEngineApp.engine.getTrafficEngine().osmData.statsDataStore.collectSummaryStatistics(id,normalizeByTime, w1, hours); + public DataTile(Integer x, Integer y, Integer z) { + super(x, y, z, "segment"); - if(baselineStats.getMean() > 0) { - averageSpeed = baselineStats.getMean() * MS_TO_KMS; - colorNum = (int) (10 / (50.0 / averageSpeed)); - if(colorNum > 10) - colorNum = 10; + } - tile.renderLineString(TrafficEngineApp.engine.getTrafficEngine().getGeometryById(id), colors[colorNum], 2); - } + @Override + public String getId() { + return super.getId(); + } - } catch (MismatchedDimensionException | TransformException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + @Override + public byte[] render() { + GeometryFactory gf = new GeometryFactory(); + Tile tile = new Tile(this); - try { - return tile.generateImage(); - } catch (IOException | ImageWriteException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } - } - } - - public static class DataTile extends TrafficTileRequest { - - public DataTile(Integer x, Integer y, Integer z) { - super(x, y, z, "segment"); - - } - - public String getId() { - return super.getId(); - } - - public byte[] render(){ - GeometryFactory gf = new GeometryFactory(); - Tile tile = new Tile(this); - - List segments = TrafficEngineApp.engine.getTrafficEngine().getOffMapTraces(tile.envelope); + List segments = TrafficEngineApp.engine + .getTrafficEngine().getOffMapTraces(tile.envelope); - Color pathColor = new Color(94/256.0f,79/256.0f,162/256.0f,0.5f); + Color pathColor = new Color(94 / 256.0f, 79 / 256.0f, 162 / 256.0f, + 0.5f); - try { - HashMap traceCounts = new HashMap<>(); + try { + HashMap traceCounts = new HashMap<>(); - for (SpatialDataItem sdi : segments) { - if(sdi.lats.length < 100) - tile.renderLineString(sdi.getGeometry(), pathColor, 2); - } + for (SpatialDataItem sdi : segments) { + if (sdi.lats.length < 100) + tile.renderLineString(sdi.getGeometry(), pathColor, 2); + } - } catch (Exception e){ - e.printStackTrace(); - } - - try { - return tile.generateImage(); - } catch (IOException | ImageWriteException e ) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } - } + } catch (Exception e) { + e.printStackTrace(); + } + + try { + return tile.generateImage(); + } catch (IOException | ImageWriteException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } } + } }