Пример #1
0
def project(
        bbox: s2.LatLngRect, size: XY, offset: XY,
        latlnglines: List[List[s2.LatLng]]) -> List[List[Tuple[float, float]]]:
    min_x = lng2x(bbox.lng_lo().degrees)
    d_x = lng2x(bbox.lng_hi().degrees) - min_x
    while d_x >= 2:
        d_x -= 2
    while d_x < 0:
        d_x += 2
    min_y = lat2y(bbox.lat_lo().degrees)
    max_y = lat2y(bbox.lat_hi().degrees)
    d_y = abs(max_y - min_y)

    scale = size.x / d_x if size.x / size.y <= d_x / d_y else size.y / d_y
    offset = offset + 0.5 * (size - scale * XY(d_x, -d_y)) - scale * XY(
        min_x, min_y)
    lines = []
    for latlngline in latlnglines:
        line = []
        for latlng in latlngline:
            if bbox.contains(latlng):
                line.append((offset + scale * latlng2xy(latlng)).tuple())
            else:
                if len(line) > 0:
                    lines.append(line)
                    line = []
        if len(line) > 0:
            lines.append(line)
    return lines
Пример #2
0
 def add_missing_flight(self, observer_name: str,
                        injected_flight: InjectedFlight,
                        rect: s2sphere.LatLngRect, injection_target: str,
                        query: fetch.Query) -> None:
     flight_id = injected_flight.flight.details_responses[0].details.id
     timestamp = datetime.datetime.utcnow(
     )  #TODO: Use query timestamp instead
     span = injected_flight.flight.get_span()
     self.issues.append(
         Issue(
             test_code='MISSING_FLIGHT',
             relevant_requirements=['NET0610'],
             severity=Severity.Critical,
             injection_target=injection_target,
             observation_source=observer_name,
             subject=flight_id,
             summary='Expected flight not found',
             details=
             'Flight {} (from {} to {}) was expected inside ({}, {})-({}, {}) when {} was queried at {}'
             .format(flight_id, span[0], span[1],
                     rect.lo().lat().degrees,
                     rect.lo().lng().degrees,
                     rect.hi().lat().degrees,
                     rect.hi().lng().degrees, observer_name, timestamp),
             queries=[query]))
Пример #3
0
def vertices_from_latlng_rect(rect: s2sphere.LatLngRect) -> List[Dict[str, float]]:
  return [
    {'lat': rect.lat_lo().degrees, 'lng': rect.lng_lo().degrees},
    {'lat': rect.lat_lo().degrees, 'lng': rect.lng_hi().degrees},
    {'lat': rect.lat_hi().degrees, 'lng': rect.lng_hi().degrees},
    {'lat': rect.lat_hi().degrees, 'lng': rect.lng_lo().degrees},
  ]
Пример #4
0
 def _determine_center(b: s2sphere.LatLngRect) -> s2sphere.LatLng:
     y1 = math.log((1 + math.sin(b.lat_lo().radians)) /
                   (1 - math.sin(b.lat_lo().radians))) / 2
     y2 = math.log((1 + math.sin(b.lat_hi().radians)) /
                   (1 - math.sin(b.lat_hi().radians))) / 2
     lat = math.atan(math.sinh((y1 + y2) / 2)) * 180 / math.pi
     lng = b.get_center().lng().degrees
     return s2sphere.LatLng.from_degrees(lat, lng)
Пример #5
0
def get_flights(resources: ResourceSet, flights_url: str, area: s2sphere.LatLngRect, include_recent_positions: bool) -> Dict:
  resp = resources.dss_client.get(flights_url, params={
    'view': '{},{},{},{}'.format(
      area.lat_lo().degrees,
      area.lng_lo().degrees,
      area.lat_hi().degrees,
      area.lng_hi().degrees,
    ),
    'include_recent_positions': 'true' if include_recent_positions else 'false',
  }, scope=rid.SCOPE_READ)
  return _json_or_error(resp)
Пример #6
0
def make_polygon(coords: List[Tuple[float, float]] = None,
                 latlngrect: s2sphere.LatLngRect = None) -> Dict:
    if coords is not None:
        return {
            "vertices": [{
                'lat': lat,
                'lng': lng
            } for (lat, lng) in coords]
        }

    return {
        "vertices": [
            {
                'lat': latlngrect.lat_lo().degrees,
                'lng': latlngrect.lng_lo().degrees
            },
            {
                'lat': latlngrect.lat_lo().degrees,
                'lng': latlngrect.lng_hi().degrees
            },
            {
                'lat': latlngrect.lat_hi().degrees,
                'lng': latlngrect.lng_hi().degrees
            },
            {
                'lat': latlngrect.lat_hi().degrees,
                'lng': latlngrect.lng_lo().degrees
            },
        ]
    }
Пример #7
0
def _evaluate_observation(injected_flights: List[InjectedFlight],
                          observer: RIDSystemObserver,
                          rect: s2sphere.LatLngRect, observation: Optional[
                              observation_api.GetDisplayDataResponse],
                          query: fetch.Query, config: EvaluationConfiguration,
                          findings: Findings) -> None:
    diagonal = rect.lo().get_distance(
        rect.hi()).degrees * geo.EARTH_CIRCUMFERENCE_KM / 360
    if diagonal > rid.NetMaxDisplayAreaDiagonal:
        _evaluate_area_to_large_observation(observer, diagonal, query,
                                            findings)
    elif diagonal > rid.NetDetailsMaxDisplayAreaDiagonal:
        _evaluate_clusters_observation(findings)
    else:
        _evaluate_normal_observation(injected_flights, observer, rect,
                                     observation, query, config, findings)
Пример #8
0
 def select_relevant_states(
         self, view: s2sphere.LatLngRect, t0: datetime.datetime,
         t1: datetime.datetime) -> List[rid.RIDAircraftState]:
     recent_states: List[rid.RIDAircraftState] = []
     previously_outside = False
     previously_inside = False
     previous_telemetry = None
     for telemetry in self.telemetry:
         if (telemetry.timestamp.datetime < t0
                 or telemetry.timestamp.datetime > t1):
             # Telemetry not relevant based on time
             continue
         pt = s2sphere.LatLng.from_degrees(telemetry.position.lat,
                                           telemetry.position.lng)
         inside_now = view.contains(pt)
         if inside_now:
             if previously_outside:
                 recent_states.append(previous_telemetry)
             recent_states.append(telemetry)
             previously_inside = True
             previously_outside = False
         else:
             if previously_inside:
                 recent_states.append(telemetry)
             previously_outside = True
             previously_inside = False
         previous_telemetry = telemetry
     return recent_states
Пример #9
0
 def observe_system(
     self, rect: s2sphere.LatLngRect
 ) -> Tuple[Optional[observation_api.GetDisplayDataResponse], fetch.Query]:
     initiated_at = datetime.datetime.utcnow()
     resp = self.session.get('/display_data?view={},{},{},{}'.format(
         rect.lo().lat().degrees,
         rect.lo().lng().degrees,
         rect.hi().lat().degrees,
         rect.hi().lng().degrees),
                             scope=rid.SCOPE_READ)
     try:
         result = (ImplicitDict.parse(
             resp.json(), observation_api.GetDisplayDataResponse)
                   if resp.status_code == 200 else None)
     except ValueError as e:
         result = None
     return (result, fetch.describe_query(resp, initiated_at))
Пример #10
0
 def add_observation_failure(self, observer_name: str,
                             rect: s2sphere.LatLngRect,
                             query: fetch.Query) -> None:
     self.issues.append(
         Issue(
             test_code='OBSERVATION_FAILED',
             severity=Severity.Critical,
             injection_target='N/A',
             observation_source=observer_name,
             summary='Observation attempt failed',
             details=
             'When queried for flights in ({}, {})-({}, {}), observer returned an invalid response with code {}'
             .format(rect.lo().lat().degrees,
                     rect.lo().lng().degrees,
                     rect.hi().lat().degrees,
                     rect.hi().lng().degrees, query.status_code),
             queries=[query]))
Пример #11
0
def _make_flight_observation(
        flight: rid.RIDFlight,
        view: s2sphere.LatLngRect) -> observation_api.Flight:
    paths: List[List[observation_api.Position]] = []
    current_path: List[observation_api.Position] = []
    previous_position: Optional[observation_api.Position] = None

    lat_min = view.lat_lo().degrees
    lat_max = view.lat_hi().degrees
    lng_min = view.lng_lo().degrees
    lng_max = view.lng_hi().degrees

    # Decompose recent positions into a list of contiguous paths
    for p in flight.recent_positions:
        lat = p.position.lat
        lng = p.position.lng
        position_report = observation_api.Position(lat=lat,
                                                   lng=lng,
                                                   alt=p.position.alt)

        inside_view = lat_min <= lat <= lat_max and lng_min <= lng <= lng_max
        if inside_view:
            # This point is inside the view
            if not current_path and previous_position:
                # Positions were previously outside the view but this one is in
                current_path.append(previous_position)
            current_path.append(position_report)
        else:
            # This point is outside the view
            if current_path:
                # Positions were previously inside the view but this one is out
                current_path.append(position_report)
                paths.append(current_path)
                current_path = []
        previous_position = position_report
    if current_path:
        paths.append(current_path)

    return observation_api.Flight(
        id=flight.id,
        most_recent_position=observation_api.Position(
            lat=flight.current_state.position.lat,
            lng=flight.current_state.position.lng,
            alt=flight.current_state.position.alt),
        recent_paths=[observation_api.Path(positions=path) for path in paths])
Пример #12
0
def flights(utm_client: infrastructure.DSSTestSession, flights_url: str,
            area: s2sphere.LatLngRect,
            include_recent_positions: bool) -> FetchedUSSFlights:
    result = fetch.query_and_describe(
        utm_client,
        'GET',
        flights_url,
        params={
            'view':
            '{},{},{},{}'.format(
                area.lat_lo().degrees,
                area.lng_lo().degrees,
                area.lat_hi().degrees,
                area.lng_hi().degrees,
            ),
            'include_recent_positions':
            'true' if include_recent_positions else 'false',
        },
        scope=rid.SCOPE_READ)
    return FetchedUSSFlights(result)
Пример #13
0
 def latLngRectFromQueryRectangleInput(
         self, QueryRectangleRequest: 'QueryRectangleRequest'):
     queryRectangleRequest = QueryRectangleRequest
     minPoint = queryRectangleRequest.getMinPoint()
     maxPoint = queryRectangleRequest.getMaxPoint()
     latLngRect = None
     if minPoint is not None and maxPoint is not None:
         minLatLng = S2LatLng.from_degrees(minPoint.getLatitude(),
                                           minPoint.getLongitude())
         maxLatLng = S2LatLng.from_degrees(maxPoint.getLatitude(),
                                           maxPoint.getLongitude())
         latLngRect = S2LatLngRect.from_point_pair(minLatLng, maxLatLng)
     return latLngRect
Пример #14
0
def cover_square(lat, lng, width, level=15):
    offset = int(width / 2)
    g = Geodesic.WGS84  # @UndefinedVariable
    r = RegionCoverer()
    r.min_level, r.min_level = level, level
    g1 = g.Direct(lat, lng, 360, offset)
    g1 = g.Direct(g1['lat2'], g1['lon2'], 270, offset)
    p1 = LatLng.from_degrees(g1['lat2'], g1['lon2'])
    g2 = g.Direct(lat, lng, 180, offset)
    g2 = g.Direct(g2['lat2'], g2['lon2'], 90, offset)
    p2 = LatLng.from_degrees(g2['lat2'], g2['lon2'])
    cells = r.get_covering(LatLngRect.from_point_pair(p1, p2))
    return cells
Пример #15
0
def cover_square(lat, lng, width, level=15):
    offset = int(width / 2)
    g = Geodesic.WGS84  # @UndefinedVariable
    r = RegionCoverer()
    r.min_level, r.min_level = level, level
    g1 = g.Direct(lat, lng, 360, offset)
    g1 = g.Direct(g1['lat2'],g1['lon2'],270,offset)
    p1 = LatLng.from_degrees(g1['lat2'],g1['lon2'])
    g2 = g.Direct(lat, lng, 180, offset)
    g2 = g.Direct(g2['lat2'],g2['lon2'], 90,offset)
    p2 = LatLng.from_degrees(g2['lat2'],g2['lon2'])
    cells = r.get_covering(LatLngRect.from_point_pair(p1, p2))
    return cells
Пример #16
0
def make_polygon(coords: List[Tuple[float, float]] = None,
                 latlngrect: s2sphere.LatLngRect = None) -> Polygon:
    if coords is not None:
        return Polygon(
            vertices=[LatLngPoint(lat=lat, lng=lng) for (lat, lng) in coords])

    return Polygon(vertices=[
        LatLngPoint(lat=latlngrect.lat_lo().degrees,
                    lng=latlngrect.lng_lo().degrees),
        LatLngPoint(lat=latlngrect.lat_lo().degrees,
                    lng=latlngrect.lng_hi().degrees),
        LatLngPoint(lat=latlngrect.lat_hi().degrees,
                    lng=latlngrect.lng_hi().degrees),
        LatLngPoint(lat=latlngrect.lat_hi().degrees,
                    lng=latlngrect.lng_lo().degrees),
    ])
Пример #17
0
def _bbox_polyfill(
    geo_json,
    res,
):
    """returns list of S2 ids"""

    lat, lon = _geo_json_to_extremes(geo_json)

    p1 = LatLng.from_degrees(min(lat), min(lon))
    p2 = LatLng.from_degrees(max(lat), max(lon))

    region = LatLngRect.from_point_pair(p1, p2)

    coverer = RegionCoverer()
    coverer.min_level = res
    coverer.max_level = res
    return coverer.get_covering(region)
Пример #18
0
def cover_region_s2(location1, location2):
    rc = RegionCoverer()
    rc.max_level = lvl_big
    rc.min_level = lvl_big
    rc.max_cells = 1000
    locations = []

    if location1[0] > location2[0]:
        lat1, lat2 = location2[0], location1[0]
    else:
        lat1, lat2 = location1[0], location2[0]

    if location1[1] > location2[1]:
        lng1, lng2 = location2[1], location1[1]
    else:
        lng1, lng2 = location1[1], location2[1]

    lng1 = (lng1 + 180) % 360 - 180
    lng2 = (lng2 + 180) % 360 - 180

    lngs = []
    if lng2 > lng1:
        lngs.append((lng1, lng2))
    elif lng2 < lng1:
        lngs.append((-180.0, lng2))
        lngs.append((lng1, 180.0))

    for lng1, lng2 in lngs:
        cids = rc.get_covering(
            LatLngRect(LatLng.from_degrees(lat1, lng1),
                       LatLng.from_degrees(lat2, lng2)))

        for cid in cids:
            ll_cid = cid.to_lat_lng()
            locations.append((ll_cid.lat().degrees, ll_cid.lng().degrees))
    return locations
Пример #19
0
def get_latlngrect_diagonal_km(rect: s2sphere.LatLngRect) -> float:
    """Compute the distance in km between two opposite corners of the rect"""
    return rect.lo().get_distance(
        rect.hi()).degrees * EARTH_CIRCUMFERENCE_KM / 360
Пример #20
0
def area_of_latlngrect(rect: s2sphere.LatLngRect) -> float:
    """Compute the approximate surface area within a lat-lng rectangle."""
    return EARTH_AREA_M2 * rect.area() / (4 * math.pi)