Mercurial > gemma
view pkg/wfs/global.go @ 5583:c1bd5f8eaf9a surveysperbottleneckid
AvailableFairwayDepthDialogue: set objnam for print is okay
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Mon, 14 Feb 2022 12:06:48 +0100 |
parents | 09346efa7f69 |
children | 31973f6f5cca |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package wfs import ( "bufio" "fmt" "io" "io/ioutil" "os" "os/exec" "path/filepath" "sync" "gemma.intevation.de/gemma/pkg/config" "gemma.intevation.de/gemma/pkg/log" ) var ( // FormatGeoJSON is a list of MIME types of // GeoJSON documents. FormatGeoJSON = []string{"geojson", "application/json"} // FormatGML is a list of MIME types // GML documents. 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", "text/xml; subtype=gml/3.2", } ) type ( // Downloader abstracts the idea of a download function for WFS. Downloader interface { Download(user, password string, handler func(string, io.Reader) error) error } // GeoJSONDownloader is a Downloader for GeoJSON. GeoJSONDownloader []string // GMLDownloader is a Downloader for GML. GMLDownloader []string ) var ( getFeaturesOnce sync.Once getFeatures func(*Capabilities, string, string) (Downloader, error) ) func getFeaturesOnceFunc() { path, err := exec.LookPath("ogr2ogr") if err != nil { log.Infoln("ogr2ogr not installed. Using direct GeoJSON WFS download.") getFeatures = getFeaturesGeoJSON } else { log.Infof("ogr2ogr found at %s. Using GML WFS download.\n", path) getFeatures = getFeaturesGML } } // GetFeatures is the default Downloader in this Gemma server. func GetFeatures( caps *Capabilities, featureTypeName string, sortBy string, ) (Downloader, error) { getFeaturesOnce.Do(getFeaturesOnceFunc) return getFeatures(caps, featureTypeName, sortBy) } func getFeaturesGeoJSON( caps *Capabilities, featureTypeName string, sortBy string, ) (Downloader, error) { urls, err := GetFeaturesGET( caps, featureTypeName, FormatGeoJSON, sortBy) return GeoJSONDownloader(urls), err } func getFeaturesGML( caps *Capabilities, featureTypeName string, sortBy string, ) (Downloader, error) { urls, err := GetFeaturesGET( caps, featureTypeName, FormatGML, sortBy) return GMLDownloader(urls), err } // Download is the GeoJSON implementation of the Downloader. func (gjd GeoJSONDownloader) Download(user, password string, handler func(string, io.Reader) error) error { return DownloadURLs(user, password, []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 } // Download is GML implementaion of the Downloader. func (gmd GMLDownloader) Download(user, password string, handler func(string, io.Reader) error) error { if len(gmd) == 0 { return nil } 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(user, password, 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)) }