def test_GeodSolve2(self): # Check fix for antipodal prolate bug found 2010-09-04 geod = Geodesic(6.4e6, -1 / 150.0) inv = geod.Inverse(0.07476, 0, -0.07476, 180) self.assertAlmostEqual(inv["azi1"], 90.00078, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 90.00078, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5) inv = geod.Inverse(0.1, 0, -0.1, 180) self.assertAlmostEqual(inv["azi1"], 90.00105, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 90.00105, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5)
def test_GeodSolve12(self): # Check fix for inverse geodesics on extreme prolate/oblate # ellipsoids Reported 2012-08-29 Stefan Guenther # <*****@*****.**>; fixed 2012-10-07 geod = Geodesic(89.8, -1.83) inv = geod.Inverse(0, 0, -10, 160) self.assertAlmostEqual(inv["azi1"], 120.27, delta=1e-2) self.assertAlmostEqual(inv["azi2"], 105.15, delta=1e-2) self.assertAlmostEqual(inv["s12"], 266.7, delta=1e-1)
def calc_dist_azi(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, radius_of_planet_in_km, flattening_of_planet): """ Given the source and receiver location, calculate the azimuth from the source to the receiver at the source, the backazimuth from the receiver to the source at the receiver and distance between the source and receiver. :param source_latitude_in_deg: Source location latitude in degrees :type source_latitude_in_deg: float :param source_longitude_in_deg: Source location longitude in degrees :type source_longitude_in_deg: float :param receiver_latitude_in_deg: Receiver location latitude in degrees :type receiver_latitude_in_deg: float :param receiver_longitude_in_deg: Receiver location longitude in degrees :type receiver_longitude_in_deg: float :param radius_of_planet_in_km: Radius of the planet in km :type radius_of_planet_in_km: float :param flattening_of_planet: Flattening of planet (0 for a sphere) :type receiver_longitude_in_deg: float :returns: distance_in_deg (in degrees), source_receiver_azimuth (in degrees) and receiver_to_source_backazimuth (in degrees). :rtype: tuple of three floats """ if geodetics.HAS_GEOGRAPHICLIB: ellipsoid = Geodesic(a=radius_of_planet_in_km * 1000.0, f=flattening_of_planet) g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg) distance_in_deg = g['a12'] source_receiver_azimuth = g['azi1'] % 360 receiver_to_source_backazimuth = (g['azi2'] + 180) % 360 else: # geographiclib is not installed - use obspy/geodetics values = gps2dist_azimuth(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, a=radius_of_planet_in_km * 1000.0, f=flattening_of_planet) distance_in_km = values[0] / 1000.0 source_receiver_azimuth = values[1] % 360 receiver_to_source_backazimuth = values[2] % 360 # NB - km2deg assumes spherical planet... generate a warning if flattening_of_planet != 0.0: msg = "Assuming spherical planet when calculating epicentral " + \ "distance. Install the Python module 'geographiclib' " + \ "to solve this." warnings.warn(msg) distance_in_deg = kilometer2degrees(distance_in_km, radius=radius_of_planet_in_km) return (distance_in_deg, source_receiver_azimuth, receiver_to_source_backazimuth)
def calc_dist(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, radius_of_earth_in_km, flattening_of_earth): """ Given the source and receiver location, calculate the azimuth and distance. :param source_latitude_in_deg: Source location latitude in degrees :type source_latitude_in_deg: float :param source_longitude_in_deg: Source location longitude in degrees :type source_longitude_in_deg: float :param receiver_latitude_in_deg: Receiver location latitude in degrees :type receiver_latitude_in_deg: float :param receiver_longitude_in_deg: Receiver location longitude in degrees :type receiver_longitude_in_deg: float :param radius_of_earth_in_km: Radius of the Earth in km :type radius_of_earth_in_km: float :param flattening_of_earth: Flattening of Earth (0 for a sphere) :type receiver_longitude_in_deg: float :return: distance_in_deg :rtype: float """ if geodetics.HAS_GEOGRAPHICLIB: ellipsoid = Geodesic(a=radius_of_earth_in_km*1000.0, f=flattening_of_earth) g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg) distance_in_deg = g['a12'] else: # geographiclib is not installed - use obspy/geodetics values = gps2dist_azimuth(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, a=radius_of_earth_in_km*1000.0, f=flattening_of_earth) distance_in_km = values[0]/1000.0 # NB - km2deg assumes spherical Earth... generate a warning if flattening_of_earth != 0.0: msg = "Assuming spherical Earth when calculating epicentral " + \ "distance. Install the Python module 'geographiclib' " + \ "to solve this." warnings.warn(msg) distance_in_deg = kilometer2degrees(distance_in_km, radius=radius_of_earth_in_km) return distance_in_deg
def test_GeodSolve33(self): # Check max(-0.0,+0.0) issues 2015-08-22 (triggered by bugs in # Octave -- sind(-0.0) = +0.0 -- and in some version of Visual # Studio -- fmod(-0.0, 360.0) = +0.0. inv = Geodesic.WGS84.Inverse(0, 0, 0, 179) self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 19926189, delta=0.5) inv = Geodesic.WGS84.Inverse(0, 0, 0, 179.5) self.assertAlmostEqual(inv["azi1"], 55.96650, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 124.03350, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 19980862, delta=0.5) inv = Geodesic.WGS84.Inverse(0, 0, 0, 180) self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5) self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20003931, delta=0.5) inv = Geodesic.WGS84.Inverse(0, 0, 1, 180) self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5) self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 19893357, delta=0.5) geod = Geodesic(6.4e6, 0) inv = geod.Inverse(0, 0, 0, 179) self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 19994492, delta=0.5) inv = geod.Inverse(0, 0, 0, 180) self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5) self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5) inv = geod.Inverse(0, 0, 1, 180) self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5) self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 19994492, delta=0.5) geod = Geodesic(6.4e6, -1 / 300.0) inv = geod.Inverse(0, 0, 0, 179) self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 19994492, delta=0.5) inv = geod.Inverse(0, 0, 0, 180) self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5) inv = geod.Inverse(0, 0, 0.5, 180) self.assertAlmostEqual(inv["azi1"], 33.02493, delta=0.5e-5) self.assertAlmostEqual(inv["azi2"], 146.97364, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20082617, delta=0.5) inv = geod.Inverse(0, 0, 1, 180) self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5) self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5) self.assertAlmostEqual(inv["s12"], 20027270, delta=0.5)
def calculate_distances(self): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Calculates the distance between all neuron positions *along the surface* (using geodesic distances) ~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # The geographiclib.geodesic module is needed to calculate geodesic distance along the surface of a spheroid. # - Library is based on Karney 2013 (seemingly written by Karney himself) # - See https://geographiclib.sourceforge.io/1.48/python/ try: from geographiclib.geodesic import Geodesic except: exitOnNetworkGeometryError("The geographiclib.geodesic module is needed to calculate geodesic distance along the surface of a spheroid, but this module could not be imported.") # The Geodesic object constructor has two parameters: # - a: the equatorial (xy) radius of the ellipsoid # - f: the flattening of the ellipsoid. b = a(1-f) --> f = 1 - b/a (where b is the polar (z) axis) a = self.r_xy b = self.r_z f = 1.0 - b/a geodesic = Geodesic(a, f) # Convert parametric coordinates (theta(lon), phi(lat)) from radian to degree angles degreecoords = numpy.degrees(self.parametricCoords) # print self.coordinates # print "degrees" # print degreecoords for i in range(self.N): for j in range(self.N): # Geodesic.Inverse(...) calculates the geodesic distance between two points along a spheroid surface. # arguments: (lat1, lon1, lat2, lon2, outmask=1025) # - expects lat1, lon1, lat2, lon2 to be latitude(theta)/longitude(phi) angles in degrees # - outmask=1025 tells it to return the distance measure # returns: a Geodesic dictionary including key-value pair 's12', which is the calculated distance between the points. lat1 = degreecoords[i][1] lon1 = degreecoords[i][0] lat2 = degreecoords[j][1] lon2 = degreecoords[j][0] # print geodesic.Inverse(lat1, lon1, lat2, lon2, outmask=1025) # print "lat" + str(lat1) + " lon" + str(lon1) + " :: lat" + str(lat2) + " lon" + str(lon2) dist = geodesic.Inverse(lat1, lon1, lat2, lon2, outmask=1025)['s12'] self.distances[i,j] = dist
def add_geo_to_arrivals(arrivals, source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, radius_of_earth_in_km, flattening_of_earth): """ Add geographical information to arrivals. :param arrivals: Set of taup arrivals :type: :class:`Arrivals` :param source_latitude_in_deg: Source location latitude in degrees :type source_latitude_in_deg: float :param source_longitude_in_deg: Source location longitude in degrees :type source_longitude_in_deg: float :param receiver_latitude_in_deg: Receiver location latitude in degrees :type receiver_latitude_in_deg: float :param receiver_longitude_in_deg: Receiver location longitude in degrees :type receiver_longitude_in_deg: float :param radius_of_earth_in_km: Radius of the Earth in km :type radius_of_earth_in_km: float :param flattening_of_earth: Flattening of Earth (0 for a sphere) :type receiver_longitude_in_deg: float :return: List of ``Arrival`` objects, each of which has the time, corresponding phase name, ray parameter, takeoff angle, etc. as attributes. :rtype: :class:`Arrivals` """ if geodetics.HAS_GEOGRAPHICLIB: ellipsoid = Geodesic(a=radius_of_earth_in_km * 1000.0, f=flattening_of_earth) g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg) azimuth = g['azi1'] line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg, azimuth) # We may need to update many arrival objects # and each could have pierce points and a # path for arrival in arrivals: if arrival.pierce is not None: geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo) for i, pierce_point in enumerate(arrival.pierce): pos = line.ArcPosition(np.degrees(pierce_point['dist'])) geo_pierce[i] = (pierce_point['p'], pierce_point['time'], pierce_point['dist'], pierce_point['depth'], pos['lat2'], pos['lon2']) arrival.pierce = geo_pierce if arrival.path is not None: geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo) for i, path_point in enumerate(arrival.path): pos = line.ArcPosition(np.degrees(path_point['dist'])) geo_path[i] = (path_point['p'], path_point['time'], path_point['dist'], path_point['depth'], pos['lat2'], pos['lon2']) arrival.path = geo_path else: # geographiclib is not installed ... # and obspy/geodetics does not help much msg = "You need to install the Python module 'geographiclib' in " + \ "order to add geographical information to arrivals." raise ImportError(msg) return arrivals
def Inverse(self, lat1, lon1, lat2, lon2, *outmask): '''Return the C{Inverse} result. ''' d = _Geodesic.Inverse(self, lat1, lon1, lat2, lon2, *outmask) return _Adict(d)
class geodesic(Distance): """ Calculate the geodesic distance between two points. Set which ellipsoidal model of the earth to use by specifying an ``ellipsoid`` keyword argument. The default is 'WGS-84', which is the most globally accurate model. If ``ellipsoid`` is a string, it is looked up in the `ELLIPSOIDS` dictionary to obtain the major and minor semiaxes and the flattening. Otherwise, it should be a tuple with those values. See the comments above the `ELLIPSOIDS` dictionary for more information. Example:: >>> from geopy.distance import geodesic >>> newport_ri = (41.49008, -71.312796) >>> cleveland_oh = (41.499498, -81.695391) >>> print(geodesic(newport_ri, cleveland_oh).miles) 538.390445368 .. versionadded:: 1.13.0 """ ellipsoid_key = None ELLIPSOID = None geod = None def __init__(self, *args, **kwargs): self.set_ellipsoid(kwargs.pop('ellipsoid', 'WGS-84')) if 'iterations' in kwargs: warnings.warn( 'Ignoring unused `iterations` kwarg for geodesic ' 'distance.', UserWarning) kwargs.pop('iterations', 0) major, minor, f = self.ELLIPSOID super(geodesic, self).__init__(*args, **kwargs) def set_ellipsoid(self, ellipsoid): """ Change the ellipsoid used in the calculation. """ if not isinstance(ellipsoid, (list, tuple)): try: self.ELLIPSOID = ELLIPSOIDS[ellipsoid] self.ellipsoid_key = ellipsoid except KeyError: raise Exception( "Invalid ellipsoid. See geopy.distance.ELLIPSOIDS") else: self.ELLIPSOID = ellipsoid self.ellipsoid_key = None return # Call geographiclib routines for measure and destination def measure(self, a, b): a, b = Point(a), Point(b) lat1, lon1 = a.latitude, a.longitude lat2, lon2 = b.latitude, b.longitude if not (isinstance(self.geod, Geodesic) and self.geod.a == self.ELLIPSOID[0] and self.geod.f == self.ELLIPSOID[2]): self.geod = Geodesic(self.ELLIPSOID[0], self.ELLIPSOID[2]) s12 = self.geod.Inverse(lat1, lon1, lat2, lon2, Geodesic.DISTANCE)['s12'] return s12 def destination(self, point, bearing, distance=None): """ TODO docs. """ point = Point(point) lat1 = point.latitude lon1 = point.longitude azi1 = bearing if distance is None: distance = self if isinstance(distance, Distance): distance = distance.kilometers if not (isinstance(self.geod, Geodesic) and self.geod.a == self.ELLIPSOID[0] and self.geod.f == self.ELLIPSOID[2]): self.geod = Geodesic(self.ELLIPSOID[0], self.ELLIPSOID[2]) r = self.geod.Direct(lat1, lon1, azi1, distance, Geodesic.LATITUDE | Geodesic.LONGITUDE) return Point(r['lat2'], r['lon2'])
def test_GeodSolve26(self): # Check 0/0 problem with area calculation on sphere 2015-09-08 geod = Geodesic(6.4e6, 0) inv = geod.Inverse(1, 2, 3, 4, Geodesic.AREA) self.assertAlmostEqual(inv["S12"], 49911046115.0, delta=0.5)
#print('{} has {} children.'.format(airports[airports.AirportID == trip.DestinationAirportID].IATA.values[0], len(secLeg))) print('{} '.format(airports[airports.AirportID == trip.DestinationAirportID].IATA.values[0])), # iterate through child routes for stID, strip in secLeg.iterrows(): if not strip.DestinationAirportID in exceptions: try: # try to get Long and Lat for this airport. Fails if AirportID in routes.dat doesn't exist in airports.dat sdestlong = airports[airports.AirportID == strip.DestinationAirportID].Longitude.values[0] sdestlat = airports[airports.AirportID == strip.DestinationAirportID].Latitude.values[0] except: exceptions.append(strip.DestinationAirportID) if not strip.DestinationAirportID in exceptions: # if we made it through the Long/Lat lookups # get the distance to the child airport (could improve by including first leg distance here) newdist = geod.Inverse(destlat, destlong, sdestlat, sdestlong)['s12'] #vector(destlong, sdestlong, destlat, sdestlat) #print('Checking child {}: '.format(strip.DestinationAirportID)), if strip.DestinationAirportID in finals.DID.values: # if we have already added this child, get the index i = finals[(finals.DID == strip.DestinationAirportID)].index.tolist()[0] # if the new distance to the child is shorter than the old one (improved route) if finals.loc[i].dist > newdist: # update the child with the new parent airport and distance #print('updating child') finals.loc[(finals['DID']==strip.DestinationAirportID)] = [[trip.DestinationAirportID, strip.DestinationAirportID, newdist]] else: pass # pass does nothing except make the indent so the else doesn't fail #print('OK') # current child still the best else: #print('Adding new child') newdf = pd.DataFrame([[trip.DestinationAirportID, strip.DestinationAirportID, newdist]], columns = ['SID', 'DID', 'dist'])
p_moscow[::-1], ellipsoid='WGS-84').meters print("#3 geopy: %s (%s)" % (distance, time() - t)) # 4 # http://jswhit.github.io/pyproj/pyproj.Geod-class.html#inv t = time() for i in range(1000000): _az12, _az21, distance = geod.inv(*list(p_minsk + p_moscow)) print("#4 pyproj: %s (%s)" % (distance, time() - t)) # 5 # http://geographiclib.sourceforge.net/1.46/python/code.html#geographiclib.geodesic.Geodesic.Inverse t = time() for i in range(1000000): r = geodesic.Inverse(*(p_minsk[::-1] + p_moscow[::-1]), outmask=geodesic.DISTANCE) print("#5 geographiclib: %s (%s)" % (r['s12'], time() - t)) # 6 # https://github.com/xoolive/geodesy t = time() for i in range(1000000): d = geo.distance(p_minsk[::-1], p_moscow[::-1]) print("#6 geodesy: %s (%s)" % (d, time() - t)) ''' #1 haversine fun: 675656.2994818708 (2.1997811794281006) #2 great circle fun: 675656.2994818711 (2.8947739601135254) #3 geopy: 677789.5312317797 (32.68954396247864) #4 pyproj: 677789.531232748 (11.323993921279907) #5 geographiclib: 677789.5312327482 (195.3897831439972) #6 geodesy: 675655.366226931 (0.7595169544219971)
def organizebounds(num_bounds,iwall,idl,idr,lona,lata,lonb,latb,bound_ind,large_wall_inds,vt_ew,vt_ns,dsegtr,dseged,polarity,rad_km): # divide trenches and edges into segments lona_temp = []; lata_temp = []; lonb_temp = []; latb_temp = []; iwall_temp = []; idl_temp = []; idr_temp = []; bound_ind_temp = [] vt_ew_temp = []; vt_ns_temp = []; polarity_temp = []; large_wall_inds_temp = []; num_segs = 0; num_wall_segs = 0 print "------------------------" print "%.0f original boundaries" % num_bounds for i in range(num_bounds): # great circle distance [km] length = haversine(lona[i],lata[i],lonb[i],latb[i],rad_km) print "orig. length of segment %.0f = %.8f km" % (i+1,length) if iwall[i] == 1: iseg = int(.999 * length/dsegtr) + 1 elif (idl[i] != idr[i]) and iwall[i] == 0: iseg = int(.999 * length/dseged) + 1 else: iseg = 1 # strike-slip (iwall=2) # https://geographiclib.sourceforge.io/html/python/ geod = Geodesic(rad_km * 1e3, 0) # sphere gd = geod.Inverse(lata[i], lona[i], latb[i], lonb[i]) # total great-circle distance line = geod.Line(gd['lat1'], gd['lon1'], gd['azi1']) for iset in range(0,iseg): pointa = line.Position((gd['s12'] / iseg) * iset) pointb = line.Position((gd['s12'] / iseg) * (iset+1)) lona2 = pointa['lon2'] if lona2 < 0.: lona2 = 360. + lona2 lona_temp.append(lona2) lata_temp.append(pointa['lat2']) lonb2 = pointb['lon2'] if lonb2 < 0.: lonb2 = 360. + lonb2 lonb_temp.append(lonb2) latb_temp.append(pointb['lat2']) iwall_temp.append(iwall[i]); idl_temp.append(idl[i]); idr_temp.append(idr[i]); bound_ind_temp.append(bound_ind[i]) large_wall_inds_temp.append(large_wall_inds[i]) vt_ew_temp.append(vt_ew[i]) vt_ns_temp.append(vt_ns[i]) polarity_temp.append(polarity[i]) num_segs += iseg; if iwall[i] == 1: num_wall_segs += iseg; # # Double up wall boundaries n_segs = num_segs + num_wall_segs lona = np.zeros((n_segs)); lata = np.zeros((n_segs)) lonb = np.zeros((n_segs)); latb = np.zeros((n_segs)) vt_ew = np.zeros((n_segs)); vt_ns = np.zeros((n_segs)); polarity = np.zeros((n_segs)); iwall = [0] * n_segs; bound_ind = [0] * n_segs idl = [0] * n_segs; idr = [0] * n_segs; large_wall_inds = [0] * n_segs nwall = 0; for i in range(num_segs): lona[i] = lona_temp[i] lata[i] = lata_temp[i] lonb[i] = lonb_temp[i] latb[i] = latb_temp[i] iwall[i] = iwall_temp[i] idl[i] = idl_temp[i] idr[i] = idr_temp[i] bound_ind[i] = bound_ind_temp[i] large_wall_inds[i] = large_wall_inds_temp[i] vt_ew[i] = vt_ew_temp[i] vt_ns[i] = vt_ns_temp[i] polarity[i] = polarity_temp[i] if iwall_temp[i] == 1: lona[num_segs+nwall] = lona_temp[i] lata[num_segs+nwall] = lata_temp[i] lonb[num_segs+nwall] = lonb_temp[i] latb[num_segs+nwall] = latb_temp[i] iwall[num_segs+nwall] = iwall_temp[i] idl[num_segs+nwall] = idl_temp[i] idr[num_segs+nwall] = idr_temp[i] bound_ind[num_segs+nwall] = bound_ind_temp[i] large_wall_inds[num_segs+nwall] = large_wall_inds_temp[i] vt_ew[num_segs+nwall] = vt_ew_temp[i] vt_ns[num_segs+nwall] = vt_ns_temp[i] polarity[num_segs+nwall] = polarity_temp[i] nwall += 1; return (n_segs,num_segs,iwall,idl,idr,lona,lata,lonb,latb,bound_ind,large_wall_inds,vt_ew,vt_ns,polarity,num_wall_segs)
longitu = lo return longitu #Calcular a distância entre a latitude/longitude máxima e mínima (geodésica)----------------------------------------- def max_min(list_lat, list_long): loc_lat_mx = np.where(list_lat == max(list_lat)) lat_mx = max(list_lat) lon_mx = list_long[loc_lat_mx] loc_lat_min = np.where(list_lat == min(list_lat)) lat_min = min(list_lat) lon_min = list_long[loc_lat_min] return lat_mx, lon_mx[0], lat_min, lon_min[0] lat1, lon1, lat2, lon2 = max_min(ss[1], ss[2]) di_mx = (geod.Inverse(lat1, lon1, lat2, lon2)['s12']) / 1000 ab = [] for i in range(0, len(ss[1]), 1): abso = ((ss[1][i])**2 + (ss[2][i])**2)**(1 / 2) ab.append(abso) bi = round(di_mx / 7) # bins é o intervalo de latitudes e a "density" é a frequencia desse intervalo------------------------------------------ hist = plt.hist(ss[1], bins=bi, normed=True) density, bins, patches = hist maiores = heapq.nlargest(bi, density) def remove_colchetes(list1): return str(list1).replace('[', '').replace(']', '')
def add_geo_to_arrivals(arrivals, source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, radius_of_planet_in_km, flattening_of_planet): """ Add geographical information to arrivals. :param arrivals: Set of taup arrivals :type: :class:`Arrivals` :param source_latitude_in_deg: Source location latitude in degrees :type source_latitude_in_deg: float :param source_longitude_in_deg: Source location longitude in degrees :type source_longitude_in_deg: float :param receiver_latitude_in_deg: Receiver location latitude in degrees :type receiver_latitude_in_deg: float :param receiver_longitude_in_deg: Receiver location longitude in degrees :type receiver_longitude_in_deg: float :param radius_of_planet_in_km: Radius of the planet in km :type radius_of_planet_in_km: float :param flattening_of_planet: Flattening of planet (0 for a sphere) :type receiver_longitude_in_deg: float :return: List of ``Arrival`` objects, each of which has the time, corresponding phase name, ray parameter, takeoff angle, etc. as attributes. :rtype: :class:`Arrivals` """ if geodetics.HAS_GEOGRAPHICLIB: if not geodetics.GEOGRAPHICLIB_VERSION_AT_LEAST_1_34: # geographiclib is not installed ... # and obspy/geodetics does not help much msg = ("This functionality needs the Python module " "'geographiclib' in version 1.34 or higher.") raise ImportError(msg) ellipsoid = Geodesic(a=radius_of_planet_in_km * 1000.0, f=flattening_of_planet) g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg) azimuth = g['azi1'] line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg, azimuth) # We may need to update many arrival objects # and each could have pierce points and a # path for arrival in arrivals: # check if we go in minor or major arc direction distance = arrival.purist_distance % 360. if distance > 180.: sign = -1 az_arr = (azimuth + 180.) % 360. else: sign = 1 az_arr = azimuth arrival.azimuth = az_arr if arrival.pierce is not None: geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo) for i, pierce_point in enumerate(arrival.pierce): dir_degrees = np.degrees(sign * pierce_point['dist']) pos = line.ArcPosition(dir_degrees) geo_pierce[i] = (pierce_point['p'], pierce_point['time'], pierce_point['dist'], pierce_point['depth'], pos['lat2'], pos['lon2']) arrival.pierce = geo_pierce if arrival.path is not None: geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo) for i, path_point in enumerate(arrival.path): dir_degrees = np.degrees(sign * path_point['dist']) pos = line.ArcPosition(dir_degrees) geo_path[i] = (path_point['p'], path_point['time'], path_point['dist'], path_point['depth'], pos['lat2'], pos['lon2']) arrival.path = geo_path else: # geographiclib is not installed ... # and obspy/geodetics does not help much msg = "You need to install the Python module 'geographiclib' in " + \ "order to add geographical information to arrivals." raise ImportError(msg) return arrivals
def add_geo_to_arrivals(arrivals, source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg, radius_of_planet_in_km, flattening_of_planet, resample=False, sampleds=5.0): """ Add geographical information to arrivals. :param arrivals: Set of taup arrivals :type: :class:`Arrivals` :param source_latitude_in_deg: Source location latitude in degrees :type source_latitude_in_deg: float :param source_longitude_in_deg: Source location longitude in degrees :type source_longitude_in_deg: float :param receiver_latitude_in_deg: Receiver location latitude in degrees :type receiver_latitude_in_deg: float :param receiver_longitude_in_deg: Receiver location longitude in degrees :type receiver_longitude_in_deg: float :param radius_of_planet_in_km: Radius of the planet in km :type radius_of_planet_in_km: float :param flattening_of_planet: Flattening of planet (0 for a sphere) :type receiver_longitude_in_deg: float :param resample: adds sample points to allow for easy cartesian interpolation. This is especially useful for phases like Pdiff. :type resample: boolean :return: List of ``Arrival`` objects, each of which has the time, corresponding phase name, ray parameter, takeoff angle, etc. as attributes. :rtype: :class:`Arrivals` """ if geodetics.HAS_GEOGRAPHICLIB: if not geodetics.GEOGRAPHICLIB_VERSION_AT_LEAST_1_34: # geographiclib is not installed ... # and obspy/geodetics does not help much msg = ("This functionality needs the Python module " "'geographiclib' in version 1.34 or higher.") raise ImportError(msg) ellipsoid = Geodesic(a=radius_of_planet_in_km * 1000.0, f=flattening_of_planet) g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg, receiver_latitude_in_deg, receiver_longitude_in_deg) azimuth = g['azi1'] line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg, azimuth) # We may need to update many arrival objects # and each could have pierce points and a # path for arrival in arrivals: # check if we go in minor or major arc direction distance = arrival.purist_distance % 360. if distance > 180.: sign = -1 az_arr = (azimuth + 180.) % 360. else: sign = 1 az_arr = azimuth arrival.azimuth = az_arr if arrival.pierce is not None: geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo) for i, pierce_point in enumerate(arrival.pierce): signed_dist = np.degrees(sign * pierce_point['dist']) pos = line.ArcPosition(signed_dist) geo_pierce[i] = (pierce_point['p'], pierce_point['time'], pierce_point['dist'], pierce_point['depth'], pos['lat2'], pos['lon2']) arrival.pierce = geo_pierce # choose whether we need to resample the trace if arrival.path is not None: if resample: rplanet = radius_of_planet_in_km # compute approximate distance between sampling points # mindist = 200 # km mindist = sampleds radii = rplanet - arrival.path['depth'] rmean = np.sqrt(radii[1:] * radii[:-1]) diff_dists = rmean * np.diff(arrival.path['dist']) npts_extra = np.floor(diff_dists / mindist).astype(np.int) # count number of extra points and initialize array npts_old = len(arrival.path) npts_new = int(npts_old + np.sum(npts_extra)) geo_path = np.empty(npts_new, dtype=TimeDistGeo) # now loop through path, adding extra points i_new = 0 for i_old, path_point in enumerate(arrival.path): # first add the original point at the new index dist = np.degrees(sign * path_point['dist']) pos = line.ArcPosition(dist) geo_path[i_new] = (path_point['p'], path_point['time'], path_point['dist'], path_point['depth'], pos['lat2'], pos['lon2']) i_new += 1 if i_old > npts_old - 2: continue # now check if we need to add new points npts_new = npts_extra[i_old] if npts_new > 0: # if yes, distribute them linearly between the old # and the next point next_point = arrival.path[i_old + 1] dist_next = np.degrees(sign * next_point['dist']) dists_new = np.linspace(dist, dist_next, npts_new + 2)[1:-1] # now get all interpolated parameters xs = [dist, dist_next] ys = [path_point['p'], next_point['p']] p_interp = np.interp(dists_new, xs, ys) ys = [path_point['time'], next_point['time']] time_interp = np.interp(dists_new, xs, ys) ys = [path_point['depth'], next_point['depth']] depth_interp = np.interp(dists_new, xs, ys) pos_interp = [ line.ArcPosition(dist_new) for dist_new in dists_new ] lat_interp = [ point['lat2'] for point in pos_interp ] lon_interp = [ point['lon2'] for point in pos_interp ] # add them to geo_path # dists_new --> np.radians(dists_new), modified by Hongjian Fang for i_extra in range(npts_new): geo_path[i_new] = (p_interp[i_extra], time_interp[i_extra], np.radians( dists_new[i_extra]), depth_interp[i_extra], lat_interp[i_extra], lon_interp[i_extra]) i_new += 1 arrival.path = geo_path else: geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo) for i, path_point in enumerate(arrival.path): signed_dist = np.degrees(sign * path_point['dist']) pos = line.ArcPosition(signed_dist) geo_path[i] = (path_point['p'], path_point['time'], path_point['dist'], path_point['depth'], pos['lat2'], pos['lon2']) arrival.path = geo_path else: # geographiclib is not installed ... # and obspy/geodetics does not help much msg = "You need to install the Python module 'geographiclib' in " + \ "order to add geographical information to arrivals." raise ImportError(msg) return arrivals