< Summary

Class:Itinero.IO.Osm.OsmEdgeTypeMap
Assembly:Itinero.IO.Osm
File(s):/home/runner/work/routing2/routing2/src/Itinero.IO.Osm/OsmEdgeTypeMap.cs
Covered lines:74
Uncovered lines:1
Coverable lines:75
Total lines:135
Line coverage:98.6% (74 of 75)
Covered branches:3
Total branches:6
Branch coverage:50% (3 of 6)
Tag:263_26948838820

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.cctor()100%1100%
.ctor()100%1100%
Map(...)100%1100%
IsRelevant(...)50%688.88%
Set(...)100%1100%

File(s)

/home/runner/work/routing2/routing2/src/Itinero.IO.Osm/OsmEdgeTypeMap.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Collections.Immutable;
 4using System.Linq;
 5using Itinero.Indexes;
 6
 7namespace Itinero.IO.Osm;
 8
 9/// <summary>
 10/// An edge type map that keeps only OSM tags relevant for routing.
 11/// Both key AND value are validated — only known routing-relevant key-value pairs are kept.
 12/// This ensures edges with different routing characteristics get different edgeTypeIds,
 13/// while irrelevant tags are stripped to maximize deduplication.
 14/// </summary>
 15public class OsmEdgeTypeMap : AttributeSetMap
 16{
 17    private static readonly ImmutableDictionary<string, ImmutableHashSet<string>> RoutingTags;
 18
 19    static OsmEdgeTypeMap()
 120    {
 121        var tags = new Dictionary<string, ImmutableHashSet<string>>();
 22
 23        // access
 124        tags["access"] = Set("customers", "delivery", "designated", "destination", "dismount",
 125            "no", "permissive", "permit", "private", "service");
 126        tags["bicycle"] = Set("designated", "dismount", "no", "official", "permissive",
 127            "permit", "private", "use_sidepath", "yes");
 128        tags["foot"] = Set("designated", "no", "official", "permissive", "permit",
 129            "private", "use_sidepath", "yes");
 130        tags["hgv"] = Set("no", "permissive", "permit", "private", "yes");
 131        tags["motor_vehicle"] = Set("customers", "destination", "no", "permissive",
 132            "permit", "private", "yes");
 133        tags["motorcar"] = Set("customers", "destination", "no", "permissive",
 134            "permit", "private", "yes");
 135        tags["emergency"] = Set("yes");
 136        tags["motorroad"] = Set("yes");
 137        tags["area"] = Set("yes");
 38
 39        // road classification — wildcard, accept any value
 140        tags["highway"] = ImmutableHashSet<string>.Empty;
 141        tags["route"] = ImmutableHashSet<string>.Empty;
 42
 143        tags["service"] = Set("alley", "bus", "driveway", "parking_aisle");
 144        tags["tracktype"] = Set("grade1", "grade2", "grade3", "grade4", "grade5");
 145        tags["railway"] = Set("abandoned");
 46
 47        // direction
 148        tags["oneway"] = Set("-1", "1", "no", "yes");
 149        tags["oneway:bicycle"] = Set("-1", "1", "no", "yes");
 150        tags["oneway:foot"] = Set("yes");
 151        tags["junction"] = Set("roundabout");
 52
 53        // speed — wildcard, validated as integer
 154        tags["maxspeed"] = ImmutableHashSet<string>.Empty;
 55
 56        // surface
 157        tags["surface"] = Set("asphalt", "cobblestone", "compacted", "concrete",
 158            "concrete:lanes", "concrete:plates", "dirt", "earth", "fine_gravel",
 159            "grass", "grass_paver", "gravel", "ground", "metal", "mud", "paved",
 160            "paving_stones", "pebblestone", "sand", "sett", "snow",
 161            "unhewn_cobblestone", "unpaved", "wood", "woodchips");
 162        tags["smoothness"] = Set("bad", "excellent", "good", "intermediate", "very_good");
 163        tags["sidewalk:surface"] = Set("asphalt", "concrete", "paving_stones", "sett");
 64
 65        // cycling
 166        tags["cycleway"] = Set("lane", "opposite", "opposite_lane", "opposite_share_busway",
 167            "opposite_track", "right", "share_busway", "shared", "shared_lane",
 168            "track", "yes");
 169        tags["cycleway:left"] = Set("lane", "opposite", "opposite_lane", "opposite_track",
 170            "share_busway", "shared", "shared_lane", "track", "yes");
 171        tags["cycleway:right"] = Set("lane", "share_busway", "shared", "shared_lane",
 172            "track", "yes");
 173        tags["cycleway:left:oneway"] = Set("no");
 174        tags["cycleway:right:oneway"] = Set("no");
 175        tags["cyclestreet"] = Set("yes");
 176        tags["cycle_highway"] = ImmutableHashSet<string>.Empty;
 177        tags["bicycle:class"] = Set("-1", "-2", "-3", "0", "1", "2", "3");
 178        tags["ramp:bicycle"] = Set("yes");
 179        tags["towpath"] = Set("yes");
 180        tags["designation"] = Set("towpath");
 81
 82        // barriers
 183        tags["barrier"] = Set("bollard", "sump_buster");
 84
 85        // incline
 186        tags["incline"] = Set("-10%", "-20%", "-30%", "0", "0%", "10%", "20%", "30%",
 187            "down", "up");
 88
 89        // other routing-relevant — wildcards
 190        tags["type"] = ImmutableHashSet<string>.Empty;
 191        tags["network:type"] = ImmutableHashSet<string>.Empty;
 192        tags["operator"] = ImmutableHashSet<string>.Empty;
 193        tags["state"] = ImmutableHashSet<string>.Empty;
 94
 195        RoutingTags = tags.ToImmutableDictionary();
 196    }
 97
 98    /// <summary>
 99    /// Creates a new OSM edge type map with the default set of routing-relevant tags.
 100    /// </summary>
 101    public OsmEdgeTypeMap()
 19102        : base(new Guid("45d22274-cb26-490c-9685-aab0ef7d7e9c"))
 19103    {
 19104    }
 105
 106    /// <inheritdoc/>
 107    public override IEnumerable<(string key, string value)> Map(
 108        IEnumerable<(string key, string value)> attributes)
 79109    {
 131110        return attributes.Where(a => IsRelevant(a.key, a.value));
 79111    }
 112
 113    /// <summary>
 114    /// Returns true if the key-value pair is relevant for routing.
 115    /// </summary>
 116    private static bool IsRelevant(string key, string value)
 52117    {
 52118        if (!RoutingTags.TryGetValue(key, out var allowedValues)) return false;
 119
 120        // if allowed values are specified, check membership.
 52121        if (allowedValues.Count > 0) return allowedValues.Contains(value);
 122
 123        // wildcard keys — custom validation per key.
 52124        return key switch
 52125        {
 0126            "maxspeed" => int.TryParse(value, out _),
 52127            _ => true
 52128        };
 52129    }
 130
 131    private static ImmutableHashSet<string> Set(params string[] values)
 31132    {
 31133        return values.ToImmutableHashSet();
 31134    }
 135}