def wrap_for_tripkit(diary): tripkit_trips = [] for idx, detected_trip in enumerate(diary['trips']): trip_num = idx + 1 if idx in diary['missing']: trip = LibraryTrip(num=trip_num, trip_code=101) start, end = detected_trip p1 = LibraryTripPoint( database_id=None, latitude=start.latitude, longitude=start.longitude, h_accuracy=0.0, distance_before=0.0, trip_distance=0.0, period_before=0, timestamp_UTC=start.timestamp_UTC, ) trip.points.append(p1) p2 = LibraryTripPoint( database_id=None, latitude=end.latitude, longitude=end.longitude, h_accuracy=0.0, distance_before=geo.distance_m(*detected_trip), trip_distance=geo.distance_m(*detected_trip), period_before=geo.duration_s(start, end), timestamp_UTC=end.timestamp_UTC, ) trip.points.append(p2) else: trip = LibraryTrip(num=trip_num, trip_code=1) trip_distance = 0.0 for point in detected_trip: p = LibraryTripPoint( database_id=None, latitude=point.latitude, longitude=point.longitude, h_accuracy=0.0, distance_before=point.distance_m, trip_distance=trip_distance, period_before=point.duration_s, timestamp_UTC=point.timestamp_UTC, ) trip.points.append(p) trip_distance += point.distance_m tripkit_trips.append(trip) return tripkit_trips
def detect_activity_location_overlap(uuid, locations, activity_proximity_m): for loc1, loc2 in itertools.combinations(locations, 2): distance_between_m = geo.distance_m(loc1, loc2) if distance_between_m <= (activity_proximity_m * 2): logger.warn( f"possible overlap in activity locations: {uuid} {loc1.label}-->{loc2.label} ({distance_between_m} m)" )
def _truncate_trace(coordinates, location, reverse=False): last_c = None last_dist_m = 10e16 truncate_idx = None if reverse: coordinates = list(reversed(coordinates)) for idx, c in enumerate(coordinates): if not last_c: # only truncate within 200m of stop location skip_c = location and geo.distance_m(c, location) > 200 if not skip_c: last_c = c continue dist_m = geo.distance_m(last_c, c) if dist_m < last_dist_m: last_dist_m = dist_m else: truncate_idx = idx break truncated = coordinates[:truncate_idx] if reverse: return list(reversed(truncated)) return truncated
def filter_too_short_segments(segments, min_distance_m=250): for segment in segments: if not segment: continue centroid = geo.centroid(segment) segment_is_valid = False for c in segment: if geo.distance_m(c, centroid) > min_distance_m: segment_is_valid = True break if segment_is_valid: yield segment
def condense_overlaps(centroids): G = networkx.Graph() connected = set() for ce1 in centroids: for ce2 in centroids: if ce1 == ce2: continue if geo.distance_m(ce1, ce2) <= CENTROID_OVERLAP_M: G.add_edge(ce1, ce2) connected.update((ce1, ce2)) unconnected = set(centroids) - connected condensed = [geo.centroid(cc) for cc in networkx.connected_components(G)] for ce in unconnected: condensed.append(ce) return condensed
def detect_missing_segments(segments, missing_segment_m=250): ''' Returns a list of missing segments consisting of the last valid segment end point and the next valid segment start point. ''' missing_segments = [] last_segment = None for segment in segments: if not last_segment: last_segment = segment continue segments_gap = geo.distance_m(last_segment[-1], segment[0]) if segments_gap > missing_segment_m: missing_segments.append([last_segment[-1], segment[0]]) last_segment = segment return missing_segments
def run(user, timezone=None): ''' Summarizes detected trips information as dictionary records for writing to .csv with each trip condensed to a single row. :param user: A py:class:`tripkit.models.User` object with detected trip information. :param tz: (Optional) A pytz timezone object for localizing the trip start and end times for UTC to the survey region's timezone. :type user: class:`tripkit.models.User` :type tz: datetime.tzinfo ''' if timezone: tz = pytz.timezone(timezone) records = [] for t in user.trips: t.start.easting, t.start.northing, _, _ = utm.from_latlon( t.start.latitude, t.start.longitude) t.end.easting, t.end.northing, _, _ = utm.from_latlon( t.end.latitude, t.end.longitude) r = { 'uuid': user.uuid, 'trip_id': t.num, 'start_UTC': t.start_UTC, 'end_UTC': t.end_UTC, 'trip_code': t.trip_code, 'olat': t.start.latitude, 'olon': t.start.longitude, 'dlat': t.end.latitude, 'dlon': t.end.longitude, 'direct_distance': geo.distance_m(t.start, t.end), 'cumulative_distance': t.distance, } if timezone: r['start'] = pytz.utc.localize(t.start_UTC).astimezone(tz) r['end'] = pytz.utc.localize(t.end_UTC).astimezone(tz) records.append(r) return records
def _intersects(point, iterpoints, dist_m=50): for test_point in iterpoints: if geo.distance_m(point, test_point) <= 50: return test_point
def _nearest_location(c, locations, buffer_m=100): for location in locations: if geo.distance_m(c, location) <= buffer_m: return location.label