changeset 4541:53b55f811666 iso-areas

Dump generated polygons as SVG.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 26 Sep 2019 15:37:56 +0200
parents e01b6e7cbe7d
children 56f4e8cbfab7
files cmd/isoareas/main.go go.mod go.sum
diffstat 3 files changed, 65 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/cmd/isoareas/main.go	Thu Sep 26 13:08:56 2019 +0200
+++ b/cmd/isoareas/main.go	Thu Sep 26 15:37:56 2019 +0200
@@ -15,15 +15,19 @@
 
 import (
 	"bufio"
+	"fmt"
 	"io"
 	"log"
 	"math"
 	"math/bits"
+	"math/rand"
 	"os"
 	"strconv"
 	"strings"
 	"time"
 
+	svg "github.com/ajstarks/svgo"
+
 	"gemma.intevation.de/gemma/pkg/octree"
 )
 
@@ -219,17 +223,73 @@
 	return mask
 }
 
+func linear(x1, y1, x2, y2 float64) func(float64) float64 {
+	// f(x1) = y1
+	// f(x2) = y2
+	// y1 = x1*a + b <=> b = y1 - x1*a
+	// y2 = x2*a + b
+
+	// y1 - y2 = a*(x1 - x2)
+	// a = (y1-y2)/(x1 - x2) for x1 != x2
+
+	if x1 == x2 {
+		return func(float64) float64 {
+			return 0.5 * (y1 + y2)
+		}
+	}
+	a := (y1 - y2) / (x1 - x2)
+	b := y1 - x1*a
+	return func(x float64) float64 {
+		return x*a + b
+	}
+}
+
 func dumpPolygonsSVG(
 	w io.Writer,
 	min, max octree.Vertex,
-	polygons [][]octree.LineStringZ,
-) error {
+	classPolygons [][]octree.LineStringZ,
+) (err error) {
 
 	ratio := (max.X - min.X) / (max.Y - min.Y)
 
 	log.Printf("ratio: %.2f\n", ratio)
 
-	// TODO: Implement me!
+	const width = 1000
+	height := int(math.Ceil(width * ratio))
+
+	px := linear(min.X, 0, max.X, width)
+	py := linear(min.Y, float64(height), max.Y, 0)
+
+	out := bufio.NewWriter(w)
+	defer func() { err = out.Flush() }()
+
+	canvas := svg.New(out)
+	canvas.Start(width, height)
+
+	rnd := rand.New(rand.NewSource(42))
+
+	for _, polygons := range classPolygons {
+
+		r := byte(rnd.Intn(256))
+		g := byte(rnd.Intn(256))
+		b := byte(rnd.Intn(256))
+		style := fmt.Sprintf("fill:#%02x%02x%02x", r, g, b)
+
+		for _, polygon := range polygons {
+
+			x := make([]int, len(polygon))
+			y := make([]int, len(polygon))
+			for i, p := range polygon {
+				x[i] = int(math.Round(px(p.X)))
+				y[i] = int(math.Round(py(p.Y)))
+			}
+
+			canvas.Polygon(x, y, style)
+		}
+
+	}
+
+	canvas.End()
 
 	return nil
 }
--- a/go.mod	Thu Sep 26 13:08:56 2019 +0200
+++ b/go.mod	Thu Sep 26 15:37:56 2019 +0200
@@ -3,6 +3,7 @@
 go 1.13
 
 require (
+	github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af
 	github.com/cockroachdb/apd v1.1.0 // indirect
 	github.com/etcd-io/bbolt v1.3.3
 	github.com/gofrs/uuid v3.2.0+incompatible // indirect
--- a/go.sum	Thu Sep 26 13:08:56 2019 +0200
+++ b/go.sum	Thu Sep 26 15:37:56 2019 +0200
@@ -2,6 +2,7 @@
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=