Skip to content

Commit

Permalink
WIP add point on feature
Browse files Browse the repository at this point in the history
  • Loading branch information
kgiann78 committed Dec 2, 2021
1 parent b72f3ef commit 3462a34
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions measurement/measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,3 +681,109 @@ func calculateRhumbDestination(origin []float64, distance float64, bearing float
// normalise to -180...+180
return []float64{(math.Mod(((λ2*180.0)/math.Pi+540), 360) - 180.0), (φ2 * 180.0) / math.Pi}
}

// PointOnFeature takes a Feature and returns a point guaranteed to be on the surface of the feature.
func PointOnFeature(f feature.Feature, properties map[string]interface{}, id string) (*geometry.Point, error) {
fs := []feature.Feature{}
fs = append(fs, f)
fc, err := feature.NewFeatureCollection(fs)
if err != nil {
return nil, err
}
return PointOnFeatureCollection(*fc, properties, id)
}

// PointOnFeatureCollection gets a feature collection and returns a point guaranteed to be on the surface of the feature.
func PointOnFeatureCollection(fc feature.Collection, properties map[string]interface{}, id string) (*geometry.Point, error) {
centroid, err := CentroidFeatureCollection(fc, properties, id)
if err != nil {
return nil, err
}
cent, err := centroid.ToPoint()
var onSurface = false

for i := 0; !onSurface && i < len(fc.Features); i++ {
var geom = fc.Features[i].Geometry
onSurface = pointOnFeatureCollection(geom, *cent)
}

return cent, nil
}

func pointOnFeatureCollection(t interface{}, cent geometry.Point) bool {
var x, y, x1, y1, x2, y2 float64
var onBorderOrPoint = false
var onSurface = false

switch gtp := t.(type) {
case geometry.Point:
if cent.Lat == gtp.Lat && cent.Lng == gtp.Lng {
onSurface = true
}
case []geometry.Point:
var onMultiPoint = false

for k := 0; !onMultiPoint && k < len(gtp); k++ {
if cent.Lat == gtp[k].Lat && cent.Lng == gtp[k].Lng {
onSurface = true
onMultiPoint = true
}
}

onBorderOrPoint = onMultiPoint
case geometry.LineString:
for k := 0; !onBorderOrPoint && k < (len(gtp.Coordinates) - 1); k++ {
x = cent.Lat
y = cent.Lng
x1 = gtp.Coordinates[k].Lat
y1 = gtp.Coordinates[k].Lng
x2 = gtp.Coordinates[k + 1].Lat
y2 = gtp.Coordinates[k + 1].Lng
if pointOnSegment(x, y, x1, y1, x2, y2) {
onBorderOrPoint = true
onSurface = true
}
}
case geometry.MultiLineString:
for j:= 0; j < len(gtp.Coordinates); j++ {
onBorderOrPoint = false
var line = gtp.Coordinates[j];
for k := 0; !onBorderOrPoint && k < len(line.Coordinates) - 1; k++ {
x = cent.Lat
y = cent.Lng
x1 = line.Coordinates[k].Lat;
y1 = line.Coordinates[k].Lng;
x2 = line.Coordinates[k + 1].Lat;
y2 = line.Coordinates[k + 1].Lng;
if pointOnSegment(x, y, x1, y1, x2, y2) {
onBorderOrPoint = true
onSurface = true
}
}
}
case geometry.Polygon:
for _, c := range gtp.Coordinates {
//todo: decide if cent is on surface
print(len(c.Coordinates))
}
onSurface = true
case geometry.MultiPolygon:
coords := gtp.Coordinates
for _, coord := range coords {
for _, pl := range coord.Coordinates {
//todo: decide if cent is on surface
print(len(pl.Coordinates))
}
}
onSurface = true
}

return onSurface || onBorderOrPoint
}

func pointOnSegment(x float64, y float64, x1 float64, y1 float64, x2 float64, y2 float64) bool {
var ab = math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
var ap = math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1))
var pb = math.Sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y))
return ab == (ap + pb)
}

0 comments on commit 3462a34

Please sign in to comment.