Mercurial > gemma
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) +}