Пример #1
0
class MeetingPlaceAroundGeo(object):

    def __init__(self, debug=2):
        self._debug = debug
        self._dist_obj = Distance()
        self._geod = Geod(ellps='WGS84')
        ############################################################
        # POI-DB
        ############################################################
        opdb = OSM_POIDb()
        for f in [ "bar.sfbayarea.xml", "restaurant.sfbayarea.xml", "cafe.sfbayarea.xml" ]:
            opdb.make_fromOSMXml(os.path.join("osm_data_xml", f))
        self._opdb = opdb

    def get_lon_lat_box(self, lon, lat, radius=10, in_miles=False):
        distance_in_metres = radius*1000
        if in_miles: distance_in_metres = distance_in_metres*1.60934
        nesw_ll = self._geod.fwd([lon]*4, [lat]*4, [0,90,180,270], [distance_in_metres]*4)
        ### print nesw_ll 
        return ( (min(nesw_ll[0]), max(nesw_ll[0])), (min(nesw_ll[1]), max(nesw_ll[1])) )


    def get_amenities_around_city(self, city, country='us', region=None, radius=10, in_miles=False):
        bb_arr = self._dist_obj.get_city_lon_lat(city, country, region)
        ### print dll_arr 
        xbb_arr = [ self.get_lon_lat_box(t[0], t[1], radius, in_miles) for t in bb_arr]
        #
        #
        for bb in xbb_arr:
            if self._debug >= 2: print "Bounding box: ", bb
            a = self._opdb.get_pois_in_lon_lat_box(bb[0][0], bb[1][0], bb[0][1], bb[1][1])
            yield a
Пример #2
0
 def midpoint_longest(north_lat, west_lon, south_lat, east_lon):
     g = Geod(ellps='WGS84')
     af, ab, dist = g.inv(west_lon, north_lat, east_lon, south_lat)
     rlon, rlat, az = g.fwd(west_lon, north_lat, af, dist/2)
     rlon += 180 if rlon < 0 else -180
     rlon = round(rlon, 6)
     rlat = round(rlat, 6)
     return rlat, rlon
Пример #3
0
    def center (self, lon, lat, dst):
        """Set the bbox given a center and a size in meter"""
        
        from pyproj import Geod

        g = Geod(ellps='WGS84')

        # go dst/2 east to find lon_max
        lon_max = g.fwd(lon, lat, 90.0, dst/2, radians=False)[0]

        # go dst/2 west to find lon_min
        lon_min = g.fwd(lon, lat, 270., dst/2, radians=False)[0]

        # go dst/2 north to find lat_max
        lat_max = g.fwd(lon, lat, 0., dst/2, radians=False)[1]

        # go dst/2 south to find lat_min
        lat_min = g.fwd(lon, lat, 180., dst/2, radians=False)[1]
        
        self.set (lon_min, lat_min, lon_max, lat_max)
Пример #4
0
def test_geod_inverse_transform():
    gg = Geod(ellps="clrk66")
    lat1pt = 42.0 + (15.0 / 60.0)
    lon1pt = -71.0 - (7.0 / 60.0)
    lat2pt = 45.0 + (31.0 / 60.0)
    lon2pt = -123.0 - (41.0 / 60.0)
    """
    distance between boston and portland, clrk66:
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84:
    -66.530 75.654  4164074.239
    testing pickling of Geod instance
    distance between boston and portland, clrk66 (from pickle):
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84 (from pickle):
    -66.530 75.654  4164074.239
    inverse transform
    from proj.4 invgeod:
    b'-66.531\t75.654\t4164192.708\n'

    """
    print("from pyproj.Geod.inv:")
    az12, az21, dist = gg.inv(lon1pt, lat1pt, lon2pt, lat2pt)
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3)

    print("forward transform")
    print("from proj.4 geod:")
    endlon, endlat, backaz = gg.fwd(lon1pt, lat1pt, az12, dist)
    assert_almost_equal((endlon, endlat, backaz), (-123.683, 45.517, 75.654), decimal=3)
    print("intermediate points:")
    print("from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:")
    npts = 4
    lonlats = gg.npts(lon1pt, lat1pt, lon2pt, lat2pt, npts)
    lonprev = lon1pt
    latprev = lat1pt
    print(dist / (npts + 1))
    print("%6.3f  %7.3f" % (lat1pt, lon1pt))
    result_dists = (
        (-66.53059478766238, 106.79071710136431, 832838.5416198927),
        (-73.20928289863558, 99.32289055927389, 832838.5416198935),
        (-80.67710944072617, 91.36325611787134, 832838.5416198947),
        (-88.63674388212858, 83.32809401477382, 832838.5416198922),
    )
    for (lon, lat), (res12, res21, resdist) in zip(lonlats, result_dists):
        az12, az21, dist = gg.inv(lonprev, latprev, lon, lat)
        assert_almost_equal((az12, az21, dist), (res12, res21, resdist))
        latprev = lat
        lonprev = lon
    az12, az21, dist = gg.inv(lonprev, latprev, lon2pt, lat2pt)
    assert_almost_equal(
        (lat2pt, lon2pt, dist), (45.517, -123.683, 832838.542), decimal=3
    )
Пример #5
0
    def getPoint(self, horizontal_distance, vertical_distance, azimuth):
        """
		Get point with given horizontal, and vertical distances (in km, 
		vertical distance: positive-downward, negative-upward) 
		and azimuth (in degrees) from current point. 
		"""
        # TODO: check horizontal distance is positive
        g = Geod(ellps="sphere")
        longitude, latitude, back_azimuth = g.fwd(
            self.longitude, self.latitude, azimuth, horizontal_distance * 1e3
        )  # 1e3 is needed to convert from km to m
        depth = self.depth + vertical_distance
        return Point(longitude, latitude, depth)
Пример #6
0
 def test_geod_nans(self):
     g = Geod(ellps='clrk66')
     (azi1, azi2, s12) = g.inv(43, 10, float('nan'), 20)
     self.assertTrue(azi1 != azi1)
     self.assertTrue(azi2 != azi2)
     self.assertTrue(s12 != s12)
     (azi1, azi2, s12) = g.inv(43, 10, 53, float('nan'))
     self.assertTrue(azi1 != azi1)
     self.assertTrue(azi2 != azi2)
     self.assertTrue(s12 != s12)
     # Illegal latitude is treated as NaN
     (azi1, azi2, s12) = g.inv(43, 10, 53, 91)
     self.assertTrue(azi1 != azi1)
     self.assertTrue(azi2 != azi2)
     self.assertTrue(s12 != s12)
     (lon2, lat2, azi2) = g.fwd(43, 10, float('nan'), 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     (lon2, lat2, azi2) = g.fwd(43, 10, 20, float('nan'))
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     (lon2, lat2, azi2) = g.fwd(43, float('nan'), 20, 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     # Illegal latitude is treated as NaN
     (lon2, lat2, azi2) = g.fwd(43, 91, 20, 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     # Only lon2 is NaN
     (lon2, lat2, azi2) = g.fwd(float('nan'), 10, 20, 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 == lat2)
     self.assertTrue(azi2 == azi2)
Пример #7
0
def divide_line(pts, spacing=6.25, runin=0.,
                ellps='WGS84', isegment0=0):
    """
    Divide a line into equally spaced segments.

    Parameters
    ----------
    pts : list of tuples 
        List of point coordinates in longitude and latitude that define the
        line.  Format is: ``[(lon_0, lat_0), (lon_1, lat_1), ...,
        (lon_n, lat_n)]``.
    spacing : float, optional
        Spacing between line segments in meters.
    runin : float, optional
        Length of a "run-in" segment prepended to the line.
    ellps : str, optional
        Name of the ellipse to use in geodetic calculations. Must be
        recognized by :class:`pyproj.Geod`.
    isegment0 : int, optional
        Sequence number of the first bin.

    Returns
    -------
    bins : list
        List of (lon, lat, offset, sequence) tuples.
    """
    gd = Geod(ellps=ellps)
    x = -runin
    _x = -runin
    ibin = isegment0
    bins = []
    for i in range(0, len(pts) - 1):
        _x0 = _x
        lon0, lat0 = pts[i]
        lon1, lat1 = pts[i + 1]
        faz, baz, dist = gd.inv(lon0, lat0, lon1, lat1)
        while _x <= dist:
            lon, lat, _ = gd.fwd(lon0, lat0, faz, _x)
            bins += [(lon, lat, x, ibin)]
            _x += spacing
            x += spacing
            ibin += 1
        _x -= dist
        x -= _x
        if _x > 0:
            x += _x
            bins += [(lon1, lat1, x, ibin - 1)]
    return bins
Пример #8
0
    def get_stat_lat_lon(self, print_msg=True):
        """Get station lat/lon"""
        if print_msg:
            print('calculating station lat/lon')
        if not os.path.isfile(self.file):
            self.dload_site(print_msg=print_msg)
        data = np.loadtxt(self.file, dtype=bytes, skiprows=1).astype(str)
        ref_lon, ref_lat = float(data[0, 6]), 0.
        e0, e_off, n0, n_off = data[0, 7:11].astype(np.float)
        e0 += e_off
        n0 += n_off

        az = np.arctan2(e0, n0) / np.pi * 180.
        dist = np.sqrt(e0**2 + n0**2)
        g = Geod(ellps='WGS84')
        self.site_lon, self.site_lat = g.fwd(ref_lon, ref_lat, az, dist)[0:2]
        return self.site_lat, self.site_lon
Пример #9
0
 def midpoint_shortest(north_lat, west_lon, south_lat, east_lon):
     g = Geod(ellps='WGS84')
     af, ab, dist = g.inv(west_lon, north_lat, east_lon, south_lat)
     rlon, rlat, az = g.fwd(west_lon, north_lat, af, dist/2)
     # decimal places   degrees      distance
     #        0         1            111   km
     #        1         0.1          11.1  km
     #        2         0.01         1.11  km
     #        3         0.001        111   m
     #        4         0.0001       11.1  m
     #        5         0.00001      1.11  m
     #        6         0.000001     0.111 m
     #        7         0.0000001    1.11  cm
     #        8         0.00000001   1.11  mm
     rlon = round(rlon, 6)
     rlat = round(rlat, 6)
     return rlat, rlon
Пример #10
0
class TestRadians(unittest.TestCase):
    """Tests issue #84"""
    def setUp(self):
        self.g = Geod(ellps='clrk66')
        self.boston_d = (-71. - (7. / 60.), 42. + (15. / 60.))
        self.boston_r = (math.radians(self.boston_d[0]), math.radians(self.boston_d[1]))
        self.portland_d = (-123. - (41. / 60.), 45. + (31. / 60.))
        self.portland_r = (math.radians(self.portland_d[0]), math.radians(self.portland_d[1]))

    def test_inv_radians(self):

        # Get bearings and distance from Boston to Portland in degrees
        az12_d, az21_d, dist_d = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False)

        # Get bearings and distance from Boston to Portland in radians
        az12_r, az21_r, dist_r = self.g.inv(
            self.boston_r[0],
            self.boston_r[1],
            self.portland_r[0],
            self.portland_r[1],
            radians=True)

        # Check they are equal
        self.assertAlmostEqual(az12_d, math.degrees(az12_r))
        self.assertAlmostEqual(az21_d, math.degrees(az21_r))
        self.assertAlmostEqual(dist_d, dist_r)

    def test_fwd_radians(self):
        # Get bearing and distance to Portland
        az12_d, az21_d, dist = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False)

        # Calculate Portland's lon/lat from bearing and distance in degrees
        endlon_d, endlat_d, backaz_d = self.g.fwd(
            self.boston_d[0],
            self.boston_d[1],
            az12_d,
            dist,
            radians=False)

        # Calculate Portland's lon/lat from bearing and distance in radians
        endlon_r, endlat_r, backaz_r = self.g.fwd(
            self.boston_r[0],
            self.boston_r[1],
            math.radians(az12_d),
            dist,
            radians=True)

        # Check they are equal
        self.assertAlmostEqual(endlon_d, math.degrees(endlon_r))
        self.assertAlmostEqual(endlat_d, math.degrees(endlat_r))
        self.assertAlmostEqual(backaz_d, math.degrees(backaz_r))

        # Check to make sure we're back in Portland
        self.assertAlmostEqual(endlon_d, self.portland_d[0])
        self.assertAlmostEqual(endlat_d, self.portland_d[1])

    def test_npts_radians(self):
        # Calculate 10 points between Boston and Portland in degrees
        points_d = self.g.npts(
            lon1=self.boston_d[0],
            lat1=self.boston_d[1],
            lon2=self.portland_d[0],
            lat2=self.portland_d[1],
            npts=10,
            radians=False)

        # Calculate 10 points between Boston and Portland in radians
        points_r = self.g.npts(
            lon1=self.boston_r[0],
            lat1=self.boston_r[1],
            lon2=self.portland_r[0],
            lat2=self.portland_r[1],
            npts=10,
            radians=True)

        # Check they are equal
        for index, dpoint in enumerate(points_d):
            self.assertAlmostEqual(dpoint[0], math.degrees(points_r[index][0]))
            self.assertAlmostEqual(dpoint[1], math.degrees(points_r[index][1]))
Пример #11
0
calc = CurveCalc(**calc_args)

# this class is useful for calculating distances on a sphere
geod = Geod(ellps="sphere")

h_obs, lat_obs, lon_obs = 1, 54.487375, -3.599760

dist_boat_1 = km_to_m(5)
height_boat_1 = 10

dist_boat_2 = km_to_m(4)
height_boat_2 = 5

heading_boats = 270

lon_boat_1, lat_boat_1, back_az_1 = geod.fwd(lon_obs, lat_obs, heading_boats,
                                             dist_boat_1)
lon_boat_2, lat_boat_2, back_az_2 = geod.fwd(lon_obs, lat_obs, heading_boats,
                                             dist_boat_2)

renderer = Renderer_35mm(calc,
                         h_obs,
                         lat_obs,
                         lon_obs,
                         270,
                         km_to_m(15),
                         vert_res=2000,
                         focal_length=2000,
                         vert_obs_angle=0.0)

# creating scene and putting objects in it to be rendered.
s = Scene()
		lat=lat.replace(' ','')
		longi=longi.replace(' ','')
		lat=lat.replace(',','')
		longi=longi.replace(',','')
		# MODIF ERIC => sert a virer 2 derniers 0 
		if  len(lat)>7 :
			lat=lat[:-2].decode('ascii', 'ignore')
			longi=longi[:-2].decode('ascii', 'ignore')
		radius=1000
		if frequency in listValeurFreq2100:
			radius=4400
			frequency="2100"
		elif frequency in listValeurFreq900:
			radius=9000
			frequency="900"
		orig_x,orig_y=pyproj.transform(e, wgs84,lat,longi)
		left_x,left_y,trash= g.fwd(orig_x,orig_y, int(azimut)-60, radius*0.8)
		right_x,right_y,trash= g.fwd(orig_x,orig_y, int(azimut)+60, radius*0.8)
		center_x,center_y,trash= g.fwd(orig_x,orig_y, azimut, radius)
		#creation ligne dans fichier JSON SANS complement adresse
		file_json.write("{\"TAC\" : "+ str(TAC) +",\"LAC\" : "+ str(LAC) +", \"CI\" :"+str(CellID)+", \"dbTime\" : "+ str(dbTime) + ", \"frequency\" : \""+ str(frequency) + "\",  \"RAT\" : \""+sys.argv[2]+"\", \"name\" : \""+cellName+"\",\"addr\" :\""+str(address).replace("\"", "").replace("\\", "-")+"\", \"code\" :\""+postalCode+"\", \"city\" :\""+str(city)+"\", \"antenna\" :["+str(orig_x)+","+str(orig_y)+"],  \"loc\" : { \"type\" : \"Polygon\", \"coordinates\" : [[["+str(orig_x)+","+str(orig_y)+ "],["+str(left_x)+","+str(left_y)+ "],["+str(center_x)+","+str(center_y)+ "],["+str(right_x)+","+str(right_y)+ "],["+str(orig_x)+","+str(orig_y)+ "]]] } }\n")	 
finally:
	print ("dbTime = ", dbTime)
	print ("nbRowCSV =", nbRowCSV)
	print ("nbRowWithoutLati =", nbRowWithoutLati)
	print ("nbAzimutNotDigit", nbAzimutNotDigit)
	f.close()      # closing
	file_json.close()
	file_badRecords.close()
	print("Fin traitement fichier CSV")
Пример #13
0
class TestRadians(unittest.TestCase):
    """Tests issue #84"""
    def setUp(self):
        self.g = Geod(ellps="clrk66")
        self.boston_d = (-71.0 - (7.0 / 60.0), 42.0 + (15.0 / 60.0))
        self.boston_r = (math.radians(self.boston_d[0]),
                         math.radians(self.boston_d[1]))
        self.portland_d = (-123.0 - (41.0 / 60.0), 45.0 + (31.0 / 60.0))
        self.portland_r = (
            math.radians(self.portland_d[0]),
            math.radians(self.portland_d[1]),
        )

    def test_inv_radians(self):

        # Get bearings and distance from Boston to Portland in degrees
        az12_d, az21_d, dist_d = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False,
        )

        # Get bearings and distance from Boston to Portland in radians
        az12_r, az21_r, dist_r = self.g.inv(
            self.boston_r[0],
            self.boston_r[1],
            self.portland_r[0],
            self.portland_r[1],
            radians=True,
        )

        # Check they are equal
        self.assertAlmostEqual(az12_d, math.degrees(az12_r))
        self.assertAlmostEqual(az21_d, math.degrees(az21_r))
        self.assertAlmostEqual(dist_d, dist_r)

    def test_fwd_radians(self):
        # Get bearing and distance to Portland
        az12_d, az21_d, dist = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False,
        )

        # Calculate Portland's lon/lat from bearing and distance in degrees
        endlon_d, endlat_d, backaz_d = self.g.fwd(self.boston_d[0],
                                                  self.boston_d[1],
                                                  az12_d,
                                                  dist,
                                                  radians=False)

        # Calculate Portland's lon/lat from bearing and distance in radians
        endlon_r, endlat_r, backaz_r = self.g.fwd(self.boston_r[0],
                                                  self.boston_r[1],
                                                  math.radians(az12_d),
                                                  dist,
                                                  radians=True)

        # Check they are equal
        self.assertAlmostEqual(endlon_d, math.degrees(endlon_r))
        self.assertAlmostEqual(endlat_d, math.degrees(endlat_r))
        self.assertAlmostEqual(backaz_d, math.degrees(backaz_r))

        # Check to make sure we're back in Portland
        self.assertAlmostEqual(endlon_d, self.portland_d[0])
        self.assertAlmostEqual(endlat_d, self.portland_d[1])

    def test_npts_radians(self):
        # Calculate 10 points between Boston and Portland in degrees
        points_d = self.g.npts(
            lon1=self.boston_d[0],
            lat1=self.boston_d[1],
            lon2=self.portland_d[0],
            lat2=self.portland_d[1],
            npts=10,
            radians=False,
        )

        # Calculate 10 points between Boston and Portland in radians
        points_r = self.g.npts(
            lon1=self.boston_r[0],
            lat1=self.boston_r[1],
            lon2=self.portland_r[0],
            lat2=self.portland_r[1],
            npts=10,
            radians=True,
        )

        # Check they are equal
        for index, dpoint in enumerate(points_d):
            self.assertAlmostEqual(dpoint[0], math.degrees(points_r[index][0]))
            self.assertAlmostEqual(dpoint[1], math.degrees(points_r[index][1]))
Пример #14
0
    def filter_on_request(self, get_request, chain, request_meta, api):
        form = SpotSearchForm(get_request)
        has_valid_search_param = False

        if not form.is_valid():
            return []

        if not get_request:
            # This is here to continue to allow the building api to request all
            # the buildings in the server.
            if api == 'buildings':
                return list(Spot.objects.all())
            return []
        query = Spot.objects.all()

        # This is here to allow only the building api to continue to be
        # contacted with the key 'campus' instead of 'extended_info:campus'
        if api == 'buildings' and 'campus' in get_request.keys():
            query = query.filter(spotextendedinfo__key='campus',
                                 spotextendedinfo__value=get_request['campus'])
            has_valid_search_param = True

        day_dict = {"Sunday": "su",
                    "Monday": "m",
                    "Tuesday": "t",
                    "Wednesday": "w",
                    "Thursday": "th",
                    "Friday": "f",
                    "Saturday": "sa", }

        # Q objects we need to chain together for the OR queries
        or_q_obj = Q()
        or_qs = []

        # Exclude things that get special consideration here, otherwise add a
        # filter for the keys
        for key in get_request:
            if key.startswith('oauth_'):
                pass
            elif key == 'campus':
                pass
            elif chain.filters_key(key):
                # this needs to happen early, before any
                # org_filter or extended_info
                pass
            elif key == "expand_radius":
                pass
            elif key == "distance":
                pass
            elif key == "center_latitude":
                pass
            elif key == "center_longitude":
                pass
            elif key == "limit":
                pass
            elif key == "open_now":
                if get_request["open_now"]:
                    today, now = self.get_datetime()
                    # Check to see if the request was made in minute
                    # gap before midnight during which no space is open,
                    # based on the server.
                    before_midnight = now.replace(hour=23,
                                                  minute=58,
                                                  second=59,
                                                  microsecond=999999)
                    right_before_midnight = now.replace(hour=23,
                                                        minute=59,
                                                        second=59,
                                                        microsecond=999999)
                    if before_midnight < now and now < right_before_midnight:
                        # Makes it so that all spaces that are open
                        # until midnight or overnight will be returned.
                        now = now.replace(hour=23,
                                          minute=58,
                                          second=0,
                                          microsecond=0)
                    query = \
                        query.filter(
                            spotavailablehours__day__iexact=today,
                            spotavailablehours__start_time__lt=now,
                            spotavailablehours__end_time__gt=now)
                    has_valid_search_param = True
            elif key == "open_until":
                if get_request["open_until"] and get_request["open_at"]:
                    until_day, until_t = \
                        get_request["open_until"].split(',')
                    at_day, at_t = get_request["open_at"].split(',')
                    until_day = day_dict[until_day]
                    at_day = day_dict[at_day]

                    if until_day == at_day:
                        if (strptime(until_t, "%H:%M") >=
                                strptime(at_t, "%H:%M")):
                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=until_day,
                                    spotavailablehours__start_time__lte=at_t,
                                    spotavailablehours__end_time__gte=until_t)
                        else:
                            days_to_test = ["su", "m",
                                            "t", "w", "th", "f", "sa"]
                            days_to_test.remove(at_day)

                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=at_day,
                                    spotavailablehours__start_time__lte=at_t,
                                    spotavailablehours__end_time__gte="23:59")
                            t1 = "00:00"
                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=until_day,
                                    spotavailablehours__start_time__lte=t1,
                                    spotavailablehours__end_time__gte=until_t)

                            for day in days_to_test:
                                t1 = "00:00"
                                t2 = "23:59"
                                query = \
                                    query.filter(
                                        spotavailablehours__day__iexact=day,
                                        spotavailablehours__start_time__lte=t1,
                                        spotavailablehours__end_time__gte=t2)
                    else:
                        days_to_test = self.get_days_in_range(
                            at_day, until_day)
                        last_day = days_to_test.pop()
                        days_to_test.reverse()
                        first_day = days_to_test.pop()

                        query = \
                            query.filter(
                                spotavailablehours__day__iexact=first_day,
                                spotavailablehours__start_time__lte=at_t,
                                spotavailablehours__end_time__gte="23:59")
                        query = \
                            query.filter(
                                spotavailablehours__day__iexact=last_day,
                                spotavailablehours__start_time__lte="00:00",
                                spotavailablehours__end_time__gte=until_t)

                        for day in days_to_test:
                            early = "00:00"
                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=day,
                                    spotavailablehours__start_time__lte=early,
                                    spotavailablehours__end_time__gte="23:59")
                    has_valid_search_param = True
            elif key == "open_at":
                if get_request["open_at"]:
                    try:
                        get_request["open_until"]
                    except MultiValueDictKeyError:
                        day, time = get_request['open_at'].split(',')
                        day = day_dict[day]
                        query = \
                            query.filter(
                                spotavailablehours__day__iexact=day,
                                spotavailablehours__start_time__lte=time,
                                spotavailablehours__end_time__gt=time)
                        has_valid_search_param = True
            elif key == "fuzzy_hours_end":
                # fuzzy search requires a start and end
                if "fuzzy_hours_start" not in get_request.keys():
                    raise RESTException("fuzzy_hours_end requires "
                                        "fuzzy_hours_start to be specified",
                                        400)
            elif key == "fuzzy_hours_start":
                # fuzzy search requires a start and end
                starts = get_request.getlist("fuzzy_hours_start")
                ends = get_request.getlist("fuzzy_hours_end")
                if ("fuzzy_hours_end" not in get_request.keys() or
                        not len(starts) is len(ends)):
                    raise RESTException("fuzzy_hours_start requires "
                                        "fuzzy_hours_end to be specified",
                                        400)

                or_small_q_obj = Q()
                for num, start in enumerate(starts):
                    start_day, start_time = start.split(',')
                    end_day, end_time = ends[num].split(',')
                    start_day = day_dict[start_day]
                    end_day = day_dict[end_day]

                    start_range_query = \
                        Q(spotavailablehours__day__iexact=start_day,
                          spotavailablehours__start_time__gte=start_time,
                          spotavailablehours__start_time__lt=end_time)
                    end_range_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__end_time__gt=start_time,
                          spotavailablehours__end_time__lte=end_time)
                    span_range_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__start_time__lte=start_time,
                          spotavailablehours__end_time__gt=end_time)
                    span_midnight_pre_query = \
                        Q(spotavailablehours__day__iexact=start_day,
                          spotavailablehours__start_time__gte=start_time,
                          spotavailablehours__start_time__lte="23:59")
                    span_midnight_post_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__end_time__lt=end_time,
                          spotavailablehours__end_time__gte="00:00")
                    span_midnight_pre_midnight_end_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__end_time__gte=start_time,
                          spotavailablehours__end_time__lte="23:59")
                    span_midnight_next_morning_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__start_time__lt=end_time,
                          spotavailablehours__start_time__gte="00:00")
                    if start_day is not end_day:
                        range_query = (start_range_query |
                                       end_range_query |
                                       span_midnight_pre_query |
                                       span_midnight_post_query |
                                       span_midnight_pre_midnight_end_query |
                                       span_midnight_next_morning_query)
                    else:
                        range_query = (start_range_query |
                                       end_range_query |
                                       span_range_query)
                    or_small_q_obj |= range_query
                query = query.filter(or_small_q_obj)
                has_valid_search_param = True
            elif key == "capacity":
                try:
                    limit = int(get_request["capacity"])
                    with_limit = Q(capacity__gte=limit)
                    with_limit |= Q(capacity__isnull=True)
                    query = query.filter(with_limit)
                    has_valid_search_param = True
                except ValueError:
                    # This we don't care about - if someone passes "", or
                    # "twenty", just ignore it
                    pass
                except Exception as e:
                    # Do something to complain??
                    pass
            elif key == "type":
                type_values = get_request.getlist(key)
                q_obj = Q()
                type_qs = [Q(spottypes__name__exact=v) for v in type_values]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key == "building_name":
                building_names = get_request.getlist(key)
                q_obj = Q()
                type_qs = [Q(building_name__exact=v) for v in building_names]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key.startswith('item:extended_info:'):
                try:
                    for value in get_request.getlist(key):
                        or_qs.append(Q(item__itemextendedinfo__key=key[19:],
                                       item__itemextendedinfo__value=value))
                    has_valid_search_param = True
                except Exception as e:
                    pass
            elif key.startswith('item:'):
                try:
                    for value in get_request.getlist(key):
                        if key[5:] == "id":
                            or_qs.append(Q(item__id=value))
                        elif key[5:] == "name":
                            or_qs.append(Q(item__name=value))
                        elif key[5:] == "category":
                            or_qs.append(Q(item__item_category=value))
                        elif key[5:] == "subcategory":
                            or_qs.append(Q(item__item_subcategory=value))
                    has_valid_search_param = True
                except Exception as e:
                    pass
            elif key.startswith('extended_info:or_group'):
                values = get_request.getlist(key)
                or_small_q_obj = Q()
                for value in values:
                    or_small_q_obj |= Q(spotextendedinfo__key=value,
                                        spotextendedinfo__value='true')
                query = query.filter(or_small_q_obj)
                has_valid_search_param = True
            elif key.startswith('extended_info:or'):
                or_qs.append(Q(spotextendedinfo__key=key[17:],
                               spotextendedinfo__value='true'))
                has_valid_search_param = True
            elif key.startswith('extended_info:'):
                kwargs = {
                    'spotextendedinfo__key': key[14:],
                    'spotextendedinfo__value__in': get_request.getlist(key)
                }
                query = query.filter(**kwargs)
                has_valid_search_param = True
            elif key == "id":
                query = query.filter(id__in=get_request.getlist(key))
                has_valid_search_param = True
            else:
                try:
                    kwargs = {
                        '%s__icontains' % key: get_request[key]
                    }
                    query = query.filter(**kwargs)
                    has_valid_search_param = True
                except Exception as e:
                    if not request_meta['SERVER_NAME'] == 'testserver':
                        print >> sys.stderr, "E: ", e

        for or_q in or_qs:
            or_q_obj |= or_q
        # This handles all of the OR queries on extended_info we've collected.
        query = query.filter(or_q_obj).distinct()
        # Always prefetch the related extended info
        query = query.prefetch_related('spotextendedinfo_set')

        query = chain.filter_query(query)
        if chain.has_valid_search_param:
            has_valid_search_param = True

        limit = int(get_request.get('limit', 20))

        if ('distance' in get_request and
                'center_longitude' in get_request and
                'center_latitude' in get_request):
            try:
                g = Geod(ellps='clrk66')
                lon = get_request['center_longitude']
                lat = get_request['center_latitude']
                dist = get_request['distance']
                # Get coordinates above/right/below/left our location
                top = g.fwd(lon, lat, 0, dist)
                right = g.fwd(lon, lat, 90, dist)
                bottom = g.fwd(lon, lat, 180, dist)
                left = g.fwd(lon, lat, 270, dist)
                # Get relevant lat or long from these points
                top_limit = "%.8f" % top[1]
                bottom_limit = "%.8f" % bottom[1]
                left_limit = "%.8f" % left[0]
                right_limit = "%.8f" % right[0]

                distance_query = query.filter(longitude__gte=left_limit,
                                              longitude__lte=right_limit,
                                              latitude__gte=bottom_limit,
                                              latitude__lte=top_limit)
                has_valid_search_param = True

                if distance_query or 'expand_radius' not in get_request:
                    query = distance_query
                else:
                    # If we're querying everything, let's make sure we only
                    # return a limited number of spaces...
                    limit = 10
            except Exception as e:
                if not request_meta['SERVER_NAME'] == 'testserver':
                    print >> sys.stderr, "E: ", e
                # query = Spot.objects.all()
        elif ('distance' in get_request or
                'center_longitude' in get_request or
                'center_latitude' in get_request):
            if ('distance' not in get_request or
                    'center_longitude' not in get_request or
                    'center_latitude' not in get_request):
                # If distance, lat, or long are specified in the server
                # request; all 3 must be present.
                raise RESTException(
                    "Must specify latitude, longitude, and distance", 400)

        # Only do this if spot api because buildings api
        # is able to not pass any valid filters
        if not has_valid_search_param and api == 'spot':
            raise RESTException(
                "missing required parameters for this type of search", 400)

        # Do this when spot api because building api is not required
        # to pass these parameters
        if limit > 0 and limit < len(query) and api == 'spot':
            try:
                lat = get_request['center_latitude']
                lon = get_request['center_longitude']
            except KeyError:
                raise RESTException(
                    "missing required parameters for this type of search", 400)

            def sortfunc(spot):
                return self.distance(spot, lon, lat)

            sorted_list = sorted(query, key=sortfunc)
            query = sorted_list[:limit]

        spots = set(query)
        spots = chain.filter_results(spots)

        return spots
Пример #15
0
    def GET(self, request):
        form = SpotSearchForm(request.GET)
        has_valid_search_param = False

        if not form.is_valid():
            return HttpResponse('[]')

        if len(request.GET) == 0:
            return HttpResponse('[]')

        query = Spot.objects.all()

        day_dict = {"Sunday": "su",
                    "Monday": "m",
                    "Tuesday": "t",
                    "Wednesday": "w",
                    "Thursday": "th",
                    "Friday": "f",
                    "Saturday": "sa", }
        # Exclude things that get special consideration here, otherwise add a filter for the keys
        for key in request.GET:
            if re.search('^oauth_', key):
                pass
            elif key == "expand_radius":
                pass
            elif key == "distance":
                pass
            elif key == "center_latitude":
                pass
            elif key == "center_longitude":
                pass
            elif key == "limit":
                pass
            elif key == "open_now":
                if request.GET["open_now"]:

                    day_lookup = ["su", "m", "t", "w", "th", "f", "sa"]
                    day_num = int(strftime("%w", localtime()))
                    today = day_lookup[day_num]
                    now = datetime.time(datetime.now())
                    query = query.filter(spotavailablehours__day__iexact=today, spotavailablehours__start_time__lt=now, spotavailablehours__end_time__gt=now)
                    has_valid_search_param = True
            elif key == "open_until":
                if request.GET["open_until"] and request.GET["open_at"]:
                    until_day, until_time = request.GET["open_until"].split(',')
                    at_day, at_time = request.GET["open_at"].split(',')
                    until_day = day_dict[until_day]
                    at_day = day_dict[at_day]

                    if until_day == at_day:
                        query = query.filter(spotavailablehours__day__iexact=until_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte=until_time)
                    else:
                        days_to_test = self.get_days_in_range(at_day, until_day)
                        last_day = days_to_test.pop()
                        days_to_test.reverse()
                        first_day = days_to_test.pop()

                        query = query.filter(spotavailablehours__day__iexact=first_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte="23:59")
                        query = query.filter(spotavailablehours__day__iexact=last_day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte=until_time)

                        for day in days_to_test:
                            query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte="23:59")
                    has_valid_search_param = True
            elif key == "open_at":
                if request.GET["open_at"]:
                    try:
                        request.GET["open_until"]
                    except:
                        day, time = request.GET['open_at'].split(',')
                        day = day_dict[day]
                        query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte=time, spotavailablehours__end_time__gt=time)
                        has_valid_search_param = True
            elif key == "extended_info:reservable":
                query = query.filter(spotextendedinfo__key="reservable", spotextendedinfo__value__in=['true', 'reservations'])
            elif key == "extended_info:noise_level":
                noise_levels = request.GET.getlist("extended_info:noise_level")

                exclude_silent = True
                exclude_quiet = True
                exclude_moderate = True
                exclude_loud = True
                exclude_variable = True

                for level in noise_levels:
                    if "silent" == level:
                        exclude_silent = False
                    if "quiet" == level:
                        exclude_quiet = False
                        exclude_variable = False
                    if "moderate" == level:
                        exclude_moderate = False
                        exclude_variable = False

                if exclude_silent:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="silent")
                if exclude_quiet:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="quiet")
                if exclude_moderate:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="moderate")
                if exclude_loud:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="loud")
                if exclude_variable:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="variable")

            elif key == "capacity":
                try:
                    limit = int(request.GET["capacity"])
                    with_limit = Q(capacity__gte=limit)
                    with_limit |= Q(capacity__isnull=True)
                    query = query.filter(with_limit)
                    has_valid_search_param = True
                except ValueError:
                    # This we don't care about - if someone passes "", or "twenty", just ignore it
                    pass
                except Exception as e:
                    # Do something to complain??
                    pass
            elif key == "type":
                type_values = request.GET.getlist(key)
                q_obj = Q()
                type_qs = [Q(spottypes__name__exact=v) for v in type_values]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key == "building_name":
                building_names = request.GET.getlist(key)
                q_obj = Q()
                type_qs = [Q(building_name__exact=v) for v in building_names]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif re.search('^extended_info:', key):
                kwargs = {
                    'spotextendedinfo__key': key[14:],
                    'spotextendedinfo__value__in': request.GET.getlist(key)
                }
                query = query.filter(**kwargs)
                has_valid_search_param = True
            elif key == "id":
                query = query.filter(id__in=request.GET.getlist(key))
                has_valid_search_param = True
            else:
                try:
                    kwargs = {
                        '%s__icontains' % key: request.GET[key]
                    }
                    query = query.filter(**kwargs)
                    has_valid_search_param = True
                except Exception as e:
                    if not request.META['SERVER_NAME'] == 'testserver':
                        print >> sys.stderr, "E: ", e

        limit = 20
        if 'limit' in request.GET:
            if request.GET['limit'] == '0':
                limit = 0
            else:
                limit = int(request.GET['limit'])

        if 'distance' in request.GET and 'center_longitude' in request.GET and 'center_latitude' in request.GET:
            try:
                g = Geod(ellps='clrk66')
                top = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 0, request.GET['distance'])
                right = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 90, request.GET['distance'])
                bottom = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 180, request.GET['distance'])
                left = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 270, request.GET['distance'])

                top_limit = "%.8f" % top[1]
                bottom_limit = "%.8f" % bottom[1]
                left_limit = "%.8f" % left[0]
                right_limit = "%.8f" % right[0]

                distance_query = query.filter(longitude__gte=left_limit)

                distance_query = distance_query.filter(longitude__lte=right_limit)
                distance_query = distance_query.filter(latitude__gte=bottom_limit)
                distance_query = distance_query.filter(latitude__lte=top_limit)
                has_valid_search_param = True

                if len(distance_query) > 0 or 'expand_radius' not in request.GET:
                    query = distance_query
                else:
                    # If we're querying everything, let's make sure we only return a limited number of spaces...
                    limit = 10
            except Exception as e:
                if not request.META['SERVER_NAME'] == 'testserver':
                    print >> sys.stderr, "E: ", e
                #query = Spot.objects.all()
        elif 'distance' in request.GET or 'center_longitude' in request.GET or 'center_latitude' in request.GET:
            if 'distance' not in request.GET or 'center_longitude' not in request.GET or 'center_latitude' not in request.GET:
                # If distance, lat, or long are specified in the server request; all 3 must be present.
                return HttpResponseBadRequest("Bad Request")

        if not has_valid_search_param:
            return HttpResponse('[]')

        if limit > 0 and limit < len(query):
            sorted_list = list(query)
            try:
                sorted_list.sort(lambda x, y: cmp(self.distance(x, request.GET['center_longitude'], request.GET['center_latitude']), self.distance(y, request.GET['center_longitude'], request.GET['center_latitude'])))
                query = sorted_list[:limit]
            except KeyError:
                response = HttpResponse('{"error":"missing required parameters for this type of search"}')
                response.status_code = 400
                return response

        response = []


# UIUC Residence Limits for Labs
# --------------------------------
# Remove any spots that the current user cannot use (i.e. login, print, etc)
        # TODO: Add to settings...
        # UIUC_REQUIRE_ADDRESS = settings.UIUC_REQUIRE_ADDRESS
        UIUC_REQUIRE_ADDRESS = 'uiuc_require_address'

# TODO: Net_ID needs to come from somehwere...

        # Prefect restrictions
        query = query.select_related('SpotExtendedInfo')

        all_the_spots = set(query)

        email = request.GET.get('email_address')

        full_address = ''
        if email:
            full_address = get_res_street_address(email)
        for spot in all_the_spots: 
            if email:
# User not logged in
                LOGGER.info("User is logged in. Show only spots they may access.")
                address_restrictions = spot.spotextendedinfo_set.get(
                    key=UIUC_REQUIRE_ADDRESS)
# This is not a restricted spot.
                if len(address_restrictions) == 0:
                    response.append(spot.json_data_structure())
                    LOGGER.debug("Not restricted.")
                else:
# Assume only one uiuc restriction per spot.
                    restrict_rule = address_restrictions[0]
                    regex_text = restrict_rule.value
                    if re.match(full_address, regex_text):
                        response.append(spot.json_data_structure())
                        LOGGER.debug("Restricted, user address matches.")
                    else:
                        LOGGER.debug("Restricted, no address match.")
            else:
                LOGGER.info("User is not logged in. Show all spots.")
                response.append(spot.json_data_structure())

        return HttpResponse(json.dumps(response))
Пример #16
0
def get_mesh_back(pfs, rfi, sd, idl):
    """
    Compute resampled profiles in the backward direction from the reference
    profile and creates the portion of the mesh 'before' the reference profile.

    :param list pfs:
        Original profiles. Each profile is a :class:`numpy.ndarray` instance
        with 3 columns and as many rows as the number of points included
    :param int rfi:
        Index of the reference profile
    :param sd:
        Sampling distance [in km] along the strike
    :param boolean idl:
        A flag used to specify cases where the model crosses the IDL
    :returns:

    """

    # Projection
    g = Geod(ellps='WGS84')

    # Initialize residual distance and last index lists
    rdist = [0 for _ in range(0, len(pfs[0]))]
    laidx = [0 for _ in range(0, len(pfs[0]))]

    # Create list containing the new profiles. We start by adding the
    # reference profile
    npr = list([copy.deepcopy(pfs[rfi])])

    # Run for all the profiles from the reference one backward
    for i in range(rfi, 0, -1):

        # Set the profiles to be used for the construction of the mesh
        pr = pfs[i-1]
        pl = pfs[i]

        # Points in common on the two profiles i.e. points that in both the
        # profiles are not NaN
        cmm = np.logical_and(np.isfinite(pr[:, 2]), np.isfinite(pl[:, 2]))

        # Transform the indexes into integers and initialise the maximum
        # index of the points in common
        cmmi = np.nonzero(cmm)[0].astype(int)
        mxx = 0
        for ll in laidx:
            if ll is not None:
                mxx = max(mxx, ll)

        # Update indexes
        for x in range(0, len(pr[:, 2])):
            if x in cmmi and laidx[x] is None:
                iii = []
                for li, lv in enumerate(laidx):
                    if lv is not None:
                        iii.append(li)
                iii = np.array(iii)
                minidx = np.argmin(abs(iii-x))
                laidx[x] = mxx
                rdist[x] = rdist[minidx]
            elif x not in cmmi:
                laidx[x] = None
                rdist[x] = 0

        # Loop over the points in common between the two profiles
        for k in list(np.nonzero(cmm)[0]):

            # Compute azimuth and horizontal distance
            az12, _, hdist = g.inv(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1])
            hdist /= 1e3
            vdist = pr[k, 2] - pl[k, 2]
            tdist = (vdist**2 + hdist**2)**.5
            ndists = int(np.floor((tdist+rdist[k])/sd))

            # Adding new points along edge with index k
            for j, _ in enumerate(range(ndists)):
                #
                # add new profile
                if len(npr)-1 < laidx[k]+1:
                    npr = add_empty_profile(npr)
                #
                # fix distance
                tmp = (j+1)*sd - rdist[k]
                lo, la, _ = g.fwd(pl[k, 0], pl[k, 1], az12,
                                  tmp*hdist/tdist*1e3)

                if idl:
                    lo = lo+360 if lo < 0 else lo

                de = pl[k, 2] + tmp*vdist/hdist
                npr[laidx[k]+1][k] = [lo, la, de]

                if (k > 0 and np.all(np.isfinite(npr[laidx[k]+1][k])) and
                        np.all(np.isfinite(npr[laidx[k]][k]))):

                    p1 = npr[laidx[k]][k]
                    p2 = npr[laidx[k]+1][k]
                    d = distance(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2])
                    #
                    # >>> TOLERANCE
                    if abs(d-sd) > TOL*sd:
                        tmpf = 'd: {:f} diff: {:f} tol: {:f} sd:{:f}'
                        tmpf += '\nresidual: {:f}'
                        tmps = tmpf.format(d, d-sd, TOL*sd, sd, rdist[k])
                        msg = 'The mesh spacing exceeds the tolerance limits'
                        tmps += '\n {:s}'.format(msg)
                        raise ValueError(tmps)

                laidx[k] += 1
            rdist[k] = tdist - sd*ndists + rdist[k]
            assert rdist[k] < sd

    tmp = []
    for i in range(len(npr)-1, 0, -1):
        tmp.append(npr[i])

    return tmp
Пример #17
0
    def GET(self, request):
        form = SpotSearchForm(request.GET)
        has_valid_search_param = False

        if not form.is_valid():
            return HttpResponse('[]')

        if len(request.GET) == 0:
            return HttpResponse('[]')

        query = Spot.objects.all()

        day_dict = {"Sunday": "su",
                    "Monday": "m",
                    "Tuesday": "t",
                    "Wednesday": "w",
                    "Thursday": "th",
                    "Friday": "f",
                    "Saturday": "sa", }
        # Exclude things that get special consideration here, otherwise add a filter for the keys
        for key in request.GET:
            if re.search('^oauth_', key):
                pass
            elif key == "expand_radius":
                pass
            elif key == "distance":
                pass
            elif key == "center_latitude":
                pass
            elif key == "center_longitude":
                pass
            elif key == "limit":
                pass
            elif key == "open_now":
                if request.GET["open_now"]:

                    day_lookup = ["su", "m", "t", "w", "th", "f", "sa"]
                    day_num = int(strftime("%w", localtime()))
                    today = day_lookup[day_num]
                    now = datetime.time(datetime.now())
                    query = query.filter(spotavailablehours__day__iexact=today, spotavailablehours__start_time__lt=now, spotavailablehours__end_time__gt=now)
                    has_valid_search_param = True
            elif key == "open_until":
                if request.GET["open_until"] and request.GET["open_at"]:
                    until_day, until_time = request.GET["open_until"].split(',')
                    at_day, at_time = request.GET["open_at"].split(',')
                    until_day = day_dict[until_day]
                    at_day = day_dict[at_day]

                    if until_day == at_day:
                        query = query.filter(spotavailablehours__day__iexact=until_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte=until_time)
                    else:
                        days_to_test = self.get_days_in_range(at_day, until_day)
                        last_day = days_to_test.pop()
                        days_to_test.reverse()
                        first_day = days_to_test.pop()

                        query = query.filter(spotavailablehours__day__iexact=first_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte="23:59")
                        query = query.filter(spotavailablehours__day__iexact=last_day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte=until_time)

                        for day in days_to_test:
                            query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte="23:59")
                    has_valid_search_param = True
            elif key == "open_at":
                if request.GET["open_at"]:
                    try:
                        request.GET["open_until"]
                    except:
                        day, time = request.GET['open_at'].split(',')
                        day = day_dict[day]
                        query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte=time, spotavailablehours__end_time__gt=time)
                        has_valid_search_param = True
            elif key == "extended_info:reservable":
                query = query.filter(spotextendedinfo__key="reservable", spotextendedinfo__value__in=['true', 'reservations'])
            elif key == "extended_info:noise_level":
                noise_levels = request.GET.getlist("extended_info:noise_level")

                exclude_silent = True
                exclude_quiet = True
                exclude_moderate = True
                exclude_loud = True
                exclude_variable = True

                for level in noise_levels:
                    if "silent" == level:
                        exclude_silent = False
                    if "quiet" == level:
                        exclude_quiet = False
                        exclude_variable = False
                    if "moderate" == level:
                        exclude_moderate = False
                        exclude_variable = False

                if exclude_silent:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="silent")
                if exclude_quiet:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="quiet")
                if exclude_moderate:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="moderate")
                if exclude_loud:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="loud")
                if exclude_variable:
                    query = query.exclude(spotextendedinfo__key="noise_level", spotextendedinfo__value__iexact="variable")


            elif key == "capacity":
                try:
                    limit = int(request.GET["capacity"])
                    with_limit = Q(capacity__gte=limit)
                    with_limit |= Q(capacity__isnull=True)
                    query = query.filter(with_limit)
                    has_valid_search_param = True
                except ValueError:
                    # This we don't care about - if someone passes "", or "twenty", just ignore it
                    pass
                except Exception as e:
                    # Do something to complain??
                    pass
            elif key == "type":
                type_values = request.GET.getlist(key)
                q_obj = Q()
                type_qs = [Q(spottypes__name__exact=v) for v in type_values]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key == "building_name":
                building_names = request.GET.getlist(key)
                q_obj = Q()
                type_qs = [Q(building_name__exact=v) for v in building_names]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif re.search('^extended_info:', key):
                kwargs = {
                    'spotextendedinfo__key': key[14:],
                    'spotextendedinfo__value__in': request.GET.getlist(key)
                }
                query = query.filter(**kwargs)
                has_valid_search_param = True
            elif key == "id":
                query = query.filter(id__in=request.GET.getlist(key))
                has_valid_search_param = True
            else:
                try:
                    kwargs = {
                        '%s__icontains' % key: request.GET[key]
                    }
                    query = query.filter(**kwargs)
                    has_valid_search_param = True
                except Exception as e:
                    if not request.META['SERVER_NAME'] == 'testserver':
                        print >> sys.stderr, "E: ", e

        limit = 20
        if 'limit' in request.GET:
            if request.GET['limit'] == '0':
                limit = 0
            else:
                limit = int(request.GET['limit'])

        if 'distance' in request.GET and 'center_longitude' in request.GET and 'center_latitude' in request.GET:
            try:
                g = Geod(ellps='clrk66')
                top = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 0, request.GET['distance'])
                right = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 90, request.GET['distance'])
                bottom = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 180, request.GET['distance'])
                left = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 270, request.GET['distance'])

                top_limit = "%.8f" % top[1]
                bottom_limit = "%.8f" % bottom[1]
                left_limit = "%.8f" % left[0]
                right_limit = "%.8f" % right[0]

                distance_query = query.filter(longitude__gte=left_limit)

                distance_query = distance_query.filter(longitude__lte=right_limit)
                distance_query = distance_query.filter(latitude__gte=bottom_limit)
                distance_query = distance_query.filter(latitude__lte=top_limit)
                has_valid_search_param = True

                if len(distance_query) >  0 or 'expand_radius' not in request.GET:
                    query = distance_query
                else:
                    # If we're querying everything, let's make sure we only return a limited number of spaces...
                    limit = 10
            except Exception as e:
                if not request.META['SERVER_NAME'] == 'testserver':
                    print >> sys.stderr, "E: ", e
                #query = Spot.objects.all()



        if not has_valid_search_param:
            return HttpResponse('[]')

        if limit > 0 and limit < len(query):
            sorted_list = list(query)
            sorted_list.sort(lambda x, y: cmp(self.distance(x, request.GET['center_longitude'], request.GET['center_latitude']), self.distance(y, request.GET['center_longitude'], request.GET['center_latitude'])))
            query = sorted_list[:limit]

        response = []

        for spot in query:
            response.append(spot.json_data_structure())

        return HttpResponse(json.dumps(response))
Пример #18
0
def _resample_profile(line, sampling_dist):
    # TODO split this function into smaller components.
    """
    :parameter line:
        An instance of :class:`openquake.hazardlib.geo.line.Line`
    :parameter sampling_dist:
        A scalar definining the distance [km] used to sample the profile
    :returns:
        An instance of :class:`openquake.hazardlib.geo.line.Line`
    """
    lo = [pnt.longitude for pnt in line.points]
    la = [pnt.latitude for pnt in line.points]
    de = [pnt.depth for pnt in line.points]

    # Set projection
    g = Geod(ellps='WGS84')

    # Add a tolerance length to the last point of the profile
    # check that final portion of the profile is not vertical
    if abs(lo[-2] - lo[-1]) > 1e-5 and abs(la[-2] - la[-1]) > 1e-5:
        az12, _, odist = g.inv(lo[-2], la[-2], lo[-1], la[-1])
        odist /= 1e3
        slope = np.arctan((de[-1] - de[-2]) / odist)
        hdist = TOL * sampling_dist * np.cos(slope)
        vdist = TOL * sampling_dist * np.sin(slope)
        endlon, endlat, _ = g.fwd(lo[-1], la[-1], az12, hdist * 1e3)
        lo[-1] = endlon
        la[-1] = endlat
        de[-1] = de[-1] + vdist
        az12, _, odist = g.inv(lo[-2], la[-2], lo[-1], la[-1])

        # Checking
        odist /= 1e3
        slopec = np.arctan((de[-1] - de[-2]) / odist)
        assert abs(slope - slopec) < 1e-3
    else:
        de[-1] = de[-1] + TOL * sampling_dist

    # Initialise the cumulated distance
    cdist = 0.

    # Get the azimuth of the profile
    azim = azimuth(lo[0], la[0], lo[-1], la[-1])

    # Initialise the list with the resampled nodes
    idx = 0
    resampled_cs = [Point(lo[idx], la[idx], de[idx])]

    # Set the starting point
    slo = lo[idx]
    sla = la[idx]
    sde = de[idx]

    # Resampling
    while 1:

        # Check loop exit condition
        if idx > len(lo) - 2:
            break

        # Compute the distance between the starting point and the next point
        # on the profile
        segment_len = distance(slo, sla, sde, lo[idx + 1], la[idx + 1],
                               de[idx + 1])

        # Search for the point
        if cdist + segment_len > sampling_dist:

            # This is the lenght of the last segment-fraction needed to
            # obtain the sampling distance
            delta = sampling_dist - cdist

            # Compute the slope of the last segment and its horizontal length.
            # We need to manage the case of a vertical segment TODO
            segment_hlen = distance(slo, sla, 0., lo[idx + 1], la[idx + 1], 0.)
            if segment_hlen > 1e-5:
                segment_slope = np.arctan((de[idx + 1] - sde) / segment_hlen)
            else:
                segment_slope = 90.

            # Horizontal and vertical lenght of delta
            delta_v = delta * np.sin(segment_slope)
            delta_h = delta * np.cos(segment_slope)

            # Add a new point to the cross section
            pnts = npoints_towards(slo, sla, sde, azim, delta_h, delta_v, 2)

            # Update the starting point
            slo = pnts[0][-1]
            sla = pnts[1][-1]
            sde = pnts[2][-1]
            resampled_cs.append(Point(slo, sla, sde))

            # Reset the cumulative distance
            cdist = 0.

        else:
            cdist += segment_len
            idx += 1
            slo = lo[idx]
            sla = la[idx]
            sde = de[idx]

    # Check the distances along the profile
    coo = [[pnt.longitude, pnt.latitude, pnt.depth] for pnt in resampled_cs]
    coo = np.array(coo)
    for i in range(0, coo.shape[0] - 1):
        dst = distance(coo[i, 0], coo[i, 1], coo[i, 2], coo[i + 1, 0],
                       coo[i + 1, 1], coo[i + 1, 2])
        if abs(dst - sampling_dist) > 0.1 * sampling_dist:
            raise ValueError('Wrong distance between points along the profile')

    return Line(resampled_cs)
Пример #19
0
    def calculate_footprint_from(self, point):
        """从点和指定的角度计算地面覆盖的矩形(footprint)

        Parameters
        ----------
        point : list 
            指定点
        angle : float
            航线方向
        width : int 
            图像长度
        iheight : int 
            图像高度
        gsd : float 
            地面分辨率

        Returns
        -------
        tuple
            返回地面覆盖的矩形的四脚点坐标
        """
        width = self.cameraWidth * self.gsd
        height = self.cameraHeight * self.gsd

        imgAngle = math.atan(self.cameraWidth*1.0 /
                             self.cameraHeight) * 180/math.pi

        geod = Geod(ellps="WGS84")

        # 矩形的对角线长
        distance = math.sqrt(math.pow(width, 2) + math.pow(height, 2))

        # 计算右上角点
        angleTR = self.courseAngle - imgAngle
        longTR, latTR, tmpAngle = geod.fwd(
            point[0], point[1], angleTR, distance/2)

        # 计算右下角点
        angleBR = self.courseAngle + imgAngle
        longBR, latBR, tmpAngle = geod.fwd(
            point[0], point[1], angleBR, distance/2)

        # 计算左下角点
        angleBL = angleTR + 180
        longBL, latBL, tmpAngle = geod.fwd(
            point[0], point[1], angleBL, distance/2)

        # 计算左上角点
        angleTL = angleBR + 180
        longTL, latTL, tmpAngle = geod.fwd(
            point[0], point[1], angleTL, distance/2)

        result = []
        result.append((longTR, latTR))
        result.append((longBR, latBR))
        result.append((longBL, latBL))
        result.append((longTL, latTL))
        # 多边形闭合
        result.append((longTR, latTR))

        return result
Пример #20
0
g = Geod(ellps='clrk66')
lat1pt = 42.+(15./60.)
lon1pt = -71.-(7./60.)
lat2pt = 45.+(31./60.)
lon2pt = -123.-(41./60.)
print lat1pt,lon1pt,lat2pt,lon2pt
print 'inverse transform'
print 'from proj.4 invgeod:'
print commands.getoutput('echo "42d15\'N 71d07\'W 45d31\'N 123d41\'W" | geod +ellps=clrk66 -I -f "%.3f"')
print 'from pyproj.Geod.inv:'
az12,az21,dist = g.inv(lon1pt,lat1pt,lon2pt,lat2pt)
print "%7.3f %6.3f %12.3f" % (az12,az21,dist)
print 'forward transform'
print 'from proj.4 geod:'
print commands.getoutput('echo "42d15\'N 71d07\'W -66d31\'50.141 4164192.708" | geod +ellps=clrk66 -f "%.3f"')
endlon,endlat,backaz = g.fwd(lon1pt,lat1pt,az12,dist)
print 'from pyproj.Geod.fwd:'
print "%6.3f  %6.3f %13.3f" % (endlat,endlon,backaz)
print 'intermediate points:'
print 'from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:'
points = '+lon_1=%s +lat_1=%s +lon_2=%s +lat_2=%s' % (lon1pt,lat1pt,lon2pt,lat2pt,)
print points
print commands.getoutput('geod +ellps=clrk66 -f "%.3f" +n_S=5 '+points)
print 'from pyproj.Geod.npts:'
npts = 4
lonlats = g.npts(lon1pt,lat1pt,lon2pt,lat2pt,npts)
lonprev = lon1pt
latprev = lat1pt
print dist/(npts+1)
print '%6.3f  %7.3f' % (lat1pt, lon1pt)
for lon, lat in lonlats:
Пример #21
0
plt.figure()
plt.scatter(CC[:, 0], CC[:, 1], s=8, lw=0, c='blue')
plt.plot(xiCC, yi, lw=2, c='k')
plt.scatter(CCvettore[:, 0], CCvettore[:, 1], marker='s', s=60, c='r')
plt.scatter(CCdetach[:, 0], CCdetach[:, 1], marker='s', s=60, c='y')
plt.ylim([-15, 0])
plt.show()

# Ok now get the parabolas at the edges of the surface trace
p = Geod(ellps='WGS84')
x_parabola = xi - xi[-1]
y_parabola = yi
p0 = surface_trace[0, :]
lon_parabola0, lat_parabola0, baz = p.fwd(p0[0] * ones(len(x_parabola)),
                                          p0[1] * ones(len(x_parabola)),
                                          azimuth * ones(len(x_parabola)),
                                          x_parabola * 1000)
x_parabola = xi - xi[-1]
y_parabola = yi
p1 = surface_trace[-1, :]
lon_parabola1, lat_parabola1, baz = p.fwd(p1[0] * ones(len(x_parabola)),
                                          p1[1] * ones(len(x_parabola)),
                                          azimuth * ones(len(x_parabola)),
                                          x_parabola * 1000)

#Filter by depth
i = where(y_parabola > max_depth)[0]
lon_parabola0 = lon_parabola0[i]
lon_parabola1 = lon_parabola1[i]
lat_parabola0 = lat_parabola0[i]
lat_parabola1 = lat_parabola1[i]
Пример #22
0
# to be used as a digital elevation model (DEM)

import srtm
from pyproj import Geod
import pandas as pd
import pickle

centerlon = 29.0  # lower left corner longitude, decimal degrees
centerlat = 47  # lower left corner latitude, decimal degrees
pixels = 100  # size of the pixels, meters
width = 500  # km, size of the DEM
length = 500  #km, size of the DEM
g = Geod(ellps='WGS84')  # Use Clarke WGS84 ellipsoid
total_pixels = (width * 1000 / pixels) * (length * 1000 / pixels)

endlon1, urcrnrlat, backaz = g.fwd(centerlon, centerlat, 0, width / 2)
urcrnrlon, endlat2, backaz = g.fwd(centerlon, centerlat, 90, width / 2)
endlon3, llcrnrlat, backaz = g.fwd(centerlon, centerlat, 180, width / 2)
llcrnrlon, endlat4, backaz = g.fwd(centerlon, centerlat, 270, width / 2)

pixel_id = list(range((width * 1000 / pixels)))
intermediate_pixels = width * 1000 / pixels - 2

lonlats = []
elevations = []
lonlats.append((llcrnrlon, llcrnrlat))
lonlats += g.npts(llcrnrlon, llcrnrlat, urcrnrlon, llcrnrlat,
                  intermediate_pixels)
lonlats.append((urcrnrlon, llcrnrlat))
el = srtm.get_data()
for i in range(len(lonlats)):
Пример #23
0
def destination(lat: T, lon: T, bearing: T, distance: T, *args,
                **kwargs) -> Tuple[T, T, T]:
    geod = Geod(ellps="WGS84")
    lon_, lat_, back_ = geod.fwd(lon, lat, bearing, distance, *args, **kwargs)
    return lat_, lon_, back_
Пример #24
0
    def filter_on_request(self, get_request, chain, request_meta, api):
        form = SpotSearchForm(get_request)
        has_valid_search_param = False

        if not form.is_valid():
            return []

        if not get_request:
            # This is here to continue to allow the building api to request all
            # the buildings in the server.
            if api == 'buildings':
                return list(Spot.objects.all())
            return []
        query = Spot.objects.all()

        # This is here to allow only the building api to continue to be
        # contacted with the key 'campus' instead of 'extended_info:campus'
        if api == 'buildings' and 'campus' in get_request.keys():
            query = query.filter(spotextendedinfo__key='campus',
                                 spotextendedinfo__value=get_request['campus'])
            has_valid_search_param = True

        day_dict = {
            "Sunday": "su",
            "Monday": "m",
            "Tuesday": "t",
            "Wednesday": "w",
            "Thursday": "th",
            "Friday": "f",
            "Saturday": "sa",
        }

        # Q objects we need to chain together for the OR queries
        or_q_obj = Q()
        or_qs = []

        # Exclude things that get special consideration here, otherwise add a
        # filter for the keys
        for key in get_request:
            if key.startswith('oauth_'):
                pass
            elif key == 'campus':
                pass
            elif chain.filters_key(key):
                # this needs to happen early, before any
                # org_filter or extended_info
                pass
            elif key == "expand_radius":
                pass
            elif key == "distance":
                pass
            elif key == "center_latitude":
                pass
            elif key == "center_longitude":
                pass
            elif key == "limit":
                pass
            elif key == "open_now":
                if get_request["open_now"]:
                    today, now = self.get_datetime()
                    # Check to see if the request was made in minute
                    # gap before midnight during which no space is open,
                    # based on the server.
                    before_midnight = now.replace(hour=23,
                                                  minute=58,
                                                  second=59,
                                                  microsecond=999999)
                    right_before_midnight = now.replace(hour=23,
                                                        minute=59,
                                                        second=59,
                                                        microsecond=999999)
                    if before_midnight < now and now < right_before_midnight:
                        # Makes it so that all spaces that are open
                        # until midnight or overnight will be returned.
                        now = now.replace(hour=23,
                                          minute=58,
                                          second=0,
                                          microsecond=0)
                    query = \
                        query.filter(
                            spotavailablehours__day__iexact=today,
                            spotavailablehours__start_time__lt=now,
                            spotavailablehours__end_time__gt=now)
                    has_valid_search_param = True
            elif key == "open_until":
                if get_request["open_until"] and get_request["open_at"]:
                    until_day, until_t = \
                        get_request["open_until"].split(',')
                    at_day, at_t = get_request["open_at"].split(',')
                    until_day = day_dict[until_day]
                    at_day = day_dict[at_day]

                    if until_day == at_day:
                        if (strptime(until_t, "%H:%M") >= strptime(
                                at_t, "%H:%M")):
                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=until_day,
                                    spotavailablehours__start_time__lte=at_t,
                                    spotavailablehours__end_time__gte=until_t)
                        else:
                            days_to_test = [
                                "su", "m", "t", "w", "th", "f", "sa"
                            ]
                            days_to_test.remove(at_day)

                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=at_day,
                                    spotavailablehours__start_time__lte=at_t,
                                    spotavailablehours__end_time__gte="23:59")
                            t1 = "00:00"
                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=until_day,
                                    spotavailablehours__start_time__lte=t1,
                                    spotavailablehours__end_time__gte=until_t)

                            for day in days_to_test:
                                t1 = "00:00"
                                t2 = "23:59"
                                query = \
                                    query.filter(
                                        spotavailablehours__day__iexact=day,
                                        spotavailablehours__start_time__lte=t1,
                                        spotavailablehours__end_time__gte=t2)
                    else:
                        days_to_test = self.get_days_in_range(
                            at_day, until_day)
                        last_day = days_to_test.pop()
                        days_to_test.reverse()
                        first_day = days_to_test.pop()

                        query = \
                            query.filter(
                                spotavailablehours__day__iexact=first_day,
                                spotavailablehours__start_time__lte=at_t,
                                spotavailablehours__end_time__gte="23:59")
                        query = \
                            query.filter(
                                spotavailablehours__day__iexact=last_day,
                                spotavailablehours__start_time__lte="00:00",
                                spotavailablehours__end_time__gte=until_t)

                        for day in days_to_test:
                            early = "00:00"
                            query = \
                                query.filter(
                                    spotavailablehours__day__iexact=day,
                                    spotavailablehours__start_time__lte=early,
                                    spotavailablehours__end_time__gte="23:59")
                    has_valid_search_param = True
            elif key == "open_at":
                if get_request["open_at"]:
                    try:
                        get_request["open_until"]
                    except:
                        day, time = get_request['open_at'].split(',')
                        day = day_dict[day]
                        query = \
                            query.filter(
                                spotavailablehours__day__iexact=day,
                                spotavailablehours__start_time__lte=time,
                                spotavailablehours__end_time__gt=time)
                        has_valid_search_param = True
            elif key == "fuzzy_hours_end":
                # fuzzy search requires a start and end
                if "fuzzy_hours_start" not in get_request.keys():
                    raise RESTException(
                        "fuzzy_hours_end requires "
                        "fuzzy_hours_start to be specified", 400)
            elif key == "fuzzy_hours_start":
                # fuzzy search requires a start and end
                starts = get_request.getlist("fuzzy_hours_start")
                ends = get_request.getlist("fuzzy_hours_end")
                if ("fuzzy_hours_end" not in get_request.keys()
                        or not len(starts) is len(ends)):
                    raise RESTException(
                        "fuzzy_hours_start requires "
                        "fuzzy_hours_end to be specified", 400)

                or_small_q_obj = Q()
                for num, start in enumerate(starts):
                    start_day, start_time = start.split(',')
                    end_day, end_time = ends[num].split(',')
                    start_day = day_dict[start_day]
                    end_day = day_dict[end_day]

                    start_range_query = \
                        Q(spotavailablehours__day__iexact=start_day,
                          spotavailablehours__start_time__gte=start_time,
                          spotavailablehours__start_time__lt=end_time)
                    end_range_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__end_time__gt=start_time,
                          spotavailablehours__end_time__lte=end_time)
                    span_range_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__start_time__lte=start_time,
                          spotavailablehours__end_time__gt=end_time)
                    span_midnight_pre_query = \
                        Q(spotavailablehours__day__iexact=start_day,
                          spotavailablehours__start_time__gte=start_time,
                          spotavailablehours__start_time__lte="23:59")
                    span_midnight_post_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__end_time__lt=end_time,
                          spotavailablehours__end_time__gte="00:00")
                    span_midnight_pre_midnight_end_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__end_time__gte=start_time,
                          spotavailablehours__end_time__lte="23:59")
                    span_midnight_next_morning_query = \
                        Q(spotavailablehours__day__iexact=end_day,
                          spotavailablehours__start_time__lt=end_time,
                          spotavailablehours__start_time__gte="00:00")
                    if start_day is not end_day:
                        range_query = (start_range_query | end_range_query
                                       | span_midnight_pre_query
                                       | span_midnight_post_query
                                       | span_midnight_pre_midnight_end_query
                                       | span_midnight_next_morning_query)
                    else:
                        range_query = (start_range_query | end_range_query
                                       | span_range_query)
                    or_small_q_obj |= range_query
                query = query.filter(or_small_q_obj)
                has_valid_search_param = True
            elif key == "capacity":
                try:
                    limit = int(get_request["capacity"])
                    with_limit = Q(capacity__gte=limit)
                    with_limit |= Q(capacity__isnull=True)
                    query = query.filter(with_limit)
                    has_valid_search_param = True
                except ValueError:
                    # This we don't care about - if someone passes "", or
                    # "twenty", just ignore it
                    pass
                except Exception as e:
                    # Do something to complain??
                    pass
            elif key == "type":
                type_values = get_request.getlist(key)
                q_obj = Q()
                type_qs = [Q(spottypes__name__exact=v) for v in type_values]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key == "building_name":
                building_names = get_request.getlist(key)
                q_obj = Q()
                type_qs = [Q(building_name__exact=v) for v in building_names]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key.startswith('item:extended_info:'):
                try:
                    for value in get_request.getlist(key):
                        or_qs.append(
                            Q(item__itemextendedinfo__key=key[19:],
                              item__itemextendedinfo__value=value))
                    has_valid_search_param = True
                except Exception as e:
                    pass
            elif key.startswith('item:'):
                try:
                    for value in get_request.getlist(key):
                        if key[5:] == "id":
                            or_qs.append(Q(item__id=value))
                        elif key[5:] == "name":
                            or_qs.append(Q(item__name=value))
                        elif key[5:] == "category":
                            or_qs.append(Q(item__item_category=value))
                        elif key[5:] == "subcategory":
                            or_qs.append(Q(item__item_subcategory=value))
                    has_valid_search_param = True
                except Exception as e:
                    pass
            elif key.startswith('extended_info:or_group'):
                values = get_request.getlist(key)
                or_small_q_obj = Q()
                for value in values:
                    or_small_q_obj |= Q(spotextendedinfo__key=value,
                                        spotextendedinfo__value='true')
                query = query.filter(or_small_q_obj)
                has_valid_search_param = True
            elif key.startswith('extended_info:or'):
                or_qs.append(
                    Q(spotextendedinfo__key=key[17:],
                      spotextendedinfo__value='true'))
                has_valid_search_param = True
            elif key.startswith('extended_info:'):
                kwargs = {
                    'spotextendedinfo__key': key[14:],
                    'spotextendedinfo__value__in': get_request.getlist(key)
                }
                query = query.filter(**kwargs)
                has_valid_search_param = True
            elif key == "id":
                query = query.filter(id__in=get_request.getlist(key))
                has_valid_search_param = True
            else:
                try:
                    kwargs = {'%s__icontains' % key: get_request[key]}
                    query = query.filter(**kwargs)
                    has_valid_search_param = True
                except Exception as e:
                    if not request_meta['SERVER_NAME'] == 'testserver':
                        print >> sys.stderr, "E: ", e

        for or_q in or_qs:
            or_q_obj |= or_q
        # This handles all of the OR queries on extended_info we've collected.
        query = query.filter(or_q_obj).distinct()
        # Always prefetch the related extended info
        query = query.select_related('SpotExtendedInfo')

        query = chain.filter_query(query)
        if chain.has_valid_search_param:
            has_valid_search_param = True

        limit = int(get_request.get('limit', 20))

        if ('distance' in get_request and 'center_longitude' in get_request
                and 'center_latitude' in get_request):
            try:
                g = Geod(ellps='clrk66')
                lon = get_request['center_longitude']
                lat = get_request['center_latitude']
                dist = get_request['distance']
                # Get coordinates above/right/below/left our location
                top = g.fwd(lon, lat, 0, dist)
                right = g.fwd(lon, lat, 90, dist)
                bottom = g.fwd(lon, lat, 180, dist)
                left = g.fwd(lon, lat, 270, dist)
                # Get relevant lat or long from these points
                top_limit = "%.8f" % top[1]
                bottom_limit = "%.8f" % bottom[1]
                left_limit = "%.8f" % left[0]
                right_limit = "%.8f" % right[0]

                distance_query = query.filter(longitude__gte=left_limit,
                                              longitude__lte=right_limit,
                                              latitude__gte=bottom_limit,
                                              latitude__lte=top_limit)
                has_valid_search_param = True

                if distance_query or 'expand_radius' not in get_request:
                    query = distance_query
                else:
                    # If we're querying everything, let's make sure we only
                    # return a limited number of spaces...
                    limit = 10
            except Exception as e:
                if not request_meta['SERVER_NAME'] == 'testserver':
                    print >> sys.stderr, "E: ", e
                # query = Spot.objects.all()
        elif ('distance' in get_request or 'center_longitude' in get_request
              or 'center_latitude' in get_request):
            if ('distance' not in get_request
                    or 'center_longitude' not in get_request
                    or 'center_latitude' not in get_request):
                # If distance, lat, or long are specified in the server
                # request; all 3 must be present.
                raise RESTException(
                    "Must specify latitude, longitude, and distance", 400)

        # Only do this if spot api because buildings api
        # is able to not pass any valid filters
        if not has_valid_search_param and api == 'spot':
            return []

        # Do this when spot api because building api is not required
        # to pass these parameters
        if limit > 0 and limit < len(query) and api == 'spot':
            try:
                lat = get_request['center_latitude']
                lon = get_request['center_longitude']
            except KeyError:
                raise RESTException(
                    "missing required parameters for this type of search", 400)

            def sortfunc(spot):
                return self.distance(spot, lon, lat)

            sorted_list = sorted(query, key=sortfunc)
            query = sorted_list[:limit]

        spots = set(query)
        spots = chain.filter_results(spots)

        return spots
Пример #25
0
    def GET(self, request):
        form = SpotSearchForm(request.GET)
        has_valid_search_param = False

        if not form.is_valid():
            return JSONResponse([])

        if len(request.GET) == 0:
            return JSONResponse([])
        chain = SearchFilterChain(request)
        query = Spot.objects.all()

        day_dict = {"Sunday": "su",
                    "Monday": "m",
                    "Tuesday": "t",
                    "Wednesday": "w",
                    "Thursday": "th",
                    "Friday": "f",
                    "Saturday": "sa", }
        # Exclude things that get special consideration here, otherwise add a filter for the keys
        for key in request.GET:
            if key.startswith('oauth_'):
                pass
            elif chain.filters_key(key):
                # this needs to happen early, before any
                # org_filter or extended_info
                pass
            elif key == "expand_radius":
                pass
            elif key == "distance":
                pass
            elif key == "center_latitude":
                pass
            elif key == "center_longitude":
                pass
            elif key == "limit":
                pass
            elif key == "open_anytime":
                pass
            elif key == "open_now":
                if request.GET["open_now"]:

                    day_lookup = ["su", "m", "t", "w", "th", "f", "sa"]
                    day_num = int(strftime("%w", localtime()))
                    today = day_lookup[day_num]
                    now = datetime.time(datetime.now())
                    query = query.filter(spotavailablehours__day__iexact=today, spotavailablehours__start_time__lt=now, spotavailablehours__end_time__gt=now)
                    has_valid_search_param = True
            elif key == "open_until":
                if request.GET["open_until"] and request.GET["open_at"]:
                    until_day, until_time = request.GET["open_until"].split(',')
                    at_day, at_time = request.GET["open_at"].split(',')
                    until_day = day_dict[until_day]
                    at_day = day_dict[at_day]

                    if until_day == at_day:
                        if strptime(until_time, "%H:%M") >= strptime(at_time, "%H:%M"):
                            query = query.filter(spotavailablehours__day__iexact=until_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte=until_time)
                        else:
                            days_to_test = ["su", "m", "t", "w", "th", "f", "sa"]
                            days_to_test.remove(at_day)

                            query = query.filter(spotavailablehours__day__iexact=at_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte="23:59")
                            query = query.filter(spotavailablehours__day__iexact=until_day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte=until_time)

                            for day in days_to_test:
                                query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte="23:59")
                    else:
                        days_to_test = self.get_days_in_range(at_day, until_day)
                        last_day = days_to_test.pop()
                        days_to_test.reverse()
                        first_day = days_to_test.pop()

                        query = query.filter(spotavailablehours__day__iexact=first_day, spotavailablehours__start_time__lte=at_time, spotavailablehours__end_time__gte="23:59")
                        query = query.filter(spotavailablehours__day__iexact=last_day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte=until_time)

                        for day in days_to_test:
                            query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte="00:00", spotavailablehours__end_time__gte="23:59")
                    has_valid_search_param = True
            elif key == "open_at":
                if request.GET["open_at"]:
                    try:
                        request.GET["open_until"]
                    except:
                        day, time = request.GET['open_at'].split(',')
                        day = day_dict[day]
                        query = query.filter(spotavailablehours__day__iexact=day, spotavailablehours__start_time__lte=time, spotavailablehours__end_time__gt=time)
                        has_valid_search_param = True
            elif key == "capacity":
                try:
                    limit = int(request.GET["capacity"])
                    with_limit = Q(capacity__gte=limit)
                    with_limit |= Q(capacity__isnull=True)
                    query = query.filter(with_limit)
                    has_valid_search_param = True
                except ValueError:
                    # This we don't care about - if someone passes "", or "twenty", just ignore it
                    pass
                except Exception as e:
                    # Do something to complain??
                    pass
            elif key == "type":
                type_values = request.GET.getlist(key)
                q_obj = Q()
                type_qs = [Q(spottypes__name__exact=v) for v in type_values]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key == "building_name":
                building_names = request.GET.getlist(key)
                q_obj = Q()
                type_qs = [Q(building_name__exact=v) for v in building_names]
                for type_q in type_qs:
                    q_obj |= type_q
                query = query.filter(q_obj).distinct()
                has_valid_search_param = True
            elif key.startswith('extended_info:'):
                kwargs = {
                    'spotextendedinfo__key': key[14:],
                    'spotextendedinfo__value__in': request.GET.getlist(key)
                }
                query = query.filter(**kwargs)
                has_valid_search_param = True
            elif key == "id":
                query = query.filter(id__in=request.GET.getlist(key))
                has_valid_search_param = True
            else:
                try:
                    kwargs = {
                        '%s__icontains' % key: request.GET[key]
                    }
                    query = query.filter(**kwargs)
                    has_valid_search_param = True
                except Exception as e:
                    if not request.META['SERVER_NAME'] == 'testserver':
                        print >> sys.stderr, "E: ", e

        # Always prefetch the related extended info
        query = query.select_related('SpotExtendedInfo')

        query = chain.filter_query(query)
        if chain.has_valid_search_param:
            has_valid_search_param = True

        limit = 20
        if 'limit' in request.GET:
            if request.GET['limit'] == '0':
                limit = 0
            else:
                limit = int(request.GET['limit'])

        if 'distance' in request.GET and 'center_longitude' in request.GET and 'center_latitude' in request.GET:
            try:
                g = Geod(ellps='clrk66')
                top = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 0, request.GET['distance'])
                right = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 90, request.GET['distance'])
                bottom = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 180, request.GET['distance'])
                left = g.fwd(request.GET['center_longitude'], request.GET['center_latitude'], 270, request.GET['distance'])

                top_limit = "%.8f" % top[1]
                bottom_limit = "%.8f" % bottom[1]
                left_limit = "%.8f" % left[0]
                right_limit = "%.8f" % right[0]

                distance_query = query.filter(longitude__gte=left_limit)

                distance_query = distance_query.filter(longitude__lte=right_limit)
                distance_query = distance_query.filter(latitude__gte=bottom_limit)
                distance_query = distance_query.filter(latitude__lte=top_limit)
                has_valid_search_param = True

                if len(distance_query) > 0 or 'expand_radius' not in request.GET:
                    query = distance_query
                else:
                    # If we're querying everything, let's make sure we only return a limited number of spaces...
                    limit = 10
            except Exception as e:
                if not request.META['SERVER_NAME'] == 'testserver':
                    print >> sys.stderr, "E: ", e
                #query = Spot.objects.all()
        elif 'distance' in request.GET or 'center_longitude' in request.GET or 'center_latitude' in request.GET:
            if 'distance' not in request.GET or 'center_longitude' not in request.GET or 'center_latitude' not in request.GET:
                # If distance, lat, or long are specified in the server request; all 3 must be present.
                raise RESTException("Must specify latitude, longitude, and distance", 400)

        if not has_valid_search_param:
            return JSONResponse([])

        if limit > 0 and limit < len(query):
            sorted_list = list(query)
            try:
                sorted_list.sort(lambda x, y: cmp(self.distance(x, request.GET['center_longitude'], request.GET['center_latitude']), self.distance(y, request.GET['center_longitude'], request.GET['center_latitude'])))
                query = sorted_list[:limit]
            except KeyError:
                raise RESTException("missing required parameters for this type of search", 400)

        response = []
        spots = set(query)
        spots = chain.filter_results(spots)

        for spot in spots:
            response.append(spot.json_data_structure())

        return JSONResponse(response)
Пример #26
0
def get_mesh(pfs, rfi, sd, idl):
    """
    From a set of profiles creates the mesh in the forward direction from the
    reference profile.

    :param pfs:
        List of :class:`openquake.hazardlib.geo.line.Line` instances
    :param rfi:
        Index of the reference profile
    :param sd:
        Sampling distance [km] for the edges
    :param idl:
        Boolean indicating the need to account for the IDL
    :returns:
        An updated list of the profiles i.e. a list of
        :class:`openquake.hazardlib.geo.line.Line` instances
    """
    g = Geod(ellps='WGS84')

    # Residual distance, last index
    rdist = [0 for _ in range(0, len(pfs[0]))]
    laidx = [0 for _ in range(0, len(pfs[0]))]

    # New profiles
    npr = list([copy.copy(pfs[rfi])])

    # Run for all the profiles 'after' the reference one
    for i in range(rfi, len(pfs)-1):

        # Profiles
        pr = pfs[i+1]
        pl = pfs[i]

        # Fixing IDL case
        if idl:
            for ii in range(0, len(pl)):
                ptmp = pl[ii][0]
                ptmp = ptmp+360 if ptmp < 0 else ptmp
                pl[ii][0] = ptmp

        # Point in common on the two profiles
        cmm = np.logical_and(np.isfinite(pr[:, 2]), np.isfinite(pl[:, 2]))
        cmmi = np.nonzero(cmm)[0].astype(int)

        # Update last profile index
        mxx = 0
        for ll in laidx:
            if ll is not None:
                mxx = max(mxx, ll)

        # Loop over the points in the right profile
        for x in range(0, len(pr[:, 2])):

            # This edge is in common between the last and the current profiles
            if x in cmmi and laidx[x] is None:
                iii = []
                for li, lv in enumerate(laidx):
                    if lv is not None:
                        iii.append(li)
                iii = np.array(iii)
                minidx = np.argmin(abs(iii-x))
                laidx[x] = mxx
                rdist[x] = rdist[minidx]
            elif x not in cmmi:
                laidx[x] = None
                rdist[x] = 0

        # Loop over profiles
        for k in list(np.nonzero(cmm)[0]):

            # Compute distance and azimuth between the corresponding points
            # on the two profiles
            az12, _, hdist = g.inv(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1])
            hdist /= 1e3
            vdist = pr[k, 2] - pl[k, 2]
            tdist = (vdist**2 + hdist**2)**.5
            ndists = int(np.floor((tdist+rdist[k])/sd))

            ll = g.npts(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1],
                        np.ceil(tdist)*20)
            ll = np.array(ll)
            lll = np.ones_like(ll)
            lll[:, 0] = pl[k, 0]
            lll[:, 1] = pl[k, 1]

            _, _, hdsts = g.inv(lll[:, 0], lll[:, 1], ll[:, 0], ll[:, 1])
            hdsts /= 1e3
            deps = np.linspace(pl[k, 2], pr[k, 2], ll.shape[0], endpoint=True)
            tdsts = (hdsts**2 + (pl[k, 2]-deps)**2)**0.5
            assert len(deps) == ll.shape[0]

            # Compute distance between consecutive profiles
            dd = distance(pl[k, 0], pl[k, 1], pl[k, 2],
                          pr[k, 0], pr[k, 1], pr[k, 2])

            # Check distance
            if abs(dd-tdist) > 0.1*tdist:
                print('dd:', dd)
                tmps = 'Error while building the mesh'
                tmps += '\nDistances: {:f} {:f}'
                raise ValueError(tmps.format(dd, tdist))

            # Adding new points along the edge with index k
            for j in range(ndists):

                # Add new profile
                if len(npr)-1 < laidx[k]+1:
                    npr = add_empty_profile(npr)

                # Compute the coordinates of intermediate points along the
                # current edge
                tmp = (j+1)*sd - rdist[k]
                lo, la, _ = g.fwd(pl[k, 0], pl[k, 1], az12,
                                  tmp*hdist/tdist*1e3)

                tidx = np.argmin(abs(tdsts-tmp))
                lo = ll[tidx, 0]
                la = ll[tidx, 1]

                # Fix longitudes
                if idl:
                    lo = lo+360 if lo < 0 else lo

                # Computing depths
                de = pl[k, 2] + tmp*vdist/hdist
                de = deps[tidx]

                npr[laidx[k]+1][k] = [lo, la, de]
                if (k > 0 and np.all(np.isfinite(npr[laidx[k]+1][k])) and
                        np.all(np.isfinite(npr[laidx[k]][k]))):

                    p1 = npr[laidx[k]][k]
                    p2 = npr[laidx[k]+1][k]
                    d = distance(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2])

                    # Check
                    if abs(d-sd) > 0.1*sd:
                        tmpf = 'd: {:f} diff: {:f} tol: {:f} sd:{:f}'
                        tmpf += '\nresidual: {:f}'
                        tmps = tmpf.format(d, d-sd, TOL*sd, sd, rdist[k])
                        raise ValueError(tmps)
                laidx[k] += 1

            rdist[k] = tdist - sd*ndists + rdist[k]
            assert rdist[k] < sd

    return npr