Skip to content

Commit

Permalink
Updated IsoChrone API with latest features/options.
Browse files Browse the repository at this point in the history
  • Loading branch information
cafesilencio committed Sep 27, 2024
1 parent b33ae25 commit 93a3561
Show file tree
Hide file tree
Showing 5 changed files with 437 additions and 12 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ Mapbox welcomes participation and contributions from everyone.

### main

### v7.3.0 - September 23, 2024

- Updated IsoChrone API to support new query parameters including contours_meters, road/route exclusions and departure time. [#1596](https://github.com/mapbox/mapbox-java/pull/1596)
- Bumped `okhttp` version to `4.10.0`. [#1595](https://github.com/mapbox/mapbox-java/pull/1595)

### v7.2.0 - August 28, 2024
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public class IsochroneCriteria {
*/
public static final String PROFILE_CYCLING = "cycling";

/**
* For fastest travel by car using current and historic traffic conditions.
* Traffic information is available for the supported geographies listed in our Traffic Data page.
*/
public static final String PROFILE_DRIVING_TRAFFIC = "driving-traffic";

/**
* Queries for a specific geometry type selector.
*
Expand All @@ -53,7 +59,8 @@ public class IsochroneCriteria {
@StringDef( {
PROFILE_WALKING,
PROFILE_DRIVING,
PROFILE_CYCLING
PROFILE_CYCLING,
PROFILE_DRIVING_TRAFFIC
})
public @interface IsochroneProfile {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ public interface IsochroneService {
* optimized generalization to use for the request. Note that the
* generalization of contours can lead to self-intersections, as well
* as intersections of adjacent contours.
* @param contoursMeters A single String which has a comma-separated integers in meters
* to use for each isochrone contour.
* @param exclude Exclude certain road types and custom locations from routing. Default
* is to not exclude anything from the list below. You can specify
* multiple values as a comma-separated list.
* @param depart The departure time from the given coordinates. Formatted in one of
* three ISO 8601 formats.
* See https://docs.mapbox.com/api/navigation/isochrone/
* If not provided then depart_at is considered to be the present time
* in the local timezone of the coordinates. The isochrone contours will
* traffic conditions at the time provided.
* @return a {@link FeatureCollection} in a Call wrapper
* @since 4.7.0
*/
Expand All @@ -64,5 +75,8 @@ Call<FeatureCollection> getCall(
@Query("contours_colors") String contoursColors,
@Query("polygons") Boolean polygons,
@Query("denoise") Float denoise,
@Query("generalize") Float generalize);
@Query("generalize") Float generalize,
@Query("contours_meters") String contoursMeters,
@Query("exclude") String exclude,
@Query("depart_at") String depart);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import com.mapbox.geojson.Point;
import com.mapbox.geojson.gson.GeoJsonAdapterFactory;

import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import retrofit2.Call;

Expand Down Expand Up @@ -50,6 +52,8 @@ protected MapboxIsochrone() {

@Override
protected GsonBuilder getGsonBuilder() {
MapboxIsochrone.Builder b = MapboxIsochrone.builder();

return new GsonBuilder()
.registerTypeAdapterFactory(GeoJsonAdapterFactory.create())
.registerTypeAdapterFactory(GeometryAdapterFactory.create());
Expand All @@ -66,7 +70,10 @@ protected Call<FeatureCollection> initializeCall() {
contoursColors(),
polygons(),
denoise(),
generalize()
generalize(),
contoursMeters(),
exclusions(),
departAt()
);
}

Expand All @@ -80,6 +87,8 @@ protected Call<FeatureCollection> initializeCall() {
public static Builder builder() {
return new AutoValue_MapboxIsochrone.Builder()
.baseUrl(Constants.BASE_API_URL)
.contoursMinutes("")
.contoursMeters("")
.user(IsochroneCriteria.PROFILE_DEFAULT_USER);
}

Expand Down Expand Up @@ -114,6 +123,15 @@ public static Builder builder() {
@Nullable
abstract Float generalize();

@Nullable
abstract String contoursMeters();

@Nullable
abstract String exclusions();

@Nullable
abstract String departAt();

/**
* This builder is used to create a new request to the Mapbox Isochrone API. At a bare minimum,
* your request must include an access token, a directions routing profile (driving, walking,
Expand All @@ -131,9 +149,11 @@ public abstract static class Builder {

private Integer[] contoursMinutes;
private String[] contoursColors;
private Integer[] contoursMeters;
private Set<String> exclusions = new HashSet<>();

/**
* Optionally change the APIs base URL to something other then the default Mapbox one.
* Optionally change the APIs base URL to something other than the default Mapbox one.
*
* @param baseUrl base url used as end point
* @return this builder for chaining options together
Expand Down Expand Up @@ -164,6 +184,8 @@ public abstract static class Builder {
/**
* A Mapbox Directions routing profile ID. Options are
* {@link IsochroneCriteria#PROFILE_DRIVING} for travel times by car,
* {@link IsochroneCriteria#PROFILE_DRIVING_TRAFFIC} for fastest travel by car using
* current and historic traffic,
* {@link IsochroneCriteria#PROFILE_WALKING} for pedestrian and hiking travel times,
* and {@link IsochroneCriteria#PROFILE_CYCLING} for travel times by bicycle.
*
Expand Down Expand Up @@ -217,6 +239,22 @@ public Builder addContoursMinutes(@NonNull @IntRange(from = 0, to = 60)
return this;
}

/**
* An integer list of meter values to use for each isochrone contour.
* The distances, in meters, to use for each isochrone contour. You
* must be in increasing order. The default maximum distance that can be specified
* is 100000 meters (100km), if you need a bigger range contact support.
*
* @param listOfMeterValues an integer list with at least one number
* for the meters which represent each contour
* @return this builder for chaining options together
* @since 7.3.0
*/
public Builder addContoursMeters(Integer... listOfMeterValues) {
this.contoursMeters = listOfMeterValues;
return this;
}

/**
* A single String which is a comma-separated list of time(s) in minutes
* to use for each isochrone contour. You must pass in at least one minute
Expand All @@ -226,12 +264,25 @@ public Builder addContoursMinutes(@NonNull @IntRange(from = 0, to = 60)
*
* @param stringListOfMinuteValues a String of at least one number for the
* minutes which represent each contour
* @return this builder for chaining optio.ns together
* @return this builder for chaining options together
*/
// Required for matching with MapboxIsochrone addContoursMinutes() method.
@SuppressWarnings("WeakerAccess")
abstract Builder contoursMinutes(@NonNull String stringListOfMinuteValues);

/**
* A single String which is a comma-separated list of values(s) in meters
* to use for each isochrone contour. The distances, in meters, to use for each
* isochrone contour. You can specify up to four contours. Distances must be in
* increasing order. The default maximum distance that can be specified
* is 100000 meters (100km), if you need a bigger range contact support.
*
* @param stringListOfMeterValues a String of at least one number for the
* meters which represent each contour
* @return this builder for chaining options together
*/
abstract Builder contoursMeters(@NonNull String stringListOfMeterValues);

/**
* A list of separate String which has a list of comma-separated
* HEX color values to use for each isochrone contour.
Expand Down Expand Up @@ -300,6 +351,107 @@ public Builder addContoursColors(@Nullable String... contoursColors) {
*/
public abstract Builder generalize(@Nullable @FloatRange(from = 0.0) Float generalize);

abstract Builder exclusions(@Nullable String exclusions);

/**
* Exclude highways or motorways. Available in mapbox/driving and
* mapbox/driving-traffic profiles.
* @param exclude indicates whether motorways should be excluded
* @return this builder for chaining options together
*
* @since 7.3.0
*/
public Builder excludeMotorways(Boolean exclude) {
if (exclude != null && exclude) {
exclusions.add("motorway");
} else {
exclusions.remove("motorway");
}
return this;
}

/**
* Exclude tolls. Available in mapbox/driving and
* mapbox/driving-traffic profiles.
* @param exclude indicates whether tolls should be excluded
* @return this builder for chaining options together
*
* @since 7.3.0
*/
public Builder excludeTolls(Boolean exclude) {
if (exclude != null && exclude) {
exclusions.add("toll");
} else {
exclusions.remove("toll");
}
return this;
}

/**
* Exclude ferries. Available in mapbox/driving and
* mapbox/driving-traffic profiles.
* @param exclude indicates whether ferries should be excluded
* @return this builder for chaining options together
*
* @since 7.3.0
*/
public Builder excludeFerries(Boolean exclude) {
if (exclude != null && exclude) {
exclusions.add("ferry");
} else {
exclusions.remove("ferry");
}
return this;
}

/**
* Exclude unpaved roads. Available in mapbox/driving and
* mapbox/driving-traffic profiles.
* @param exclude indicates whether unpaved roads should be excluded
* @return this builder for chaining options together
*
* @since 7.3.0
*/
public Builder excludeUnpavedRoads(Boolean exclude) {
if (exclude != null && exclude) {
exclusions.add("unpaved");
} else {
exclusions.remove("unpaved");
}
return this;
}

/**
* Exclude cash only toll roads. Available in mapbox/driving and
* mapbox/driving-traffic profiles.
* @param exclude indicates whether cash only toll roads should be excluded
* @return this builder for chaining options together
*
* @since 7.3.0
*/
public Builder excludeCashOnlyTollRoads(Boolean exclude) {
if (exclude != null && exclude) {
exclusions.add("cash_only_tolls");
} else {
exclusions.remove("cash_only_tolls");
}
return this;
}

/**
* The departure time from the given coordinates.
* <a href="https://docs.mapbox.com/api/navigation/isochrone/">One of three formats.</a>.
* If not provided then 'depart at' is considered to be the present time in the local
* timezone of the coordinates. The isochrone contours will reflect traffic
* conditions at the time provided.
*
* @param depart the departure date/time
* @return this builder for chaining options together
*
* @since 7.3.0
*/
public abstract Builder departAt(@NonNull String depart);

/**
* @return this builder for chaining options together
* @since 4.6.0
Expand All @@ -314,6 +466,8 @@ public Builder addContoursColors(@Nullable String... contoursColors) {
*/
public MapboxIsochrone build() {

exclusions(TextUtils.join(",", exclusions.toArray()));

if (contoursMinutes != null) {
if (contoursMinutes.length < 1) {
throw new ServicesException("A query with at least one specified "
Expand All @@ -331,6 +485,23 @@ public MapboxIsochrone build() {
contoursMinutes(TextUtils.join(",", contoursMinutes));
}

if (contoursMeters != null) {
if (contoursMeters.length < 1) {
throw new ServicesException("A query with at least one specified "
+ "meter value is required.");
}

if (contoursMeters.length >= 2) {
for (int x = 0; x < contoursMeters.length - 1; x++) {
if (contoursMeters[x] > contoursMeters[x + 1]) {
throw new ServicesException("The meters must be listed"
+ " in order from the lowest number to the highest number.");
}
}
contoursMeters(TextUtils.join(",", contoursMeters));
}
}

if (contoursColors != null) {
contoursColors(TextUtils.join(",", contoursColors));
}
Expand All @@ -342,6 +513,17 @@ public MapboxIsochrone build() {
+ "must match number of minute elements provided.");
}

if (contoursColors != null
&& contoursMeters != null
&& contoursColors.length != contoursMeters.length) {
throw new ServicesException("Number of color elements "
+ "must match number of meter elements provided.");
}

if (contoursMinutes != null && contoursMeters != null) {
throw new ServicesException("Cannot specify both contoursMinutes and contoursMeters.");
}

MapboxIsochrone isochrone = autoBuild();

if (!MapboxUtils.isAccessTokenValid(isochrone.accessToken())) {
Expand All @@ -359,9 +541,10 @@ public MapboxIsochrone build() {
+ " walking, or driving) is required.");
}

if (TextUtils.isEmpty(isochrone.contoursMinutes())) {
if (TextUtils.isEmpty(isochrone.contoursMinutes())
&& TextUtils.isEmpty(isochrone.contoursMeters())) {
throw new ServicesException("A query with at least one specified minute amount"
+ " is required.");
+ " or meter value is required.");
}

if (isochrone.contoursColors() != null) {
Expand Down
Loading

0 comments on commit 93a3561

Please sign in to comment.