Пример #1
0
	def process(self):
		"""A trip has just ended. What do we do with it?"""
		# As this may be being REprocessed we need to clean up any traces of the 
		# result of earlier processing so that we have a fresh start
		db.scrub_trip(self.trip_id)
		# see if we have enough stuff to bother with
		if len(self.vehicles) < 5: # km
			return db.ignore_trip(self.trip_id,'too few vehicles')
		# calculate vector of segment speeds
		self.segment_speeds = self.get_segment_speeds()
		# check for very short trips
		if self.length < 0.8: # km
			return db.ignore_trip(self.trip_id,'too short')
		# check for errors and attempt to correct them
		while self.has_errors():
			# make sure it's still long enough to bother with
			if len(self.vehicles) < 5:
				return db.ignore_trip(self.trip_id,'processing made too short')
			# still long enough to try fixing
			self.fix_error()
			# update the segment speeds for the next iteration
			self.segment_speeds = self.get_segment_speeds()
		# trip is clean, so store the cleaned line 
		db.set_trip_clean_geom(
			self.trip_id,
			dumpWKB( self.get_geom(), hex=True )
		)
		# get the stops (as a list of Stop objects)
		self.stops = db.get_stops(self.direction_id,self.last_seen)
		# and begin matching
		self.map_match_trip()
		if not self.match.is_useable:
			return db.ignore_trip(self.trip_id,'match problem')
		self.interpolate_stop_times()
Пример #2
0
 def process(self):
     """A trip has just ended. What do we do with it?"""
     # As this may be being REprocessed we need to clean up any traces of the
     # result of earlier processing so that we have a fresh start
     db.scrub_trip(self.trip_id)
     # see if we have enough stuff to bother with
     if len(self.vehicles) < 5:  # km
         return db.ignore_trip(self.trip_id, 'too few vehicles')
     # calculate vector of segment speeds
     self.segment_speeds = self.get_segment_speeds()
     # check for very short trips
     if self.length < 0.8:  # km
         return db.ignore_trip(self.trip_id, 'too short')
     # check for errors and attempt to correct them
     while self.has_errors():
         # make sure it's still long enough to bother with
         if len(self.vehicles) < 5:
             return db.ignore_trip(self.trip_id,
                                   'processing made too short')
         # still long enough to try fixing
         self.fix_error()
         # update the segment speeds for the next iteration
         self.segment_speeds = self.get_segment_speeds()
     # trip is clean, so store the cleaned line
     db.set_trip_clean_geom(self.trip_id, dumpWKB(self.get_geom(),
                                                  hex=True))
     # and begin matching
     self.map_match_trip()
     if len(self.vehicles) == 0:
         return db.ignore_trip(
             self.trip_id, 'too many vehicles removed during measurement')
     self.interpolate_stop_times()
Пример #3
0
    def get_geom(self):
        """return a clean WKB geometry string using all vehicles
			in the local projection"""
        line = []
        for v in self.vehicles:
            line.append(v['geom'])
        return dumpWKB(LineString(line), hex=True)
Пример #4
0
    def save(self):
        """Store a record of this trip in the DB. This allows us to 
			reprocess as from the beginning with different parameters, 
			data, etc. GPS points are stored as an array of times and 
			a linestring. This function is to be called just before 
			process() as data is being collected."""
        times = []
        for v in self.vehicles:
            times.append(v.time)
        db.insert_trip(self.trip_id, self.block_id, self.route_id,
                       self.direction_id, self.vehicle_id, times,
                       dumpWKB(self.get_geom(), hex=True))
Пример #5
0
    def map_match_trip(self):
        """1) Match the trip GPS points to the road network, id est, improve
			the spatial accuracy of the trip.
			2) Get the location/measure of stops and vehicles along the path.
			4) Interpolate sequence of stop_times from vehicle times."""
        # create a match object, passing it this trip to get it started
        self.match = map_api.match(self)
        if not self.match.is_useable:
            return db.ignore_trip(self.trip_id, 'match problem')
        # store the match info and geom in the DB
        db.add_trip_match(self.trip_id, self.match.confidence,
                          dumpWKB(self.match.geometry, hex=True))
        # find the measure of the vehicles for time interpolation
        self.match.locate_vehicles_on_route()
Пример #6
0
	def map_match_trip(self):
		"""Match the trip GPS points to the road network, ie, improve
			the spatial accuracy of the trip. Get the location/measure of stops 
			and vehicles along the path."""
		# create a match object, passing it this trip to get it started
		self.match = map_api.match(self)
		if not self.match.is_useable:
			return db.ignore_trip(self.trip_id,'match problem')
		# store the match info and geom in the DB
		db.add_trip_match(
			self.trip_id,
			self.match.confidence,
			dumpWKB(self.match.geometry,hex=True)
		)
Пример #7
0
	def save(self):
		"""Store a record of this trip in the DB. This allows us to 
			reprocess as from the beginning with different parameters, 
			data, etc. GPS points are stored as an array of times and 
			a linestring. This function is to be called just before 
			process() as data is being collected."""
		db.insert_trip(
			self.trip_id,
			self.block_id,
			self.route_id, 
			self.direction_id,
			self.vehicle_id,
			[ v.time for v in self.vehicles ],
			dumpWKB( self.get_geom(), hex=True )
		)
Пример #8
0
    dest = random_point(zones[trip_dest])

    # create and send the request
    response = requests.get('http://localhost:5000/route/v1/bicycle/' +
                            str(orig.x) + ',' + str(orig.y) + ';' +
                            str(dest.x) + ',' + str(dest.y),
                            params=options,
                            timeout=1)
    # parse the output
    j = json.loads(response.text)
    if j['code'] != 'Ok':
        print(response.text, '\n')
        continue
    # good respone - now parse and store it
    results = {}
    results['uid'] = trip_uid
    results['network_distance'] = j['routes'][0]['distance']
    results['orig_geom'] = dumpWKB(orig)
    results['dest_geom'] = dumpWKB(dest)
    results['path_geom'] = dumpWKB(asShape(j['routes'][0]['geometry']))

    cursor2.execute(
        """
		UPDATE syn_trips SET 
			network_trip_distance = %(network_distance)s,
			orig_geog = %(orig_geom)s::geography,
			dest_geog = %(dest_geom)s::geography,
			network_trip_geog = %(path_geom)s::geography
		WHERE uid = %(uid)s;
	""", results)
Пример #9
0
			edgeB.forward_count * edgeB.geometry.length
		) / newGeom.length )
	new_reverse_count = round( (
			edgeA.reverse_count * edgeA.geometry.length + 
			edgeB.reverse_count * edgeB.geometry.length
		) / newGeom.length )
	# delete the first edge and update the second one
	edge_cursor.execute("""
		UPDATE street_edges SET 
			node_1 = %(node_1)s, 
			node_2 = %(node_2)s,
			r = %(r)s,
			f = %(f)s,
			edge = ST_SetSRID(%(geom)s::geometry,3857),
			renovated = TRUE
		WHERE uid = %(edge1id)s;
		DELETE FROM street_edges WHERE uid = %(edge2id)s;
	""",{
		'edge1id':edgeA.db_uid,
		'edge2id':edgeB.db_uid,
		'node_1': new_from_id,
		'node_2': new_to_id,
		'f':new_forward_count,
		'r':new_reverse_count,
		'geom': dumpWKB( newGeom, hex=True )
	})
	connection.commit()



Пример #10
0
    def match(self):
        """Match the trip to the road network, and do all the
			things that follow therefrom."""
        match = map_api.match(self.vehicles)
        if not match.is_useable:
            return db.ignore_trip(self.trip_id, 'match problem')
        self.match_confidence = match.confidence
        # store the trip geometry
        self.match_geom = match.geometry()
        # and reproject it
        self.match_geom = reproject(conf['projection'], self.match_geom)
        # simplify slightly for speed (2 meter simplification)
        self.match_geom = self.match_geom.simplify(2)
        # if the multi actually just had one line, this simplifies to a
        # linestring, which can cause problems down the road
        if self.match_geom.geom_type == 'LineString':
            self.match_geom = MultiLineString([self.match_geom])
        # store the match info and geom in the DB
        db.add_trip_match(self.trip_id, self.match_confidence,
                          dumpWKB(self.match_geom, hex=True))
        # drop vehicles that did not contribute to the match
        vehicles_used = match.vehicles_used()
        for i in reversed(range(0, len(self.vehicles))):
            if not vehicles_used[i]: del self.vehicles[i]
        # get distances of each vehicle along the match geom
        for vehicle, cum_dist in zip(self.vehicles, match.cum_distances()):
            vehicle['cum_dist'] = cum_dist
        # However, because we've simplified the line, the distances will be slightly off
        # and need correcting
        adjust_factor = self.match_geom.length / self.vehicles[-1]['cum_dist']
        for v in self.vehicles:
            v['cum_dist'] = v['cum_dist'] * adjust_factor
        # get the stops as a list of objects
        # with keys {'id':stop_id,'g':geom}
        self.stops = db.get_stops(self.direction_id, self.last_seen)
        # process the geoms
        for stop in self.stops:
            stop['geom'] = loadWKB(stop['geom'], hex=True)
        # now match stops to the trip geometry, 750m at a time
        path = self.match_geom
        traversed = 0
        # while there is more than 750m of path remaining
        while path.length > 0:
            subpath, path = cut(path, 750)
            # check for nearby stops
            for stop in self.stops:
                # if the stop is close enough
                stop_dist = subpath.distance(stop['geom'])
                if stop_dist <= conf['stop_dist']:
                    # measure how far it is along the trip
                    measure = traversed + subpath.project(stop['geom'])
                    # add it to a list of possible stop times
                    self.add_arrival(stop['id'], measure, stop_dist)
            # note what we have already traversed
            traversed += 750
        # sort stops by arrival time
        self.timepoints = sorted(self.timepoints, key=lambda k: k['time'])
        # there is more than one stop, right?
        if len(self.timepoints) > 1:
            # store the stop times
            db.store_timepoints(self.trip_id, self.timepoints)
            # Now set the service_id, which is the (local) DAY equivalent of
            # the unix epoch, which is centered on Greenwich.
            # (The service_id is distinct to a day in the local timezone)
            # First, shift the second_based epoch to local time
            tlocal = self.timepoints[0]['time'] + conf['timezone'] * 3600
            # then find the "epoch day"
            service_id = math.floor(tlocal / (24 * 3600))
            # and store it in the DB
            db.set_service_id(self.trip_id, service_id)
        else:
            db.ignore_trip(self.trip_id, 'one or fewer timepoints')
        return