public void TestHighway() { Itinero.Osm.Vehicles.Vehicle.RegisterVehicles(); var tags = new AttributeCollection(); var profileTags = new AttributeCollection(); var metaTags = new AttributeCollection(); Assert.IsFalse(tags.Normalize(profileTags, metaTags, Itinero.Osm.Vehicles.Vehicle.GetAllRegistered())); tags.AddOrReplace(new Attribute("highway", "residential")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, Itinero.Osm.Vehicles.Vehicle.GetAllRegistered())); Assert.IsTrue(profileTags.Contains("highway", "residential")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace(new Attribute("highway", "footway")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, Itinero.Osm.Vehicles.Vehicle.GetAllRegistered())); Assert.IsTrue(profileTags.Contains("highway", "footway")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace(new Attribute("highway", "motorway")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, Itinero.Osm.Vehicles.Vehicle.GetAllRegistered())); Assert.IsTrue(profileTags.Contains("highway", "motorway")); profileTags.Clear(); tags.Clear(); }
/// <summary> /// Converts an NTS attributes table to an attributes collection. /// </summary> public static IAttributeCollection ToAttributesCollection(this IAttributesTable table) { if (table == null) { return(null); } var attributes = new AttributeCollection(); var name = table.GetNames(); var values = table.GetValues(); for (var i = 0; i < name.Length; i++) { var value = values[i]; if (value == null) { attributes.AddOrReplace(name[i], string.Empty); } else { attributes.AddOrReplace(name[i], value.ToInvariantString()); } } return(attributes); }
/// <summary> /// Normalizes the oneway tag. /// </summary> public static void NormalizeOneway(this AttributeCollection tags, AttributeCollection profileTags, AttributeCollection metaTags) { string oneway; if (!tags.TryGetValue("oneway", out oneway)) { // nothing to normalize. return; } bool defaultOnewayFound; if (!OnewayValues.TryGetValue(oneway, out defaultOnewayFound)) { // invalid value. return; } if (defaultOnewayFound) { profileTags.AddOrReplace("oneway", "yes"); } else { profileTags.AddOrReplace("oneway", "-1"); } }
/// <summary> /// Normalizes maxspeed. /// </summary> public static void NormalizeMaxspeed(this AttributeCollection tags, AttributeCollection profileTags, AttributeCollection metaTags) { string maxspeed; if (!tags.TryGetValue("maxspeed", out maxspeed)) { // nothing to normalize. return; } int maxSpeedValue; if (int.TryParse(maxspeed, out maxSpeedValue) && maxSpeedValue > 0 && maxSpeedValue <= 200) { profileTags.AddOrReplace("maxspeed", maxspeed); } else if (maxspeed.EndsWith("mph")) { if (int.TryParse(maxspeed.Substring(0, maxspeed.Length - 4), out maxSpeedValue) && maxSpeedValue > 0 && maxSpeedValue <= 150) { profileTags.AddOrReplace("maxspeed", maxspeed); } } }
/// <summary> /// Normalizes access for the given hierarchy of access tags. /// </summary> public static void NormalizeAccess(this AttributeCollection tags, AttributeCollection profileTags, bool defaultAccess, params string[] accessTags) { bool?access = tags.InterpretAccessValue("access"); for (var i = 0; i < accessTags.Length; i++) { var currentAccess = tags.InterpretAccessValue(accessTags[i]); if (currentAccess != null) { access = currentAccess; } } if (access != null && access.Value != defaultAccess) { if (access.Value) { profileTags.AddOrReplace(accessTags[accessTags.Length - 1], "yes"); } else { profileTags.AddOrReplace(accessTags[accessTags.Length - 1], "no"); } } }
public static Route ToRoute(this Journey <TransferStats> journey, TransitDb.TransitDbSnapShot snapshot) { var stopsReader = snapshot.StopsDb.GetReader(); var shape = new List <Coordinate>(); var stops = new List <Route.Stop>(); while (journey != null) { if (stopsReader.MoveTo(journey.Location)) { var attributes = new AttributeCollection(); if (stopsReader.Attributes != null) { foreach (var a in stopsReader.Attributes) { attributes.AddOrReplace(a.Key, a.Value); } } attributes.AddOrReplace("id", stopsReader.GlobalId); attributes.AddOrReplace("type", "stop"); stops.Add(new Route.Stop() { Shape = shape.Count, Attributes = attributes, Coordinate = new Coordinate((float)stopsReader.Latitude, (float)stopsReader.Longitude) }); shape.Add(new Coordinate((float)stopsReader.Latitude, (float)stopsReader.Longitude)); } journey = journey.PreviousLink; } shape.Reverse(); stops.Reverse(); return(new Route() { Shape = shape.ToArray(), ShapeMeta = new [] { new Route.Meta() { Shape = 0 }, new Route.Meta() { Shape = shape.Count - 1, Attributes = new AttributeCollection(new Attribute("profile", "train")) } }, Stops = stops.ToArray() }); }
public void TestBicycleRestrictions() { Itinero.Osm.Vehicles.Vehicle.RegisterVehicles(); var vehicles = new Itinero.Osm.Vehicles.Vehicle[] { Itinero.Osm.Vehicles.Vehicle.Bicycle }; var tags = new AttributeCollection(); var profileTags = new AttributeCollection(); var metaTags = new AttributeCollection(); tags.AddOrReplace(new Attribute("highway", "residential")); tags.AddOrReplace(new Attribute("bicycle", "yes")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.IsTrue(profileTags.Contains("highway", "residential")); Assert.IsFalse(profileTags.Contains("bicycle", "yes")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace(new Attribute("highway", "residential")); tags.AddOrReplace(new Attribute("bicycle", "no")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.IsTrue(profileTags.Contains("highway", "residential")); Assert.IsTrue(profileTags.Contains("bicycle", "no")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace(new Attribute("highway", "residential")); tags.AddOrReplace(new Attribute("bicycle", "mistake")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.IsTrue(profileTags.Contains("highway", "residential")); Assert.IsFalse(profileTags.Contains("bicycle", "mistake")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace(new Attribute("highway", "footway")); tags.AddOrReplace(new Attribute("bicycle", "no")); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.IsTrue(profileTags.Contains("highway", "footway")); Assert.IsFalse(profileTags.Contains("bicycle", "no")); profileTags.Clear(); tags.Clear(); vehicles = new Itinero.Osm.Vehicles.Vehicle[] { Itinero.Osm.Vehicles.Vehicle.Car }; tags.AddOrReplace("highway", "residential"); tags.AddOrReplace("bicycle", "no"); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.IsTrue(profileTags.Contains("highway", "residential")); Assert.IsFalse(profileTags.Contains("bicycle", "no")); profileTags.Clear(); tags.Clear(); }
/// <summary> /// Converts this LRP to a feature. /// </summary> public static Feature ToFeature(this OpenLR.Model.LocationReferencePoint point) { var tags = new AttributeCollection(); tags.AddOrReplace("bearing", point.Bearing == null ? string.Empty : point.Bearing.ToInvariantString()); tags.AddOrReplace("distance_to_next", point.DistanceToNext.ToInvariantString()); tags.AddOrReplace("form_of_way", point.FormOfWay == null ? string.Empty : point.FormOfWay.ToInvariantString()); tags.AddOrReplace("functional_road_class", point.FuntionalRoadClass == null ? string.Empty : point.FuntionalRoadClass.ToInvariantString()); tags.AddOrReplace("lowest_functional_road_class", point.LowestFunctionalRoadClassToNext == null ? string.Empty : point.LowestFunctionalRoadClassToNext.ToInvariantString()); var table = tags.ToAttributes(); return(new Feature(new Point(point.Coordinate.ToCoordinate()), table)); }
/// <summary> /// Adds a trip for the given agency. /// </summary> public static uint AddTrip(this TransitDb db, Trip trip, global::GTFS.Entities.Route route, uint agencyId, uint scheduleId) { var attributes = new AttributeCollection(); attributes.AddOrReplace("id", trip.Id); attributes.AddNotNullOrWhiteSpace("accessibility_type", trip.AccessibilityType == null ? string.Empty : trip.AccessibilityType.ToInvariantString()); attributes.AddNotNullOrWhiteSpace("block_id", trip.BlockId); attributes.AddNotNullOrWhiteSpace("direction", trip.Direction == null ? string.Empty : trip.Direction.ToInvariantString()); attributes.AddNotNullOrWhiteSpace("headsign", trip.Headsign); attributes.AddNotNullOrWhiteSpace("route_id", trip.RouteId); attributes.AddNotNullOrWhiteSpace("service_id", trip.ServiceId); attributes.AddNotNullOrWhiteSpace("shape_id", trip.ShapeId); attributes.AddNotNullOrWhiteSpace("short_name", trip.ShortName); attributes.AddNotNullOrWhiteSpace("route_color", route.Color.ToHexColorString()); attributes.AddNotNullOrWhiteSpace("route_description", route.Description); attributes.AddNotNullOrWhiteSpace("route_long_name", route.LongName); attributes.AddNotNullOrWhiteSpace("route_short_name", route.ShortName); attributes.AddNotNullOrWhiteSpace("route_text_color", route.TextColor.ToHexColorString()); var metaId = db.TripAttributes.Add(attributes); return(db.AddTrip(scheduleId, agencyId, metaId)); }
/// <summary> /// Returns true if any of the vehicle can traverse the given way. /// </summary> public bool AnyCanTraverse(IAttributeCollection attributes, bool filter = true) { IAttributeCollection filtered = attributes; if (filter) { filtered = new AttributeCollection(); foreach (var attribute in attributes) { if (_vehicles.IsOnProfileWhiteList(attribute.Key)) { filtered.AddOrReplace(attribute); } } } Whitelist whitelist; if (this.TryGetCached(filtered, out whitelist, false)) { return(whitelist.Count > 0); } bool[] canTraverse; if (this.Add(filtered, out whitelist, out canTraverse, false)) { return(whitelist.Count > 0); } return(false); }
/// <summary> /// Returns true if the given vehicle can traverse the given edge. /// </summary> public bool CanTraverse(IAttributeCollection attributes1, Vehicle vehicle, bool filter = true) { IAttributeCollection filtered = attributes1; if (filter) { filtered = new AttributeCollection(); foreach (var attribute in attributes1) { if (_vehicles.IsOnProfileWhiteList(attribute.Key)) { filtered.AddOrReplace(attribute); } } } for (var i = 0; i < _vehicles.Length; i++) { if (_vehicles[i].Name == vehicle.Name) { bool[] canTraverse; Whitelist whitelist; if (!this.TryGetCached(filtered, out whitelist, out canTraverse, false)) { if (!this.Add(filtered, out whitelist, out canTraverse, false)) { return(false); } } return(canTraverse[i]); } } throw new System.Exception("Cannot request data for an uncached vehicle."); }
/// <summary> /// Gets the OSM tags from the given node/way or relation. /// </summary> /// <param name="osmGeo">The node, way or relation json-ld part.</param> /// <param name="reverseMappings">The reverse mappings.</param> /// <returns>The tags.</returns> private static AttributeCollection GetTags(JToken osmGeo, Dictionary <string, TagMapperConfig> reverseMappings) { var attributes = new AttributeCollection(); // interpret all tags with defined semantics. foreach (var child in osmGeo.Children()) { if (!(child is JProperty property)) { continue; } if (property.Name == "@id" || property.Name == "@type") { continue; } if (property.Value is JArray) { continue; } var attribute = property.Map(reverseMappings); if (attribute == null) { continue; } attributes.AddOrReplace(attribute.Value.Key, attribute.Value.Value); } return(attributes); }
public void TestRamp() { Itinero.Osm.Vehicles.Vehicle.RegisterVehicles(); var tags = new AttributeCollection(); var profileTags = new AttributeCollection(); var metaTags = new AttributeCollection(); tags.AddOrReplace("highway", "steps"); tags.AddOrReplace("ramp", "yes"); Assert.IsTrue(tags.Normalize(profileTags, metaTags, Itinero.Osm.Vehicles.Vehicle.GetAllRegistered())); Assert.IsTrue(profileTags.Contains("highway", "steps")); Assert.IsTrue(profileTags.Contains("ramp", "yes")); profileTags.Clear(); tags.Clear(); }
/// <summary> /// Tests getting factor and speed. /// </summary> protected void TestFactorAndSpeed(Itinero.Profiles.IProfileInstance profile, short?direction, float?factor, float?speed, params string[] tags) { var attributesCollection = new AttributeCollection(); for (int idx = 0; idx < tags.Length; idx = idx + 2) { attributesCollection.AddOrReplace(tags[idx], tags[idx + 1]); } var factorAndSpeed = profile.FactorAndSpeed(attributesCollection); if (direction != null) { Assert.AreEqual(direction.Value, factorAndSpeed.Direction); } if (factor != null) { Assert.AreEqual(factor.Value, factorAndSpeed.Value, 0.0001); } if (speed != null) { if (speed == 0) { Assert.AreEqual(0, factorAndSpeed.SpeedFactor, 0.0001); } else { Assert.AreEqual(1.0f / (speed.Value / 3.6), factorAndSpeed.SpeedFactor, 0.0001); } } }
/// <summary> /// Adds the key value pair if the value is not null, empty or whitespace. /// </summary> public static void AddNotNullOrWhiteSpace(this AttributeCollection attributes, string key, string value) { if (!string.IsNullOrWhiteSpace(value)) { attributes.AddOrReplace(key, value); } }
/// <summary> /// Normalize the cycleway tag. /// </summary> public static void NormalizeCycleway(this AttributeCollection tags, AttributeCollection profileTags, AttributeCollection metaTags) { string cycleway; if (!tags.TryGetValue("cycleway", out cycleway)) { // nothing to normalize. return; } if (cycleway == "cyclestreet") { profileTags.AddOrReplace("cycleway", "cyclestreet"); } else if (cycleway == "lane") { profileTags.AddOrReplace("cycleway", "lane"); } // TODO: add the unidirectional cycleway stuff. WARNING: direction of 'left' and 'right' depends on country. }
/// <summary> /// Returns one attribute collection containing both the profile and meta tags. /// </summary> public static IAttributeCollection GetProfileAndMeta(this RouterDb db, uint profileId, uint meta) { var tags = new AttributeCollection(); var metaTags = db.EdgeMeta.Get(meta); if (metaTags != null) { tags.AddOrReplace(metaTags); } var profileTags = db.EdgeProfiles.Get(profileId); if (profileTags != null) { tags.AddOrReplace(profileTags); } return(tags); }
/// <summary> /// Tests the probable speed. /// </summary> protected void TextProbableSpeed(Vehicle vehicle, double speed, params string[] tags) { // build tags collection. var tagsCollection = new AttributeCollection(); for (int idx = 0; idx < tags.Length; idx = idx + 2) { tagsCollection.AddOrReplace(tags[idx], tags[idx + 1]); } Assert.AreEqual(speed, vehicle.ProbableSpeed(tagsCollection), 0.001f); }
/// <summary> /// Normalizes the oneway bicycle tag. /// </summary> public static void NormalizeOnewayBicycle(this AttributeCollection tags, AttributeCollection profileTags, AttributeCollection metaTags) { string oneway; if (!tags.TryGetValue("oneway:bicycle", out oneway)) { // nothing to normalize. return; } if (oneway == "no") { profileTags.AddOrReplace("oneway:bicycle", "no"); } }
/// <summary> /// Normalizes the junction tag. /// </summary> /// <returns></returns> public static void NormalizeJunction(this AttributeCollection tags, AttributeCollection profileTags, AttributeCollection metaTags) { string junction; if (!tags.TryGetValue("junction", out junction)) { // nothing to normalize. return; } if (junction == "roundabout") { profileTags.AddOrReplace("junction", "roundabout"); } }
/// <summary> /// Adds an agency. /// </summary> public static uint AddAgency(this TransitDb db, Agency agency) { var attributes = new AttributeCollection(); attributes.AddOrReplace("id", agency.Id.ToStringEmptyWhenNull()); attributes.AddNotNullOrWhiteSpace("fare_url", agency.FareURL); attributes.AddNotNullOrWhiteSpace("language_code", agency.LanguageCode); attributes.AddNotNullOrWhiteSpace("name", agency.Name); attributes.AddNotNullOrWhiteSpace("phone", agency.Phone); attributes.AddNotNullOrWhiteSpace("timezone", agency.Timezone); attributes.AddNotNullOrWhiteSpace("url", agency.URL); return(db.AgencyAttributes.Add(attributes)); }
/// <summary> /// Converts the given tags collection to an attributes collection. /// </summary> public static IAttributeCollection ToAttributes(this TagsCollectionBase tagsCollection) { if (tagsCollection == null) { return(null); } var attributeCollection = new AttributeCollection(); foreach (var tag in tagsCollection) { attributeCollection.AddOrReplace(tag.Key, tag.Value); } return(attributeCollection); }
/// <summary> /// Tests the can traverse functionality. /// </summary> protected void TestVehicleCanTranverse(Vehicle vehicle, bool result, params string[] tags) { var tagsCollection = new AttributeCollection(); for (int idx = 0; idx < tags.Length; idx = idx + 2) { tagsCollection.AddOrReplace(tags[idx], tags[idx + 1]); } if (result) { // assume the result is true. Assert.IsTrue(vehicle.CanTraverse(tagsCollection)); } else { // assume the result is false. Assert.IsFalse(vehicle.CanTraverse(tagsCollection)); } }
/// <summary> /// Adds a stop. /// </summary> /// <returns></returns> public static uint AddStop(this TransitDb db, Stop stop) { var attributes = new AttributeCollection(); attributes.AddOrReplace("id", stop.Id); attributes.AddNotNullOrWhiteSpace("code", stop.Code); attributes.AddNotNullOrWhiteSpace("description", stop.Description); attributes.AddNotNullOrWhiteSpace("location_type", stop.LocationType == null ? string.Empty : stop.LocationType.Value.ToInvariantString()); attributes.AddNotNullOrWhiteSpace("name", stop.Name); attributes.AddNotNullOrWhiteSpace("timezone", stop.Timezone); attributes.AddNotNullOrWhiteSpace("url", stop.Url); attributes.AddNotNullOrWhiteSpace("wheelchairboarding", stop.WheelchairBoarding); attributes.AddNotNullOrWhiteSpace("zone", stop.Zone); var metaId = db.StopAttributes.Add(attributes); return(db.AddStop((float)stop.Latitude, (float)stop.Longitude, metaId)); }
/// <summary> /// Adds a new collection to cache if appropriate. /// </summary> public bool Add(IAttributeCollection attributes, out Whitelist whitelist, out bool[] canTraverse, bool filter = true) { IAttributeCollection filtered = attributes; if (filter) { filtered = new AttributeCollection(); foreach (var attribute in attributes) { if (_vehicles.IsOnProfileWhiteList(attribute.Key)) { filtered.AddOrReplace(attribute); } } } if (filtered.Count == 0) { whitelist = null; canTraverse = null; return(false); } var id = _edgeProfiles.Add(filtered); WhitelistAndFlags whitelistAndFlags; if (!_cache.TryGetValue(id, out whitelistAndFlags)) { whitelist = new Whitelist(); canTraverse = new bool[_vehicles.Length]; _vehicles.AddToWhiteList(filtered, whitelist, canTraverse); _cache[id] = new WhitelistAndFlags() { CanTraverse = canTraverse, Whitelist = whitelist }; return(true); } whitelist = whitelistAndFlags.Whitelist; canTraverse = whitelistAndFlags.CanTraverse; return(true); }
/// <summary> /// Returns true if node is relevant. /// </summary> private IAttributeCollection GetAttributesFor(Node node) { if (_nodeTagProcessor == null) { return(null); } var nodeTags = node.Tags; if (nodeTags == null || nodeTags.Count == 0) { return(null); } lock (_vehicle.Script) { // build lua table. _attributesTable.Clear(); foreach (var attribute in nodeTags) { _attributesTable.Set(attribute.Key, DynValue.NewString(attribute.Value)); } // call factor_and_speed function. _resultsTable.Clear(); _vehicle.Script.Call(_nodeTagProcessor, _attributesTable, _resultsTable); // get the result. var resultAttributes = new AttributeCollection(); var dynAttributesToKeep = _resultsTable.Get("attributes_to_keep"); if (dynAttributesToKeep != null && dynAttributesToKeep.Type != DataType.Nil && dynAttributesToKeep.Table.Keys.Count() > 0) { foreach (var attribute in dynAttributesToKeep.Table.Pairs) { resultAttributes.AddOrReplace(attribute.Key.String, attribute.Value.String); } } return(resultAttributes); } }
/// <summary> /// Normalizes the ramp tag. /// </summary> public static void NormalizeRamp(this AttributeCollection tags, AttributeCollection profileTags, AttributeCollection metaTags, bool defaultAccess) { string ramp; if (!tags.TryGetValue("ramp", out ramp)) { // nothing to normalize. return; } bool?defaultAccessFound; if (!RampValues.TryGetValue(ramp, out defaultAccessFound)) { // invalid value. return; } if (defaultAccess != defaultAccessFound) { profileTags.AddOrReplace("ramp", ramp); } }
public void BuildTraffic(Coder coder, IQueryable <TrafficDataModel> trafficDatas) { var edges = new Dictionary <string, IAttributeCollection>(); var attributes = new AttributeCollection(); // STAGING: create some linestrings: encode edge(s) and pair them off with tags. foreach (TrafficDataModel entry in trafficDatas) { attributes.AddOrReplace("maxspeed", entry.Speed + " mph"); //there's a much faster way of doing this using Dictionary class string[] points = entry.Link_Points.Split(' '); foreach (var point in points) { string[] coor = point.Split(','); if (coor.Length == 2) { float.TryParse(coor[0], out float _lat); float.TryParse(coor[1], out float _long); //Encode edges and add attributes. try { edges[coder.EncodeClosestEdge(new Coordinate(_lat, _long), searchDistanceInMeter)] = attributes; } catch (Exception e) { //skip edge if error } } } } // decode edges and augment routerdb. foreach (var pair in edges) { var encodedLine = pair.Key; var attribute = pair.Value; coder.DecodeLine(encodedLine, attribute); } }
public void TestMotorwayAccess() { Itinero.Osm.Vehicles.Vehicle.RegisterVehicles(); var vehicles = new Itinero.Osm.Vehicles.Vehicle[] { Itinero.Osm.Vehicles.Vehicle.Pedestrian, Itinero.Osm.Vehicles.Vehicle.Bicycle, Itinero.Osm.Vehicles.Vehicle.Car }; var tags = new AttributeCollection(); var profileTags = new AttributeCollection(); var metaTags = new AttributeCollection(); tags.AddOrReplace("highway", "motorway"); tags.AddOrReplace("access", "no"); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.AreEqual(2, profileTags.Count); Assert.IsTrue(profileTags.Contains("highway", "motorway")); Assert.IsTrue(profileTags.Contains("motorcar", "no")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace("highway", "motorway"); tags.AddOrReplace("access", "yes"); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.AreEqual(3, profileTags.Count); Assert.IsTrue(profileTags.Contains("highway", "motorway")); Assert.IsTrue(profileTags.Contains("bicycle", "yes")); Assert.IsTrue(profileTags.Contains("foot", "yes")); profileTags.Clear(); tags.Clear(); tags.AddOrReplace("highway", "motorway"); tags.AddOrReplace("access", "no"); tags.AddOrReplace("vehicle", "yes"); Assert.IsTrue(tags.Normalize(profileTags, metaTags, vehicles)); Assert.AreEqual(2, profileTags.Count); Assert.IsTrue(profileTags.Contains("highway", "motorway")); Assert.IsTrue(profileTags.Contains("bicycle", "yes")); profileTags.Clear(); tags.Clear(); }
private static IAttributeCollection ReadAttributes(dynamic token) { var attributeCollection = new AttributeCollection(); foreach (var aAttribute in token) { var aAttributeToken = aAttribute as Newtonsoft.Json.Linq.JToken; if (!(aAttributeToken?.First is JProperty aAttributeProperty)) { continue; } var name = aAttributeProperty.Name; var value = string.Empty; if (aAttributeProperty.Value != null) { value = aAttributeProperty.Value.ToString(); } attributeCollection.AddOrReplace(name, value); } return(attributeCollection); }