Mercurial > gemma
changeset 960:e23ae2c83427
Load boundary polygon of sounding result from ZIP file.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 17 Oct 2018 12:23:39 +0200 |
parents | 6ab012d0f0c2 |
children | a4c92e0ef2e1 d7f34791b18d |
files | 3rdpartylibs.sh pkg/imports/sr.go |
diffstat | 2 files changed, 84 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/3rdpartylibs.sh Tue Oct 16 18:20:50 2018 +0200 +++ b/3rdpartylibs.sh Wed Oct 17 12:23:39 2018 +0200 @@ -9,3 +9,4 @@ go get -u -v github.com/rs/cors go get -u -v golang.org/x/net/html/charset go get -u -v github.com/golang/snappy +go get -u -v github.com/jonas-p/go-shp
--- a/pkg/imports/sr.go Tue Oct 16 18:20:50 2018 +0200 +++ b/pkg/imports/sr.go Wed Oct 17 12:23:39 2018 +0200 @@ -11,17 +11,19 @@ "io" "log" "os" - "path/filepath" + "path" "strconv" "strings" "time" + shp "github.com/jonas-p/go-shp" + "gemma.intevation.de/gemma/pkg/octree" ) type SoundingResult struct { who string - dir string + zip string } const SoundingResultDateFormat = "2006-01-02" @@ -52,7 +54,7 @@ } func (sr *SoundingResult) CleanUp() error { - return os.RemoveAll(sr.dir) + return os.RemoveAll(sr.zip) } func find(needle string, haystack []*zip.File) *zip.File { @@ -157,9 +159,77 @@ return loadXYZReader(r) } +type ( + Point struct { + X float64 + Y float64 + } + LineString []Point + Polygon []LineString +) + +func toPolygon(numParts int32, parts []int32, points []shp.Point) Polygon { + out := make(Polygon, numParts) + pos := 0 + for i := range out { + ps := parts[i] + line := make(LineString, ps) + for j := int32(0); j < ps; j, pos = j+1, pos+1 { + p := &points[pos] + line[j] = Point{p.X, p.Y} + } + out[i] = line + } + return out +} + +func loadBoundary(z *zip.ReadCloser) (Polygon, error) { + shpF := find(".shp", z.File) + if shpF == nil { + return nil, nil + } + prefix := strings.TrimSuffix(shpF.Name, path.Ext(shpF.Name)) + dbfF := find(prefix+".dbf", z.File) + if dbfF == nil { + return nil, fmt.Errorf("No DBF file found for %s", shpF.Name) + } + + shpR, err := shpF.Open() + if err != nil { + return nil, err + } + + dbfR, err := dbfF.Open() + if err != nil { + shpR.Close() + return nil, err + } + sr := shp.SequentialReaderFromExt(shpR, dbfR) + defer sr.Close() + + if !sr.Next() { + return nil, sr.Err() + } + + _, s := sr.Shape() + if s == nil { + return nil, sr.Err() + } + + switch p := s.(type) { + case *shp.Polygon: + return toPolygon(p.NumParts, p.Parts, p.Points), nil + case *shp.PolygonZ: + return toPolygon(p.NumParts, p.Parts, p.Points), nil + case *shp.PolygonM: + return toPolygon(p.NumParts, p.Parts, p.Points), nil + } + return nil, fmt.Errorf("Unsupported shape type %T", s) +} + func (sr *SoundingResult) Do(conn *sql.Conn) error { - z, err := zip.OpenReader(filepath.Join(sr.dir, "upload.zip")) + z, err := zip.OpenReader(sr.zip) if err != nil { return err } @@ -193,7 +263,15 @@ return errors.New("XYZ does not contain any vertices.") } - // TODO: Implement more. + // Is there a boundary shapefile in the ZIP archive? + polygon, err := loadBoundary(z) + if err != nil { + return err + } + + _ = polygon + + // TODO: Send to database. return nil }