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;
+ }
}
+ }
}