bbox_core/
ogcapi.rs

1use serde::Serialize;
2use std::collections::HashMap;
3
4#[derive(Debug, Serialize)]
5/// <http://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_api_landing_page>
6pub struct CoreLandingPage {
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub title: Option<String>,
9    #[serde(skip_serializing_if = "Option::is_none")]
10    pub description: Option<String>,
11    pub links: Vec<ApiLink>,
12}
13
14#[derive(Clone, Debug, Serialize)]
15/// <http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/link.yaml>
16pub struct ApiLink {
17    pub href: String,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub rel: Option<String>,
20    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
21    pub type_: Option<String>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub hreflang: Option<String>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub title: Option<String>,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub length: Option<u64>,
28}
29
30#[derive(Debug, Serialize)]
31#[serde(rename_all = "camelCase")]
32/// <http://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_declaration_of_conformance_classes>
33pub struct CoreConformsTo {
34    pub conforms_to: Vec<String>,
35}
36
37#[derive(Debug, Serialize)]
38/// /collections
39/// <http://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_collections_>
40pub struct CoreCollections {
41    pub links: Vec<ApiLink>,
42    pub collections: Vec<CoreCollection>,
43}
44
45#[derive(Clone, Debug, Serialize)]
46#[serde(rename_all = "camelCase")]
47/// /collections/{collectionId}.
48/// <https://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_collection_>
49/// <http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/schemas/collection.yaml>
50pub struct CoreCollection {
51    pub id: String,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub title: Option<String>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub description: Option<String>,
56    pub links: Vec<ApiLink>,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub extent: Option<CoreExtent>,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub item_type: Option<String>,
61    #[serde(skip_serializing_if = "Vec::is_empty")]
62    pub crs: Vec<String>,
63}
64
65#[derive(Clone, Debug, Serialize)]
66pub struct CoreExtent {
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub spatial: Option<CoreExtentSpatial>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub temporal: Option<CoreExtentTemporal>,
71}
72
73#[derive(Clone, Debug, Serialize)]
74pub struct CoreExtentSpatial {
75    pub bbox: Vec<Vec<f64>>,
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub crs: Option<String>,
78}
79
80#[derive(Clone, Debug, Serialize)]
81pub struct CoreExtentTemporal {
82    pub interval: Vec<Vec<Option<String>>>, // date-time
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub trs: Option<String>,
85}
86
87#[derive(Debug, Serialize)]
88#[serde(rename_all = "camelCase")]
89/// /collections/{collectionId}/items
90/// <https://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_response_6>
91pub struct CoreFeatures {
92    // featureCollectionGeoJSON
93    #[serde(rename = "type")]
94    pub type_: String, // FeatureCollection
95    #[serde(skip_serializing_if = "Vec::is_empty")]
96    pub links: Vec<ApiLink>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub time_stamp: Option<String>,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub number_matched: Option<u64>,
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub number_returned: Option<u64>,
103    #[serde(skip_serializing_if = "Vec::is_empty")]
104    pub features: Vec<CoreFeature>,
105}
106
107#[derive(Debug, Serialize)]
108/// /collections/{collectionId}/items/{featureId}
109/// <https://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_feature_>
110pub struct CoreFeature {
111    #[serde(rename = "type")]
112    pub type_: String, // Feature
113    pub geometry: GeoJsonGeometry,
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub properties: Option<GeoJsonProperties>,
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub id: Option<String>, // string or integer
118    #[serde(skip_serializing_if = "Vec::is_empty")]
119    pub links: Vec<ApiLink>,
120}
121
122#[derive(Debug, Serialize)]
123/// <https://docs.ogc.org/DRAFTS/19-079r1.html#queryables>
124pub struct Queryables {
125    #[serde(rename = "type")]
126    pub type_: String, // Feature
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub title: Option<String>,
129    #[serde(rename = "$id")]
130    pub id: String,
131    #[serde(rename = "$schema")]
132    pub schema: String,
133    pub properties: HashMap<String, QueryableProperty>,
134}
135
136#[derive(Debug, Serialize)]
137/// <https://docs.ogc.org/DRAFTS/19-079r1.html#queryables>
138pub struct QueryableProperty {
139    #[serde(rename = "type")]
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub type_: Option<QueryableType>,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub title: Option<String>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub format: Option<String>,
146}
147
148#[derive(Clone, Debug, Serialize)]
149/// <https://docs.ogc.org/DRAFTS/19-079r1.html#queryables>
150pub enum QueryableType {
151    #[serde(rename = "string")]
152    String,
153    #[serde(rename = "integer")]
154    Integer,
155    #[serde(rename = "number")]
156    Number,
157    #[serde(rename = "boolean")]
158    Bool,
159    #[serde(rename = "datetime")]
160    Datetime,
161}
162
163pub type GeoJsonProperties = serde_json::value::Value;
164pub type GeoJsonGeometry = serde_json::value::Value;