Mercurial > gemma
diff pkg/wfs/global.go @ 2711:3956de9b6b32
WFS downloader: Implemented GML download to file, ogr2ogr to GeoJSON.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 18 Mar 2019 17:20:02 +0100 |
parents | d7ef169fd0d3 |
children | 2b6f73c30016 |
line wrap: on
line diff
--- a/pkg/wfs/global.go Mon Mar 18 17:01:47 2019 +0100 +++ b/pkg/wfs/global.go Mon Mar 18 17:20:02 2019 +0100 @@ -14,14 +14,23 @@ package wfs import ( + "bufio" + "errors" + "fmt" "io" + "io/ioutil" "log" + "os" "os/exec" + "path/filepath" + + "gemma.intevation.de/gemma/pkg/config" ) var ( FormatGeoJSON = []string{"geojson", "application/json"} FormatGML = []string{ + "application/gml+xml; version=3.2", "gml2", "gml3", "gml32", "text/xml; subtype=gml/2.1.2", "text/xml; subtype=gml/3.1.1", @@ -80,7 +89,66 @@ return DownloadURLs([]string(gjd), handler) } +func places(n int) int { + places := 1 + if n < 0 { + places++ + n = -n + } + for value := 10; n >= value; value *= 10 { + places++ + } + return places +} + func (gmd GMLDownloader) Download(handler func(string, io.Reader) error) error { - // TODO: Implement, me! - return nil + + if len(gmd) == 0 { + return errors.New("Nothing to download") + } + + tmpDir := config.TmpDir() + dlDir, err := ioutil.TempDir(tmpDir, "wfs-downloads") + if err != nil { + return err + } + defer os.RemoveAll(dlDir) + digits := places(len(gmd)) + + var files []string + + for i, url := range gmd { + fname := filepath.Join(dlDir, fmt.Sprintf("%0*d.gml", digits, i)) + if err := downloadURL(url, func(_ string, r io.Reader) error { + f, err := os.Create(fname) + if err != nil { + return err + } + if _, err = io.Copy(f, r); err != nil { + f.Close() + return err + } + return f.Close() + }); err != nil { + return err + } + files = append(files, fname) + } + + out := filepath.Join(dlDir, "out.geojson") + + cmd := exec.Command("ogr2ogr", append([]string{"-f", "GeoJSON", out}, files...)...) + + msg, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("ogr2ogr failed: %s", msg) + } + + in, err := os.Open(out) + if err != nil { + return err + } + defer in.Close() + + return handler(gmd[0], bufio.NewReader(in)) }