async def get_nearby_stops(db, lat: float, lon: float, radius: int): """ Get stops in the specified radius (in meters) """ radius_in_km = radius/1000 latlon = (lat, lon) # Build the (square) bounding box distance = geopy.distance.distance() north = distance.destination(latlon, 0, radius_in_km).latitude east = distance.destination(latlon, 90, radius_in_km).longitude south = distance.destination(latlon, 180, radius_in_km).latitude west = distance.destination(latlon, -90, radius_in_km).longitude # Get a list of stops stops = await db.all(Stop.query. where(Stop.stop_lon < east). where(Stop.stop_lon > west). where(Stop.stop_lat < north). where(Stop.stop_lat > south)) # the gino way to do sql AND is ugly :( ret = [] for stop in stops: dist = geopy.distance.distance(latlon, (stop.stop_lat, stop.stop_lon)).meters # Narrow down the returned list into a circular radius if dist <= radius: name = await Translation.get(db, stop.stop_name) ret.append({"code": stop.stop_code, "name": name, "distance": round(dist, 2), "location": {"lat": stop.stop_lat, "lon": stop.stop_lon}}) return ret
def get_location_by_offset_meters_and_heading(self, distance, heading): """Get Position in passed distance meters and heading degrees. """ distance = geopy.distance.distance(meters=distance) destination = distance.destination(geopy.Point(self.lat, self.lon), heading) return Position(lat=destination.latitude, lon=destination.longitude, alt=self.alt)
def _get_location_vincenty(self, dist): #Replaced by Loc + dist/Loc - dist """Return a latitude and a longitude dist away from the Location object using the Vincenty method from Geopy. """ point = (degrees(self.lat), degrees(self.lon)) distance = geopy.distance.VincentyDistance( kilometers=dist.get_magnitude() / 1000) bearing = degrees(dist.get_bearing()) out = distance.destination(point=point, bearing=bearing) return (radians(out.latitude), radians(out.longitude))
def get_fake_position(self, speed=None, last_direction=None, last_latitude=None, last_longitude=None): """Returns a new {latitude, longitude} position from generated or provided speed, direction, and last position. Keyword arguments: speed -- provided speed to abide (default None) last_direction -- previous heading (default None) last_latitude -- previous latitude (default None) last_longitude -- previous longitude (default None) """ new_speed = 0 new_latitude = 0.0 new_longitude = 0.0 new_direction = 0 if speed is None: if last_latitude is None and last_longitude is None: new_speed = self.get_fake_speed( last_speed=random.randint(3, 8)) else: new_speed = self.get_fake_speed() else: # speed was provided, do not create fake new_speed = speed if last_direction is None: new_direction = self.get_fake_direction() else: new_direction = self.get_fake_direction( last_direction=last_direction) if last_latitude is not None and last_longitude is not None: distance_traveled = new_speed * 1.852 # distance in km, from nm start = geopy.Point(last_latitude, last_longitude) distance = geopy.distance.VincentyDistance( kilometers=distance_traveled) end = distance.destination(point=start, bearing=new_direction) new_latitude = end.latitude new_longitude = end.longitude else: # a latitude or longitude was provided, but both were not new_latitude = random.uniform(-90, 90) new_longitude = random.uniform(-180, 180) new_position = {"latitude": new_latitude, "longitude": new_longitude} return new_position
def filter(select, query): if query.start is not None: select = select.where(measurements.c.recorded >= query.start) if query.end is not None: select = select.where(measurements.c.recorded <= query.end) if query.source is not None: select = select.where(measurements.c.source == query.source) if query.distance is not None: longitude = query.longitude if query.longitude is not None else 0.0 latitude = query.latitude if query.latitude is not None else 0.0 location = geopy.Point(latitude, longitude) distance = geopy.distance.distance(kilometers=query.distance) north = distance.destination(point=location, bearing=0) east = distance.destination(point=location, bearing=90) south = distance.destination(point=location, bearing=180) west = distance.destination(point=location, bearing=270) select = select.where(measurements.c.latitude <= north.latitude) select = select.where(measurements.c.longitude <= east.longitude) select = select.where(measurements.c.latitude >= south.latitude) select = select.where(measurements.c.longitude >= west.longitude) return select
def index(self, document): """ The method that actually performs the indexing. :param document: The document as a memory file. """ from django.contrib.gis.geos import ( Point, LineString, MultiLineString) from obspy import read_events # Collect all indices in a list. Each index has to be a dictionary. indices = [] inv = read_events(document, format="quakeml") for event in inv: if event.origins: org = event.preferred_origin() or event.origins[0] else: org = None if event.magnitudes: mag = event.preferred_magnitude() or event.magnitudes[0] else: mag = None has_focal_mechanism = False has_moment_tensor = False if event.focal_mechanisms: has_focal_mechanism = True if any(mt for mt in event.focal_mechanisms): has_moment_tensor = True # Parse attributes in the baynet namespace. # The public attribute defaults to None, it can only be set to # True by utilizing the baynet namespace as of now. extra = event.get("extra", {}) if "public" in extra: public = extra["public"]["value"] if public.lower() in ["false", "f"]: public = False elif public.lower() in ["true", "t"]: public = True else: public = None else: public = None if "evaluationMode" in extra: evaluation_mode = extra["evaluationMode"]["value"] else: evaluation_mode = None # parse horizontal uncertainties if org and org.origin_uncertainty: org_unc = org.origin_uncertainty if org_unc.preferred_description == 'horizontal uncertainty': horizontal_uncertainty_max = org_unc.horizontal_uncertainty horizontal_uncertainty_min = org_unc.horizontal_uncertainty horizontal_uncertainty_max_azimuth = 0 elif org_unc.preferred_description == 'uncertainty ellipse': horizontal_uncertainty_max = \ org_unc.max_horizontal_uncertainty horizontal_uncertainty_min = \ org_unc.min_horizontal_uncertainty horizontal_uncertainty_max_azimuth = \ org_unc.azimuth_max_horizontal_uncertainty else: horizontal_uncertainty_max = None horizontal_uncertainty_min = None horizontal_uncertainty_max_azimuth = None else: horizontal_uncertainty_max = None horizontal_uncertainty_min = None horizontal_uncertainty_max_azimuth = None geometry = None if org: geometry = [Point(org.longitude, org.latitude)] if all(value is not None for value in ( horizontal_uncertainty_max, horizontal_uncertainty_min, horizontal_uncertainty_max_azimuth)): import geopy import geopy.distance start = geopy.Point(latitude=org.latitude, longitude=org.longitude) lines = [] for distance, azimuth in ( (horizontal_uncertainty_max, horizontal_uncertainty_max_azimuth), (horizontal_uncertainty_min, horizontal_uncertainty_max_azimuth + 90)): azimuth = azimuth % 180 distance = geopy.distance.VincentyDistance( kilometers=distance / 1e3) end1 = distance.destination( point=start, bearing=azimuth) end2 = distance.destination( point=start, bearing=azimuth + 180) line = LineString((end1.longitude, end1.latitude), (org.longitude, org.latitude), (end2.longitude, end2.latitude)) lines.append(line) geometry.append(MultiLineString(lines)) else: geometry.append(MultiLineString([])) # phase counts used_phase_count = None used_p = None used_s = None if org: if org.quality: used_phase_count = org.quality.used_phase_count if org.quality and org.quality.get('extra'): extra = org.quality.get('extra', {}) used_p = extra.get( 'usedPhaseCountP', {}).get('value', None) used_s = extra.get( 'usedPhaseCountS', {}).get('value', None) if used_p is not None: used_p = int(used_p) if used_s is not None: used_s = int(used_s) # set first/last pick times first_pick_time = None last_pick_time = None if event.picks: pick_times = [ pick.time for pick in event.picks if pick.time is not None] if pick_times: first_pick_time = str(min(pick_times)) last_pick_time = str(max(pick_times)) indices.append({ "quakeml_id": str(event.resource_id), "latitude": org.latitude if org else None, "longitude": org.longitude if org else None, "depth_in_m": org.depth if org else None, "origin_time": str(org.time) if org else None, "first_pick_time": first_pick_time, "last_pick_time": last_pick_time, "used_phase_count": used_phase_count, "used_p": used_p, "used_s": used_s, "magnitude": mag.mag if mag else None, "magnitude_type": mag.magnitude_type if mag else None, "agency": event.creation_info and event.creation_info.agency_id or None, "author": event.creation_info and event.creation_info.author or None, "public": public, "evaluation_mode": evaluation_mode, "event_type": event.event_type, "has_focal_mechanism": has_focal_mechanism, "has_moment_tensor": has_moment_tensor, # The special key geometry can be used to store geographic # information about the indexes geometry. Useful for very # fast queries using PostGIS. "geometry": geometry, "horizontal_uncertainty_max": horizontal_uncertainty_max, "horizontal_uncertainty_min": horizontal_uncertainty_min, "horizontal_uncertainty_max_azimuth": horizontal_uncertainty_max_azimuth, }) return indices
def index(self, document): """ The method that actually performs the indexing. :param document: The document as a memory file. """ from django.contrib.gis.geos import ( Point, LineString, MultiLineString) from obspy import read_events # Collect all indices in a list. Each index has to be a dictionary. indices = [] inv = read_events(document, format="quakeml") for event in inv: if event.origins: org = event.preferred_origin() or event.origins[0] else: org = None if event.magnitudes: mag = event.preferred_magnitude() or event.magnitudes[0] else: mag = None has_focal_mechanism = False has_moment_tensor = False if event.focal_mechanisms: has_focal_mechanism = True if any(mt for mt in event.focal_mechanisms): has_moment_tensor = True # Parse attributes in the baynet namespace. # The public attribute defaults to True, it can only be set to # False by utilizing the baynet namespace as of now. extra = event.get("extra", {}) if "public" in extra: public = extra["public"]["value"] if public.lower() in ["false", "f"]: public = False elif public.lower() in ["true", "t"]: public = True else: public = None else: public = True if "evaluationMode" in extra: evaluation_mode = extra["evaluationMode"]["value"] else: evaluation_mode = None # parse horizontal uncertainties if org and org.origin_uncertainty: org_unc = org.origin_uncertainty if org_unc.preferred_description == 'horizontal uncertainty': horizontal_uncertainty_max = org_unc.horizontal_uncertainty horizontal_uncertainty_min = org_unc.horizontal_uncertainty horizontal_uncertainty_max_azimuth = 0 elif org_unc.preferred_description == 'uncertainty ellipse': horizontal_uncertainty_max = \ org_unc.max_horizontal_uncertainty horizontal_uncertainty_min = \ org_unc.min_horizontal_uncertainty horizontal_uncertainty_max_azimuth = \ org_unc.azimuth_max_horizontal_uncertainty else: horizontal_uncertainty_max = None horizontal_uncertainty_min = None horizontal_uncertainty_max_azimuth = None else: horizontal_uncertainty_max = None horizontal_uncertainty_min = None horizontal_uncertainty_max_azimuth = None geometry = None if org: geometry = [Point(org.longitude, org.latitude)] if all(value is not None for value in ( horizontal_uncertainty_max, horizontal_uncertainty_min, horizontal_uncertainty_max_azimuth)): import geopy import geopy.distance start = geopy.Point(latitude=org.latitude, longitude=org.longitude) lines = [] for distance, azimuth in ( (horizontal_uncertainty_max, horizontal_uncertainty_max_azimuth), (horizontal_uncertainty_min, horizontal_uncertainty_max_azimuth + 90)): azimuth = azimuth % 180 distance = geopy.distance.VincentyDistance( kilometers=distance / 1e3) end1 = distance.destination( point=start, bearing=azimuth) end2 = distance.destination( point=start, bearing=azimuth + 180) line = LineString((end1.longitude, end1.latitude), (org.longitude, org.latitude), (end2.longitude, end2.latitude)) lines.append(line) geometry.append(MultiLineString(lines)) else: geometry.append(MultiLineString([])) indices.append({ "quakeml_id": str(event.resource_id), "latitude": org.latitude if org else None, "longitude": org.longitude if org else None, "depth_in_m": org.depth if org else None, "origin_time": str(org.time) if org else None, "magnitude": mag.mag if mag else None, "magnitude_type": mag.magnitude_type if mag else None, "agency": event.creation_info and event.creation_info.agency_id or None, "author": event.creation_info and event.creation_info.author or None, "public": public, "evaluation_mode": evaluation_mode, "event_type": event.event_type, "has_focal_mechanism": has_focal_mechanism, "has_moment_tensor": has_moment_tensor, # The special key geometry can be used to store geographic # information about the indexes geometry. Useful for very # fast queries using PostGIS. "geometry": geometry, "horizontal_uncertainty_max": horizontal_uncertainty_max, "horizontal_uncertainty_min": horizontal_uncertainty_min, "horizontal_uncertainty_max_azimuth": horizontal_uncertainty_max_azimuth, }) return indices