parseOSM.js
1 /*global parseOSM*/ 2 3 function haveTag(obj, key, value) { 4 if (!obj || ! obj.tags) { 5 return false; 6 } 7 if(!value) { 8 return (key in obj.tags); 9 } 10 return (obj.tags[key] == value); 11 } 12 13 function parseOSM (data, previous) { 14 var d; 15 if(previous !== undefined) { 16 d = previous; 17 } else { 18 d = {}; 19 d.nodes = {}; 20 d.ways = {}; 21 d.rels = {}; 22 23 d.stop_positions = {}; 24 d.platforms = {}; 25 d.stop_areas = {}; 26 d.routes = {}; 27 d.route_masters = {}; 28 } 29 30 // Add all features to nodes/way/rels according to their type 31 data.elements.forEach(function(e) { 32 switch(e.type) { 33 case "node": 34 d.nodes[e.id] = e; 35 d.nodes[e.id].ways = []; 36 break; 37 case "way": 38 d.ways[e.id] = e; 39 break; 40 case "relation": 41 d.rels[e.id] = e; 42 break; 43 } 44 }); 45 46 47 // Attach nodes and ways 48 _.each(d.ways, function(w) { 49 newMembers = []; 50 w.nodes.forEach(function(m) { 51 newMembers.push(d.nodes[m]); 52 d.nodes[m].ways[w.id] = w; 53 }); 54 w.nodes = newMembers; 55 56 if (haveTag(w, 'public_transport', 'platform')) { 57 d.platforms[w.id] = w; 58 } 59 }); 60 61 // Attach relation members to their parent relations 62 _.each(d.rels, function(r) { 63 newMembers = []; 64 _.each(r.members, function(m) { 65 var newMember; 66 switch(m.type) { 67 case "node": 68 newMember = d.nodes[m.ref]; 69 break; 70 case "way": 71 newMember = d.ways[m.ref]; 72 break; 73 case "relation": 74 newMember = d.rels[m.ref]; 75 break; 76 } 77 if(newMember) { 78 newMember.role = m.role; 79 newMembers.push(newMember); 80 } 81 }); 82 r.members = newMembers; 83 84 if(haveTag(r, 'type', 'public_transport') && 85 haveTag(r, 'public_transport', 'stop_area')) { 86 d.stop_areas[r.id] = r; 87 _.each(r.members, function(member) { 88 member.stop_area = r; 89 }); 90 } 91 else if (haveTag(r, 'type', 'route')) { 92 d.routes[r.id] = r; 93 r.stop_positions = []; 94 r.platforms = []; 95 r.paths = []; 96 _.each(r.members, function(m) { 97 switch(m.role) { 98 case "stop": 99 case "stop_entry_only": 100 case "stop_exit_only": 101 r.stop_positions.push(m); 102 break; 103 case "platform": 104 case "platform_entry_only": 105 case "platform_exit_only": 106 r.platforms.push(m); 107 break; 108 case "": 109 case "forward": 110 case "backward": 111 r.paths.push(m); 112 break; 113 } 114 }); 115 } 116 else if (haveTag(r, 'type', 'route_master')) { 117 d.route_masters[r.id] = r; 118 } 119 }); 120 121 _.each(d.nodes, function(n) { 122 if(haveTag(n, 'public_transport', 'stop_position')) { 123 d.stop_positions[n.id] = n; 124 } 125 else if (haveTag(n, 'public_transport', 'platform')) { 126 d.platforms[n.id] = n; 127 } 128 }); 129 130 return d; 131 }