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))
 }