Mercurial > gemma
changeset 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 | f393fabfdd35 |
children | 0ac077897ce5 |
files | cmd/wfs/dump.go cmd/wfs/main.go pkg/wfs/global.go |
diffstat | 3 files changed, 78 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/cmd/wfs/dump.go Mon Mar 18 17:01:47 2019 +0100 +++ b/cmd/wfs/dump.go Mon Mar 18 17:20:02 2019 +0100 @@ -24,9 +24,10 @@ "gemma.intevation.de/gemma/pkg/wfs" ) -func parseFeatures(urls []string, defaultCRS string) error { +func parseFeatures(downloader wfs.Downloader, defaultCRS string) error { - return wfs.DownloadURLs(urls, func(url string, r io.Reader) error { + return downloader.Download(func(url string, r io.Reader) error { + log.Printf("Get features from: '%s'\n", url) rfc, err := wfs.ParseRawFeatureCollection(r) if err != nil {
--- a/cmd/wfs/main.go Mon Mar 18 17:01:47 2019 +0100 +++ b/cmd/wfs/main.go Mon Mar 18 17:20:02 2019 +0100 @@ -28,10 +28,9 @@ func main() { var ( - dumpCaps = flag.Bool("dump-caps", false, "Dump capabilities document") - dumpFeatures = flag.Bool("dump-features", false, "Dump features") - featureType = flag.String("features", "", "feature to get") - sortBy = flag.String("sortby", "", "Sort features by this property") + dumpCaps = flag.Bool("dump-caps", false, "Dump capabilities document") + featureType = flag.String("features", "", "feature to get") + sortBy = flag.String("sortby", "", "Sort features by this property") ) flag.Parse() @@ -51,15 +50,9 @@ log.Fatalf("Unknown feature type '%s'\n", *featureType) } - urls, err := wfs.GetFeaturesGET( - caps, *featureType, wfs.FormatGeoJSON, *sortBy) + dl, err := wfs.GetFeatures(caps, *featureType, *sortBy) check(err) - log.Printf("urls: %v\n", urls) - if *dumpFeatures { - check(dumpURLs(urls)) - } - - parseFeatures(urls, feature.DefaultCRS) + parseFeatures(dl, feature.DefaultCRS) } }
--- 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)) }