Skip to content

Commit

Permalink
Cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
pramsey committed Dec 19, 2019
1 parent c5fce23 commit 950c2e1
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 209 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ LANGUAGE 'sql';

```sql
CREATE OR REPLACE
FUNCTION squares(z integer, x integer, y integer, depth integer)
FUNCTION squares(z integer, x integer, y integer, depth integer default 2)
RETURNS bytea
AS $$
DECLARE
Expand All @@ -58,7 +58,10 @@ BEGIN
RETURN rslt;
END;
$$
LANGUAGE 'plpgsql';
LANGUAGE 'plpgsql'
IMMUTABLE
STRICT
PARALLEL SAFE;
```


Expand Down
14 changes: 4 additions & 10 deletions layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func (lt layerType) String() string {
}
}

// A Layer is a LayerTable or a LayerFunction
// in either case it should be able to generate
// a TileRequest containing SQL to produce tiles
// given an input tile
type Layer interface {
GetType() layerType
GetId() string
Expand Down Expand Up @@ -99,13 +103,3 @@ func GetJsonLayers(r *http.Request) map[string]LayerJson {
}
return json
}

// R http.Request

// GetLayers(R) => []LayerJson
// GetLayerDetail(R, Id) => LayerDetailJson

// GetTile(R, Id, ZXY)

// GetTileRequest(Tile, R, Layer, ) => TileRequest
// GetMVT(TileRequest) => []byte
5 changes: 0 additions & 5 deletions layer_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ import (
"github.com/spf13/viper"
)

// x-correlation-id
// A Layer is a LayerTable or a LayerFunction
// in either case it should be able to generate
// SQL to produce tiles given an input tile

type LayerTable struct {
Id string
Schema string
Expand Down
226 changes: 44 additions & 182 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package main

import (
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"strconv"
"text/template"

// "text/template"
"time"

// REST routing
Expand All @@ -25,31 +24,6 @@ import (
"github.com/spf13/viper"
)

// Age = 198
// Cats = [ "Cauchy", "Plato" ]
// Pi = 3.14
// Perfection = [ 6, 28, 496, 8128 ]
// DOB = 1987-07-05T05:45:00Z

// Then you can load it into your Go program with something like

// type Config struct {
// Age int
// Cats []string
// Pi float64
// Perfection []int
// DOB time.Time
// }

// var conf Config
// if _, err := toml.DecodeFile("something.toml", &conf); err != nil {
// // handle error
// }

// type Coordinate struct {
// x, y float64
// }

// programName is the name string we use
const programName string = "pg_tileserv"

Expand All @@ -59,17 +33,7 @@ const programVersion string = "0.1"
// worldMercWidth is the width of the Web Mercator plane
const worldMercWidth float64 = 40075016.6855784

// A global array of Layer where the state is held for performance
// Refreshed when LoadLayerTableList is called
// Key is of the form: schemaname.tablename
var globalLayerTables map[string]LayerTable

// A global array of LayerFunc where the state is held for performance
// Refreshed when LoadLayerTableList is called
// Key is of the form: schemaname.procname
var globalLayerFunctions map[string]LayerFunction

// A global database connection pointer
// globalDb is a global database connection pointer
var globalDb *pgxpool.Pool = nil

/******************************************************************************/
Expand All @@ -79,7 +43,7 @@ func main() {
viper.SetDefault("DbConnection", "sslmode=disable")
viper.SetDefault("HttpHost", "0.0.0.0")
viper.SetDefault("HttpPort", 7800)
viper.SetDefault("UrlBase", "http://localhost:7800")
viper.SetDefault("UrlBase", "")
viper.SetDefault("DefaultResolution", 4096)
viper.SetDefault("DefaultBuffer", 256)
viper.SetDefault("MaxFeaturesPerTile", 50)
Expand Down Expand Up @@ -131,13 +95,14 @@ func main() {
}

// Get to work
HandleRequests()
handleRequests()
}

/******************************************************************************/

/******************************************************************************/

/*
func HandleRequestRoot(w http.ResponseWriter, r *http.Request) {
log.WithFields(log.Fields{
"event": "handlerequest",
Expand All @@ -164,65 +129,6 @@ func HandleRequestRoot(w http.ResponseWriter, r *http.Request) {
t.Execute(w, info)
}
func HandleRequestTableList(w http.ResponseWriter, r *http.Request) {
log.WithFields(log.Fields{
"event": "handlerequest",
"topic": "tablelist",
}).Trace("HandleRequestTableList")
// Update the local copy
// LoadLayerTableList()
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(globalLayerTables)
}

func HandleRequestFunctionList(w http.ResponseWriter, r *http.Request) {
log.WithFields(log.Fields{
"event": "handlerequest",
"topic": "proclist",
}).Trace("HandleRequestFunctionList")
// Update the local copy
// LoadLayerFunctionList()
// todo ERROR on db
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(globalLayerFunctions)
}

func HandleRequestTable(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
lyrname := vars["name"]
log.WithFields(log.Fields{
"event": "handlerequest",
"topic": "table",
"key": lyrname,
}).Tracef("HandleRequestTable: %s", lyrname)

if lyr, ok := globalLayerTables[lyrname]; ok {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(lyr)
}
// todo ERROR
}

func HandleRequestFunction(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
lyrname := vars["name"]
log.WithFields(log.Fields{
"event": "handlerequest",
"topic": "proc",
"key": lyrname,
}).Tracef("HandleRequestFunction: %s", lyrname)

if lyr, ok := globalLayerFunctions[lyrname]; ok {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(lyr)
}
// todo ERROR
}

func HandleRequestTablePreview(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
lyrname := vars["name"]
Expand All @@ -240,98 +146,57 @@ func HandleRequestTablePreview(w http.ResponseWriter, r *http.Request) {
t.Execute(w, lyr)
}
}
*/

func MakeTile(vars map[string]string) (Tile, error) {
// Route restriction should ensure these are numbers
x, _ := strconv.Atoi(vars["x"])
y, _ := strconv.Atoi(vars["y"])
zoom, _ := strconv.Atoi(vars["zoom"])
ext := vars["ext"]
tile := Tile{Zoom: zoom, X: x, Y: y, Ext: ext}
if !tile.IsValid() {
return tile, errors.New(fmt.Sprintf("invalid tile address %s", tile.String()))
}
return tile, nil
}

// func HandleRequestFunctionTile(w http.ResponseWriter, r *http.Request) {
// vars := mux.Vars(r)
// lyrname := vars["name"]
// if lyr, ok := globalLayerFunctions[lyrname]; ok {
// tile, _ := MakeTile(vars)
// log.WithFields(log.Fields{
// "event": "handlerequest",
// "topic": "proctile",
// "key": tile.String(),
// }).Tracef("HandleRequestFunctionTile: %s", tile.String())

// // Replace with SQL fun
// procArgs := lyr.GetLayerFunctionArgs(r.URL.Query())
// pbf, err := lyr.GetTile(&tile, procArgs)

// if err != nil {
// // TODO return a 500 or something
// }
// w.Header().Set("Access-Control-Allow-Origin", "*")
// w.Header().Add("Content-Type", "application/vnd.mapbox-vector-tile")
// _, err = w.Write(pbf)
// return
// }

// }

func RequestListJson(w http.ResponseWriter, r *http.Request) {
func requestListJson(w http.ResponseWriter, r *http.Request) error {
log.WithFields(log.Fields{
"event": "request",
"topic": "layerlist",
}).Trace("RequestLayerList")
// Update the global in-memory list from
// the database
if err := LoadLayers(); err != nil {
// return nil, err
return
return err
}
w.Header().Add("Content-Type", "application/json")
jsonLayers := GetJsonLayers(r)
json.NewEncoder(w).Encode(jsonLayers)
return nil
}

func RequestDetailJson(w http.ResponseWriter, r *http.Request) {
func requestDetailJson(w http.ResponseWriter, r *http.Request) error {
lyrId := mux.Vars(r)["name"]
log.WithFields(log.Fields{
"event": "request",
"topic": "layerdetail",
}).Tracef("RequestLayerDetail(%s)", lyrId)

// Refresh the layers list
if err := LoadLayers(); err != nil {
// return nil, error
return
return err
}

lyr, errLyr := GetLayer(lyrId)
if errLyr != nil {
// return nil, errLyr
return
return errLyr
}

errWrite := lyr.WriteLayerJson(w, r)
if errWrite != nil {
// return nil, errWrite
return
return errWrite
}
return nil
}

func RequestLayerTile(w http.ResponseWriter, r *http.Request) {
func requestTile(w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
lyr, errLyr := GetLayer(vars["name"])
if errLyr != nil {
// return nil, errLyr
return
return errLyr
}
tile, errTile := MakeTile(vars)
tile, errTile := makeTile(vars)
if errTile != nil {
// return nil, errTile
return
return errTile
}

log.WithFields(log.Fields{
Expand All @@ -343,38 +208,40 @@ func RequestLayerTile(w http.ResponseWriter, r *http.Request) {
tilerequest := lyr.GetTileRequest(tile, r)
mvt, errMvt := DBTileRequest(&tilerequest)
if errMvt != nil {
// return nil, errMvt
return
return errMvt
}

if _, errWrite := w.Write(mvt); errWrite != nil {
return errWrite
}
w.Header().Add("Content-Type", "application/vnd.mapbox-vector-tile")

if _, err := w.Write(mvt); err != nil {
// return nil, errWrite
return
return nil
}

type tileAppHandler func(w http.ResponseWriter, r *http.Request) error

func (fn tileAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
log.Error(err)
}
return
}

func HandleRequests() {
// TODO, propogate id headers to error logging
// TODO, ensure all logging uses fields
// x-correlation-id

func handleRequests() {

// creates a new instance of a mux router
r := mux.NewRouter().StrictSlash(true)
// replace http.HandleFunc with myRouter.HandleFunc
// r.HandleFunc("/", HandleRequestRoot).Methods("GET")
// r.HandleFunc("/index.html", HandleRequestRoot).Methods("GET")
// r.HandleFunc("/index.json", HandleRequestTableList).Methods("GET")
// r.HandleFunc("/{name}.html", HandleRequestTablePreview).Methods("GET")
// r.HandleFunc("/{name}/tilejson.json", HandleRequestTableTileJSON).Methods("GET")
// r.HandleFunc("/{name}/{zoom:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.{ext}", HandleRequestTableTile).Methods("GET")

// r.HandleFunc("/func/index.json", HandleRequestFunctionList).Methods("GET")
// r.HandleFunc("/func/{name}.json", HandleRequestFunction).Methods("GET")
// r.HandleFunc("/func/{name}/{zoom:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.{ext}", HandleRequestFunctionTile)

r.HandleFunc("/index.json", RequestListJson).Methods("GET")
r.HandleFunc("/{name}.json", RequestDetailJson).Methods("GET")
r.HandleFunc("/{name}/{zoom:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.{ext}", RequestLayerTile).Methods("GET")
// r.HandleFunc("/", RequestListHtml).Methods("GET")
// r.HandleFunc("/index.html", RequestListHtml).Methods("GET")
// r.HandleFunc("/{name}.html", RequestDetailHtml).Methods("GET")
r.Handle("/index.json", tileAppHandler(requestListJson))
r.Handle("/{name}.json", tileAppHandler(requestDetailJson))
r.Handle("/{name}/{z:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.{ext}", tileAppHandler(requestTile))

// Allow CORS from anywhere
corsOpt := handlers.AllowedOrigins([]string{"*"})
Expand All @@ -394,8 +261,3 @@ func HandleRequests() {
}

/******************************************************************************/

type StatusMessage struct {
Status string `json:"status"`
Message string `json:"message"`
}
Loading

0 comments on commit 950c2e1

Please sign in to comment.