view pkg/octree/polygon.go @ 2489:4f292ff74d9e octree-diff

Added a WKB reader for clipping polygon.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sun, 03 Mar 2019 18:08:40 +0100
parents cb55d7eaaa36
children c9164ff98871
line wrap: on
line source

// This is Free Software under GNU Affero General Public License v >= 3.0
// without warranty, see README.md and license for details.
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// License-Filename: LICENSES/AGPL-3.0.txt
//
// Copyright (C) 2018 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>

package octree

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math"

	"gemma.intevation.de/gemma/pkg/wkb"
)

type Polygon struct {
	// TODO: Implement me!
	rings [][]float64
}

type IntersectionType byte

const (
	IntersectionInside IntersectionType = iota
	IntersectionOutSide
	IntersectionOverlaps
)

func (p *Polygon) IntersectionBox2D(box Box2D) IntersectionType {
	// TODO: Implement me
	return IntersectionOutSide
}

func (p *Polygon) IntersectionWithTriangle(t *Triangle) IntersectionType {
	// TODO: Implement me
	return IntersectionOutSide
}

func (p *Polygon) FromWKB(data []byte) error {

	r := bytes.NewReader(data)

	endian, err := r.ReadByte()

	var order binary.ByteOrder

	switch {
	case err != nil:
		return err
	case endian == wkb.NDR:
		order = binary.LittleEndian
	case endian == wkb.XDR:
		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 != wkb.Polygon:
		return fmt.Errorf("unknown geometry type %x", geomType)
	}

	var numRings uint32
	if err = binary.Read(r, order, &numRings); err != nil {
		return err
	}

	rings := make([][]float64, numRings)

	for ring := uint32(0); ring < numRings; ring++ {
		var numVertices uint32
		if err = binary.Read(r, order, &numVertices); err != nil {
			return err
		}

		vertices := make([]float64, 2*numVertices)

		for v := uint32(0); v < numVertices; v++ {
			var lat, lon uint64
			if err = binary.Read(r, order, &lat); err != nil {
				return err
			}
			if err = binary.Read(r, order, &lon); err != nil {
				return err
			}
			vertices[v*2] = math.Float64frombits(lat)
			vertices[v*2+1] = math.Float64frombits(lon)
		}

		rings[ring] = vertices
	}

	p.rings = rings

	return nil
}