# HG changeset patch # User Sascha L. Teichmann # Date 1567439864 -7200 # Node ID fee5794f3b7ae9fb222f925933c2210f4e0e6f2b # Parent 3e0755af1177d11d8367f7790deacb6c640d0f3a Return stretch as a ZIPed ESRI shape file from end point. TODO: Write the actual geometries to the shape file. diff -r 3e0755af1177 -r fee5794f3b7a pkg/controllers/routes.go --- a/pkg/controllers/routes.go Mon Sep 02 17:45:18 2019 +0200 +++ b/pkg/controllers/routes.go Mon Sep 02 17:57:44 2019 +0200 @@ -309,7 +309,7 @@ // Handler to serve data to the client. - api.Handle("/data/{kind:stretch|section}/shape/{name}", any( + api.Handle("/data/stretch/shape/{name}", any( mw.DBConn(http.HandlerFunc(stretchShapeDownload)))).Methods(http.MethodGet) api.Handle("/data/{kind:stretch|section}/availability/{name}", any( diff -r 3e0755af1177 -r fee5794f3b7a pkg/controllers/stretches.go --- a/pkg/controllers/stretches.go Mon Sep 02 17:45:18 2019 +0200 +++ b/pkg/controllers/stretches.go Mon Sep 02 17:57:44 2019 +0200 @@ -14,20 +14,28 @@ package controllers import ( + "archive/zip" "context" "database/sql" "encoding/csv" "fmt" + "io" + "io/ioutil" "log" "net/http" + "os" + "path/filepath" "runtime" "strings" "sync" "time" + "github.com/gorilla/mux" + "github.com/jonas-p/go-shp" + + "gemma.intevation.de/gemma/pkg/config" "gemma.intevation.de/gemma/pkg/middleware" "gemma.intevation.de/gemma/pkg/wkb" - "github.com/gorilla/mux" ) const ( @@ -681,17 +689,8 @@ func stretchShapeDownload(rw http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) - stretch := vars["kind"] == "stretch" name := vars["name"] - // TODO: Implement me! - if !stretch { - http.Error( - rw, "Not implemented, yet!", - http.StatusBadRequest) - return - } - conn := middleware.GetDBConn(req) ctx := req.Context() @@ -766,6 +765,93 @@ return } - // TODO: Serialize as ESRI shapefile. + tmp := config.TmpDir() + + dir, err := ioutil.TempDir(tmp, "stretch-download") + if err != nil { + http.Error( + rw, fmt.Sprintf("Cannot create temp dir: %v.", err), + http.StatusInternalServerError) + return + } + defer os.RemoveAll(dir) + + shpDir := filepath.Join(dir, "stretch") + + if err := os.Mkdir(shpDir, os.ModePerm); err != nil { + http.Error( + rw, fmt.Sprintf("Cannot create temp dir: %v.", err), + http.StatusInternalServerError) + return + } + + filename := filepath.Join(shpDir, "stretch") + + if err := func() error { + writer, err := shp.Create(filename, shp.POLYGON) + if err != nil { + return err + } + defer writer.Close() + + // TODO: Write geometry + + return nil + }(); err != nil { + http.Error( + rw, fmt.Sprintf("creating shapefile failed: %v.", err), + http.StatusInternalServerError) + return + } + entries, err := func() ([]os.FileInfo, error) { + f, err := os.Open(shpDir) + if err != nil { + return nil, err + } + defer f.Close() + return f.Readdir(-1) + }() + if err != nil { + http.Error( + rw, fmt.Sprintf("cannot read directory: %v.", err), + http.StatusInternalServerError) + return + } + + rw.Header().Set("Content-Type", "application/zip") + rw.Header().Set("Content-Disposition", `attachment; filename="stretch.zip"`) + + zipfile := zip.NewWriter(rw) + defer zipfile.Close() + + now := time.Now() + + base := filepath.Base(shpDir) + for _, info := range entries { + if !info.Mode().IsRegular() { + continue + } + if err := func() error { + srcFile, err := os.Open(filepath.Join(shpDir, info.Name())) + if err != nil { + return err + } + defer srcFile.Close() + header := &zip.FileHeader{ + Name: base + "/" + info.Name(), + Method: zip.Deflate, + Modified: now, + } + out, err := zipfile.CreateHeader(header) + if err != nil { + return err + } + _, err = io.Copy(out, srcFile) + return err + }(); err != nil { + log.Printf("error: cannot write file: %v\n", err) + return + } + } } diff -r 3e0755af1177 -r fee5794f3b7a pkg/wkb/data.go --- a/pkg/wkb/data.go Mon Sep 02 17:45:18 2019 +0200 +++ b/pkg/wkb/data.go Mon Sep 02 17:57:44 2019 +0200 @@ -64,8 +64,6 @@ polygons := make([]PolygonGeom, numPolygons) - // TODO: Parse the polygons. - for i := range polygons { switch endian, err := r.ReadByte(); { case err != nil: