Beispiel #1
0
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
Beispiel #2
0
 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)
Beispiel #3
0
    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))
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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