1
2
3 """POI example: routing to selected POI
4 - routed movement
5 - moving alternately to random destination and POI
6 - destination POI taken from OSM data selected by node tag amenity=(bar|cafe|pub)
7 - POI need not to be connected to road network,
8 they are connected to next way node by simulation
9 routing for the new connecting waySegment is done here also
10 (see GO_TO_CAFE, ENTER_CAFE and LEAVE_CAFE)
11 - destination nodes and POI are printed to stderr
12 """
13
14 import sys
15 sys.path.append("..")
16
17 import struct
18 import random
19
20 from mosp.core import Simulation, Person
21 from mosp.locations import Exit
22 from mosp.geo import osm, utils
23 from mosp.monitors import PipePlayerMonitor, SocketPlayerMonitor
24
25 __author__ = "B. Henne"
26 __contact__ = "henne@dcsec.uni-hannover.de"
27 __copyright__ = "(c) 2011, DCSec, Leibniz Universitaet Hannover, Germany"
28 __license__ = "GPLv3"
29
30
31 COLOR = {0: [1.0, 0.0, 0.0, 1.0],
32 1: [0.0, 1.0, 0.0, 1.0]}
33
34 GO_TO_CAFE, ENTER_CAFE, LEAVE_CAFE, GO_SOMEWHERE = range(4)
35
36
38 """Implements a moving person, moving to somewhere and POI alternatively.
39
40 Currently just works with the libchamplain-based viewer.
41 @author: B. Henne"""
42
44 """Inits the PoiWiggler person."""
45 super(PoiWiggler, self).__init__(*args, **kwargs)
46 Person.__init__(self, *args)
47 self.dest_node = self.next_node
48 if kwargs.get("cafes"):
49 self.cafes = kwargs["cafes"]
50 else:
51 self.cafes = None
52 self.p_state = GO_SOMEWHERE
53 self.p_cafe = None
54 self.p_color = self.p_id
55 self.p_color_rgba = COLOR[self.p_id]
56 self.next_target = self.next_target_routed
57
59 """Think about what to do next."""
60 if self.next_node == self.dest_node:
61 if self.p_state == GO_SOMEWHERE:
62 self.dest_node = self._random.choice(self.sim.geo.way_nodes)
63 sys.stderr.write('-> %s moving to somewhere (node %s)\n' % (self.p_id, self.dest_node.id))
64 self.p_state = GO_TO_CAFE
65 elif self.p_state == GO_TO_CAFE:
66
67 if not self.cafes:
68 self.last_node = self.next_node
69 self.p_state == GO_SOMEWHERE
70 return -1
71 self.p_cafe = self._random.choice(self.cafes)
72 if 'name' in self.p_cafe.tags:
73 sys.stderr.write('-> %s moving to POI \"%s\"\n' % (self.p_id, self.p_cafe.tags['name'].encode('ascii', 'ignore')))
74 else:
75 sys.stderr.write('-> %s moving to POI without name\n' % self.p_id)
76 self.dest_node = self.p_cafe.n[0]
77 self.sim.monitors[0].draw_point(self.p_id + 100, self.dest_node.lat, self.dest_node.lon, 5, self.p_color_rgba, ttl=0)
78 self.p_state = ENTER_CAFE
79 elif self.p_state == ENTER_CAFE:
80
81 self.last_node = self.next_node
82 self.dest_node = self.next_node = self.p_cafe
83 self.p_state = LEAVE_CAFE
84 self.sim.monitors[0].remove_object('point', self.p_id + 100)
85 return -1
86 elif self.p_state == LEAVE_CAFE:
87
88 self.last_node = self.next_node
89 self.dest_node = self.next_node = self.p_cafe.n[0]
90 self.p_state = GO_SOMEWHERE
91 return -1
92
93 self.need_next_target = True
94 return -1
95
97 """Find a new next_node to move to.
98 Person gets routed to it."""
99 self.last_node = self.next_node
100 next = self.last_node.get_route(self.dest_node)
101 if not next:
102 self.dest_node = self.next_node
103 self._duration = 1
104 else:
105 self.next_node = next
106
107
109 """Defines the simulation, map, monitors, persons. Connects POI with road network."""
110 s = Simulation(geo=osm.OSMModel('../data/hannover2.osm'), rel_speed=30)
111
112 cafes = [node for node in s.geo.non_way_nodes if "amenity" in node.tags and node.tags["amenity"] in ("bar","cafe","pub")]
113 for cafe in cafes:
114
115 dist = float('inf')
116 nearest = None
117 if not cafe.neighbors:
118 for node in s.geo.way_nodes:
119 d = utils.distance(cafe, node)
120 if d < dist and node.neighbors:
121 dist = d
122 nearest = node
123
124 cafe.neighbors[nearest] = int(dist)
125 nearest.neighbors[cafe] = int(dist)
126 cafe.n = [nearest]
127
128 way = osm.WaySegment(cafe, nearest)
129 cafe.ways[nearest] = way
130 nearest.ways[cafe] = way
131 s.geo.add(way)
132
133 m = s.add_monitor(SocketPlayerMonitor, 2)
134 s.add_persons(PoiWiggler, 2, monitor=m, args={"cafes": cafes})
135 s.run(until=10000, real_time=True, monitor=True)
136
137
138
139
140 if __name__ == '__main__':
141 main()
142