Skip to content

Commit

Permalink
remove gospline & rewrite predictNextPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
efremropelato committed Nov 5, 2024
1 parent 36db6d9 commit db63ce7
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ require (

require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cnkei/gospline v0.0.0-20191204052713-d67fac29a294
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
Expand Down
65 changes: 51 additions & 14 deletions pkg/functions/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ package functions
import (
"fmt"
"math"
"os"

"github.com/cnkei/gospline"
"github.com/jrnd-io/jr/pkg/ctx"
)

Expand Down Expand Up @@ -234,12 +232,12 @@ func isPointInPolygon(point []float64, vertices [][]float64) bool {

// predictNextPoint predicts the next latitude and longitude using cubic spline interpolation
func predictNextPoint(latitudes, longitudes []float64) (float64, float64) {
if len(longitudes) != len(latitudes) {
if len(latitudes) != len(longitudes) {
println("Need at least two points and matching latitude/longitude arrays: latitudes: ", len(latitudes), " e longitudes:", len(longitudes))
os.Exit(1)
return 0, 0
}

if len(latitudes) < 2 && len(longitudes) < 2 {
if len(latitudes) < 2 || len(longitudes) < 2 {
fmt.Println("Need at least two points !")
return 0, 0
}
Expand All @@ -250,20 +248,59 @@ func predictNextPoint(latitudes, longitudes []float64) (float64, float64) {
x[i] = float64(i)
}

// Create splines for latitude and longitude
latSpline := gospline.NewCubicSpline(x, latitudes)
lonSpline := gospline.NewCubicSpline(x, longitudes)

// Predict the next index position (next point in the sequence)
// Implement cubic spline interpolation
nextX := float64(len(latitudes))

// Interpolate to get the predicted latitude and longitude for nextX
nextLatitude := latSpline.At(nextX)
nextLongitude := lonSpline.At(nextX)
nextLatitude := cubicSplineInterpolate(x, latitudes, nextX)
nextLongitude := cubicSplineInterpolate(x, longitudes, nextX)

return nextLatitude, nextLongitude
}

func cubicSplineInterpolate(x, y []float64, nextX float64) float64 {
n := len(x)
h := make([]float64, n)
a := make([]float64, n)
b := make([]float64, n)
c := make([]float64, n)
d := make([]float64, n)

// Calculate the coefficients for the cubic spline
for i := 1; i < n; i++ {
h[i-1] = x[i] - x[i-1]
a[i] = (y[i] - y[i-1]) / h[i-1]
}

b[0] = 0
for i := 1; i < n-1; i++ {
b[i] = 3 * (a[i+1] - a[i])
}
b[n-1] = 0

c[0] = 0
for i := 1; i < n-1; i++ {
c[i] = (b[i] - c[i-1]) / (2 * h[i-1])
}
c[n-1] = 0

d[0] = 0
for i := 1; i < n; i++ {
d[i-1] = (a[i] - c[i-1]) / h[i-1]
}

// Interpolate the value at the next X
index := 0
for i := 1; i < n; i++ {
if x[i] <= nextX {
index = i
} else {
break
}
}

dx := nextX - x[index-1]
return y[index-1] + d[index-1]*dx + c[index-1]*dx*dx + b[index-1]*dx*dx*dx
}

// selectRandomPoint selects a random point within the polygon defined by the given coordinates.
func selectRandomPoint(coords [][]float64) (float64, float64) {
if len(coords) == 0 {
Expand Down
2 changes: 1 addition & 1 deletion pkg/functions/functionsDescription.go
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ var funcDesc = map[string]FunctionDescription{
Parameters: "string",
Localizable: false,
Return: "string",
Example: `jr template run --embedded '{{nearby_gps_into_polygon 10}}' --geojson testfiles/poligon.geojson`,
Example: `jr template run --embedded '{{nearby_gps_into_polygon_without_start 10}}' --geojson testfiles/poligon.geojson`,
Output: "41.8963 12.4975",
},
"now_add": {
Expand Down

0 comments on commit db63ce7

Please sign in to comment.