github.com/go-spatial/go-wfs@v0.1.4-0.20190401000911-c9fba2bb5188/wfs3/wfs3_types.go (about) 1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 // The MIT License (MIT) 4 // Copyright (c) 2018 Jivan Amara 5 // 6 // Permission is hereby granted, free of charge, to any person obtaining a copy 7 // of this software and associated documentation files (the "Software"), to 8 // deal in the Software without restriction, including without limitation the 9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 // sell copies of the Software, and to permit persons to whom the Software is 11 // furnished to do so, subject to the following conditions: 12 // 13 // The above copyright notice and this permission notice shall be included in 14 // all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 // USE OR OTHER DEALINGS IN THE SOFTWARE. 23 // 24 /////////////////////////////////////////////////////////////////////////////// 25 26 // jivan project wfs3_schema.go 27 28 package wfs3 29 30 import ( 31 "html/template" 32 33 "github.com/go-spatial/geom/encoding/geojson" 34 "github.com/go-spatial/jivan/config" 35 "github.com/go-spatial/jivan/util" 36 "github.com/getkin/kin-openapi/openapi3" 37 ) 38 39 // --- @See http://raw.githubusercontent.com/opengeospatial/WFS_FES/master/core/openapi/schemas/root.yaml 40 // for rootContentSchema Definition 41 // What the endpoint at "/" returns 42 type RootContent struct { 43 Links []*Link `json:"links"` 44 } 45 46 func (rc *RootContent) MarshalHTML(c config.Config) ([]byte, error) { 47 body := map[string]interface{}{"config": c, "data": rc} 48 49 content, err := util.RenderTemplate(tmpl_root, body) 50 51 if err != nil { 52 return content, err 53 } 54 55 data := map[string]interface{}{"config": c, "body": template.HTML(content), "links": rc.Links} 56 57 return util.RenderTemplate(tmpl_base, data) 58 } 59 60 var RootContentSchema openapi3.Schema = openapi3.Schema{ 61 Type: "object", 62 Required: []string{"links"}, 63 Properties: map[string]*openapi3.SchemaRef{ 64 "links": { 65 Value: &openapi3.Schema{ 66 Type: "array", 67 Items: &openapi3.SchemaRef{ 68 Value: &LinkSchema, 69 }, 70 }, 71 }, 72 }, 73 } 74 75 // --- @See https://raw.githubusercontent.com/opengeospatial/WFS_FES/master/core/openapi/schemas/bbox.yaml 76 // for bbox schema 77 // maxItems is needed for setting the bbox array MaxItems in the below Schema literal. 78 var maxItems int64 = 4 79 80 type Bbox struct { 81 Crs string `json:"crs"` 82 Bbox []float64 `json:"bbox"` 83 } 84 85 var BboxSchema openapi3.Schema = openapi3.Schema{ 86 Type: "object", 87 Required: []string{"bbox"}, 88 Properties: map[string]*openapi3.SchemaRef{ 89 "crs": { 90 // TODO: This is supposed to have an enum & default based on: http://www.opengis.net/def/crs/OGC/1.3/CRS84 91 Value: openapi3.NewStringSchema(), 92 }, 93 "bbox": { 94 Value: &openapi3.Schema{ 95 Type: "array", 96 MinItems: 4, 97 MaxItems: &maxItems, 98 Items: openapi3.NewSchemaRef("", openapi3.NewFloat64Schema().WithMin(-180).WithMax(180)), 99 }, 100 }, 101 }, 102 } 103 104 // --- @See https://raw.githubusercontent.com/opengeospatial/WFS_FES/master/core/openapi/schemas/link.yaml 105 // for link schema 106 type Link struct { 107 Href string `json:"href"` 108 Rel string `json:"rel"` 109 Type string `json:"type"` 110 Hreflang string `json:"hreflang"` 111 Title string `json:"title"` 112 } 113 114 var LinkSchema openapi3.Schema = openapi3.Schema{ 115 Type: "object", 116 Required: []string{"href"}, 117 Properties: map[string]*openapi3.SchemaRef{ 118 "href": { 119 Value: &openapi3.Schema{ 120 Type: "string", 121 }, 122 }, 123 "rel": { 124 Value: &openapi3.Schema{ 125 Type: "string", 126 }, 127 }, 128 "type": { 129 Value: &openapi3.Schema{ 130 Type: "string", 131 }, 132 }, 133 "hreflang": { 134 Value: &openapi3.Schema{ 135 Type: "string", 136 }, 137 }, 138 "title": { 139 Value: &openapi3.Schema{ 140 Type: "string", 141 }, 142 }, 143 }, 144 } 145 146 func (l *Link) ContentType(contentType string) { 147 l.Type = contentType 148 } 149 150 // --- @See https://raw.githubusercontent.com/opengeospatial/WFS_FES/master/core/openapi/schemas/collectionInfo.yaml 151 // for collectionInfo schema 152 type CollectionInfo struct { 153 Name string `json:"name"` 154 Title string `json:"title,omitempty"` 155 Description string `json:"description,omitempty"` 156 Links []*Link `json:"links"` 157 Extent *Bbox `json:"extent,omitempty"` 158 Crs []string `json:"crs,omitempty"` 159 } 160 161 func (ci *CollectionInfo) MarshalHTML(c config.Config) ([]byte, error) { 162 body := map[string]interface{}{"config": c, "data": ci} 163 164 content, err := util.RenderTemplate(tmpl_collection, body) 165 166 if err != nil { 167 return content, err 168 } 169 170 data := map[string]interface{}{"config": c, "body": template.HTML(content), "links": ci.Links} 171 172 return util.RenderTemplate(tmpl_base, data) 173 } 174 175 func (ci *CollectionInfo) ContentType(contentType string) { 176 for _, l := range ci.Links { 177 if l.Type == "" { 178 l.ContentType(contentType) 179 } 180 } 181 } 182 183 var CollectionInfoSchema openapi3.Schema = openapi3.Schema{ 184 Type: "object", 185 Required: []string{"name", "links"}, 186 Properties: map[string]*openapi3.SchemaRef{ 187 "name": { 188 Value: &openapi3.Schema{ 189 Type: "string", 190 }, 191 }, 192 "title": { 193 Value: &openapi3.Schema{ 194 Type: "string", 195 }, 196 }, 197 "description": { 198 Value: &openapi3.Schema{ 199 Type: "string", 200 }, 201 }, 202 "links": { 203 Value: &openapi3.Schema{ 204 Type: "array", 205 Items: &openapi3.SchemaRef{ 206 Value: &LinkSchema, 207 }, 208 }, 209 }, 210 "extent": { 211 Value: &BboxSchema, 212 }, 213 "crs": { 214 Value: &openapi3.Schema{ 215 Type: "array", 216 Items: &openapi3.SchemaRef{ 217 Value: &openapi3.Schema{ 218 Type: "string", 219 }, 220 }, 221 }, 222 }, 223 }, 224 } 225 226 // --- @See https://raw.githubusercontent.com/opengeospatial/WFS_FES/master/core/openapi/schemas/content.yaml 227 // for collectionsInfo schema. 228 type CollectionsInfo struct { 229 Links []*Link `json:"links"` 230 Collections []*CollectionInfo `json:"collections"` 231 } 232 233 func (csi *CollectionsInfo) MarshalHTML(c config.Config) ([]byte, error) { 234 body := map[string]interface{}{"config": c, "data": csi} 235 236 content, err := util.RenderTemplate(tmpl_collections, body) 237 238 if err != nil { 239 return content, err 240 } 241 242 data := map[string]interface{}{"config": c, "body": template.HTML(content), "links": csi.Links} 243 244 return util.RenderTemplate(tmpl_base, data) 245 } 246 247 func (csi *CollectionsInfo) ContentType(contentType string) { 248 for _, l := range csi.Links { 249 if l.Type == "" { 250 l.ContentType(contentType) 251 } 252 } 253 for _, c := range csi.Collections { 254 c.ContentType(contentType) 255 } 256 } 257 258 var CollectionsInfoSchema openapi3.Schema = openapi3.Schema{ 259 Type: "object", 260 Required: []string{"links", "collections"}, 261 Properties: map[string]*openapi3.SchemaRef{ 262 "links": { 263 Value: &openapi3.Schema{ 264 Type: "array", 265 Items: &openapi3.SchemaRef{ 266 Value: &LinkSchema, 267 }, 268 }, 269 }, 270 "collections": { 271 Value: &openapi3.Schema{ 272 Type: "array", 273 Items: &openapi3.SchemaRef{ 274 Value: &CollectionInfoSchema, 275 }, 276 }, 277 }, 278 }, 279 } 280 281 // --- @See https://raw.githubusercontent.com/opengeospatial/WFS_FES/master/core/openapi/schemas/req-classes.yaml 282 // for ConformanceClasses schema 283 type ConformanceClasses struct { 284 ConformsTo []string `json:"conformsTo"` 285 } 286 287 func (ccs *ConformanceClasses) MarshalHTML(c config.Config) ([]byte, error) { 288 body := map[string]interface{}{"config": c, "data": ccs} 289 290 content, err := util.RenderTemplate(tmpl_conformance, body) 291 292 if err != nil { 293 return content, err 294 } 295 296 data := map[string]interface{}{"config": c, "body": template.HTML(content)} 297 298 return util.RenderTemplate(tmpl_base, data) 299 } 300 301 var ConformanceClassesSchema openapi3.Schema = openapi3.Schema{ 302 Type: "object", 303 Required: []string{"conformsTo"}, 304 Properties: map[string]*openapi3.SchemaRef{ 305 "conformsTo": { 306 Value: &openapi3.Schema{ 307 Type: "array", 308 Items: &openapi3.SchemaRef{ 309 Value: &openapi3.Schema{ 310 Type: "string", 311 }, 312 }, 313 }, 314 }, 315 }, 316 } 317 318 type FeatureCollection struct { 319 geojson.FeatureCollection 320 Links []*Link `json:"links,omitempty"` 321 NumberMatched uint `json:"numberMatched,omitempty"` 322 NumberReturned uint `json:"numberReturned,omitempty"` 323 } 324 325 func (fc *FeatureCollection) MarshalHTML(c config.Config) ([]byte, error) { 326 body := map[string]interface{}{"config": c, "data": fc} 327 328 content, err := util.RenderTemplate(tmpl_collection_features, body) 329 330 if err != nil { 331 return content, err 332 } 333 334 data := map[string]interface{}{"config": c, "body": template.HTML(content), "links": fc.Links} 335 336 return util.RenderTemplate(tmpl_base, data) 337 } 338 339 type Feature struct { 340 geojson.Feature 341 Links []*Link `json:"links,omitempty"` 342 } 343 344 func (f *Feature) MarshalHTML(c config.Config) ([]byte, error) { 345 body := map[string]interface{}{"config": c, "data": f} 346 347 content, err := util.RenderTemplate(tmpl_collection_feature, body) 348 349 if err != nil { 350 return content, err 351 } 352 353 data := map[string]interface{}{"config": c, "body": template.HTML(content), "links": f.Links} 354 355 return util.RenderTemplate(tmpl_base, data) 356 } 357 358 func pint64(i int) *int64 { 359 i64 := int64(i) 360 return &i64 361 } 362 363 var BBoxSchema openapi3.Schema = openapi3.Schema{ 364 Type: "array", 365 Items: &openapi3.SchemaRef{Value: openapi3.NewFloat64Schema()}, 366 MinLength: int64(4), 367 MaxLength: pint64(4), 368 }