mirror of
https://github.com/Pygmalion69/OpenTopoMapViewer.git
synced 2025-10-06 00:02:42 +02:00
docs: improve ORS client documentation (#37)
This commit is contained in:
@@ -25,9 +25,14 @@ import org.nitri.ors.domain.snap.SnapRequest
|
||||
import org.nitri.ors.domain.snap.SnapResponse
|
||||
import org.nitri.ors.restclient.OpenRouteServiceRestClient
|
||||
|
||||
/**
|
||||
* Default implementation of [OrsClient] using the Retrofit based
|
||||
* [OpenRouteServiceRestClient].
|
||||
*/
|
||||
class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
private val api = OpenRouteServiceRestClient.create(apiKey, context)
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getRoute(
|
||||
profile: Profile,
|
||||
routeRequest: RouteRequest
|
||||
@@ -35,6 +40,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getRoute(profile.key, routeRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getRouteGpx(
|
||||
profile: Profile,
|
||||
routeRequest: RouteRequest
|
||||
@@ -42,6 +48,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getRouteGpx(profile.key, routeRequest).body()?.string() ?: ""
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getRouteGeoJson(
|
||||
profile: Profile,
|
||||
routeRequest: RouteRequest
|
||||
@@ -49,6 +56,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getRouteGeoJson(profile.key, routeRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun export(
|
||||
profile: Profile,
|
||||
exportRequest: ExportRequest
|
||||
@@ -56,6 +64,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.export(profile.key, exportRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun exportJson(
|
||||
profile: Profile,
|
||||
exportRequest: ExportRequest
|
||||
@@ -63,6 +72,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.exportJson(profile.key, exportRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun exportTopoJson(
|
||||
profile: Profile,
|
||||
exportRequest: ExportRequest
|
||||
@@ -70,6 +80,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.exportTopoJson(profile.key, exportRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getIsochrones(
|
||||
profile: Profile,
|
||||
isochronesRequest: IsochronesRequest
|
||||
@@ -77,6 +88,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getIsochrones(profile.key, isochronesRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getMatrix(
|
||||
profile: Profile,
|
||||
matrixRequest: MatrixRequest
|
||||
@@ -84,6 +96,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getMatrix(profile.key, matrixRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getSnap(
|
||||
profile: Profile,
|
||||
snapRequest: SnapRequest
|
||||
@@ -91,6 +104,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getSnap(profile.key, snapRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getSnapJson(
|
||||
profile: Profile,
|
||||
snapRequest: SnapRequest
|
||||
@@ -98,6 +112,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getSnapJson(profile.key, snapRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getSnapGeoJson(
|
||||
profile: Profile,
|
||||
snapRequest: SnapRequest
|
||||
@@ -105,6 +120,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return api.getSnapGeoJson(profile.key, snapRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getPois(poisRequest: PoisRequest): PoisGeoJsonResponse {
|
||||
val raw = api.getPois(poisRequest)
|
||||
fun PoisGeoJsonResponse.sanitized(): PoisGeoJsonResponse =
|
||||
@@ -112,22 +128,26 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
return raw.sanitized()
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getOptimization(optimizationRequest: OptimizationRequest): OptimizationResponse {
|
||||
return api.getOptimization(optimizationRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getElevationLine(
|
||||
elevationLineRequest: ElevationLineRequest
|
||||
): ElevationLineResponse {
|
||||
return api.getElevationLine(elevationLineRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun getElevationPoint(
|
||||
elevationPointRequest: ElevationPointRequest
|
||||
): ElevationPointResponse {
|
||||
return api.getElevationPoint(elevationPointRequest)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun geocodeSearch(
|
||||
text: String,
|
||||
apiKey: String,
|
||||
@@ -166,6 +186,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun geocodeAutocomplete(
|
||||
apiKey: String,
|
||||
text: String,
|
||||
@@ -202,6 +223,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun geocodeStructured(
|
||||
apiKey: String,
|
||||
address: String?,
|
||||
@@ -252,6 +274,7 @@ class DefaultOrsClient(apiKey: String, context: Context) : OrsClient {
|
||||
)
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
override suspend fun geocodeReverse(
|
||||
apiKey: String,
|
||||
lon: Double,
|
||||
|
@@ -2,8 +2,16 @@ package org.nitri.ors
|
||||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* Factory for obtaining [OrsClient] instances.
|
||||
*/
|
||||
object Ors {
|
||||
/** If you already construct the Retrofit API elsewhere, inject it here. */
|
||||
/**
|
||||
* Creates a default [OrsClient] backed by Retrofit.
|
||||
*
|
||||
* @param apiKey API key obtained from openrouteservice.org
|
||||
* @param context Android context used for HTTP client construction
|
||||
*/
|
||||
@JvmStatic
|
||||
fun create(apiKey: String, context: Context): OrsClient = DefaultOrsClient(apiKey, context)
|
||||
}
|
@@ -23,6 +23,11 @@ import org.nitri.ors.domain.snap.SnapGeoJsonResponse
|
||||
import org.nitri.ors.domain.snap.SnapRequest
|
||||
import org.nitri.ors.domain.snap.SnapResponse
|
||||
|
||||
/**
|
||||
* Supported routing profiles used across the OpenRouteService endpoints.
|
||||
*
|
||||
* The [key] corresponds to the profile identifier expected by the HTTP API.
|
||||
*/
|
||||
enum class Profile(val key: String) {
|
||||
DRIVING_CAR("driving-car"),
|
||||
DRIVING_HGV("driving-hgv"),
|
||||
@@ -35,44 +40,84 @@ enum class Profile(val key: String) {
|
||||
WHEELCHAIR("wheelchair")
|
||||
}
|
||||
|
||||
@JvmInline value class Lon(val v: Double)
|
||||
@JvmInline value class Lat(val v: Double)
|
||||
/** Longitude value wrapper used by the DSL builders. */
|
||||
@JvmInline
|
||||
value class Lon(val v: Double)
|
||||
|
||||
/** Latitude value wrapper used by the DSL builders. */
|
||||
@JvmInline
|
||||
value class Lat(val v: Double)
|
||||
|
||||
/** Convenience pair for longitude/latitude coordinates. */
|
||||
data class LonLat(val lon: Double, val lat: Double)
|
||||
|
||||
/**
|
||||
* Abstraction over the OpenRouteService HTTP API.
|
||||
*
|
||||
* Implementations map these suspending functions to the respective REST
|
||||
* endpoints as documented in the
|
||||
* [OpenRouteService API reference](https://openrouteservice.org/dev/#/api-docs).
|
||||
*/
|
||||
interface OrsClient {
|
||||
|
||||
// Directions
|
||||
/**
|
||||
* Requests a route using the Directions endpoint.
|
||||
* `GET /v2/directions/{profile}`
|
||||
*/
|
||||
suspend fun getRoute(profile: Profile, routeRequest: RouteRequest): RouteResponse
|
||||
|
||||
/** Retrieves the route as GPX. */
|
||||
suspend fun getRouteGpx(profile: Profile, routeRequest: RouteRequest): String
|
||||
|
||||
/** Retrieves the route as GeoJSON feature collection. */
|
||||
suspend fun getRouteGeoJson(profile: Profile, routeRequest: RouteRequest): GeoJsonRouteResponse
|
||||
|
||||
// Export
|
||||
/** Calls the export endpoint returning plain JSON. */
|
||||
suspend fun export(profile: Profile, exportRequest: ExportRequest): ExportResponse
|
||||
|
||||
/** Same as [export] but explicitly requesting JSON output. */
|
||||
suspend fun exportJson(profile: Profile, exportRequest: ExportRequest): ExportResponse
|
||||
|
||||
/** Requests TopoJSON output from the export endpoint. */
|
||||
suspend fun exportTopoJson(profile: Profile, exportRequest: ExportRequest): TopoJsonExportResponse
|
||||
|
||||
// Isochrones
|
||||
/** Accesses the isochrones endpoint. */
|
||||
suspend fun getIsochrones(profile: Profile, isochronesRequest: IsochronesRequest): IsochronesResponse
|
||||
|
||||
// Matrix
|
||||
/** Calls the matrix endpoint and returns distance/duration matrices. */
|
||||
suspend fun getMatrix(profile: Profile, matrixRequest: MatrixRequest): MatrixResponse
|
||||
|
||||
// Snapping
|
||||
/** Snaps coordinates to the road network. */
|
||||
suspend fun getSnap(profile: Profile, snapRequest: SnapRequest): SnapResponse
|
||||
|
||||
/** Snaps coordinates and returns the JSON variant of the response. */
|
||||
suspend fun getSnapJson(profile: Profile, snapRequest: SnapRequest): SnapResponse
|
||||
|
||||
/** Snaps coordinates and returns a GeoJSON response. */
|
||||
suspend fun getSnapGeoJson(profile: Profile, snapRequest: SnapRequest): SnapGeoJsonResponse
|
||||
|
||||
// POIs
|
||||
/** Queries points of interest and returns a GeoJSON feature collection. */
|
||||
suspend fun getPois(poisRequest: PoisRequest): PoisGeoJsonResponse
|
||||
|
||||
// Optimization
|
||||
/** Delegates to the VROOM based optimization service. */
|
||||
suspend fun getOptimization(optimizationRequest: OptimizationRequest): OptimizationResponse
|
||||
|
||||
// Elevation
|
||||
/** Calls the elevation/line endpoint. */
|
||||
suspend fun getElevationLine(elevationLineRequest: ElevationLineRequest): ElevationLineResponse
|
||||
|
||||
/** Calls the elevation/point endpoint. */
|
||||
suspend fun getElevationPoint(elevationPointRequest: ElevationPointRequest): ElevationPointResponse
|
||||
|
||||
// Geocode
|
||||
/** Forward geocoding search endpoint. */
|
||||
suspend fun geocodeSearch(
|
||||
text: String,
|
||||
apiKey: String,
|
||||
@@ -92,6 +137,7 @@ interface OrsClient {
|
||||
size: Int? = 10,
|
||||
): GeocodeSearchResponse
|
||||
|
||||
/** Autocomplete endpoint returning suggestions for a partial query. */
|
||||
suspend fun geocodeAutocomplete(
|
||||
apiKey: String,
|
||||
text: String,
|
||||
@@ -110,6 +156,7 @@ interface OrsClient {
|
||||
size: Int? = null,
|
||||
): GeocodeSearchResponse
|
||||
|
||||
/** Structured forward geocoding using discrete address fields. */
|
||||
suspend fun geocodeStructured(
|
||||
apiKey: String,
|
||||
address: String? = null,
|
||||
@@ -135,6 +182,7 @@ interface OrsClient {
|
||||
size: Int? = null,
|
||||
): GeocodeSearchResponse
|
||||
|
||||
/** Reverse geocoding for a single coordinate. */
|
||||
suspend fun geocodeReverse(
|
||||
apiKey: String,
|
||||
lon: Double,
|
||||
|
@@ -5,10 +5,11 @@ import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.buildJsonArray
|
||||
|
||||
// Kotlin DSL for ElevationLineRequest
|
||||
/** DSL for building [ElevationLineRequest] instances. */
|
||||
inline fun elevationLineRequest(build: ElevationLineRequestBuilder.() -> Unit): ElevationLineRequest =
|
||||
ElevationLineRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [elevationLineRequest]. */
|
||||
class ElevationLineRequestBuilder {
|
||||
var formatIn: String = ElevationFormats.POLYLINE
|
||||
var formatOut: String = ElevationFormats.GEOJSON
|
||||
@@ -40,10 +41,11 @@ class ElevationLineRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Kotlin DSL for ElevationPointRequest
|
||||
/** DSL for constructing [ElevationPointRequest] objects. */
|
||||
inline fun elevationPointRequest(build: ElevationPointRequestBuilder.() -> Unit): ElevationPointRequest =
|
||||
ElevationPointRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [elevationPointRequest]. */
|
||||
class ElevationPointRequestBuilder {
|
||||
var formatIn: String = "point"
|
||||
var formatOut: String = "geojson"
|
||||
@@ -92,4 +94,4 @@ class ElevationPointRequestBuilderJ {
|
||||
fun dataset(v: String?) = apply { dsl.dataset = v }
|
||||
fun point(lon: Double, lat: Double) = apply { dsl.point(lon, lat) }
|
||||
fun build(): ElevationPointRequest = dsl.build()
|
||||
}
|
||||
}
|
||||
|
@@ -3,15 +3,20 @@ package org.nitri.ors.domain.elevation
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** Request for the `elevation/point` endpoint. */
|
||||
@Serializable
|
||||
data class ElevationPointRequest(
|
||||
@SerialName("format_in")
|
||||
val formatIn: String, // Input format, must be provided (e.g., "point")
|
||||
/** Input format, e.g. `point`. */
|
||||
val formatIn: String,
|
||||
|
||||
@SerialName("format_out")
|
||||
val formatOut: String = "geojson", // "geojson" or "point"
|
||||
/** Output format: `geojson` or `point`. */
|
||||
val formatOut: String = "geojson",
|
||||
|
||||
val dataset: String? = null, // Optional dataset, e.g. "srtm"
|
||||
/** Optional elevation dataset name, e.g. `srtm`. */
|
||||
val dataset: String? = null,
|
||||
|
||||
val geometry: List<Double> // [lon, lat]
|
||||
/** Coordinate as `[lon, lat]`. */
|
||||
val geometry: List<Double>
|
||||
)
|
||||
|
@@ -1,9 +1,10 @@
|
||||
package org.nitri.ors.domain.export
|
||||
|
||||
// Kotlin DSL for ExportRequest
|
||||
/** DSL for creating [ExportRequest] objects. */
|
||||
inline fun exportRequest(build: ExportRequestBuilder.() -> Unit): ExportRequest =
|
||||
ExportRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [exportRequest]. */
|
||||
class ExportRequestBuilder {
|
||||
private var bbox: List<List<Double>>? = null
|
||||
private var id: String? = null
|
||||
@@ -23,7 +24,7 @@ class ExportRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Java-friendly builder
|
||||
/** Java-friendly builder counterpart. */
|
||||
class ExportRequestBuilderJ {
|
||||
private var bbox: List<List<Double>>? = null
|
||||
private var id: String? = null
|
||||
@@ -41,4 +42,4 @@ class ExportRequestBuilderJ {
|
||||
val i = id ?: "export_request"
|
||||
return ExportRequest(bbox = b, id = i, geometry = geometry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,9 +2,13 @@ package org.nitri.ors.domain.export
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** Request payload for the export endpoint. */
|
||||
@Serializable
|
||||
data class ExportRequest(
|
||||
val bbox: List<List<Double>>, // [minLon, minLat, maxLon, maxLat]
|
||||
/** Bounding box specified as `[[minLon,minLat],[maxLon,maxLat]]`. */
|
||||
val bbox: List<List<Double>>,
|
||||
/** Client-specified identifier. */
|
||||
val id: String,
|
||||
/** Whether to include full geometry in the response. */
|
||||
val geometry: Boolean? = null
|
||||
)
|
||||
|
@@ -12,23 +12,26 @@ import kotlinx.serialization.json.JsonDecoder
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.doubleOrNull
|
||||
|
||||
/** Graph export response containing nodes and edges. */
|
||||
@Serializable
|
||||
data class ExportResponse(
|
||||
val nodes: List<Node> = emptyList(),
|
||||
val edges: List<GraphEdge> = emptyList()
|
||||
)
|
||||
|
||||
/** Node entry in an [ExportResponse]. */
|
||||
@Serializable
|
||||
data class Node(
|
||||
@SerialName("nodeId") val nodeId: Long,
|
||||
/** [lon, lat] */
|
||||
/** `[lon, lat]` coordinate. */
|
||||
val location: List<Double>
|
||||
)
|
||||
|
||||
/** Graph edge entry in an [ExportResponse]. */
|
||||
@Serializable
|
||||
data class GraphEdge(
|
||||
@SerialName("fromId") val fromId: Long,
|
||||
@SerialName("toId") val toId: Long,
|
||||
@SerialName("toId") val toId: Long,
|
||||
@Serializable(with = StringAsDoubleSerializer::class)
|
||||
val weight: Double
|
||||
)
|
||||
|
@@ -3,13 +3,14 @@ package org.nitri.ors.domain.export
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** TopoJSON variant of the export response. */
|
||||
@Serializable
|
||||
data class TopoJsonExportResponse(
|
||||
val type: String, // "Topology"
|
||||
val type: String,
|
||||
val objects: TopoObjects,
|
||||
/** Top-level arcs are arrays of [lon, lat] Double coordinates */
|
||||
/** Top-level arcs represented as `[lon, lat]` coordinate pairs. */
|
||||
val arcs: List<List<List<Double>>>,
|
||||
val bbox: List<Double> // [minLon, minLat, maxLon, maxLat]
|
||||
val bbox: List<Double>
|
||||
)
|
||||
|
||||
@Serializable
|
||||
@@ -19,23 +20,23 @@ data class TopoObjects(
|
||||
|
||||
@Serializable
|
||||
data class GeometryCollection(
|
||||
val type: String, // "GeometryCollection"
|
||||
val type: String,
|
||||
val geometries: List<TopoGeometry>
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class TopoGeometry(
|
||||
val type: String, // "LineString" (currently)
|
||||
/** These are indices into the top-level arcs array (can be negative to indicate reversal) */
|
||||
val type: String,
|
||||
/** Indices into the top-level [TopoJsonExportResponse.arcs] array. */
|
||||
val arcs: List<Int>,
|
||||
val properties: GeometryProps? = null // be lenient; fields can vary
|
||||
val properties: GeometryProps? = null
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GeometryProps(
|
||||
// weight often arrives as a string in this endpoint
|
||||
/** Edge weight often supplied as a string. */
|
||||
val weight: String? = null,
|
||||
@SerialName("node_from") val nodeFrom: Long? = null,
|
||||
@SerialName("node_to") val nodeTo: Long? = null
|
||||
@SerialName("node_to") val nodeTo: Long? = null
|
||||
)
|
||||
|
||||
|
@@ -1,9 +1,10 @@
|
||||
package org.nitri.ors.domain.isochrones
|
||||
|
||||
// Kotlin DSL for IsochronesRequest
|
||||
/** DSL for constructing [IsochronesRequest] objects. */
|
||||
inline fun isochronesRequest(build: IsochronesRequestBuilder.() -> Unit): IsochronesRequest =
|
||||
IsochronesRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [isochronesRequest]. */
|
||||
class IsochronesRequestBuilder {
|
||||
private val locations = mutableListOf<List<Double>>()
|
||||
private var range: MutableList<Int> = mutableListOf()
|
||||
@@ -38,7 +39,7 @@ class IsochronesRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Java-friendly builder
|
||||
/** Java-friendly builder counterpart. */
|
||||
class IsochronesRequestBuilderJ {
|
||||
private val locations = mutableListOf<List<Double>>()
|
||||
private val range: MutableList<Int> = mutableListOf()
|
||||
@@ -80,4 +81,4 @@ class IsochronesRequestBuilderJ {
|
||||
options = options
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package org.nitri.ors.domain.isochrones
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** GeoJSON response returned by the isochrones endpoint. */
|
||||
@Serializable
|
||||
data class IsochronesResponse(
|
||||
val type: String,
|
||||
@@ -11,6 +12,7 @@ data class IsochronesResponse(
|
||||
val metadata: IsochronesMetadata
|
||||
)
|
||||
|
||||
/** Individual isochrone feature. */
|
||||
@Serializable
|
||||
data class IsochroneFeature(
|
||||
val type: String,
|
||||
@@ -25,12 +27,11 @@ data class IsochroneProperties(
|
||||
val center: List<Double>
|
||||
)
|
||||
|
||||
/** Geometry of an isochrone feature. */
|
||||
@Serializable
|
||||
data class IsochroneGeometry(
|
||||
val type: String, // "Polygon" (sometimes "MultiPolygon")
|
||||
// ORS is returning Polygon for your case:
|
||||
val type: String,
|
||||
val coordinates: List<List<List<Double>>>
|
||||
// If you later see MultiPolygon, change to List<List<List<List<Double>>>> or make it polymorphic.
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
@@ -1,9 +1,10 @@
|
||||
package org.nitri.ors.domain.matrix
|
||||
|
||||
// Kotlin DSL for MatrixRequest
|
||||
/** DSL for building [MatrixRequest] instances. */
|
||||
inline fun matrixRequest(build: MatrixRequestBuilder.() -> Unit): MatrixRequest =
|
||||
MatrixRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [matrixRequest]. */
|
||||
class MatrixRequestBuilder {
|
||||
private val locations = mutableListOf<List<Double>>()
|
||||
var destinations: List<Int>? = null
|
||||
@@ -27,7 +28,7 @@ class MatrixRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Java-friendly builder
|
||||
/** Java-friendly builder counterpart. */
|
||||
class MatrixRequestBuilderJ {
|
||||
private val locations = mutableListOf<List<Double>>()
|
||||
private var destinations: List<Int>? = null
|
||||
@@ -54,4 +55,4 @@ class MatrixRequestBuilderJ {
|
||||
sources = sources
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
package org.nitri.ors.domain.optimization
|
||||
|
||||
// Kotlin DSL for OptimizationRequest (minimal and pragmatic)
|
||||
/** DSL for building [OptimizationRequest] payloads. */
|
||||
inline fun optimizationRequest(build: OptimizationRequestBuilder.() -> Unit): OptimizationRequest =
|
||||
OptimizationRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [optimizationRequest]. */
|
||||
class OptimizationRequestBuilder {
|
||||
private val jobs = mutableListOf<Job>()
|
||||
private val shipments = mutableListOf<Shipment>()
|
||||
@@ -62,7 +63,7 @@ class OptimizationRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Java-friendly builder
|
||||
/** Java-friendly builder counterpart. */
|
||||
class OptimizationRequestBuilderJ {
|
||||
private val dsl = OptimizationRequestBuilder()
|
||||
|
||||
@@ -82,4 +83,4 @@ class OptimizationRequestBuilderJ {
|
||||
fun options(o: Map<String, kotlinx.serialization.json.JsonElement>?) = apply { dsl.options(o) }
|
||||
|
||||
fun build(): OptimizationRequest = dsl.build()
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
package org.nitri.ors.domain.pois
|
||||
|
||||
// Kotlin DSL for PoisRequest
|
||||
/** DSL for constructing [PoisRequest] objects. */
|
||||
inline fun poisRequest(build: PoisRequestBuilder.() -> Unit): PoisRequest =
|
||||
PoisRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [poisRequest]. */
|
||||
class PoisRequestBuilder {
|
||||
private var bbox: List<List<Double>>? = null
|
||||
private var geojson: GeoJsonGeometry? = null
|
||||
@@ -38,7 +39,7 @@ class PoisRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Java-friendly builder
|
||||
/** Java-friendly builder counterpart. */
|
||||
class PoisRequestBuilderJ {
|
||||
private var bbox: List<List<Double>>? = null
|
||||
private var geojson: GeoJsonGeometry? = null
|
||||
@@ -75,4 +76,4 @@ class PoisRequestBuilderJ {
|
||||
sortby = sortby
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package org.nitri.ors.domain.pois
|
||||
import kotlinx.serialization.Required
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/** Request for the POIs endpoint. */
|
||||
@Serializable
|
||||
data class PoisRequest(
|
||||
@Required val request: String = "pois",
|
||||
@@ -14,13 +15,17 @@ data class PoisRequest(
|
||||
|
||||
@Serializable
|
||||
data class Geometry(
|
||||
val bbox: List<List<Double>>? = null, // [[minLon,minLat],[maxLon,maxLat]]
|
||||
val geojson: GeoJsonGeometry? = null, // optional: GeoJSON geometry
|
||||
val buffer: Int? = null // optional: buffer in meters
|
||||
/** Bounding box `[[minLon,minLat],[maxLon,maxLat]]` if set. */
|
||||
val bbox: List<List<Double>>? = null,
|
||||
/** Optional GeoJSON geometry. */
|
||||
val geojson: GeoJsonGeometry? = null,
|
||||
/** Optional buffer in meters applied to the geometry. */
|
||||
val buffer: Int? = null
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class GeoJsonGeometry(
|
||||
val type: String, // e.g., "Point"
|
||||
val coordinates: List<Double> // [lon, lat]
|
||||
val type: String,
|
||||
/** `[lon, lat]` pair defining the point location. */
|
||||
val coordinates: List<Double>
|
||||
)
|
||||
|
@@ -2,21 +2,22 @@ package org.nitri.ors.domain.route
|
||||
|
||||
import org.nitri.ors.LonLat
|
||||
|
||||
// Kotlin DSL
|
||||
/** DSL for constructing [RouteRequest] instances. */
|
||||
inline fun routeRequest(build: RouteRequestBuilder.() -> Unit): RouteRequest =
|
||||
RouteRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [routeRequest]. */
|
||||
class RouteRequestBuilder {
|
||||
private val coords = mutableListOf<LonLat>()
|
||||
var language: String? = null
|
||||
|
||||
fun start(lon: Double, lat: Double) = apply { coords.add(LonLat(lon, lat)) }
|
||||
fun end(lon: Double, lat: Double) = apply { coords.add(LonLat(lon, lat)) }
|
||||
fun end(lon: Double, lat: Double) = apply { coords.add(LonLat(lon, lat)) }
|
||||
fun coordinate(lon: Double, lat: Double) = apply { coords.add(LonLat(lon, lat)) }
|
||||
|
||||
fun build(): RouteRequest {
|
||||
require(coords.size >= 2) { "At least start and end coordinates required" }
|
||||
val coordinates = coords.map { listOf(it.lon, it.lat) }
|
||||
return RouteRequest(coordinates, language = language)
|
||||
return RouteRequest(coordinates, language = language)
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package org.nitri.ors.domain.route
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.nitri.ors.domain.meta.Metadata
|
||||
|
||||
/** GeoJSON response for the directions endpoint. */
|
||||
@Serializable
|
||||
data class GeoJsonRouteResponse(
|
||||
val type: String,
|
||||
@@ -11,6 +12,7 @@ data class GeoJsonRouteResponse(
|
||||
val metadata: Metadata
|
||||
)
|
||||
|
||||
/** A single GeoJSON feature within the route response. */
|
||||
@Serializable
|
||||
data class Feature(
|
||||
val type: String,
|
||||
@@ -18,6 +20,7 @@ data class Feature(
|
||||
val properties: Map<String, kotlinx.serialization.json.JsonElement> = emptyMap()
|
||||
)
|
||||
|
||||
/** Geometry of a route feature. */
|
||||
@Serializable
|
||||
data class Geometry(
|
||||
val type: String,
|
||||
|
@@ -3,6 +3,7 @@ package org.nitri.ors.domain.route
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
|
||||
/** GPX response returned by the directions endpoint when requesting GPX. */
|
||||
@Serializable
|
||||
data class GpxResponse(
|
||||
val metadata: GpxMetadata,
|
||||
|
@@ -3,39 +3,65 @@ package org.nitri.ors.domain.route
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Payload for the directions `v2/directions/{profile}` endpoint.
|
||||
*
|
||||
* All parameters map to the official ORS API; nullable properties are omitted
|
||||
* from the serialized JSON when not provided.
|
||||
*/
|
||||
@Serializable
|
||||
data class RouteRequest(
|
||||
/** List of `[lon, lat]` coordinate pairs in order of travel. */
|
||||
val coordinates: List<List<Double>>,
|
||||
/** Search radiuses around each coordinate in meters. */
|
||||
val radiuses: List<Double>? = null,
|
||||
/** List of `[bearing, range]` constraints for each coordinate. */
|
||||
val bearings: List<List<Double>>? = null,
|
||||
/** Include elevation data in response. */
|
||||
val elevation: Boolean? = null,
|
||||
@SerialName("extra_info")
|
||||
/** Additional information to include, e.g., `waytype`. */
|
||||
val extraInfo: List<String>? = null,
|
||||
/** Whether to return turn-by-turn instructions. */
|
||||
val instructions: Boolean? = null,
|
||||
@SerialName("instructions_format")
|
||||
/** Format of instructions such as `html` or `text`. */
|
||||
val instructionsFormat: String? = null,
|
||||
/** Preferred language for textual parts of the response. */
|
||||
val language: String? = null,
|
||||
/** Routing preference such as `fastest` or `shortest`. */
|
||||
val preference: String? = null,
|
||||
/** Unit system for distances. */
|
||||
val units: String? = null,
|
||||
/** Whether to include geometry. */
|
||||
val geometry: Boolean? = null,
|
||||
@SerialName("geometry_simplify")
|
||||
/** Simplify the returned geometry. */
|
||||
val geometrySimplify: Boolean? = null,
|
||||
@SerialName("roundabout_exits")
|
||||
/** Return `exit` indices for roundabouts. */
|
||||
val roundaboutExits: Boolean? = null,
|
||||
/** Additional attributes to include for each segment. */
|
||||
val attributes: List<String>? = null,
|
||||
/** Include a list of maneuvers. */
|
||||
val maneuvers: Boolean? = null,
|
||||
@SerialName("continue_straight")
|
||||
/** Force continue straight at waypoints? */
|
||||
val continueStraight: Boolean? = null,
|
||||
/** Optional advanced options. */
|
||||
val options: RouteOptions? = null
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RouteOptions(
|
||||
@SerialName("avoid_features")
|
||||
/** Features to avoid, e.g., `ferries` or `tollways`. */
|
||||
val avoidFeatures: List<String>? = null,
|
||||
@SerialName("avoid_polygons")
|
||||
/** Optional polygon geometry to avoid. */
|
||||
val avoidPolygons: AvoidPolygons? = null,
|
||||
@SerialName("profile_params")
|
||||
/** Profile specific parameters such as restrictions. */
|
||||
val profileParams: ProfileParams? = null
|
||||
)
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import org.nitri.ors.domain.meta.Metadata
|
||||
|
||||
/** Response from the directions endpoint. */
|
||||
@Serializable
|
||||
data class RouteResponse(
|
||||
val routes: List<Route>,
|
||||
@@ -11,6 +12,7 @@ data class RouteResponse(
|
||||
val metadata: Metadata? = null
|
||||
)
|
||||
|
||||
/** Single route variant returned by the API. */
|
||||
@Serializable
|
||||
data class Route(
|
||||
val summary: RouteSummary,
|
||||
@@ -20,6 +22,7 @@ data class Route(
|
||||
val wayPoints: List<Int>? = null
|
||||
)
|
||||
|
||||
/** Aggregated summary of a route. */
|
||||
@Serializable
|
||||
data class RouteSummary(
|
||||
val distance: Double,
|
||||
@@ -28,6 +31,7 @@ data class RouteSummary(
|
||||
val descent: Double? = null
|
||||
)
|
||||
|
||||
/** One segment between intermediate waypoints. */
|
||||
@Serializable
|
||||
data class Segment(
|
||||
val distance: Double,
|
||||
@@ -40,6 +44,7 @@ data class Segment(
|
||||
val percentage: Double? = null
|
||||
)
|
||||
|
||||
/** Turn instruction within a segment. */
|
||||
@Serializable
|
||||
data class Step(
|
||||
val distance: Double,
|
||||
|
@@ -1,9 +1,10 @@
|
||||
package org.nitri.ors.domain.snap
|
||||
|
||||
// Kotlin DSL for SnapRequest
|
||||
/** DSL for constructing [SnapRequest] objects. */
|
||||
inline fun snapRequest(build: SnapRequestBuilder.() -> Unit): SnapRequest =
|
||||
SnapRequestBuilder().apply(build).build()
|
||||
|
||||
/** Builder used by [snapRequest]. */
|
||||
class SnapRequestBuilder {
|
||||
private val locations = mutableListOf<List<Double>>()
|
||||
private var radius: Int? = null
|
||||
@@ -19,7 +20,7 @@ class SnapRequestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Java-friendly builder
|
||||
/** Java-friendly builder counterpart. */
|
||||
class SnapRequestBuilderJ {
|
||||
private val locations = mutableListOf<List<Double>>()
|
||||
private var radius: Int? = null
|
||||
@@ -34,4 +35,4 @@ class SnapRequestBuilderJ {
|
||||
val r = requireNotNull(radius) { "radius is required" }
|
||||
return SnapRequest(locations = locations.toList(), radius = r, id = id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,8 @@ import org.nitri.ors.domain.elevation.ElevationLineResponse
|
||||
import org.nitri.ors.domain.elevation.ElevationPointRequest
|
||||
import org.nitri.ors.domain.elevation.ElevationPointResponse
|
||||
|
||||
class ElevationHelper() {
|
||||
/** Helper functions for the ORS elevation endpoints. */
|
||||
class ElevationHelper {
|
||||
|
||||
/**
|
||||
* Convenience helper to request elevation for a LineString provided as list of [lon, lat] pairs.
|
||||
|
@@ -6,8 +6,10 @@ import org.nitri.ors.domain.export.ExportRequest
|
||||
import org.nitri.ors.domain.export.ExportResponse
|
||||
import org.nitri.ors.domain.export.TopoJsonExportResponse
|
||||
|
||||
class ExportHelper() {
|
||||
/** Helpers for the export endpoints. */
|
||||
class ExportHelper {
|
||||
|
||||
/** Requests the export endpoint with bounding box [bbox]. */
|
||||
suspend fun OrsClient.export(bbox: List<List<Double>>, geometry: Boolean? = null, profile: Profile): ExportResponse {
|
||||
val request = ExportRequest(
|
||||
bbox = bbox,
|
||||
@@ -17,6 +19,7 @@ class ExportHelper() {
|
||||
return export(profile, request)
|
||||
}
|
||||
|
||||
/** Requests the export endpoint asking explicitly for JSON output. */
|
||||
suspend fun OrsClient.exportJson(bbox: List<List<Double>>, geometry: Boolean? = null, profile: Profile): ExportResponse {
|
||||
val request = ExportRequest(
|
||||
bbox = bbox,
|
||||
@@ -26,6 +29,7 @@ class ExportHelper() {
|
||||
return exportJson(profile, request)
|
||||
}
|
||||
|
||||
/** Requests the export endpoint with TopoJSON output. */
|
||||
suspend fun OrsClient.exportTopoJson(bbox: List<List<Double>>, geometry: Boolean? = null, profile: Profile): TopoJsonExportResponse {
|
||||
val request = ExportRequest(
|
||||
bbox = bbox,
|
||||
|
@@ -6,9 +6,9 @@ import org.nitri.ors.domain.geocode.GeocodeSearchResponse
|
||||
/**
|
||||
* Repository for ORS Geocoding endpoints using GET requests only.
|
||||
*
|
||||
* Methods are member extensions on OrsClient and delegate to OrsClient.
|
||||
* Methods are member extensions on [OrsClient] and delegate to it.
|
||||
*/
|
||||
class GeocodeHelper() {
|
||||
class GeocodeHelper {
|
||||
|
||||
/**
|
||||
* Forward geocoding search.
|
||||
|
@@ -5,8 +5,10 @@ import org.nitri.ors.Profile
|
||||
import org.nitri.ors.domain.isochrones.IsochronesRequest
|
||||
import org.nitri.ors.domain.isochrones.IsochronesResponse
|
||||
|
||||
class IsochronesHelper() {
|
||||
/** Helpers for requesting isochrones. */
|
||||
class IsochronesHelper {
|
||||
|
||||
/** Calls the isochrones endpoint with the given parameters. */
|
||||
suspend fun OrsClient.getIsochrones(
|
||||
locations: List<List<Double>>,
|
||||
range: List<Int>,
|
||||
|
@@ -5,11 +5,10 @@ import org.nitri.ors.Profile
|
||||
import org.nitri.ors.domain.matrix.MatrixRequest
|
||||
import org.nitri.ors.domain.matrix.MatrixResponse
|
||||
|
||||
class MatrixHelper() {
|
||||
/** Helpers for the matrix endpoint. */
|
||||
class MatrixHelper {
|
||||
|
||||
/**
|
||||
* Calls the ORS Matrix endpoint for the given profile.
|
||||
*/
|
||||
/** Calls the ORS Matrix endpoint for the given [profile]. */
|
||||
suspend fun OrsClient.getMatrix(
|
||||
locations: List<List<Double>>,
|
||||
profile: Profile,
|
||||
|
@@ -10,9 +10,9 @@ import org.nitri.ors.domain.optimization.Shipment
|
||||
import org.nitri.ors.domain.optimization.Vehicle
|
||||
|
||||
/**
|
||||
* Repository for the OpenRouteService Optimization endpoint using OrsClient.
|
||||
* Repository for the OpenRouteService Optimization endpoint using [OrsClient].
|
||||
*/
|
||||
class OptimizationHelper() {
|
||||
class OptimizationHelper {
|
||||
|
||||
/**
|
||||
* Calls the ORS Optimization endpoint with provided arguments and builds the request.
|
||||
|
@@ -6,7 +6,8 @@ import org.nitri.ors.domain.pois.Geometry
|
||||
import org.nitri.ors.domain.pois.PoisGeoJsonResponse
|
||||
import org.nitri.ors.domain.pois.PoisRequest
|
||||
|
||||
class PoisHelper() {
|
||||
/** Convenience extensions for the POIs endpoints. */
|
||||
class PoisHelper {
|
||||
|
||||
/**
|
||||
* Query POIs within a bounding box.
|
||||
|
@@ -6,12 +6,19 @@ import org.nitri.ors.domain.route.GeoJsonRouteResponse
|
||||
import org.nitri.ors.domain.route.RouteRequest
|
||||
import org.nitri.ors.domain.route.RouteResponse
|
||||
|
||||
class RouteHelper() {
|
||||
/**
|
||||
* Convenience extensions for invoking the directions endpoints.
|
||||
*/
|
||||
class RouteHelper {
|
||||
|
||||
/** Converts a profile key string to the corresponding [Profile] enum. */
|
||||
private fun profileFromKey(key: String): Profile =
|
||||
Profile.entries.firstOrNull { it.key == key }
|
||||
?: throw IllegalArgumentException("Unknown profile key: $key")
|
||||
|
||||
/**
|
||||
* Retrieves a route between two coordinates.
|
||||
*/
|
||||
suspend fun OrsClient.getRoute(
|
||||
start: Pair<Double, Double>,
|
||||
end: Pair<Double, Double>,
|
||||
@@ -26,6 +33,9 @@ class RouteHelper() {
|
||||
return getRoute(profileFromKey(profile), request)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a route as GPX between two coordinates.
|
||||
*/
|
||||
suspend fun OrsClient.getRouteGpx(
|
||||
start: Pair<Double, Double>,
|
||||
end: Pair<Double, Double>,
|
||||
@@ -40,6 +50,9 @@ class RouteHelper() {
|
||||
return getRouteGpx(profileFromKey(profile), request)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a route as GPX for an arbitrary coordinate list.
|
||||
*/
|
||||
suspend fun OrsClient.getRouteGpx(
|
||||
coordinates: List<List<Double>>,
|
||||
language: String,
|
||||
@@ -49,6 +62,9 @@ class RouteHelper() {
|
||||
return getRouteGpx(profileFromKey(profile), request)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a route as GeoJSON feature collection.
|
||||
*/
|
||||
suspend fun OrsClient.getRouteGeoJson(
|
||||
start: Pair<Double, Double>,
|
||||
end: Pair<Double, Double>,
|
||||
|
@@ -6,11 +6,10 @@ import org.nitri.ors.domain.snap.SnapGeoJsonResponse
|
||||
import org.nitri.ors.domain.snap.SnapRequest
|
||||
import org.nitri.ors.domain.snap.SnapResponse
|
||||
|
||||
class SnapHelper() {
|
||||
/** Helpers for the snap endpoints. */
|
||||
class SnapHelper {
|
||||
|
||||
/**
|
||||
* Calls the ORS Snap endpoint for the given profile.
|
||||
*/
|
||||
/** Calls the ORS Snap endpoint for the given [profile]. */
|
||||
suspend fun OrsClient.getSnap(
|
||||
locations: List<List<Double>>,
|
||||
radius: Int,
|
||||
@@ -25,9 +24,7 @@ class SnapHelper() {
|
||||
return getSnap(profile, request)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the ORS Snap JSON endpoint.
|
||||
*/
|
||||
/** Calls the ORS Snap JSON endpoint. */
|
||||
suspend fun OrsClient.getSnapJson(
|
||||
locations: List<List<Double>>,
|
||||
radius: Int,
|
||||
@@ -42,9 +39,7 @@ class SnapHelper() {
|
||||
return getSnapJson(profile, request)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the ORS Snap GeoJSON endpoint.
|
||||
*/
|
||||
/** Calls the ORS Snap GeoJSON endpoint. */
|
||||
suspend fun OrsClient.getSnapGeoJson(
|
||||
locations: List<List<Double>>,
|
||||
radius: Int,
|
||||
|
@@ -11,7 +11,17 @@ import org.nitri.ors.api.OpenRouteServiceApi
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Builds a Retrofit HTTP client configured for the public
|
||||
* [OpenRouteService](https://openrouteservice.org/) API.
|
||||
*/
|
||||
object OpenRouteServiceRestClient {
|
||||
/**
|
||||
* Creates an [OpenRouteServiceApi] with authorization and sensible defaults.
|
||||
*
|
||||
* @param apiKey ORS API key used in the Authorization header
|
||||
* @param context Android context used for user-agent construction
|
||||
*/
|
||||
fun create(apiKey: String, context: Context): OpenRouteServiceApi {
|
||||
|
||||
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
||||
|
Reference in New Issue
Block a user