def load_roads(self, filenames): shapeRecords = reduce( lambda r1, r2: x + y, map(lambda f: shapefile.Reader(f).shapeRecords(), filenames)) self.roads += filter(lambda n: len(n) > 2, map(lambda r: r.shape.points, shapeRecords)) self.road_names += map(lambda r: r.record[0], shapeRecords) min_lon = min(map(lambda r: min(map(lambda p: p[0], r)), self.roads)) max_lon = max(map(lambda r: max(map(lambda p: p[0], r)), self.roads)) min_lat = min(map(lambda r: min(map(lambda p: p[1], r)), self.roads)) max_lat = max(map(lambda r: max(map(lambda p: p[1], r)), self.roads)) self.min_longitude = min_lon self.max_longitude = max_lon self.min_latitude = min_lat self.max_latitude = max_lat m_longitude = (self.min_longitude + self.max_longitude) / 2 m_latitude = (self.min_latitude + self.max_latitude) / 2 self.UNIT_LONGITUDE_DISTANCE = map_dist( self.min_longitude, m_latitude, self.max_longitude, m_latitude) / (self.max_longitude - self.min_longitude) self.UNIT_LATITUDE_DISTANCE = map_dist( m_longitude, self.min_latitude, m_longitude, self.max_latitude) / (self.max_latitude - self.min_latitude) self.GRID_INTERVAL_LONGITUDE = self.GRID_INTERVAL / self.UNIT_LONGITUDE_DISTANCE self.GRID_INTERVAL_LATITUDE = self.GRID_INTERVAL / self.UNIT_LATITUDE_DISTANCE self.TOTAL_GRID_ROWS = int((self.max_latitude - self.min_latitude) / self.GRID_INTERVAL_LATITUDE) + 1 self.TOTAL_GRID_COLS = int((self.max_longitude - self.min_longitude) / self.GRID_INTERVAL_LONGITUDE) + 1
def load_roads(self, filenames): shapeRecords = reduce(lambda r1, r2: x + y, map(lambda f: shapefile.Reader(f).shapeRecords(), filenames)) self.roads += filter(lambda n: len(n) > 2, map(lambda r: r.shape.points, shapeRecords)) self.road_names += map(lambda r: r.record[0], shapeRecords) min_lon = min(map(lambda r: min(map(lambda p: p[0], r)), self.roads)) max_lon = max(map(lambda r: max(map(lambda p: p[0], r)), self.roads)) min_lat = min(map(lambda r: min(map(lambda p: p[1], r)), self.roads)) max_lat = max(map(lambda r: max(map(lambda p: p[1], r)), self.roads)) self.min_longitude = min_lon self.max_longitude = max_lon self.min_latitude = min_lat self.max_latitude = max_lat m_longitude = (self.min_longitude + self.max_longitude) / 2 m_latitude = (self.min_latitude + self.max_latitude) / 2 self.UNIT_LONGITUDE_DISTANCE = map_dist(self.min_longitude, m_latitude, self.max_longitude, m_latitude) / ( self.max_longitude - self.min_longitude ) self.UNIT_LATITUDE_DISTANCE = map_dist(m_longitude, self.min_latitude, m_longitude, self.max_latitude) / ( self.max_latitude - self.min_latitude ) self.GRID_INTERVAL_LONGITUDE = self.GRID_INTERVAL / self.UNIT_LONGITUDE_DISTANCE self.GRID_INTERVAL_LATITUDE = self.GRID_INTERVAL / self.UNIT_LATITUDE_DISTANCE self.TOTAL_GRID_ROWS = int((self.max_latitude - self.min_latitude) / self.GRID_INTERVAL_LATITUDE) + 1 self.TOTAL_GRID_COLS = int((self.max_longitude - self.min_longitude) / self.GRID_INTERVAL_LONGITUDE) + 1
def Dijkstra(self, road_id, segment_id, roads, road_intersections, cursor_to): INF = 999999 S = [] U = [] row1, col1 = self.lon_lat_to_grid_row_col( roads[road_id][segment_id][0], roads[road_id][segment_id][1]) row2, col2 = self.lon_lat_to_grid_row_col( roads[road_id][segment_id + 1][0], roads[road_id][segment_id + 1][1]) row_l = max(0, min(row1, row2) - 1) row_h = min( self.TOTAL_GRID_ROWS - 1, max(row1, row2) + 1 ) #index is one less than actual number, so the max index is TOTAL_GRID_ROWS -1 col_l = max(0, min(col1, col2) - 1) col_h = min(self.TOTAL_GRID_COLS - 1, max(col1, col2) + 1) search_range = [] for i in range(row_l, row_h + 1): for j in range(col_l, col_h + 1): search_range += self.grid_road_index[i][j] search_range = set(search_range) # remove the duplicated elements SegmentDistance = {} for r in search_range: SegmentDistance[r] = [ INF, -1, -1 ] #First is distance from this segment, Second and Third are road_id and seg_id of the previous segment in shortest path U.append(r) SegmentDistance[(road_id, segment_id)] = [0, road_id, segment_id] while len(U) != 0: minimum = INF for seg in U: if SegmentDistance[seg][0] < minimum: minimum = SegmentDistance[seg][0] minidx = seg if minimum == INF: break S.append(minidx) U.remove(minidx) lon1 = roads[minidx[0]][minidx[1]][0] lat1 = roads[minidx[0]][minidx[1]][1] lon2 = roads[minidx[0]][minidx[1] + 1][0] lat2 = roads[minidx[0]][minidx[1] + 1][1] length = map_dist(lon1, lat1, lon2, lat2) if minidx[ 0] in road_intersections: #renew all intersected segments for ist in road_intersections[minidx[0]]: if ist[2] == minidx[1]: neighbor = ist[3] else: continue if not SegmentDistance.has_key(neighbor): continue if minimum + length < SegmentDistance[neighbor][0]: SegmentDistance[neighbor][0] = minimum + length SegmentDistance[neighbor][1:] = minidx if minidx[1] > 0 and SegmentDistance.has_key( (minidx[0], minidx[1] - 1)): #renew adjacent segment in the same road if minimum + length < SegmentDistance[(minidx[0], minidx[1] - 1)][0]: SegmentDistance[(minidx[0], minidx[1] - 1)][0] = minimum + length SegmentDistance[(minidx[0], minidx[1] - 1)][1:] = minidx if minidx[1] < len( roads[minidx[0]]) - 2 and SegmentDistance.has_key( (minidx[0], minidx[1] + 1)): #renew adjacent segment in the same road if minimum + length < SegmentDistance[(minidx[0], minidx[1] + 1)][0]: SegmentDistance[(minidx[0], minidx[1] + 1)][0] = minimum + length SegmentDistance[(minidx[0], minidx[1] + 1)][1:] = minidx l0 = map_dist(roads[road_id][segment_id][0], roads[road_id][segment_id][1], roads[road_id][segment_id + 1][0], roads[road_id][segment_id + 1][1]) for seg in S: if SegmentDistance[seg][0] <= INF and SegmentDistance[seg][0] > 0: distance = max(0, SegmentDistance[seg][0] - l0) sql = "INSERT INTO shortest_path(src_roadid,src_segmentid,dst_roadid,dst_segmentid,prev_roadid,prev_segmentid,dist) values(%d,%d,%d,%d,%d,%d,%f)" % ( road_id, segment_id, seg[0], seg[1], SegmentDistance[seg][1], SegmentDistance[seg][2], distance) cursor_to.execute(sql) self.num_sp += 1 print "Shortest Path %8d from %4d/%4d-%3d to %4d-%3d prev: %4d-%3d dist:%8.3f" % ( self.num_sp, road_id, len(roads) - 1, segment_id, seg[0], seg[1], SegmentDistance[seg][1], SegmentDistance[seg][2], distance)
def Dijkstra(self, road_id, segment_id, roads, road_intersections, cursor_to): INF = 999999 S = [] U = [] row1, col1 = self.lon_lat_to_grid_row_col(roads[road_id][segment_id][0], roads[road_id][segment_id][1]) row2, col2 = self.lon_lat_to_grid_row_col(roads[road_id][segment_id + 1][0], roads[road_id][segment_id + 1][1]) row_l = max(0, min(row1, row2) - 1) row_h = min( self.TOTAL_GRID_ROWS - 1, max(row1, row2) + 1 ) # index is one less than actual number, so the max index is TOTAL_GRID_ROWS -1 col_l = max(0, min(col1, col2) - 1) col_h = min(self.TOTAL_GRID_COLS - 1, max(col1, col2) + 1) search_range = [] for i in range(row_l, row_h + 1): for j in range(col_l, col_h + 1): search_range += self.grid_road_index[i][j] search_range = set(search_range) # remove the duplicated elements SegmentDistance = {} for r in search_range: SegmentDistance[r] = [ INF, -1, -1, ] # First is distance from this segment, Second and Third are road_id and seg_id of the previous segment in shortest path U.append(r) SegmentDistance[(road_id, segment_id)] = [0, road_id, segment_id] while len(U) != 0: minimum = INF for seg in U: if SegmentDistance[seg][0] < minimum: minimum = SegmentDistance[seg][0] minidx = seg if minimum == INF: break S.append(minidx) U.remove(minidx) lon1 = roads[minidx[0]][minidx[1]][0] lat1 = roads[minidx[0]][minidx[1]][1] lon2 = roads[minidx[0]][minidx[1] + 1][0] lat2 = roads[minidx[0]][minidx[1] + 1][1] length = map_dist(lon1, lat1, lon2, lat2) if minidx[0] in road_intersections: # renew all intersected segments for ist in road_intersections[minidx[0]]: if ist[2] == minidx[1]: neighbor = ist[3] else: continue if not SegmentDistance.has_key(neighbor): continue if minimum + length < SegmentDistance[neighbor][0]: SegmentDistance[neighbor][0] = minimum + length SegmentDistance[neighbor][1:] = minidx if minidx[1] > 0 and SegmentDistance.has_key( (minidx[0], minidx[1] - 1) ): # renew adjacent segment in the same road if minimum + length < SegmentDistance[(minidx[0], minidx[1] - 1)][0]: SegmentDistance[(minidx[0], minidx[1] - 1)][0] = minimum + length SegmentDistance[(minidx[0], minidx[1] - 1)][1:] = minidx if minidx[1] < len(roads[minidx[0]]) - 2 and SegmentDistance.has_key( (minidx[0], minidx[1] + 1) ): # renew adjacent segment in the same road if minimum + length < SegmentDistance[(minidx[0], minidx[1] + 1)][0]: SegmentDistance[(minidx[0], minidx[1] + 1)][0] = minimum + length SegmentDistance[(minidx[0], minidx[1] + 1)][1:] = minidx l0 = map_dist( roads[road_id][segment_id][0], roads[road_id][segment_id][1], roads[road_id][segment_id + 1][0], roads[road_id][segment_id + 1][1], ) for seg in S: if SegmentDistance[seg][0] <= INF and SegmentDistance[seg][0] > 0: distance = max(0, SegmentDistance[seg][0] - l0) sql = ( "INSERT INTO shortest_path(src_roadid,src_segmentid,dst_roadid,dst_segmentid,prev_roadid,prev_segmentid,dist) values(%d,%d,%d,%d,%d,%d,%f)" % (road_id, segment_id, seg[0], seg[1], SegmentDistance[seg][1], SegmentDistance[seg][2], distance) ) cursor_to.execute(sql) self.num_sp += 1 print "Shortest Path %8d from %4d/%4d-%3d to %4d-%3d prev: %4d-%3d dist:%8.3f" % ( self.num_sp, road_id, len(roads) - 1, segment_id, seg[0], seg[1], SegmentDistance[seg][1], SegmentDistance[seg][2], distance, )