Skip to content

Commit

Permalink
feat: add multi goroutine for Predict
Browse files Browse the repository at this point in the history
  • Loading branch information
lvisei committed Dec 9, 2020
1 parent a793df1 commit 7a7a04d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

[![GoDoc](https://godoc.org/github.com/liuvigongzuoshi/go-kriging?status.svg)](https://godoc.org/github.com/liuvigongzuoshi/go-kriging)

Golang library for geospatial prediction and mapping via ordinary kriging
Golang Multi-Goroutines spatial interpolation algorithm library for geospatial prediction and mapping via ordinary kriging
1 change: 1 addition & 0 deletions examples/csv/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func readCsvFile(filePath string) (map[string][]float64, error) {
data := map[string][]float64{"values": values, "x": lons, "y": lats}

//fmt.Printf("values %#v\n lons %#v\n lats %#v\n", values, lons, lats)
// writeFile("data.json", data)

return data, nil
}
Expand Down
70 changes: 50 additions & 20 deletions ordinary/ordinary.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"image/color"
"math"
"sort"
"sync"

"github.com/liuvigongzuoshi/go-kriging/canvas"
)
Expand Down Expand Up @@ -255,6 +256,8 @@ func (variogram *Variogram) Variance(x, y float64) {

// Grid gridded matrices or contour paths
// 根据 PolygonCoordinates 生成裁剪过的矩阵网格数据
// 这里 polygon 是一个三维数组,可以变相的支持的多个面,但不符合 Polygon 规范
// PolygonCoordinates [[[x,y]],[[x,y]]] 两个面
func (variogram *Variogram) Grid(polygon PolygonCoordinates, width float64) *GridMatrices {
n := len(polygon)
if n == 0 {
Expand Down Expand Up @@ -285,54 +288,81 @@ func (variogram *Variogram) Grid(polygon PolygonCoordinates, width float64) *Gri
}

// Alloc for O(N^2) space
var a, b [2]int
var lxlim [2]float64 // Local dimensions
var lylim [2]float64 // Local dimensions
x := int(math.Ceil((xlim[1] - xlim[0]) / width))
y := int(math.Ceil((ylim[1] - ylim[0]) / width))

A := make([][]float64, x+1)
for i := 0; i <= x; i++ {
A[i] = make([]float64, y+1)
}

for i := 0; i < n; i++ {
// Range for polygon[i]
lxlim[0] = polygon[i][0][0]
currentPolygon := polygon[i]
var lxlim [2]float64 // Local dimensions
var lylim [2]float64 // Local dimensions
// Range for currentPolygon
lxlim[0] = currentPolygon[0][0]
lxlim[1] = lxlim[0]
lylim[0] = polygon[i][0][1]
lylim[0] = currentPolygon[0][1]
lylim[1] = lylim[0]
for j := 1; j < len(polygon[i]); j++ { // Vertices
if polygon[i][j][0] < lxlim[0] {
lxlim[0] = polygon[i][j][0]
for j := 1; j < len(currentPolygon); j++ { // Vertices
if currentPolygon[j][0] < lxlim[0] {
lxlim[0] = currentPolygon[j][0]
}
if polygon[i][j][0] > lxlim[1] {
lxlim[1] = polygon[i][j][0]
if currentPolygon[j][0] > lxlim[1] {
lxlim[1] = currentPolygon[j][0]
}
if polygon[i][j][1] < lylim[0] {
lylim[0] = polygon[i][j][1]
if currentPolygon[j][1] < lylim[0] {
lylim[0] = currentPolygon[j][1]
}
if polygon[i][j][1] > lylim[1] {
lylim[1] = polygon[i][j][1]
if currentPolygon[j][1] > lylim[1] {
lylim[1] = currentPolygon[j][1]
}
}

var a, b [2]int
// Loop through polygon subspace
a[0] = int(math.Floor(((lxlim[0] - math.Mod(lxlim[0]-xlim[0], width)) - xlim[0]) / width))
a[1] = int(math.Ceil(((lxlim[1] - math.Mod(lxlim[1]-xlim[1], width)) - xlim[0]) / width))
b[0] = int(math.Floor(((lylim[0] - math.Mod(lylim[0]-ylim[0], width)) - ylim[0]) / width))
b[1] = int(math.Ceil(((lylim[1] - math.Mod(lylim[1]-ylim[1], width)) - ylim[0]) / width))

var wg sync.WaitGroup
predictCh := make(chan *PredictDate, (b[1]-b[0])*(a[1]-a[0]))
var parallel = func(j, k int, polygon []Point, xTarget, yTarget float64) {
predictDate := &PredictDate{X: j, Y: k}
if pipFloat64(polygon, xTarget, yTarget) {
predictDate.Value = variogram.Predict(xTarget,
yTarget,
)
predictCh <- predictDate
}
defer wg.Done()
}

var xTarget, yTarget float64
for j := a[0]; j <= a[1]; j++ {
xTarget = xlim[0] + float64(j)*width
for k := b[0]; k <= b[1]; k++ {
yTarget = ylim[0] + float64(k)*width
if pipFloat64(polygon[i], xTarget, yTarget) {
A[j][k] = variogram.Predict(xTarget,
yTarget,
)
}
wg.Add(1)
go parallel(j, k, currentPolygon, xTarget, yTarget)
}
}

go func() {
wg.Wait()
close(predictCh)
}()

for predictDate := range predictCh {
if predictDate.Value != 0 {
j := predictDate.X
k := predictDate.Y
A[j][k] = predictDate.Value
}

}
}

gridMatrices := &GridMatrices{
Expand Down
6 changes: 6 additions & 0 deletions ordinary/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,9 @@ type GridLevelColor struct {
Value [2]float64 `json:"value"` // 值区间 [0, 5]
Color color.RGBA `json:"color"` // RGBA颜色 {255, 255, 255, 255}
}

type PredictDate struct {
X int
Y int
Value float64
}

0 comments on commit 7a7a04d

Please sign in to comment.