diff pkg/models/cross.go @ 808:e10a8a682297

Cross sections: Clip result against area of the sounding result. This also includes the re-projections back to WGS84 and encoding the final result as GeoJSON.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 27 Sep 2018 16:30:15 +0200
parents b6a1779ffb42
children 3bb275235c89
line wrap: on
line diff
--- a/pkg/models/cross.go	Thu Sep 27 16:13:59 2018 +0200
+++ b/pkg/models/cross.go	Thu Sep 27 16:30:15 2018 +0200
@@ -133,10 +133,11 @@
 }
 
 const (
-	wkbXDR         byte   = 0
-	wkbNDR         byte   = 1
-	wkbLineString  uint32 = 2
-	wkbLineStringZ uint32 = 1000 + 2
+	wkbXDR              byte   = 0
+	wkbNDR              byte   = 1
+	wkbLineString       uint32 = 2
+	wkbLineStringZ      uint32 = 1000 + 2
+	wkbMultiLineStringZ uint32 = 1000 + 5
 )
 
 func (lc GeoJSONLineCoordinates) AsWKB() []byte {
@@ -256,3 +257,98 @@
 	x := dLng * math.Cos(deg2rad((cz.Lat+other.Lat)/2.0))
 	return math.Sqrt(dLat*dLat+x*x) * EarthRadius
 }
+
+func (mls *GeoJSONMultiLineCoordinatesZ) FromWKB(data []byte) error {
+	r := bytes.NewReader(data)
+
+	var order binary.ByteOrder
+
+	endian, err := r.ReadByte()
+
+	switch {
+	case err != nil:
+		return err
+	case endian == wkbNDR:
+		order = binary.LittleEndian
+	case endian == wkbXDR:
+		order = binary.BigEndian
+	default:
+		return fmt.Errorf("unknown byte order %x", endian)
+	}
+
+	var geomType uint32
+	err = binary.Read(r, order, &geomType)
+
+	switch {
+	case err != nil:
+		return err
+	case geomType != wkbMultiLineStringZ:
+		return fmt.Errorf("unknown geometry type %d", geomType)
+	}
+
+	var numLines uint32
+	if err = binary.Read(r, order, &numLines); err != nil {
+		return err
+	}
+
+	lines := make(GeoJSONMultiLineCoordinatesZ, numLines)
+
+	for i := range lines {
+		endian, err = r.ReadByte()
+
+		switch {
+		case err != nil:
+			return err
+		case endian == wkbNDR:
+			order = binary.LittleEndian
+		case endian == wkbXDR:
+			order = binary.BigEndian
+		default:
+			return fmt.Errorf("unknown byte order %x", endian)
+		}
+
+		err = binary.Read(r, order, &geomType)
+		switch {
+		case err != nil:
+			return err
+		case geomType != wkbLineStringZ:
+			return fmt.Errorf("unknown geometry type %d", geomType)
+		}
+
+		var numPoints uint32
+		if err = binary.Read(r, order, &numPoints); err != nil {
+			return err
+		}
+
+		points := make(GeoJSONLineCoordinatesZ, numPoints)
+		for j := range points {
+			var lat, lon, z uint64
+			if err = binary.Read(r, order, &lat); err != nil {
+				return err
+			}
+			if err = binary.Read(r, order, &lon); err != nil {
+				return err
+			}
+			if err = binary.Read(r, order, &z); err != nil {
+				return err
+			}
+			c := &points[j]
+			c.Lat = math.Float64frombits(lat)
+			c.Lon = math.Float64frombits(lon)
+			c.Z = math.Float64frombits(z)
+		}
+		lines[i] = points
+	}
+
+	*mls = lines
+
+	return nil
+}
+
+func (mls *GeoJSONMultiLineCoordinatesZ) Scan(src interface{}) error {
+	data, ok := src.([]byte)
+	if !ok {
+		return errNoByteSlice
+	}
+	return mls.FromWKB(data)
+}