public static Feature Along(LineString line, double distance, string units = "kilometers") { var coords = line.Coordinates; double travelled = 0; for (var i = 0; i < coords.Count; i++) { if (distance >= travelled && i == coords.Count - 1) { break; } else if (travelled >= distance) { var overshot = distance - travelled; if (Math.Abs(overshot) < double.Epsilon) { return(Turf.Point(coords[i])); } else { var direction = Turf.Bearing(coords[i], coords[i - 1]) - 180; var interpolated = Turf.Destination(coords[i], overshot, direction, units); return(interpolated); } } else { travelled += Turf.Distance(coords[i], coords[i + 1], units); } } return(Turf.Point(coords[coords.Count - 1])); }
/** * Takes a {@link Feature} or {@link FeatureCollection} and returns the absolute center point of all features. * * @name center * @param {(Feature|FeatureCollection)} layer input features * @return {Feature<Point>} a Point feature at the absolute center point of all input features * @example * var features = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.522259, 35.4691] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.502754, 35.463455] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.508269, 35.463245] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.516809, 35.465779] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.515372, 35.467072] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.509363, 35.463053] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.511123, 35.466601] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.518547, 35.469327] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.519706, 35.469659] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.517839, 35.466998] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.508678, 35.464942] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-97.514914, 35.463453] * } * } * ] * }; * * var centerPt = turf.center(features); * centerPt.properties['marker-size'] = 'large'; * centerPt.properties['marker-color'] = '#000'; * * var resultFeatures = features.features.concat(centerPt); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ public static Feature Center(IGeoJSONObject layer) { var ext = Bbox(layer); var x = (ext[0] + ext[2]) / 2; var y = (ext[1] + ext[3]) / 2; return(Turf.Point(new double[] { x, y })); }
/** * Takes a feature or set of features and returns all positions as * {@link Point|points}. * * @name explode * @param {(Feature|FeatureCollection)} geojson input features * @return {FeatureCollection<point>} points representing the exploded input features * @throws {Error} if it encounters an unknown geometry type * @example * var poly = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [177.434692, -17.77517], * [177.402076, -17.779093], * [177.38079, -17.803937], * [177.40242, -17.826164], * [177.438468, -17.824857], * [177.454948, -17.796746], * [177.434692, -17.77517] * ]] * } * }; * * var points = turf.explode(poly); * * //=poly * * //=points */ public static FeatureCollection Explode(IGeoJSONObject geojson) { var points = new List <Feature>(); CoordEach(geojson, (GeographicPosition coord) => { points.Add(Turf.Point(coord)); }); return(new FeatureCollection(points)); }
/** * Takes one or more features and calculates the centroid using * the mean of all vertices. * This lessens the effect of small islands and artifacts when calculating * the centroid of a set of polygons. * * @name centroid * @param {(Feature|FeatureCollection)} features input features * @return {Feature<Point>} the centroid of the input features * @example * var poly = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [105.818939,21.004714], * [105.818939,21.061754], * [105.890007,21.061754], * [105.890007,21.004714], * [105.818939,21.004714] * ]] * } * }; * * var centroidPt = turf.centroid(poly); * * var result = { * "type": "FeatureCollection", * "features": [poly, centroidPt] * }; * * //=result */ public static Feature Centroid(IGeoJSONObject features) { double xSum = 0; double ySum = 0; int len = 0; Turf.CoordEach(features, (List <double> coord) => { xSum += coord[0]; ySum += coord[1]; len++; }, true); return(Turf.Point(new double[] { xSum / (double)len, ySum / (double)len })); }
private static Feature Destination(List <double> from, double distance, double bearing, string units = "kilometers") { var degrees2radians = Math.PI / 180; var radians2degrees = 180 / Math.PI; var coordinates1 = Turf.GetCoord(from); var longitude1 = degrees2radians * coordinates1[0]; var latitude1 = degrees2radians * coordinates1[1]; var bearing_rad = degrees2radians * bearing; var radians = Turf.DistanceToRadians(distance, units); var latitude2 = Math.Asin(Math.Sin(latitude1) * Math.Cos(radians) + Math.Cos(latitude1) * Math.Sin(radians) * Math.Cos(bearing_rad)); var longitude2 = longitude1 + Math.Atan2(Math.Sin(bearing_rad) * Math.Sin(radians) * Math.Cos(latitude1), Math.Cos(radians) - Math.Sin(latitude1) * Math.Sin(latitude2)); return(Turf.Point(new double[] { radians2degrees *longitude2, radians2degrees *latitude2 })); }