Skip to content

Commit

Permalink
Merge pull request #4529 from HSLdevcom/vector-tile-translations
Browse files Browse the repository at this point in the history
Translations for vector tiles sandbox
  • Loading branch information
optionsome committed Oct 31, 2022
2 parents 0d7d232 + e1c1d6b commit 57dba94
Show file tree
Hide file tree
Showing 27 changed files with 607 additions and 246 deletions.
44 changes: 39 additions & 5 deletions docs/sandbox/MapboxVectorTilesApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public transit entities on the map.
The tiles can be fetched from `/otp/routers/{routerId}/vectorTiles/{layers}/{z}/{x}/{y}.pbf`,
where `layers` is a comma separated list of layer names from the configuration.

Translatable fields in the tiles are translated based on the `accept-language` header in requests.
Currently, only the language with the highest priority from the header is used.

### Configuration

To enable this you need to add the feature `SandboxAPIMapboxVectorTilesApi` in `otp-config.json`.
Expand All @@ -40,38 +43,64 @@ The feature must be configured in `router-config.json` as follows
"minZoom": 12,
"cacheMaxSeconds": 600
},
// all rental places: stations and free-floating vehicles
{
"name": "citybikes",
"type": "VehicleRental", // all rental places: stations and free-floating vehicles
"type": "VehicleRental",
"mapper": "Digitransit",
"maxZoom": 20,
"minZoom": 14,
"cacheMaxSeconds": 60,
"expansionFactor": 0.25
},
// just free-floating vehicles
{
"name": "rentalVehicles",
"type": "VehicleRentalVehicle", // just free-floating vehicles
"mapper": "Digitransit",
"type": "VehicleRentalVehicle",
"mapper": "DigitransitRealtime",
"maxZoom": 20,
"minZoom": 14,
"cacheMaxSeconds": 60
},
// just rental stations
{
"name": "rentalStations",
"type": "VehicleRentalStation", // just rental stations
"type": "VehicleRentalStation",
"mapper": "Digitransit",
"maxZoom": 20,
"minZoom": 14,
"cacheMaxSeconds": 600
},
// Contains just stations and realtime information for them
{
"name": "realtimeRentalStations",
"type": "VehicleRentalStation",
"mapper": "DigitransitRealtime",
"maxZoom": 20,
"minZoom": 14,
"cacheMaxSeconds": 60
},
// This exists for backwards compatibility. At some point, we might want
// to add a new realtime parking mapper with better translation support
// and less unnecessary fields.
{
"name": "stadtnaviVehicleParking",
"type": "VehicleParking",
"mapper": "Stadtnavi",
"maxZoom": 20,
"minZoom": 14,
"cacheMaxSeconds": 60,
"expansionFactor": 0.25
},
// no realtime, translatable fields are translated based on accept-language header
// and contains less fields than the Stadtnavi mapper
{
"name": "vehicleParking",
"type": "VehicleParking",
"mapper": "Digitransit",
"maxZoom": 20,
"minZoom": 14,
"cacheMaxSeconds": 60,
"cacheMaxSeconds": 600,
"expansionFactor": 0.25
},
{
Expand Down Expand Up @@ -148,3 +177,8 @@ key, and a function to create the mapper, with a `Graph` object as a parameter,
- 2022-08-23: Remove patterns and add route gtfsTypes to stop layer [#4404](https://github.com/opentripplanner/OpenTripPlanner/pull/4404)
- 2022-10-11: Added layer for VehicleParkingGroups [#4510](https://github.com/opentripplanner/OpenTripPlanner/pull/4510)
- 2022-10-14: Add separate layers for vehicle rental place types [#4516](https://github.com/opentripplanner/OpenTripPlanner/pull/4516)
- 2022-10-19 [#4529](https://github.com/opentripplanner/OpenTripPlanner/pull/4529):
* Translatable fields are now translated based on accept-language header
* Added DigitransitRealtime for vehicle rental stations
* Changed old vehicle parking mapper to be Stadtnavi
* Added a new Digitransit vehicle parking mapper with no realtime information and less fields

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package org.opentripplanner.ext.vectortiles.layers.stops;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opentripplanner.transit.model.basic.TranslatedString;
import org.opentripplanner.transit.model.framework.Deduplicator;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.site.RegularStop;
import org.opentripplanner.transit.service.DefaultTransitService;
import org.opentripplanner.transit.service.StopModel;
import org.opentripplanner.transit.service.TransitModel;

public class StopsLayerTest {

private RegularStop stop;

@BeforeEach
public void setUp() {
var nameTranslations = TranslatedString.getI18NString(
new HashMap<>() {
{
put(null, "name");
put("de", "nameDE");
}
},
false,
false
);
var descTranslations = TranslatedString.getI18NString(
new HashMap<>() {
{
put(null, "desc");
put("de", "descDE");
}
},
false,
false
);
stop =
RegularStop
.of(new FeedScopedId("F", "name"))
.withName(nameTranslations)
.withDescription(descTranslations)
.withCoordinate(50, 10)
.build();
}

@Test
public void digitransitStopPropertyMapperTest() {
var deduplicator = new Deduplicator();
var transitModel = new TransitModel(new StopModel(), deduplicator);
transitModel.index();
var transitService = new DefaultTransitService(transitModel);

DigitransitStopPropertyMapper mapper = DigitransitStopPropertyMapper.create(
transitService,
new Locale("en-US")
);

Map<String, Object> map = new HashMap<>();
mapper.map(stop).forEach(o -> map.put(o.first, o.second));

assertEquals("F:name", map.get("gtfsId"));
assertEquals("name", map.get("name"));
assertEquals("desc", map.get("desc"));
}

@Test
public void digitransitStopPropertyMapperTranslationTest() {
var deduplicator = new Deduplicator();
var transitModel = new TransitModel(new StopModel(), deduplicator);
transitModel.index();
var transitService = new DefaultTransitService(transitModel);

DigitransitStopPropertyMapper mapper = DigitransitStopPropertyMapper.create(
transitService,
new Locale("de")
);

Map<String, Object> map = new HashMap<>();
mapper.map(stop).forEach(o -> map.put(o.first, o.second));

assertEquals("nameDE", map.get("name"));
assertEquals("descDE", map.get("desc"));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.opentripplanner.ext.vectortiles;
package org.opentripplanner.ext.vectortiles.layers.vehicleparkings;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
Expand All @@ -8,16 +8,15 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.opentripplanner.common.model.T2;
import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.DigitransitVehicleParkingGroupPropertyMapper;
import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingAndGroup;
import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingGroupsLayerBuilder;
import org.opentripplanner.ext.vectortiles.VectorTilesResource;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.vehicle_parking.VehicleParking;
import org.opentripplanner.routing.vehicle_parking.VehicleParkingGroup;
Expand Down Expand Up @@ -123,7 +122,8 @@ public void vehicleParkingGroupGeometryTest() {
assertEquals(1, tiles.layers().size());
VehicleParkingGroupsLayerBuilderWithPublicGeometry builder = new VehicleParkingGroupsLayerBuilderWithPublicGeometry(
graph,
tiles.layers().get(0)
tiles.layers().get(0),
Locale.US
);

List<Geometry> geometries = builder.getGeometries(new Envelope(0.99, 1.01, 1.99, 2.01));
Expand All @@ -140,7 +140,9 @@ public void vehicleParkingGroupGeometryTest() {

@Test
public void digitransitVehicleParkingGroupPropertyMapperTest() {
VehicleParkingGroupPropertyMapperWithPublicMap mapper = new VehicleParkingGroupPropertyMapperWithPublicMap();
VehicleParkingGroupPropertyMapperWithPublicMap mapper = new VehicleParkingGroupPropertyMapperWithPublicMap(
Locale.US
);
Map<String, Object> map = new HashMap<>();
mapper
.map(new VehicleParkingAndGroup(vehicleParkingGroup, Set.of(vehicleParking)))
Expand All @@ -155,14 +157,33 @@ public void digitransitVehicleParkingGroupPropertyMapperTest() {
);
}

@Test
public void digitransitVehicleParkingGroupPropertyMapperTranslationTest() {
VehicleParkingGroupPropertyMapperWithPublicMap mapper = new VehicleParkingGroupPropertyMapperWithPublicMap(
new Locale("de")
);
Map<String, Object> map = new HashMap<>();
mapper
.map(new VehicleParkingAndGroup(vehicleParkingGroup, Set.of(vehicleParking)))
.forEach(o -> map.put(o.first, o.second));

assertEquals("groupDE", map.get("name").toString());

assertEquals(
"[{\"bicyclePlaces\":false,\"carPlaces\":true,\"name\":\"DE\",\"id\":\"F:id\"}]",
map.get("vehicleParking")
);
}

private static class VehicleParkingGroupsLayerBuilderWithPublicGeometry
extends VehicleParkingGroupsLayerBuilder {

public VehicleParkingGroupsLayerBuilderWithPublicGeometry(
Graph graph,
VectorTilesResource.LayerParameters layerParameters
VectorTilesResource.LayerParameters layerParameters,
Locale locale
) {
super(graph, null, layerParameters);
super(graph, layerParameters, locale);
}

@Override
Expand All @@ -174,8 +195,8 @@ public List<Geometry> getGeometries(Envelope query) {
private static class VehicleParkingGroupPropertyMapperWithPublicMap
extends DigitransitVehicleParkingGroupPropertyMapper {

public VehicleParkingGroupPropertyMapperWithPublicMap() {
super();
public VehicleParkingGroupPropertyMapperWithPublicMap(Locale locale) {
super(locale);
}

@Override
Expand Down

0 comments on commit 57dba94

Please sign in to comment.