changeset 645:794592cad75a

Cross sections: Fixed SQL, endian, WKB and JSON encoding errors.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 13 Sep 2018 12:59:18 +0200
parents c1a31858ad54
children 4450f2ab41e0
files pkg/controllers/cross.go pkg/models/common.go pkg/models/cross.go
diffstat 3 files changed, 19 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/cross.go	Thu Sep 13 12:14:25 2018 +0200
+++ b/pkg/controllers/cross.go	Thu Sep 13 12:59:18 2018 +0200
@@ -12,12 +12,12 @@
 SELECT ST_AsBinary((ST_Dump(ST_Multi(ST_3DIntersection(
   ST_Translate(
     ST_Extrude(
-      ST_FromWKB($1, 4326),
+      ST_GeomFromWKB($1, 4326),
     0, 0, 100),
    0, 0, -150),
    geom)))).geom)
 FROM b442017
-WHERE ST_Intersects(geom, ST_FromWKB($1, 4326))
+WHERE ST_Intersects(geom, ST_GeomFromWKB($1, 4326))
 `
 
 func crossSection(
@@ -34,7 +34,8 @@
 
 	var rows *sql.Rows
 
-	rows, err = db.QueryContext(req.Context(), csi.Coordinates.AsWKB())
+	rows, err = db.QueryContext(
+		req.Context(), crossSQL, csi.Coordinates.AsWKB())
 	if err != nil {
 		return
 	}
--- a/pkg/models/common.go	Thu Sep 13 12:14:25 2018 +0200
+++ b/pkg/models/common.go	Thu Sep 13 12:59:18 2018 +0200
@@ -2,4 +2,7 @@
 
 import "errors"
 
-var errNoString = errors.New("Not a string")
+var (
+	errNoString    = errors.New("Not a string")
+	errNoByteSlice = errors.New("Not a byte slice")
+)
--- a/pkg/models/cross.go	Thu Sep 13 12:14:25 2018 +0200
+++ b/pkg/models/cross.go	Thu Sep 13 12:59:18 2018 +0200
@@ -7,7 +7,6 @@
 	"errors"
 	"fmt"
 	"math"
-	"strings"
 	"time"
 )
 
@@ -42,7 +41,7 @@
 
 	CrossSectionInput struct {
 		Type        GeoJSONFeature              `json:"type"`
-		Geometry    GeoJSONLineString           `json:"geometry"`
+		Geometry    GeoJSONLineStringType       `json:"geometry"`
 		Coordinates GeoJSONLineCoordinates      `json:"coordinates"`
 		Properties  CrossSectionInputProperties `json:"properties"`
 	}
@@ -131,7 +130,7 @@
 	wkbLineStringZ uint32 = 1000 + 2
 )
 
-func (lc GeoJSONLineCoordinates) AsWKB() string {
+func (lc GeoJSONLineCoordinates) AsWKB() []byte {
 
 	size := 1 + 4 + 4 + len(lc)*(1+4+2*8)
 
@@ -143,32 +142,30 @@
 
 	for i := range lc {
 		c := &lc[i]
-		binary.Write(buf, binary.LittleEndian, wkbNDR)
-		binary.Write(buf, binary.LittleEndian, wkbPoint)
 		binary.Write(buf, binary.LittleEndian, math.Float64bits(c.Lon))
 		binary.Write(buf, binary.LittleEndian, math.Float64bits(c.Lat))
 	}
 
-	return buf.String()
+	return buf.Bytes()
 }
 
 func (cz GeoJSONCoordinateZ) MarshalJSON() ([]byte, error) {
 	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "[%.8f %.8f %.8f]", cz.Lon, cz.Lat, cz.Z)
+	fmt.Fprintf(&buf, "[%.8f,%.8f,%.8f]", cz.Lon, cz.Lat, cz.Z)
 	return buf.Bytes(), nil
 }
 
 func (lcz *GeoJSONLineCoordinatesZ) Scan(src interface{}) error {
-	data, ok := src.(string)
+	data, ok := src.([]byte)
 	if !ok {
-		return errNoString
+		return errNoByteSlice
 	}
 	return lcz.FromWKB(data)
 }
 
-func (lcz *GeoJSONLineCoordinatesZ) FromWKB(data string) error {
+func (lcz *GeoJSONLineCoordinatesZ) FromWKB(data []byte) error {
 
-	r := strings.NewReader(data)
+	r := bytes.NewReader(data)
 
 	endian, err := r.ReadByte()
 
@@ -178,9 +175,9 @@
 	case err != nil:
 		return err
 	case endian == wkbNDR:
-		order = binary.BigEndian
+		order = binary.LittleEndian
 	case endian == wkbXDR:
-		order = binary.LittleEndian
+		order = binary.BigEndian
 	default:
 		return fmt.Errorf("unknown byte order %x", endian)
 	}
@@ -192,7 +189,7 @@
 	case err != nil:
 		return err
 	case geomType != wkbLineStringZ:
-		return fmt.Errorf("unknown geometry type %d", geomType)
+		return fmt.Errorf("unknown geometry type %x", geomType)
 	}
 
 	var num uint32
@@ -203,13 +200,6 @@
 	coords := make(GeoJSONLineCoordinatesZ, num)
 
 	for i := range coords {
-		err = binary.Read(r, order, &geomType)
-		switch {
-		case err != nil:
-			return err
-		case geomType != wkbPointZ:
-			return fmt.Errorf("unknown geometry type %d", geomType)
-		}
 		c := &coords[i]
 		for _, addr := range []*float64{&c.Lat, &c.Lon, &c.Z} {
 			if err = binary.Read(r, order, addr); err != nil {