Beispiel #1
0
        /**
         * Takes a set of features, calculates the bbox of all input features, and returns a bounding box.
         *
         * @name bbox
         * @param {(Feature|FeatureCollection)} geojson input features
         * @return {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
         * @example
         * var pt1 = point([114.175329, 22.2524])
         * var pt2 = point([114.170007, 22.267969])
         * var pt3 = point([114.200649, 22.274641])
         * var pt4 = point([114.200649, 22.274641])
         * var pt5 = point([114.186744, 22.265745])
         * var features = featureCollection([pt1, pt2, pt3, pt4, pt5])
         *
         * var bbox = turf.bbox(features);
         *
         * var bboxPolygon = turf.bboxPolygon(bbox);
         *
         * //=bbox
         *
         * //=bboxPolygon
         */
        public static List <double> Bbox(IGeoJSONObject geojson)
        {
            var bbox = new List <double>()
            {
                double.PositiveInfinity, double.PositiveInfinity, double.NegativeInfinity, double.NegativeInfinity
            };

            Turf.CoordEach(geojson, (List <double> coord) => {
                if (bbox[0] > coord[0])
                {
                    bbox[0] = coord[0];
                }
                if (bbox[1] > coord[1])
                {
                    bbox[1] = coord[1];
                }
                if (bbox[2] < coord[0])
                {
                    bbox[2] = coord[0];
                }
                if (bbox[3] < coord[1])
                {
                    bbox[3] = coord[1];
                }
            });
            return(bbox);
        }
Beispiel #2
0
        static public void CoordEach(IGeoJSONObject layer, Action <GeographicPosition> callback, bool excludeWrapCoord = false)
        {
            var isFeatureCollection = layer.Type == GeoJSONObjectType.FeatureCollection;
            var isFeature           = layer.Type == GeoJSONObjectType.Feature;
            var stop = isFeatureCollection ? ((FeatureCollection)layer).Features.Count : 1;

            // This logic may look a little weird. The reason why it is that way
            // is because it's trying to be fast. GeoJSON supports multiple kinds
            // of objects at its root: FeatureCollection, Features, Geometries.
            // This function has the responsibility of handling all of them, and that
            // means that some of the `for` loops you see below actually just don't apply
            // to certain inputs. For instance, if you give this just a
            // Point geometry, then both loops are short-circuited and all we do
            // is gradually rename the input until it's called 'geometry'.
            //
            // This also aims to allocate as few resources as possible: just a
            // few numbers and booleans, rather than any temporary arrays as would
            // be required with the normalization approach.
            for (var i = 0; i < stop; i++)
            {
                var geometryMaybeCollection = isFeatureCollection ?
                                              (IGeometryObject)((FeatureCollection)layer).Features[i].Geometry :
                                              isFeature ? (IGeometryObject)((Feature)layer).Geometry :
                                              (IGeometryObject)layer;
                CoordEach(geometryMaybeCollection, callback, excludeWrapCoord);
            }
        }
Beispiel #3
0
        /**
         * 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 }));
        }
Beispiel #4
0
        /**
         * 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));
        }
Beispiel #5
0
        /**
         * Reduce coordinates in any GeoJSON object into a single value,
         * similar to how Array.reduce works. However, in this case we lazily run
         * the reduction, so an array of all coordinates is unnecessary.
         *
         * @name coordReduce
         * @param {Object} layer any GeoJSON object
         * @param {Function} callback a method that takes (memo, value) and returns
         * a new memo
         * @param {*} memo the starting value of memo: can be any type.
         * @param {boolean=} excludeWrapCoord whether or not to include
         * the final coordinate of LinearRings that wraps the ring in its iteration.
         * @returns {*} combined value
         */
        static public object CoordReduce(IGeoJSONObject layer, Func <object, GeographicPosition, object> callback,
                                         object memo, bool excludeWrapCoord = false)
        {
            object ret = memo;
            Action <GeographicPosition> internal_cb = (GeographicPosition coord) => {
                ret = callback(ret, coord);
            };

            CoordEach(layer, internal_cb, excludeWrapCoord);
            return(ret);
        }
Beispiel #6
0
        /**
         * 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 }));
        }
Beispiel #7
0
        public void Parse_PointStringWithNameCrsExtraParameter_SuccessfulParse()
        {
            string         strGeometry   = "{\"type\": \"Point\",\"coordinates\": [-105.01621,39.57422], \"crs\": {\"type\": \"name\", \"properties\": {\"name\": \"urn:ogc:def:crs:OGC:1.3:CRS84\", \"extra\": [1, 0]}}}";
            IGeoJSONObject geoJsonObject = (IGeoJSONObject)JsonConvert.DeserializeObject <IGeometryObject>(strGeometry, new GeometryConverter());

            // Assert CRS is parsed
            Assert.AreEqual(CRSType.Name, geoJsonObject.CRS.Type);
            NamedCRS namedCrs = (NamedCRS)geoJsonObject.CRS;

            Assert.AreEqual("urn:ogc:def:crs:OGC:1.3:CRS84", namedCrs.Name);
            Assert.IsTrue(namedCrs.Properties.ContainsKey("extra"));
            Assert.IsNotNull(namedCrs.Properties["extra"]);
        }
        public bool UpdateSource(string sourceId, IGeoJSONObject featureCollection)
        {
            var source = mapStyle.SourceWithIdentifier(sourceId) as MGLShapeSource;

            if (source == null)
            {
                return(false);
            }

            source.Shape = featureCollection.ToShape();

            return(true);
        }
Beispiel #9
0
        /**
         * Takes a {@link LineString} or {@link Polygon} and measures its length in the specified units.
         *
         * @name lineDistance
         * @param {Feature<(LineString|Polygon)>|FeatureCollection<(LineString|Polygon)>} line line to measure
         * @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
         * @return {number} length of the input line
         * @example
         * var line = {
         *   "type": "Feature",
         *   "properties": {},
         *   "geometry": {
         *     "type": "LineString",
         *     "coordinates": [
         *       [-77.031669, 38.878605],
         *       [-77.029609, 38.881946],
         *       [-77.020339, 38.884084],
         *       [-77.025661, 38.885821],
         *       [-77.021884, 38.889563],
         *       [-77.019824, 38.892368]
         *     ]
         *   }
         * };
         *
         * var length = turf.lineDistance(line, 'miles');
         *
         * //=line
         *
         * //=length
         */
        public static double LineDistance(IGeoJSONObject line, string units = "kilometers")
        {
            if (line.Type == GeoJSONObjectType.FeatureCollection)
            {
                return(((FeatureCollection)line).Features.Aggregate(0, (double memo, Feature feature) => {
                    return memo + LineDistance(feature);
                }));
            }

            var geometry = line.Type == GeoJSONObjectType.Feature ? ((Feature)line).Geometry : (IGeometryObject)line;

            if (geometry.Type == GeoJSONObjectType.LineString)
            {
                return(Length(((LineString)geometry).Coordinates, units));
            }
            else if (geometry.Type == GeoJSONObjectType.Polygon || geometry.Type == GeoJSONObjectType.MultiLineString)
            {
                double d     = 0;
                var    lines = geometry.Type == GeoJSONObjectType.Polygon ?
                               ((Polygon)geometry).Coordinates : ((MultiLineString)geometry).Coordinates;
                for (var i = 0; i < lines.Count; i++)
                {
                    var points = ((LineString)lines[i]).Coordinates;
                    d += Length(points, units);
                }
                return(d);
            }
            else if (geometry.Type == GeoJSONObjectType.MultiPolygon)
            {
                double d        = 0;
                var    polygons = ((MultiPolygon)geometry).Coordinates;
                for (var i = 0; i < polygons.Count; i++)
                {
                    var lines = ((Polygon)polygons[i]).Coordinates;
                    for (var j = 0; j < lines.Count; j++)
                    {
                        var points = ((LineString)lines[j]).Coordinates;
                        d += Length(points, units);
                    }
                }
                return(d);
            }
            else
            {
                throw new Exception("input must be a LineString, MultiLineString, " +
                                    "Polygon, or MultiPolygon Feature or Geometry (or a FeatureCollection " +
                                    "containing only those types)");
            }
        }
Beispiel #10
0
 /**
  * Iterate over property objects in any GeoJSON object, similar to
  * Array.forEach.
  *
  * @name propEach
  * @param {Object} layer any GeoJSON object
  * @param {Function} callback a method that takes (value)
  * @example
  * var point = { type: 'Feature', geometry: null, properties: { foo: 1 } };
  * propEach(point, function(props) {
  *   // props is equal to { foo: 1}
  * });
  */
 static public void PropEach(IGeoJSONObject layer, Action <Dictionary <string, object>, int> callback)
 {
     if (layer.Type == GeoJSONObjectType.FeatureCollection)
     {
         for (var i = 0; i < ((FeatureCollection)layer).Features.Count; i++)
         {
             callback(((FeatureCollection)layer).Features[i].Properties, i);
         }
     }
     else if (layer.Type == GeoJSONObjectType.Feature)
     {
         callback(((Feature)layer).Properties, 0);
     }
     else
     {
         throw new Exception("Feature or FeatureCollection must be given");
     }
 }
Beispiel #11
0
        public void Parse_PointStringWithLinkCrs_SuccessfulParse()
        {
            string         strGeometry   = "{\"type\": \"Point\",\"coordinates\": [-105.01621,39.57422], \"crs\": {\"type\": \"link\", \"properties\": { \"href\": \"http://example.com/crs/42\", \"type\": \"proj4\"}}}";
            IGeoJSONObject geoJsonObject = (IGeoJSONObject)JsonConvert.DeserializeObject <IGeometryObject>(strGeometry, new GeometryConverter());

            // Assert CRS is parsed
            Assert.AreEqual(CRSType.Link, geoJsonObject.CRS.Type);
            LinkedCRS linkedCrs = (LinkedCRS)geoJsonObject.CRS;

            Assert.AreEqual("http://example.com/crs/42", linkedCrs.Href);
            Assert.AreEqual("proj4", linkedCrs.Properties["type"]);


            // Deserialization without specifying Converter
            Point point = JsonConvert.DeserializeObject <Point>(strGeometry);

            // Assert CRS is parsed
            Assert.AreEqual(CRSType.Link, point.CRS.Type);
            linkedCrs = (LinkedCRS)point.CRS;
            Assert.AreEqual("http://example.com/crs/42", linkedCrs.Href);
            Assert.AreEqual("proj4", linkedCrs.Properties["type"]);
        }
Beispiel #12
0
        public void Parse_PointStringWithNameCrs_SuccessfulParse()
        {
            string strGeometry = "{\"type\": \"Point\",\"coordinates\": [-105.01621,39.57422], \"crs\": {\"type\": \"name\", \"properties\": {\"name\": \"urn:ogc:def:crs:OGC:1.3:CRS84\"}}}";

            IGeometryObject geometryObject = JsonConvert.DeserializeObject <IGeometryObject>(strGeometry, new GeometryConverter());
            IGeoJSONObject  geoJsonObject  = (IGeoJSONObject)geometryObject;

            // Assert CRS is parsed
            Assert.AreEqual(CRSType.Name, geoJsonObject.CRS.Type);
            NamedCRS namedCrs = (NamedCRS)geoJsonObject.CRS;

            Assert.AreEqual("urn:ogc:def:crs:OGC:1.3:CRS84", namedCrs.Name);



            // Deserialization without specifying Converter
            Point point = JsonConvert.DeserializeObject <Point>(strGeometry);

            // Assert CRS is parsed
            Assert.AreEqual(CRSType.Name, point.CRS.Type);
            namedCrs = (NamedCRS)point.CRS;
            Assert.AreEqual("urn:ogc:def:crs:OGC:1.3:CRS84", namedCrs.Name);
        }
        public bool UpdateSource(string sourceId, IGeoJSONObject geoJsonObject)
        {
            var source = mapStyle.GetSource(sourceId) as Com.Mapbox.Mapboxsdk.Style.Sources.GeoJsonSource;

            if (source == null)
            {
                return(false);
            }

            var json = JsonConvert.SerializeObject(geoJsonObject);

            switch (geoJsonObject)
            {
            case GeoJSON.Net.Feature.Feature feature:
                source.SetGeoJson(Feature.FromJson(json));
                break;

            default:
                source.SetGeoJson(FeatureCollection.FromJson(json));
                break;
            }

            return(true);
        }
Beispiel #14
0
 int INpgsqlTypeHandler <IGeoJSONObject> .ValidateAndGetLength(IGeoJSONObject value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter)
 => ValidateAndGetLength((GeoJSONObject)value, ref lengthCache, parameter);
Beispiel #15
0
 public GeoJsonSource(string id, IGeoJSONObject data)
 {
     Id   = id;
     Data = data;
 }
Beispiel #16
0
 /**
  * Takes any number of features and returns a rectangular {@link Polygon} that encompasses all vertices.
  *
  * @name envelope
  * @param {(Feature|FeatureCollection)} features input features
  * @return {Feature<Polygon>} a rectangular Polygon feature that encompasses all vertices
  * @example
  * var fc = {
  *   "type": "FeatureCollection",
  *   "features": [
  *     {
  *       "type": "Feature",
  *       "properties": {
  *         "name": "Location A"
  *       },
  *       "geometry": {
  *         "type": "Point",
  *         "coordinates": [-75.343, 39.984]
  *       }
  *     }, {
  *       "type": "Feature",
  *       "properties": {
  *         "name": "Location B"
  *       },
  *       "geometry": {
  *         "type": "Point",
  *         "coordinates": [-75.833, 39.284]
  *       }
  *     }, {
  *       "type": "Feature",
  *       "properties": {
  *         "name": "Location C"
  *       },
  *       "geometry": {
  *         "type": "Point",
  *         "coordinates": [-75.534, 39.123]
  *       }
  *     }
  *   ]
  * };
  *
  * var enveloped = turf.envelope(fc);
  *
  * var resultFeatures = fc.features.concat(enveloped);
  * var result = {
  *   "type": "FeatureCollection",
  *   "features": resultFeatures
  * };
  *
  * //=result
  */
 public static Feature Envelope(IGeoJSONObject features)
 {
     return(BboxPolygon(Bbox(features)));
 }
Beispiel #17
0
 Task INpgsqlTypeHandler <IGeoJSONObject> .Write(IGeoJSONObject value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
 => Write((GeoJSONObject)value, buf, lengthCache, parameter, async);
Beispiel #18
0
 /**
  * Iterate over coordinates in any GeoJSON object, similar to
  * Array.forEach.
  *
  * @name coordEach
  * @param {Object} layer any GeoJSON object
  * @param {Function} callback a method that takes (value)
  * @param {boolean=} excludeWrapCoord whether or not to include
  * the final coordinate of LinearRings that wraps the ring in its iteration.
  * @example
  * var point = { type: 'Point', coordinates: [0, 0] };
  * coordEach(point, function(coords) {
  *   // coords is equal to [0, 0]
  * });
  */
 static public void CoordEach(IGeoJSONObject layer, Action <List <double> > callback, bool excludeWrapCoord = false)
 {
     CoordEach(layer, (GeographicPosition obj) => { callback(GetCoord(obj)); }, excludeWrapCoord);
 }