directions: function()

in modules/osm/node.js [50:143]


    directions: function(resolver, projection) {
        var val;
        var i;

        // which tag to use?
        if (this.isHighwayIntersection(resolver) && (this.tags.stop || '').toLowerCase() === 'all') {
            // all-way stop tag on a highway intersection
            val = 'all';
        } else {
            // generic direction tag
            val = (this.tags.direction || '').toLowerCase();

            // better suffix-style direction tag
            var re = /:direction$/i;
            var keys = Object.keys(this.tags);
            for (i = 0; i < keys.length; i++) {
                if (re.test(keys[i])) {
                    val = this.tags[keys[i]].toLowerCase();
                    break;
                }
            }
        }

        if (val === '') return [];

        var cardinal = {
            north: 0,               n: 0,
            northnortheast: 22,     nne: 22,
            northeast: 45,          ne: 45,
            eastnortheast: 67,      ene: 67,
            east: 90,               e: 90,
            eastsoutheast: 112,     ese: 112,
            southeast: 135,         se: 135,
            southsoutheast: 157,    sse: 157,
            south: 180,             s: 180,
            southsouthwest: 202,    ssw: 202,
            southwest: 225,         sw: 225,
            westsouthwest: 247,     wsw: 247,
            west: 270,              w: 270,
            westnorthwest: 292,     wnw: 292,
            northwest: 315,         nw: 315,
            northnorthwest: 337,    nnw: 337
        };


        var values = val.split(';');
        var results = [];

        values.forEach(function(v) {
            // swap cardinal for numeric directions
            if (cardinal[v] !== undefined) {
                v = cardinal[v];
            }

            // numeric direction - just add to results
            if (v !== '' && !isNaN(+v)) {
                results.push(+v);
                return;
            }

            // string direction - inspect parent ways
            var lookBackward =
                (this.tags['traffic_sign:backward'] || v === 'backward' || v === 'both' || v === 'all');
            var lookForward =
                (this.tags['traffic_sign:forward'] || v === 'forward' || v === 'both' || v === 'all');

            if (!lookForward && !lookBackward) return;

            var nodeIds = {};
            resolver.parentWays(this).forEach(function(parent) {
                var nodes = parent.nodes;
                for (i = 0; i < nodes.length; i++) {
                    if (nodes[i] === this.id) {  // match current entity
                        if (lookForward && i > 0) {
                            nodeIds[nodes[i - 1]] = true;  // look back to prev node
                        }
                        if (lookBackward && i < nodes.length - 1) {
                            nodeIds[nodes[i + 1]] = true;  // look ahead to next node
                        }
                    }
                }
            }, this);

            Object.keys(nodeIds).forEach(function(nodeId) {
                // +90 because vecAngle returns angle from X axis, not Y (north)
                var a = projection(this.loc);
                var b = projection(resolver.entity(nodeId).loc);
                results.push( (vecAngle(a, b) * 180 / Math.PI) + 90 );
            }, this);

        }, this);

        return utilArrayUniq(results);
    },