changeset 972:17a03a84b0e8

Split out polygon code out of sounding result importer source file.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 18 Oct 2018 12:22:08 +0200
parents f9fb6c399f3f
children b6fec8f85599
files pkg/imports/polygon.go pkg/imports/sr.go
diffstat 2 files changed, 79 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/polygon.go	Thu Oct 18 12:22:08 2018 +0200
@@ -0,0 +1,78 @@
+package imports
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"math"
+
+	shp "github.com/jonas-p/go-shp"
+)
+
+type (
+	Point struct {
+		X float64
+		Y float64
+	}
+	LineString []Point
+	Polygon    []LineString
+)
+
+const (
+	wkbNDR     byte   = 1
+	wkbPolygon uint32 = 3
+)
+
+func shapeToPolygon(s shp.Shape) (Polygon, error) {
+	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 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 (p Polygon) AsWBK() []byte {
+	if p == nil {
+		return nil
+	}
+	// pre-calculate size to avoid reallocations.
+	size := 1 + 4 + 4
+	for _, ring := range p {
+		size += 4 + len(ring)*2*8
+	}
+
+	buf := bytes.NewBuffer(make([]byte, 0, size))
+
+	binary.Write(buf, binary.LittleEndian, wkbNDR)
+	binary.Write(buf, binary.LittleEndian, wkbPolygon)
+	binary.Write(buf, binary.LittleEndian, uint32(len(p)))
+
+	for _, ring := range p {
+		binary.Write(buf, binary.LittleEndian, uint32(len(ring)))
+		for _, v := range ring {
+			binary.Write(buf, binary.LittleEndian, math.Float64bits(v.X))
+			binary.Write(buf, binary.LittleEndian, math.Float64bits(v.Y))
+		}
+	}
+
+	return buf.Bytes()
+}
--- a/pkg/imports/sr.go	Thu Oct 18 11:52:13 2018 +0200
+++ b/pkg/imports/sr.go	Thu Oct 18 12:22:08 2018 +0200
@@ -3,16 +3,13 @@
 import (
 	"archive/zip"
 	"bufio"
-	"bytes"
 	"context"
 	"database/sql"
-	"encoding/binary"
 	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
 	"log"
-	"math"
 	"os"
 	"path"
 	"strconv"
@@ -40,18 +37,6 @@
 		EPSG           uint               `json:"epsg"`
 		DepthReference string             `json:"depth-reference"`
 	}
-
-	Point struct {
-		X float64
-		Y float64
-	}
-	LineString []Point
-	Polygon    []LineString
-)
-
-const (
-	wkbNDR     byte   = 1
-	wkbPolygon uint32 = 3
 )
 
 const (
@@ -206,21 +191,6 @@
 	return loadXYZReader(r)
 }
 
-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 {
@@ -254,15 +224,7 @@
 		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)
+	return shapeToPolygon(s)
 }
 
 func (sr *SoundingResult) Do(conn *sql.Conn) error {
@@ -334,30 +296,3 @@
 
 	return tx.Commit()
 }
-
-func (p Polygon) AsWBK() []byte {
-	if p == nil {
-		return nil
-	}
-	// pre-calculate size to avoid reallocations.
-	size := 1 + 4 + 4
-	for _, ring := range p {
-		size += 4 + len(ring)*2*8
-	}
-
-	buf := bytes.NewBuffer(make([]byte, 0, size))
-
-	binary.Write(buf, binary.LittleEndian, wkbNDR)
-	binary.Write(buf, binary.LittleEndian, wkbPolygon)
-	binary.Write(buf, binary.LittleEndian, uint32(len(p)))
-
-	for _, ring := range p {
-		binary.Write(buf, binary.LittleEndian, uint32(len(ring)))
-		for _, v := range ring {
-			binary.Write(buf, binary.LittleEndian, math.Float64bits(v.X))
-			binary.Write(buf, binary.LittleEndian, math.Float64bits(v.Y))
-		}
-	}
-
-	return buf.Bytes()
-}