diff --git a/enabler/src/de/schildbach/pte/CmtaProvider.java b/enabler/src/de/schildbach/pte/CmtaProvider.java
new file mode 100644
index 00000000..26c870c4
--- /dev/null
+++ b/enabler/src/de/schildbach/pte/CmtaProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright the original author or authors.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.schildbach.pte;
+
+import de.schildbach.pte.dto.Product;
+
+import okhttp3.HttpUrl;
+
+/**
+ * @author Colin Murphy
+ */
+public class CmtaProvider extends AbstractHafasMobileProvider {
+ private static final HttpUrl API_BASE = HttpUrl.parse("https://capmetro.hafas.cloud/bin/");
+ // MetroRail: 8, MetroBus: 32, MetroRapid: 4096
+ private static final Product[] PRODUCTS_MAP = { null, null, null, Product.REGIONAL_TRAIN, null, Product.BUS, null,
+ null, null, null, null, null, Product.BUS };
+
+ public CmtaProvider() {
+ super(NetworkId.CMTA, API_BASE, PRODUCTS_MAP);
+ setTimeZone("America/Chicago");
+ setApiVersion("1.13");
+ setApiClient("{\"id\":\"CMTA\"}");
+ }
+}
diff --git a/enabler/src/de/schildbach/pte/NetworkId.java b/enabler/src/de/schildbach/pte/NetworkId.java
index 7849e7d6..f39124b3 100644
--- a/enabler/src/de/schildbach/pte/NetworkId.java
+++ b/enabler/src/de/schildbach/pte/NetworkId.java
@@ -76,7 +76,7 @@ public enum NetworkId {
DUB,
// United States
- RTACHICAGO, OREGON, MASSACHUSETTS,
+ RTACHICAGO, OREGON, MASSACHUSETTS, CMTA,
// Canada
ONTARIO, QUEBEC, BRITISHCOLUMBIA,
diff --git a/enabler/test/de/schildbach/pte/live/CmtaProviderLiveTest.java b/enabler/test/de/schildbach/pte/live/CmtaProviderLiveTest.java
new file mode 100644
index 00000000..96e6a85d
--- /dev/null
+++ b/enabler/test/de/schildbach/pte/live/CmtaProviderLiveTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright the original author or authors.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.schildbach.pte.live;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.Date;
+import java.util.EnumSet;
+
+import org.junit.Test;
+
+import de.schildbach.pte.CmtaProvider;
+import de.schildbach.pte.NetworkProvider;
+import de.schildbach.pte.dto.Location;
+import de.schildbach.pte.dto.LocationType;
+import de.schildbach.pte.dto.NearbyLocationsResult;
+import de.schildbach.pte.dto.Product;
+import de.schildbach.pte.dto.QueryDeparturesResult;
+import de.schildbach.pte.dto.QueryTripsResult;
+import de.schildbach.pte.dto.SuggestLocationsResult;
+
+/**
+ * @author Colin Murphy
+ */
+public class CmtaProviderLiveTest extends AbstractProviderLiveTest {
+ public CmtaProviderLiveTest() {
+ super(new CmtaProvider());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nearbyStations() throws Exception {
+ final NearbyLocationsResult result = queryNearbyStations(new Location(LocationType.STATION, "591"));
+ print(result);
+ }
+
+ @Test
+ public void nearbyStationsByCoordinate() throws Exception {
+ final NearbyLocationsResult result = queryNearbyStations(Location.coord(30275000, -97740000));
+ print(result);
+ assertThat(result.locations, hasItem(new Location(LocationType.STATION, "591")));
+ }
+
+ @Test
+ public void nearbyPOIsByCoordinate() throws Exception {
+ final NearbyLocationsResult result = queryNearbyLocations(EnumSet.of(LocationType.POI),
+ Location.coord(30275000, -97740000));
+ print(result);
+ assertThat(result.locations,
+ hasItem(new Location(LocationType.POI,
+ "A=4@O=Texas State Capitol@X=-97740215@Y=30275103@u=0@U=130@L=9819105@", 30275103, -97740215,
+ null, "Texas State Capitol")));
+ }
+
+ @Test
+ public void queryDepartures() throws Exception {
+ final QueryDeparturesResult result = queryDepartures("591", false);
+ print(result);
+ }
+
+ @Test
+ public void queryDeparturesInvalidStation() throws Exception {
+ final QueryDeparturesResult result = queryDepartures("999999", 0, false);
+ assertEquals(QueryDeparturesResult.Status.INVALID_STATION, result.status);
+ }
+
+ @Test
+ public void suggestLocations() throws Exception {
+ final SuggestLocationsResult result = suggestLocations("Capitol Station");
+ print(result);
+ assertThat(result.getLocations(), hasItem(new Location(LocationType.STATION, "591")));
+ }
+
+ @Test
+ public void shortTrip() throws Exception {
+ final QueryTripsResult result = queryTrips(
+ new Location(LocationType.STATION, "591", null, "Capitol Station (NB)"), null,
+ new Location(LocationType.STATION, "5940", null, "Lavaca/17th (Midblock)"), new Date(), true,
+ Product.ALL, NetworkProvider.WalkSpeed.NORMAL, NetworkProvider.Accessibility.NEUTRAL);
+ assertEquals(QueryTripsResult.Status.OK, result.status);
+ print(result);
+
+ if (!result.context.canQueryLater())
+ return;
+
+ final QueryTripsResult laterResult = queryMoreTrips(result.context, true);
+ print(laterResult);
+ }
+
+ @Test
+ public void addressTrip() throws Exception {
+ final QueryTripsResult result = queryTrips(new Location(LocationType.ADDRESS, null, null, "1501 Colorado St"),
+ null, new Location(LocationType.ADDRESS, null, null, "4299 Duval St"), new Date(), true, Product.ALL,
+ NetworkProvider.WalkSpeed.NORMAL, NetworkProvider.Accessibility.NEUTRAL);
+ assertEquals(QueryTripsResult.Status.OK, result.status);
+ print(result);
+
+ if (!result.context.canQueryLater())
+ return;
+
+ final QueryTripsResult laterResult = queryMoreTrips(result.context, true);
+ print(laterResult);
+ }
+}