/// <summary> /// Creates a new MapCSS object with a geometry object. /// </summary> /// <param name="feature"></param> public MapCSSObject(Feature feature) { if (feature == null) throw new ArgumentNullException(); this.Feature = feature; if (!(this.Feature.Geometry is LineairRing || this.Feature.Geometry is Polygon || this.Feature.Geometry is MultiPolygon || this.Feature.Geometry is LineString)) { throw new Exception("Invalid MapCSS type."); } }
public void TestFeatureCollectionSerialization() { var geometry = new Point(new GeoCoordinate(0, 1)); var feature1 = new Feature(geometry); var feature2 = new Feature(geometry, new SimpleGeometryAttributeCollection(new GeometryAttribute[] { new GeometryAttribute() { Key = "key1", Value = "value1" } })); var featureCollection = new FeatureCollection(new Feature[] { feature1, feature2 }); var serialized = featureCollection.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"FeatureCollection\",\"features\":[" + "{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1.0,0.0]}}," + "{\"type\":\"Feature\",\"properties\":{\"key1\":\"value1\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1.0,0.0]}}" + "]}", serialized); }
/// <summary> /// Returns false if this mapcss interpreter does not contain an interpretation for an area with the given tags. /// </summary> /// <param name="tagsCollection"></param> /// <returns></returns> private bool AppliesToArea(TagsCollectionBase tagsCollection) { var feature = new Feature(new LineairRing(), new SimpleGeometryAttributeCollection(tagsCollection)); var rules = this.BuildRules(new MapCSSObject(feature)); return rules != null && rules.Count > 0; }
/// <summary> /// Resets this source. /// </summary> public void Reset() { _current = null; _source.Reset(); }
/// <summary> /// Moves to the next feature. /// </summary> /// <returns></returns> public bool MoveNext() { if(_currentEnumerator != null && _currentEnumerator.MoveNext()) { // there is still a current enumerator. _current = _currentEnumerator.Current; return true; } _currentEnumerator = null; while(_source.MoveNext()) { var features = _interpreter.Interpret(_source.Current()); if (features != null) { // an object was succesfully converted. _currentEnumerator = features.GetEnumerator(); if(_currentEnumerator.MoveNext()) { // move to first object in feature collection. _current = _currentEnumerator.Current; return true; } else { // an empty feature collection, try next one. _currentEnumerator.Dispose(); _currentEnumerator = null; } } } return false; }
/// <summary> /// Initializes this source. /// </summary> public void Initialize() { _source.Reset(); _source.Initialize(); _current = null; }
/// <summary> /// Closes this source. /// </summary> public void Close() { _current = null; }
/// <summary> /// Reads a gpx v1.1 object into corresponding geometries. /// </summary> /// <param name="gpx"></param> private void ReadGpxv1_1(IO.Xml.Gpx.v1_1.gpxType gpx) { this.FeatureCollection.Clear(); // do the waypoints. if (gpx.wpt != null) { // there are waypoints. foreach (var wpt in gpx.wpt) { var geometry = new Point( new GeoCoordinate((double)wpt.lat, (double)wpt.lon)); var point = new Feature(geometry); if (wpt.ageofdgpsdataSpecified) { point.Attributes.Add("ageofdgpsdata", wpt.ageofdgpsdata); } if (wpt.eleSpecified) { point.Attributes.Add("ele", wpt.ele); } if (wpt.fixSpecified) { point.Attributes.Add("fix", wpt.fix); } if (wpt.geoidheightSpecified) { point.Attributes.Add("geoidheight", wpt.geoidheight); } if (wpt.hdopSpecified) { point.Attributes.Add("hdop", wpt.hdop); } if (wpt.magvarSpecified) { point.Attributes.Add("magvar", wpt.magvar); } if (wpt.pdopSpecified) { point.Attributes.Add("pdop", wpt.pdop); } if (wpt.timeSpecified) { point.Attributes.Add("time", wpt.time); } if (wpt.vdopSpecified) { point.Attributes.Add("vdop", wpt.vdop); } if (wpt.cmt != null) { point.Attributes.Add("cmt", wpt.cmt); } if (wpt.desc != null) { point.Attributes.Add("desc", wpt.desc); } if (wpt.dgpsid != null) { point.Attributes.Add("dgpsid", wpt.dgpsid); } if (wpt.name != null) { point.Attributes.Add("name", wpt.name); } if (wpt.sat != null) { point.Attributes.Add("sat", wpt.sat); } if (wpt.src != null) { point.Attributes.Add("src", wpt.src); } if (wpt.sym != null) { point.Attributes.Add("sym", wpt.sym); } if (wpt.type != null) { point.Attributes.Add("type", wpt.type); } this.FeatureCollection.Add(point); } } // do the routes. if (gpx.rte != null) { foreach (var rte in gpx.rte) { // convert to a line-string var coordinates = new List<GeoCoordinate>(); foreach (var rtept in rte.rtept) { var coordinate = new GeoCoordinate((double)rtept.lat, (double)rtept.lon); coordinates.Add(coordinate); if (_createTrackPoints) { var geometry = new Point(coordinate); var point = new Feature(geometry); if (rtept.ageofdgpsdataSpecified) { point.Attributes.Add("ageofdgpsdata", rtept.ageofdgpsdata); } if (rtept.eleSpecified) { point.Attributes.Add("ele", rtept.ele); } if (rtept.fixSpecified) { point.Attributes.Add("fix", rtept.fix); } if (rtept.geoidheightSpecified) { point.Attributes.Add("geoidheight", rtept.geoidheight); } if (rtept.hdopSpecified) { point.Attributes.Add("hdop", rtept.hdop); } if (rtept.magvarSpecified) { point.Attributes.Add("magvar", rtept.magvar); } if (rtept.pdopSpecified) { point.Attributes.Add("pdop", rtept.pdop); } if (rtept.timeSpecified) { point.Attributes.Add("time", rtept.time); } if (rtept.vdopSpecified) { point.Attributes.Add("vdop", rtept.vdop); } if (rtept.cmt != null) { point.Attributes.Add("cmt", rtept.cmt); } if (rtept.desc != null) { point.Attributes.Add("desc", rtept.desc); } if (rtept.dgpsid != null) { point.Attributes.Add("dgpsid", rtept.dgpsid); } if (rtept.name != null) { point.Attributes.Add("name", rtept.name); } if (rtept.sat != null) { point.Attributes.Add("sat", rtept.sat); } if (rtept.src != null) { point.Attributes.Add("src", rtept.src); } if (rtept.sym != null) { point.Attributes.Add("sym", rtept.sym); } if (rtept.type != null) { point.Attributes.Add("type", rtept.type); } this.FeatureCollection.Add(point); } } // creates a new linestring. var lineString = new Feature(new LineString(coordinates)); if (rte.cmt != null) { lineString.Attributes.Add("cmt", rte.cmt); } if (rte.desc != null) { lineString.Attributes.Add("desc", rte.desc); } if (rte.name != null) { lineString.Attributes.Add("name", rte.name); } if (rte.number != null) { lineString.Attributes.Add("number", rte.number); } if (rte.src != null) { lineString.Attributes.Add("src", rte.src); } this.FeatureCollection.Add(lineString); } } // do the tracks. foreach (var trk in gpx.trk) { // convert to a line-string var coordinates = new List<GeoCoordinate>(); foreach (var trkseg in trk.trkseg) { foreach (var wpt in trkseg.trkpt) { var coordinate = new GeoCoordinate((double)wpt.lat, (double)wpt.lon); // only add new coordinates. if (coordinates.Count == 0 || coordinates[coordinates.Count - 1] != coordinate) { coordinates.Add(coordinate); } if (_createTrackPoints) { var point = new Feature(new Point(coordinate)); if (wpt.ageofdgpsdataSpecified) { point.Attributes.Add("ageofdgpsdata", wpt.ageofdgpsdata); } if (wpt.eleSpecified) { point.Attributes.Add("ele", wpt.ele); } if (wpt.fixSpecified) { point.Attributes.Add("fix", wpt.fix); } if (wpt.geoidheightSpecified) { point.Attributes.Add("geoidheight", wpt.geoidheight); } if (wpt.hdopSpecified) { point.Attributes.Add("hdop", wpt.hdop); } if (wpt.magvarSpecified) { point.Attributes.Add("magvar", wpt.magvar); } if (wpt.pdopSpecified) { point.Attributes.Add("pdop", wpt.pdop); } if (wpt.timeSpecified) { point.Attributes.Add("time", wpt.time); } if (wpt.vdopSpecified) { point.Attributes.Add("vdop", wpt.vdop); } if (wpt.cmt != null) { point.Attributes.Add("cmt", wpt.cmt); } if (wpt.desc != null) { point.Attributes.Add("desc", wpt.desc); } if (wpt.dgpsid != null) { point.Attributes.Add("dgpsid", wpt.dgpsid); } if (wpt.name != null) { point.Attributes.Add("name", wpt.name); } if (wpt.sat != null) { point.Attributes.Add("sat", wpt.sat); } if (wpt.src != null) { point.Attributes.Add("src", wpt.src); } if (wpt.sym != null) { point.Attributes.Add("sym", wpt.sym); } if (wpt.type != null) { point.Attributes.Add("type", wpt.type); } this.FeatureCollection.Add(point); } } } // creates a new linestring. var lineString = new Feature(new LineString(coordinates)); if (trk.cmt != null) { lineString.Attributes.Add("cmt", trk.cmt); } if (trk.desc != null) { lineString.Attributes.Add("desc", trk.desc); } if (trk.name != null) { lineString.Attributes.Add("name", trk.name); } if (trk.number != null) { lineString.Attributes.Add("number", trk.number); } if (trk.src != null) { lineString.Attributes.Add("src", trk.src); } this.FeatureCollection.Add(lineString); } }
/// <summary> /// Translates a lineair ring. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="feature"></param> private void TranslateLineairRing(Scene2D scene, IProjection projection, Feature feature) { var lineairRing = feature.Geometry as LineairRing; // build the rules. var rules = this.BuildRules(new MapCSSObject(feature)); // validate what's there. if (rules.Count == 0) { return; } // get x/y. double[] x = null, y = null; if (lineairRing.Coordinates != null && lineairRing.Coordinates.Count > 0) { // pre-calculate x/y. x = new double[lineairRing.Coordinates.Count]; y = new double[lineairRing.Coordinates.Count]; for (int idx = 0; idx < lineairRing.Coordinates.Count; idx++) { x[idx] = projection.LongitudeToX( lineairRing.Coordinates[idx].Longitude); y[idx] = projection.LatitudeToY( lineairRing.Coordinates[idx].Latitude); } // simplify. if (x.Length > 2) { double[][] simplified = SimplifyCurve.Simplify(new double[][] { x, y }, 0.0001); x = simplified[0]; y = simplified[1]; } } // add the z-index. foreach (var rule in rules) { float minZoom = (float)projection.ToZoomFactor(rule.MinZoom); float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom); int zIndex; if (!rule.TryGetProperty<int>("zIndex", out zIndex)) { zIndex = 0; } // interpret the results. if (x != null) { // there is a valid interpretation of this way. int color; int fillColor; if (rule.TryGetProperty("fillColor", out fillColor)) { // render as an area. float fillOpacity; if(rule.TryGetProperty("fillOpacity", out fillOpacity)) { SimpleColor simpleFillColor = new SimpleColor() { Value = fillColor }; fillColor = SimpleColor.FromArgb((int)(255 * fillOpacity), simpleFillColor.R, simpleFillColor.G, simpleFillColor.B).Value; } uint? pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true); if (rule.TryGetProperty("color", out color)) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false); } } } } } }
/// <summary> /// Adds the given feature. /// </summary> public void AddFeature(Feature feature, int color, float width, bool fill) { if (feature == null) { throw new ArgumentNullException(); } this.AddGeometry(feature.Geometry, color, width, fill); }
/// <summary> /// Tries to interpret a given multipolygon relation. /// </summary> /// <param name="relation"></param> /// <returns></returns> private Feature InterpretMultipolygonRelation(CompleteRelation relation) { Feature feature = null; if (relation.Members == null) { // the relation has no members. return feature; } // build lists of outer and inner ways. var ways = new List<KeyValuePair<bool, CompleteWay>>(); // outer=true foreach (var member in relation.Members) { if (member.Role == "inner" && member.Member is CompleteWay) { // an inner member. ways.Add(new KeyValuePair<bool, CompleteWay>( false, member.Member as CompleteWay)); } else if (member.Role == "outer" && member.Member is CompleteWay) { // an outer member. ways.Add(new KeyValuePair<bool, CompleteWay>( true, member.Member as CompleteWay)); } } // started a similar algorithm and then found this: // loosely based on: http://wiki.openstreetmap.org/wiki/Relation:multipolygon/Algorithm // recusively try to assign the rings. List<KeyValuePair<bool, LineairRing>> rings; if (!this.AssignRings(ways, out rings)) { OsmSharp.Logging.Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error, string.Format("Ring assignment failed: invalid multipolygon relation [{0}] detected!", relation.Id)); } // group the rings and create a multipolygon. var geometry = this.GroupRings(rings); if (geometry != null) { feature = new Feature(geometry, new SimpleGeometryAttributeCollection(relation.Tags)); } return feature; }
/// <summary> /// Interprets an OSM-object and returns the corresponding geometry. /// </summary> /// <param name="osmObject"></param> /// <returns></returns> public override FeatureCollection Interpret(ICompleteOsmGeo osmObject) { // DISCLAIMER: this is a very very very simple geometry interpreter and // contains hardcoded all relevant tags. var collection = new FeatureCollection(); TagsCollectionBase tags; if (osmObject != null) { switch (osmObject.Type) { case CompleteOsmType.Node: var newCollection = new TagsCollection( osmObject.Tags); newCollection.RemoveKey("FIXME"); newCollection.RemoveKey("node"); newCollection.RemoveKey("source"); if (newCollection.Count > 0) { // there is still some relevant information left. collection.Add(new Feature(new Point((osmObject as Node).Coordinate), new SimpleGeometryAttributeCollection(osmObject.Tags))); } break; case CompleteOsmType.Way: tags = osmObject.Tags; bool isArea = false; if ((tags.ContainsKey("building") && !tags.IsFalse("building")) || (tags.ContainsKey("landuse") && !tags.IsFalse("landuse")) || (tags.ContainsKey("amenity") && !tags.IsFalse("amenity")) || (tags.ContainsKey("harbour") && !tags.IsFalse("harbour")) || (tags.ContainsKey("historic") && !tags.IsFalse("historic")) || (tags.ContainsKey("leisure") && !tags.IsFalse("leisure")) || (tags.ContainsKey("man_made") && !tags.IsFalse("man_made")) || (tags.ContainsKey("military") && !tags.IsFalse("military")) || (tags.ContainsKey("natural") && !tags.IsFalse("natural")) || (tags.ContainsKey("office") && !tags.IsFalse("office")) || (tags.ContainsKey("place") && !tags.IsFalse("place")) || (tags.ContainsKey("power") && !tags.IsFalse("power")) || (tags.ContainsKey("public_transport") && !tags.IsFalse("public_transport")) || (tags.ContainsKey("shop") && !tags.IsFalse("shop")) || (tags.ContainsKey("sport") && !tags.IsFalse("sport")) || (tags.ContainsKey("tourism") && !tags.IsFalse("tourism")) || (tags.ContainsKey("waterway") && !tags.IsFalse("waterway")) || (tags.ContainsKey("wetland") && !tags.IsFalse("wetland")) || (tags.ContainsKey("water") && !tags.IsFalse("water")) || (tags.ContainsKey("aeroway") && !tags.IsFalse("aeroway"))) { // these tags usually indicate an area. isArea = true; } if (tags.IsTrue("area")) { // explicitly indicated that this is an area. isArea = true; } else if (tags.IsFalse("area")) { // explicitly indicated that this is not an area. isArea = false; } if (isArea) { // area tags leads to simple polygon var lineairRing = new Feature(new LineairRing((osmObject as CompleteWay).GetCoordinates().ToArray<GeoCoordinate>()), new SimpleGeometryAttributeCollection(tags)); collection.Add(lineairRing); } else { // no area tag leads to just a line. var lineString = new Feature(new LineString((osmObject as CompleteWay).GetCoordinates().ToArray<GeoCoordinate>()), new SimpleGeometryAttributeCollection(tags)); collection.Add(lineString); } break; case CompleteOsmType.Relation: var relation = (osmObject as CompleteRelation); tags = relation.Tags; string typeValue; if (tags.TryGetValue("type", out typeValue)) { // there is a type in this relation. if (typeValue == "multipolygon") { // this relation is a multipolygon. var feature = this.InterpretMultipolygonRelation(relation); if (feature != null) { // add the geometry. collection.Add(feature); } } else if (typeValue == "boundary") { // this relation is a boundary. } } break; } } return collection; }
/// <summary> /// Converts the given route to a line string. /// </summary> /// <returns></returns> public override FeatureCollection GetFeatures(Route route, RouteAggregationType aggregationType) { if (aggregationType == RouteAggregationType.All || aggregationType == RouteAggregationType.Modal) { // one mode, one LineString. var featureCollection = new FeatureCollection(); var coordinates = route.GetPoints(); if (coordinates.Count > 1) { var lineString = new LineString(coordinates.ToArray()); var attributes = new SimpleGeometryAttributeCollection(); attributes.Add("osmsharp:total_time", route.TotalTime.ToInvariantString()); attributes.Add("osmsharp:total_distance", route.TotalDistance.ToInvariantString()); var feature = new Feature(lineString, attributes); featureCollection.Add(feature); } return featureCollection; } else { // one LineString per instruction. var instructions = this.GetInstructions(route); var featureCollection = new FeatureCollection(); for (int i = 0; i < instructions.Count; i++) { var instruction = instructions[i]; var coordinates = new List<GeoCoordinate>(); for (int segmentIdx = instruction.FirstSegmentIdx; segmentIdx <= instruction.LastSegmentIdx; segmentIdx++) { coordinates.Add(new GeoCoordinate(route.Segments[segmentIdx].Latitude, route.Segments[segmentIdx].Longitude)); } // build attributes. var currentArcTags = instruction.MetaData; var attributesTable = new SimpleGeometryAttributeCollection(); if (currentArcTags != null) { // there are tags. foreach (var tag in currentArcTags) { if (tag.Value != null) { var t = tag.Value.GetType(); if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String)) { attributesTable.Add(tag.Key, tag.Value); } } } } // build feature. var lineString = new LineString(coordinates); featureCollection.Add(new Feature(lineString, attributesTable)); // build poi-features if any. if (instruction.Pois != null) { foreach (var poi in instruction.Pois) { // build attributes. var poiTags = poi.Tags; var poiAttributesTable = new SimpleGeometryAttributeCollection(); if (poiTags != null) { // there are tags. foreach (var tag in poiTags) { poiAttributesTable.Add(tag.Key, tag.Value); } } // build feature. var point = new Point(poi.Location); featureCollection.Add(new Feature(point, poiAttributesTable)); } } } return featureCollection; } }
/// <summary> /// Converts a point into an oms object. /// </summary> /// <param name="point"></param> /// <returns></returns> private static Feature ConvertPoint(OsmSharp.IO.Xml.Kml.v2_1.PointType point) { // convert the coordiantes. var coordinates = KmlFeatureStreamSource.ConvertCoordinates(point.coordinates); // create the point. var feature = new Feature(new Point(coordinates[0])); if (point.targetId != null) { feature.Attributes.Add("targetId", point.targetId); } feature.Attributes.Add("altitude", point.altitudeMode); if (point.extrude) { feature.Attributes.Add("extrude", point.extrude); } if (point.id != null) { feature.Attributes.Add("id", point.id); } return feature; }
/// <summary> /// Converts a line string into an osm object. /// </summary> /// <param name="lineString"></param> /// <returns></returns> private static Feature ConvertLineString(OsmSharp.IO.Xml.Kml.v2_1.LineStringType lineString) { // convert the coordinates. var coordinates = KmlFeatureStreamSource.ConvertCoordinates(lineString.coordinates); // create the ring. var feature = new Feature(new LineString(coordinates)); feature.Attributes.Add("id", lineString.id); return feature; }
/// <summary> /// Translates a multipolygon. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="multiPolygon"></param> private void TranslateMultiPolygon(Scene2D scene, IProjection projection, Feature multiPolygon) { foreach(var polygon in multiPolygon.Geometry as MultiPolygon) { this.TranslatePolygon(scene, projection, new Feature(polygon, multiPolygon.Attributes)); } }
/// <summary> /// Translates a polygon. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="polygon"></param> private void TranslatePolygon(Scene2D scene, IProjection projection, Feature polygon) { this.TranslateLineairRing(scene, projection, new Feature((polygon.Geometry as Polygon).Ring, polygon.Attributes)); }
public void TestFeatureSerialization() { // a feature with a point. var geometry = (Geometry)new Point(new GeoCoordinate(0, 1)); var feature = new Feature(geometry); var serialized = feature.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1.0,0.0]}}", serialized); feature = new Feature(geometry, new SimpleGeometryAttributeCollection(new GeometryAttribute[] { new GeometryAttribute() { Key = "key1", Value = "value1" } })); serialized = feature.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{\"key1\":\"value1\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1.0,0.0]}}", serialized); // a feature with a linestring. geometry = new LineString( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0) }); feature = new Feature(geometry); serialized = feature.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]]}}", serialized); // a featurer with a linearring. geometry = new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0), new GeoCoordinate(0, 0) }); feature = new Feature(geometry); serialized = feature.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]}}", serialized); // a featurer with a polygon. geometry = new Polygon(new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0), new GeoCoordinate(0, 0) })); feature = new Feature(geometry); serialized = feature.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]}}", serialized); }
/// <summary> /// Generates GeoJson for the given feature. /// </summary> /// <param name="writer"></param> /// <param name="feature"></param> internal static void Write(JsonWriter writer, Feature feature) { if (writer == null) { throw new ArgumentNullException("writer"); } if (feature == null) { throw new ArgumentNullException("feature"); } writer.WriteStartObject(); writer.WritePropertyName("type"); writer.WriteValue("Feature"); writer.WritePropertyName("properties"); GeoJsonConverter.Write(writer, feature.Attributes); writer.WritePropertyName("geometry"); GeoJsonConverter.Write(writer, feature.Geometry); writer.WriteEndObject(); }
/// <summary> /// Gets a feature collection representing the given route based on the given aggregation type. /// </summary> /// <param name="route"></param> /// <param name="aggregationType"></param> /// <returns></returns> public override FeatureCollection GetFeatures(Route route, RouteAggregationType aggregationType) { if (route == null) { throw new ArgumentNullException("route"); } if (aggregationType == RouteAggregationType.All) { // one LineString. var featureCollection = new FeatureCollection(); var coordinates = route.GetPoints(); if (coordinates.Count > 1) { var lineString = new LineString(coordinates.ToArray()); var attributes = new SimpleGeometryAttributeCollection(); attributes.Add("osmsharp:total_time", route.TotalTime.ToInvariantString()); attributes.Add("osmsharp:total_distance", route.TotalDistance.ToInvariantString()); var feature = new Feature(lineString, attributes); featureCollection.Add(feature); } return featureCollection; } else if(aggregationType == RouteAggregationType.Modal) { // modal. // aggregate. var aggregator = new ModalAggregator(new OsmRoutingInterpreter()); var microPlanner = new ModalMicroPlanner(new ModalLanguageGenerator(), new OsmRoutingInterpreter()); var aggregated = aggregator.Aggregate(route); var instructions = InstructionGenerator.Generate(microPlanner, route, aggregated); return this.GetFeatures(route, instructions); } else // modal and instructions. { // instructions. var instructions = this.GetInstructions(route); return this.GetFeatures(route, instructions); } }