Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Commit 532ca5f

Browse files
authored
Merge pull request #46 from PDOK/code-cleanup
Code cleanup
2 parents 2120400 + 99a9681 commit 532ca5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+764
-1195
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ A a GeoJSON implementation with a Geopackage as a data provider.
2424

2525
The specification is a preliminary one, with `go generate` the routing based on api spec, provider interfaces en types structs and convenient parameter extractions are generated to stay easily up to date.
2626

27-
* FeatureCollectionGeoJSON is overridden in the GeoPackage provider to use the [GeoJSON](https://github.com/go-spatial/geom/tree/master/encoding/geojson) equivalent for decoding blobs
27+
* FeatureCollection is overridden in the GeoPackage provider to use the [GeoJSON](https://github.com/go-spatial/geom/tree/master/encoding/geojson) equivalent for decoding blobs
2828
* <https://github.com/opengeospatial/ogcapi-features/blob/master/core/openapi/ogcapi-features-1.yaml>
2929

3030
## Build

core/api.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package core
2+
3+
import (
4+
"net/http"
5+
"oaf-server/codegen"
6+
7+
"github.com/getkin/kin-openapi/openapi3"
8+
)
9+
10+
// GetApiProvider is returned by the NewGetApiProvider
11+
// containing the data and contenttype for the response
12+
type GetApiProvider struct {
13+
data *openapi3.T
14+
contenttype string
15+
}
16+
17+
// NewGetApiProvider handles the request and return the GetApiProvider
18+
func NewGetApiProvider(api *openapi3.T) func(r *http.Request) (codegen.Provider, error) {
19+
20+
return func(r *http.Request) (codegen.Provider, error) {
21+
p := &GetApiProvider{}
22+
23+
ct, err := GetContentType(r, p.String())
24+
if err != nil {
25+
return nil, err
26+
}
27+
28+
p.contenttype = ct
29+
p.data = api
30+
31+
return p, nil
32+
}
33+
}
34+
35+
// Provide provides the data
36+
func (gap *GetApiProvider) Provide() (interface{}, error) {
37+
return gap.data, nil
38+
}
39+
40+
// ContentType returns the ContentType
41+
func (gap *GetApiProvider) ContentType() string {
42+
return gap.contenttype
43+
}
44+
45+
// String returns the provider name
46+
func (gap *GetApiProvider) String() string {
47+
return "api"
48+
}
49+
50+
// SrsId returns the srsid
51+
func (gap *GetApiProvider) SrsId() string {
52+
return "n.a"
53+
}

core/collection.go

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package core
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"oaf-server/codegen"
7+
)
8+
9+
// DescribeCollectionProvider is returned by the NewDescribeCollectionProvider
10+
// containing the data and contenttype for the response
11+
type DescribeCollectionProvider struct {
12+
data codegen.Collection
13+
contenttype string
14+
}
15+
16+
// NewDescribeCollectionProvider handles the request and return the DescribeCollectionProvider
17+
func NewDescribeCollectionProvider(config Config) func(r *http.Request) (codegen.Provider, error) {
18+
19+
return func(r *http.Request) (codegen.Provider, error) {
20+
path := r.URL.Path // collections/{{collectionId}}
21+
22+
collectionId, _ := codegen.ParametersForDescribeCollection(r)
23+
24+
p := &DescribeCollectionProvider{}
25+
26+
ct, err := GetContentType(r, p.String())
27+
if err != nil {
28+
return nil, err
29+
}
30+
p.contenttype = ct
31+
32+
for _, cn := range config.Datasource.Collections {
33+
// maybe convert to map, but not thread safe!
34+
if cn.Identifier != collectionId {
35+
continue
36+
}
37+
38+
cInfo := codegen.Collection{
39+
Id: cn.Identifier,
40+
Title: cn.Identifier,
41+
Description: cn.Description,
42+
Crs: []string{config.Crs[fmt.Sprintf("%d", cn.Srid)]},
43+
Links: []codegen.Link{},
44+
}
45+
46+
// create links
47+
hrefBase := fmt.Sprintf("%s%s", config.Service.Url, path) // /collections
48+
links, _ := CreateLinks(collectionId, p.String(), hrefBase, "self", ct)
49+
50+
cihrefBase := fmt.Sprintf("%s/items", hrefBase)
51+
ilinks, _ := CreateLinks("items of "+collectionId, p.String(), cihrefBase, "item", ct)
52+
cInfo.Links = append(links, ilinks...)
53+
54+
for _, c := range config.Datasource.Collections {
55+
if c.Identifier == cn.Identifier {
56+
if len(c.Links) != 0 {
57+
cInfo.Links = append(cInfo.Links, c.Links...)
58+
}
59+
break
60+
}
61+
}
62+
63+
p.data = cInfo
64+
break
65+
}
66+
67+
return p, nil
68+
}
69+
70+
}
71+
72+
// Provide returns the srsid
73+
func (dcp *DescribeCollectionProvider) Provide() (interface{}, error) {
74+
return dcp.data, nil
75+
}
76+
77+
// ContentType returns the srsid
78+
func (dcp *DescribeCollectionProvider) ContentType() string {
79+
return dcp.contenttype
80+
}
81+
82+
// SrsStringId returns the provider name
83+
func (dcp *DescribeCollectionProvider) String() string {
84+
return "collection"
85+
}
86+
87+
// SrsId returns the srsid
88+
func (dcp *DescribeCollectionProvider) SrsId() string {
89+
return "n.a."
90+
}

core/collections.go

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package core
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"oaf-server/codegen"
7+
)
8+
9+
// GetCollectionsProvider is returned by the NewGetCollectionsProvider
10+
// containing the data and contenttype for the response
11+
type GetCollectionsProvider struct {
12+
data codegen.Collections
13+
contenttype string
14+
}
15+
16+
// NewGetCollectionsProvider handles the request and return the GetCollectionsProvider
17+
func NewGetCollectionsProvider(config Config) func(r *http.Request) (codegen.Provider, error) {
18+
19+
return func(r *http.Request) (codegen.Provider, error) {
20+
path := r.URL.Path // collections
21+
22+
p := &GetCollectionsProvider{}
23+
24+
ct, err := GetContentType(r, p.String())
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
p.contenttype = ct
30+
31+
csInfo := codegen.Collections{Links: []codegen.Link{}, Collections: []codegen.Collection{}}
32+
// create Links
33+
hrefBase := fmt.Sprintf("%s%s", config.Service.Url, path) // /collections
34+
links, _ := CreateLinks("collections ", p.String(), hrefBase, "self", ct)
35+
csInfo.Links = append(csInfo.Links, links...)
36+
for _, cn := range config.Datasource.Collections {
37+
clinks, _ := CreateLinks("collection "+cn.Identifier, p.String(), fmt.Sprintf("%s/%s", hrefBase, cn.Identifier), "item", ct)
38+
csInfo.Links = append(csInfo.Links, clinks...)
39+
}
40+
41+
for _, cn := range config.Datasource.Collections {
42+
43+
cInfo := codegen.Collection{
44+
Id: cn.Identifier,
45+
Title: cn.Identifier,
46+
Description: cn.Description,
47+
Crs: []string{config.Crs[fmt.Sprintf("%d", cn.Srid)]},
48+
Links: []codegen.Link{},
49+
}
50+
51+
chrefBase := fmt.Sprintf("%s/%s", hrefBase, cn.Identifier)
52+
53+
clinks, _ := CreateLinks("collection "+cn.Identifier, p.String(), chrefBase, "self", ct)
54+
cInfo.Links = append(cInfo.Links, clinks...)
55+
56+
cihrefBase := fmt.Sprintf("%s/items", chrefBase)
57+
ilinks, _ := CreateLinks("items "+cn.Identifier, p.String(), cihrefBase, "item", ct)
58+
cInfo.Links = append(cInfo.Links, ilinks...)
59+
60+
for _, c := range config.Datasource.Collections {
61+
if c.Identifier == cn.Identifier {
62+
if len(c.Links) != 0 {
63+
cInfo.Links = append(cInfo.Links, c.Links...)
64+
}
65+
break
66+
}
67+
}
68+
69+
csInfo.Collections = append(csInfo.Collections, cInfo)
70+
}
71+
72+
p.data = csInfo
73+
74+
return p, nil
75+
}
76+
}
77+
78+
// Provide provides the data
79+
func (gcp *GetCollectionsProvider) Provide() (interface{}, error) {
80+
return gcp.data, nil
81+
}
82+
83+
// ContentType returns the ContentType
84+
func (gcp *GetCollectionsProvider) ContentType() string {
85+
return gcp.contenttype
86+
}
87+
88+
// String returns the provider name
89+
func (gcp *GetCollectionsProvider) String() string {
90+
return "collections"
91+
}
92+
93+
// SrsId returns the srsid
94+
func (gcp *GetCollectionsProvider) SrsId() string {
95+
return "n.a."
96+
}

provider/config.go renamed to core/config.go

+24-5
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1-
package provider
1+
package core
22

33
import (
44
"io/ioutil"
55
"log"
66
"oaf-server/codegen"
77

8-
"gopkg.in/yaml.v2"
8+
"gopkg.in/yaml.v3"
99
)
1010

11+
// Config wrappes all the available configuration
1112
type Config struct {
1213
ApplicationId string `yaml:"applicationid,omitempty"`
1314
UserVersion string `yaml:"userversion,omitempty"`
1415

15-
Openapi string `yaml:"openapi"`
16-
DefaultFeatureLimit int `yaml:"defaultfeaturelimit"`
17-
MaxFeatureLimit int `yaml:"maxfeaturelimit"`
16+
Openapi string `yaml:"openapi"`
17+
DefaultFeatureLimit int `yaml:"defaultfeaturelimit"`
18+
MaxFeatureLimit int `yaml:"maxfeaturelimit"`
19+
Crs map[string]string `yaml:"crs"`
1820
Datasource Datasource
1921
Service Service `yaml:"service" json:"service"`
2022
}
2123

24+
// ContactPoint needed for the ld+json
2225
type ContactPoint struct {
2326
Type string `yaml:"@type" json:"@type,omitempty"`
2427
Email string `yaml:"email" json:"email,omitempty"`
@@ -27,6 +30,8 @@ type ContactPoint struct {
2730
ContactType string `yaml:"contactType" json:"contactType,omitempty"`
2831
Description string `yaml:"description" json:"description,omitempty"`
2932
}
33+
34+
// Address needed for the ld+json
3035
type Address struct {
3136
Type string `yaml:"@type" json:"@type,omitempty"`
3237
StreetAddress string `yaml:"streetAddress" json:"streetAddress,omitempty"`
@@ -36,6 +41,7 @@ type Address struct {
3641
AddressCountry string `yaml:"addressCountry" json:"addressCountry,omitempty"`
3742
}
3843

44+
// Provider needed for the ld+json
3945
type Provider struct {
4046
Type string `yaml:"@type" json:"@type"`
4147
Name string `yaml:"name" json:"name"`
@@ -44,6 +50,7 @@ type Provider struct {
4450
ContactPoint *ContactPoint `yaml:"contactPoint" json:"contactPoint,omitempty"` // pointer, omitting when empty
4551
}
4652

53+
// Service contains the necessary information for building the right ld+json objects
4754
type Service struct {
4855
Context string `yaml:"@context" json:"@context"`
4956
Type string `yaml:"@type" json:"@type"`
@@ -57,6 +64,7 @@ type Service struct {
5764
Provider Provider `yaml:"provider" json:"provider"`
5865
}
5966

67+
// Datasource wrappes the datasources, collections, dataset boundingbox and SRID
6068
type Datasource struct {
6169
Geopackage *Geopackage `yaml:"gpkg"`
6270
PostGIS *PostGIS `yaml:"postgis"`
@@ -65,15 +73,18 @@ type Datasource struct {
6573
Srid int `yaml:"srid"`
6674
}
6775

76+
// Geopackage contains the Geopackage file locations and a alternative Fid column
6877
type Geopackage struct {
6978
File string `yaml:"file"`
7079
Fid string `yaml:"fid"`
7180
}
7281

82+
// PostGIS contains the PostGIS connection string
7383
type PostGIS struct {
7484
Connection string `yaml:"connection"`
7585
}
7686

87+
// Collection contains all the needed information for a collections
7788
type Collection struct {
7889
Schemaname string `yaml:"schemaname"`
7990
Tablename string `yaml:"tablename"`
@@ -92,13 +103,15 @@ type Collection struct {
92103
Links []codegen.Link `yaml:"links"`
93104
}
94105

106+
// Columns stores the Fid, Offset, BoundingBox and Geometry columns from the datasources
95107
type Columns struct {
96108
Fid string `yaml:"fid"`
97109
Offset string `yaml:"offset"`
98110
BBox string `yaml:"bbox"`
99111
Geometry string `yaml:"geometry"`
100112
}
101113

114+
// NewService initializes a Service
102115
func NewService() Service {
103116
address := Address{
104117
Type: "PostalAddress",
@@ -119,6 +132,7 @@ func NewService() Service {
119132
return service
120133
}
121134

135+
// ReadConfig reads the from the given path the configuration
122136
func (c *Config) ReadConfig(path string) {
123137
bytes, err := ioutil.ReadFile(path)
124138
if err != nil {
@@ -153,6 +167,11 @@ func (c *Config) ReadConfig(path string) {
153167
c.MaxFeatureLimit = 500
154168
}
155169

170+
if len(c.Crs) == 0 {
171+
crs := map[string]string{`4326`: `http://www.opengis.net/def/crs/EPSG/0/4326`}
172+
c.Crs = crs
173+
}
174+
156175
if c.Openapi == "" {
157176
c.Openapi = "spec/oaf.json"
158177
}

0 commit comments

Comments
 (0)