changeset 2574:2833ff156cb2

Morphological differences: Moved loading of clipping polygon into octree package.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 11 Mar 2019 14:36:34 +0100
parents 4486ca003b55
children 59e7a011d347
files cmd/octreediff/main.go pkg/controllers/diff.go pkg/octree/polygon.go
diffstat 3 files changed, 109 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/cmd/octreediff/main.go	Mon Mar 11 14:18:14 2019 +0100
+++ b/cmd/octreediff/main.go	Mon Mar 11 14:36:34 2019 +0100
@@ -65,22 +65,6 @@
     4326
   )
 `
-	clippingPolygonSQL = `
-WITH joined AS (
-  SELECT
-    sr.area      AS area,
-    sr.date_info AS date_info
-  FROM waterway.sounding_results sr JOIN
-     waterway.bottlenecks bn ON sr.bottleneck_id = bn.id
-  WHERE bn.bottleneck_id = $1
-)
-SELECT ST_AsBinary(
-  ST_intersection(
-    (SELECT ST_Transform(area::geometry, $2::int) FROM joined WHERE date_info = $3::date),
-    (SELECT ST_Transform(area::geometry, $2::int) FROM joined WHERE date_info = $4::date)
-  )
-  ) AS area
-`
 	insertContourSQLClipped = `
 WITH joined AS (
   SELECT
@@ -226,23 +210,17 @@
 		last = now
 		log.Printf("num points: %d\n", len(result))
 
-		var clip []byte
-
-		if err := tx.QueryRowContext(
-			ctx, clippingPolygonSQL,
+		clippingPolygon, err := octree.LoadClippingPolygon(
+			ctx,
+			conn,
+			first.EPSG,
 			bottleneck,
-			first.EPSG,
 			firstDate, secondDate,
-		).Scan(&clip); err != nil {
+		)
+		if err != nil {
 			return err
 		}
 
-		var clippingPolygon octree.Polygon
-		if err := clippingPolygon.FromWKB(clip); err != nil {
-			return err
-		}
-		clippingPolygon.Indexify()
-
 		now = time.Now()
 		log.Printf("loading clipping polygon took %v\n", now.Sub(last))
 		last = now
@@ -266,7 +244,7 @@
 		log.Printf("building STR tree took %v\n", now.Sub(last))
 		last = now
 
-		removed := str.Clip(&clippingPolygon)
+		removed := str.Clip(clippingPolygon)
 		now = time.Now()
 		log.Printf("clipping STR tree took %v\n", now.Sub(last))
 		last = now
--- a/pkg/controllers/diff.go	Mon Mar 11 14:18:14 2019 +0100
+++ b/pkg/controllers/diff.go	Mon Mar 11 14:36:34 2019 +0100
@@ -18,6 +18,7 @@
 	"fmt"
 	"log"
 	"net/http"
+	"sync"
 	"time"
 
 	"golang.org/x/sync/semaphore"
@@ -103,14 +104,59 @@
 	points := minuendTree.Diff(subtrahendTree)
 	log.Printf("info: A - B took %v\n", time.Since(start))
 
-	start = time.Now()
-	var tri *octree.Triangulation
-	if tri, err = points.Triangulate(); err != nil {
+	// The Triangulation and the loading of the clipping
+	// polygon can be done concurrently.
+
+	jobs := make(chan func())
+
+	wg := new(sync.WaitGroup)
+	for i := 0; i < 2; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			for job := range jobs {
+				job()
+			}
+		}()
+	}
+
+	var (
+		tri     *octree.Triangulation
+		triErr  error
+		clip    *octree.Polygon
+		clipErr error
+	)
+
+	jobs <- func() {
+		start := time.Now()
+		tri, triErr = points.Triangulate()
+		log.Printf("info: triangulation took %v\n", time.Since(start))
+	}
+
+	jobs <- func() {
+		start := time.Now()
+		clip, clipErr = octree.LoadClippingPolygon(
+			ctx, conn,
+			minuendTree.EPSG,
+			dci.Bottleneck,
+			dci.Minuend.Time,
+			dci.Subtrahend.Time)
+		log.Printf("info: loading clipping polygon took %v\n", time.Since(start))
+	}
+	close(jobs)
+	wg.Wait()
+
+	switch {
+	case triErr != nil && clipErr != nil:
+		err = fmt.Errorf("%v %v", triErr, clipErr)
+		return
+	case triErr != nil:
+		err = triErr
+		return
+	case clipErr != nil:
+		err = clipErr
 		return
 	}
-	log.Printf("triangulation took %v\n", time.Since(start))
-
-	_ = tri
 
 	// TODO: Implement me!
 
--- a/pkg/octree/polygon.go	Mon Mar 11 14:18:14 2019 +0100
+++ b/pkg/octree/polygon.go	Mon Mar 11 14:36:34 2019 +0100
@@ -15,10 +15,13 @@
 
 import (
 	"bytes"
+	"context"
+	"database/sql"
 	"encoding/binary"
 	"fmt"
 	"log"
 	"math"
+	"time"
 
 	"github.com/tidwall/rtree"
 
@@ -29,9 +32,7 @@
 	ring []float64
 
 	Polygon struct {
-		// TODO: Implement me!
-		rings []ring
-
+		rings   []ring
 		indices []*rtree.RTree
 	}
 
@@ -41,11 +42,57 @@
 )
 
 const (
+	clippingPolygonSQL = `
+WITH joined AS (
+  SELECT
+    sr.area      AS area,
+    sr.date_info AS date_info
+  FROM waterway.sounding_results sr JOIN
+     waterway.bottlenecks bn ON sr.bottleneck_id = bn.id
+  WHERE bn.bottleneck_id = $1
+)
+SELECT ST_AsBinary(
+  ST_intersection(
+    (SELECT ST_Transform(area::geometry, $2::int) FROM joined WHERE date_info = $3::date),
+    (SELECT ST_Transform(area::geometry, $2::int) FROM joined WHERE date_info = $4::date)
+  )
+  ) AS area
+`
+)
+
+const (
 	IntersectionInside IntersectionType = iota
 	IntersectionOutSide
 	IntersectionOverlaps
 )
 
+func LoadClippingPolygon(
+	ctx context.Context,
+	conn *sql.Conn,
+	epsg uint32,
+	bottleneck string,
+	first, second time.Time,
+) (*Polygon, error) {
+
+	var clip []byte
+
+	if err := conn.QueryRowContext(
+		ctx, clippingPolygonSQL,
+		bottleneck,
+		epsg,
+		first, second,
+	).Scan(&clip); err != nil {
+		return nil, err
+	}
+
+	var polygon Polygon
+	if err := polygon.FromWKB(clip); err != nil {
+		return nil, err
+	}
+	polygon.Indexify()
+	return &polygon, nil
+}
+
 func (ls lineSegment) Rect(interface{}) ([]float64, []float64) {
 
 	var min, max [2]float64