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
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
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)
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 )
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)
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)
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
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
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
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]))
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")
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]))
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
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))
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
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))
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)
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
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:
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]
# 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)):
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_
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
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)
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