Skip to content

Instantly share code, notes, and snippets.

@chrispahm
Created December 4, 2017 20:54
Show Gist options
  • Save chrispahm/8fcdd7a20ab03d226c9e4e5f60b8d68e to your computer and use it in GitHub Desktop.
Save chrispahm/8fcdd7a20ab03d226c9e4e5f60b8d68e to your computer and use it in GitHub Desktop.
/*
Vorgewende
API Methods
lineString (poly, (angle), (distance)) - Returns array consisting of a GeoJSON lineString for each headland for the given field
Polygon (poly, workingWidth, (angle), (distance))- Returns an array consisting of a GeoJSON Polygon for each headland using the working width as its width for the given field
*/
const GJV = require("geojson-validation")
const turf = require('@turf/turf')
module.exports = {
lineString: function (poly, angle = 30, distance = 10) {
//console.log(angle)
// Will contain all headland LineStrings as features
let headlands = []
// first validate if polygon matches GeoJSON prerequisites
GJV.isPolygon(poly.geometry, function(valid, err) {
if (!valid) {
throw "Invalid Polygon, " + err
}
const coords = turf.getCoords(poly)[0]
// Start with first two coordinates in order to create an initial path
let curLineString = [coords[0], coords[1]]
// Get angle between the starting coordinates as a reference
let refAngle = angleCoords(coords[0],coords[1])
let j = 1
let uncertainPolys = []
let curAngle, curDistance, angleDiff
for (var i = 2; i < coords.length; i++) {
curAngle = angleCoords(coords[i-j],coords[i])
curDistance = turf.distance(turf.point(coords[i-j]), turf.point(coords[i])) * 1000
angleDiff = angleBetCoords(refAngle, curAngle)
}
if (angleDiff <= angle && angleDiff >= -angle) {
curLineString.push(coords[i])
refAngle = curAngle
}
else {
headlands.push(turf.lineString(curLineString))
curLineString = [coords[i-1], coords[i]]
refAngle = curAngle
}
}
// Join headland LineStrings if first and last coordinates are equal,
// as in this case the headland was drawn from the "middle" of the headland
let finalAngle = angleBetCoords(angleCoords(coords[0],coords[1]), curAngle)
if (finalAngle <= angle && finalAngle >= -angle) {
headlandPartA = curLineString
headlandPartB = turf.getCoords(headlands[0])
headlandConcat = headlandPartA.concat(headlandPartB)
headlands[0] = turf.lineString(headlandConcat)
}
// Push the last headland into the array if the headlands are not connected
else {
headlands.push(turf.lineString(curLineString))
}
})
return headlands
}
}
function angleCoords(p1,p2) {
return Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180 / Math.PI
}
function angleBetCoords(a,b) {
let difference = a - (b)
if (difference < - 180) difference += 360
else if (difference > 180) difference -= 360
return difference
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment