class GeodSharedMemoryBugTestIssue64(unittest.TestCase): def setUp(self): self.g = Geod(ellps='clrk66') self.ga = self.g.a self.mercury = Geod(a=2439700) # Mercury 2000 ellipsoid # Mercury is much smaller than earth. def test_not_shared_memory(self): self.assertEqual(self.ga, self.g.a) # mecury must have a different major axis from earth self.assertNotEqual(self.g.a, self.mercury.a) self.assertNotEqual(self.g.b, self.mercury.b) self.assertNotEqual(self.g.sphere, self.mercury.sphere) self.assertNotEqual(self.g.f, self.mercury.f) self.assertNotEqual(self.g.es, self.mercury.es) # initstrings were not shared in issue #64 self.assertNotEqual(self.g.initstring, self.mercury.initstring) def test_distances(self): # note calculated distance was not an issue with #64, but it still a shared memory test boston_lat = 42.+(15./60.); boston_lon = -71.-(7./60.) portland_lat = 45.+(31./60.); portland_lon = -123.-(41./60.) az12,az21,dist_g = self.g.inv(boston_lon,boston_lat,portland_lon,portland_lat) az12,az21,dist_mercury = self.mercury.inv(boston_lon,boston_lat,portland_lon,portland_lat) self.assertLess(dist_mercury, dist_g)
def getAzimuth(self, point): """ Get azimuth (in degrees) between current point and provided point (point). """ g = Geod(ellps="sphere") forward_azimuth, back_azimuth, distance = g.inv(self.longitude, self.latitude, point.longitude, point.latitude) return forward_azimuth
def compute_lagdistances(sta,stnum,lon,lat): ''' Compute the lag distances between all stations in the given set Input: sta: Array with strings of station names (n x 1) stnum: Array with unique station numbers (n x 1) lon: Array with station longitudes (n x 1) lat: Array with station latitudes (n x 1) Output: lagdistance: Upper triangular matrix with lag distances for all station pairs (n x n) ''' from pyproj import Geod import numpy as np # Make projection: p = Geod(ellps='WGS84') # Make lag matrix: lagdistance_full = np.zeros((len(stnum),len(stnum))) ## Start to fill in lag matrix # Loop over all stations, make a matrix with the lon and lat of just that station, and compute the distance to all other stations (lon,lat): for stationi in range(len(stnum)): azimuthi,backazimuthi,distancei = p.inv(lon[stationi]*np.ones(len(stnum)),lat[stationi]*np.ones(len(stnum)), lon, lat) # Fill the matrix with these distances for this station: lagdistance_full[stationi,:] = distancei/1000 # Turn it into an upper triangular matrix: lagdistance = np.triu(lagdistance_full) # Return lag distance: return lagdistance
def c1ompare_points_old(a, b, dx, proj='LongLat'): if isinstance(dx, float): dx = [dx, dx] tolerance = [0.6 * x for x in dx] if (proj == 'horizontal'): pa = project(a, projection_type='proj_cartesian') pb = project(b, projection_type='proj_cartesian') #print tolerance, pa, pb if ( not (abs(pa[1] - pb[1]) < tolerance[1]) ): return False elif (abs(pa[0] - pb[0]) < tolerance[0]): return True else: return False else: from pyproj import Geod wgs84_geod = Geod(ellps='WGS84') az12,az21,dist = wgs84_geod.inv(a[0],a[1],a[0],a[1]) return dist < tolerance[0] * 1e5 if ( not (abs(a[1] - b[1]) < tolerance[1]) ): #AddComment('lat differ') return False elif (abs(a[0] - b[0]) < tolerance[0]): #AddComment('long same') return True elif ((abs(abs(a[0]) - 180) < tolerance[0]) and (abs(abs(b[0]) - 180) < tolerance[0])): #AddComment('long +/-180') return True else: #AddComment('not same %g %g' % (abs(abs(a[0]) - 180), abs(abs(b[0]) - 180) ) ) return False
def find_closest_soundings(l1b_file, tgt_latitude, tgt_longitude, max_distance, log_output=sys.stdout): l1b_obj = acos_file.L1B(l1b_file) sounding_ids = l1b_obj.get_sounding_ids() # Average over band first since this is likely to be consistent for # different types of L1B files latitudes = l1b_obj.get_sounding_info('sounding_latitude') longitudes = l1b_obj.get_sounding_info('sounding_longitude') # Average over any non sounding id sized dimensions while len(latitudes.shape) > 1: extra_dims = numpy.where(numpy.array(latitudes.shape) != sounding_ids.shape[0]) latitudes = numpy.average(latitudes, extra_dims[0][0]) longitudes = numpy.average(longitudes, extra_dims[0][0]) g = Geod(ellps='WGS84') # Find all distances in file distances = numpy.zeros(len(sounding_ids), dtype=float) for dist_idx, lat_lon_tuple in enumerate(zip(latitudes, longitudes)): curr_lat, curr_lon = lat_lon_tuple az12, az21, dist = g.inv(tgt_longitude,tgt_latitude,curr_lon,curr_lat) # Convert to km distances[dist_idx] = dist/1000. closest = numpy.where(distances <= max_distance) if len(closest[0]) > 0: print >>log_output, "%s" % l1b_file for close_idx in closest[0]: print >>log_output, '%d %f' % (sounding_ids[close_idx], distances[close_idx]) print >>log_output, "" else: print >>sys.stderr, "No soundings found in %s closer than %f km" % (l1b_file, max_distance)
def grcrcl1(lon_1, lat_1, lon_2, lat_2): g = Geod(ellps='WGS84') az, az_inv, dist = g.inv(lon_1, lat_1, lon_2, lat_2) return dist
def gdlComp(self, lons_lats, km_pts=20): """ Compute geodesic line lons_lats: input coordinates. (start longitude, start latitude, end longitude, end latitude) km_pts: compute one point each 20 km (default). """ try: lon_1, lat_1, lon_2, lat_2 = lons_lats pygd = Geod(ellps='WGS84') res = pygd.inv(lon_1, lat_1, lon_2, lat_2) dist = res[2] pts = int(math.ceil(dist) / (km_pts * 1000)) coords = pygd.npts(lon_1, lat_1, lon_2, lat_2, pts) coords_se = [(lon_1, lat_1)] + coords coords_se.append((lon_2, lat_2)) self.__logger.info("Geodesic line succesfully created!") self.__logger.info("Total points = {:,}".format(pts)) self.__logger.info("{:,.4f} km".format(dist / 1000.)) return coords_se except Exception as e: self.__logger.error("Error: {0}".format(e.message))
def __init__(self, srs, bbox, width=None, height=None, format=None, resource_id=None): super(WmsQuery, self).__init__() self.query_type = 'WMS' self.srs = srs self.bbox = bbox self.width = width self.height = height self.format = format self.resource_id = resource_id if width is not None and height is not None: # calculate resolution... this should slow things down, yay... :-( p = Proj(init=srs.lower()) if not p.is_latlong(): min_lon, min_lat = p(bbox.min_x,bbox.min_y, inverse=True) max_lon, max_lat = p(bbox.max_x,bbox.max_y, inverse=True) else: min_lon, min_lat = bbox.min_x, bbox.min_y max_lon, max_lat = bbox.max_x, bbox.max_y g = Geod(ellps='clrk66') # Use Clarke 1966 ellipsoid. _,_,diagonal = g.inv(min_lon, min_lat, max_lon, max_lat) # distance calculated geodesic dist_x = sqrt(diagonal**2 / (1 + float(height)/float(width)) ) dist_y = dist_x * (float(height)/float(width)) self.x_res = dist_x / float(width) self.y_res = dist_y / float(height) else: self.x_res = None self.y_res = None
def distance_matrix(pts, lon='lon', lat='lat', ellps='WGS84'): """ Calculate distance between all points Parameters ---------- pts: pandas.DataFrame Table of points with at least the collumns given by ``lon`` and ``lat`` lon, lat: str, optional Column names for the longitude and latitude fields. Defaults are 'lon' and 'lat'. ellps: str, optional Name of the ellipsoid. See :class:`pyproj.Geod` for valid names. Returns ------- distances: numpy.ndarray len(pts) x len(pts) array of distances between all points in ``pts``. """ gd = Geod(ellps=ellps) npts = len(pts) G = np.zeros((npts, npts)) for i in range(npts): for j in range(npts): _, _, G[i][j] = gd.inv(pts.ix[i][lon], pts.ix[i][lat], pts.ix[j][lon], pts.ix[j][lat]) return G
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 build_great_circle(self, start_latlng, end_latlng, distance): num_points = int(distance / self.ARC_LENGTH_SPACING) geod = Geod(ellps='WGS84') start_lat, start_lon = start_latlng end_lat, end_lon = end_latlng lonlats = geod.npts(start_lon, start_lat, end_lon, end_lat, num_points) latlngs = util.swap_pairs(lonlats) return latlngs
def addLengthMeters(self, stream_network): """ Adds length field in meters to network (The added field name will be 'LENGTH_M'). .. note:: This may be needed for generating the kfac file depending on the units of your raster. See: :doc:`gis_tools`. Parameters: stream_network(str): Path to stream network file. Here is an example of how to use this: .. code:: python import os from RAPIDpy.gis.taudem import TauDEM td = TauDEM() output_directory = '/path/to/output/files' td.addLengthMeters(os.path.join(output_directory,"stream_reach_file.shp")) """ network_shapefile = ogr.Open(stream_network, 1) network_layer = network_shapefile.GetLayer() network_layer_defn = network_layer.GetLayerDefn() #make sure projection EPSG:4326 network_layer_proj = network_layer.GetSpatialRef() geographic_proj = osr.SpatialReference() geographic_proj.ImportFromEPSG(4326) proj_transform = None if network_layer_proj != geographic_proj: proj_transform = osr.CoordinateTransformation(network_layer_proj, geographic_proj) #check for field create_field=True for i in xrange(network_layer_defn.GetFieldCount()): field_name = network_layer_defn.GetFieldDefn(i).GetName() if field_name == 'LENGTH_M': create_field=False break if create_field: network_layer.CreateField(ogr.FieldDefn('LENGTH_M', ogr.OFTReal)) geo_manager = Geod(ellps="WGS84") for network_feature in network_layer: feat_geom = network_feature.GetGeometryRef() #make sure coordinates are geographic if proj_transform: feat_geom.Transform(proj_transform) line = shapely_loads(feat_geom.ExportToWkb()) lon_list, lat_list = line.xy az1, az2, dist = geo_manager.inv(lon_list[:-1], lat_list[:-1], lon_list[1:], lat_list[1:]) network_feature.SetField('LENGTH_M', sum(dist)) network_layer.SetFeature(network_feature)
def getHorizontalDistance(self, point): """ Get horizontal distance (great circle distance, in km) between current point and provided point (point). """ g = Geod(ellps="sphere") forward_azimuth, back_azimuth, horizontal_distance = g.inv( self.longitude, self.latitude, point.longitude, point.latitude ) return horizontal_distance * 1e-3 # 1e-3 is needed to convert from m to km
def _distance(self, start, to): ''' Return distance. ''' q = Geod(ellps='WGS84') fa, ba, d =\ q.inv(start['lon'], start['lat'], to['lon'], to['lat']) return d
def lat_lon_grid_deltas(longitude, latitude, **kwargs): r"""Calculate the delta between grid points that are in a latitude/longitude format. Calculate the signed delta distance between grid points when the grid spacing is defined by delta lat/lon rather than delta x/y Parameters ---------- longitude : array_like array of longitudes defining the grid latitude : array_like array of latitudes defining the grid kwargs Other keyword arguments to pass to :class:`~pyproj.Geod` Returns ------- dx, dy: at least two dimensional arrays of signed deltas between grid points in the x and y direction Notes ----- Accepts 1D, 2D, or higher arrays for latitude and longitude Assumes [..., Y, X] for >=2 dimensional arrays """ from pyproj import Geod # Inputs must be the same number of dimensions if latitude.ndim != longitude.ndim: raise ValueError('Latitude and longitude must have the same number of dimensions.') # If we were given 1D arrays, make a mesh grid if latitude.ndim < 2: longitude, latitude = np.meshgrid(longitude, latitude) geod_args = {'ellps': 'sphere'} if kwargs: geod_args = kwargs g = Geod(**geod_args) forward_az, _, dy = g.inv(longitude[..., :-1, :], latitude[..., :-1, :], longitude[..., 1:, :], latitude[..., 1:, :]) dy[(forward_az < -90.) | (forward_az > 90.)] *= -1 forward_az, _, dx = g.inv(longitude[..., :, :-1], latitude[..., :, :-1], longitude[..., :, 1:], latitude[..., :, 1:]) dx[(forward_az < 0.) | (forward_az > 180.)] *= -1 return dx * units.meter, dy * units.meter
def cell_height(self): cell_height = np.full(self.shape, np.nan) geod = Geod(ellps='WGS84') for i in range(self.shape[0]): _az12, _az21, cell_length = geod.inv( self.longitude[i, 0], self.latitude[i, 0] + .25, self.longitude[i, 0], self.latitude[i, 0] - .25, ) cell_height[i, :] = cell_length return cell_height
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 build_bins(pts, spacing=6.25, width=50, runin=0, isequence0=1000, ellps='WGS84'): """ Build bins along a line of points. """ gd = Geod(ellps=ellps) div_pts = divide_line(pts, spacing=spacing, runin=runin, ellps=ellps) bins = [] ndiv = len(div_pts) ibin = isequence0 align_to_last_bin = False for i in range(0, ndiv - 1): lon0, lat0, x0, i0 = div_pts[i] lon1, lat1, x1, i1 = div_pts[i + 1] faz, baz, dist = gd.inv(lon0, lat0, lon1, lat1) # bin corners _bin = _build_bin(lon0, lat0, lon1, lat1, width, gd) # bin center _center = _calculate_center(_bin) # put it all together bins.append([ibin, None, _center, _bin]) # handle bends in the line if align_to_last_bin: # align bins bins[-1][3][0] = bins[-2][3][1] bins[-1][3][3] = bins[-2][3][2] # recalculate center and offset bins[-1][2] = _calculate_center(bins[-1][3]) align_to_last_bin = False if i0 == i1: ibin -= 1 i += 1 _bin = bins[-1] del bins[-1] align_to_last_bin = True # distance on line and line azimuth if i == 0: bins[-1][1] = div_pts[0][2] bins[-1] += [None] else: az, _, dx = gd.inv(bins[-1][2][0], bins[-1][2][1], bins[-2][2][0], bins[-2][2][1]) bins[-1][1] = bins[-2][1] + dx bins[-1] += [az] # increment bin number ibin += 1 # assume first azimuth is the same as 2nd azimuth bins[0][4] = [bins[1][4]] return bins
def size (self): from pyproj import Geod g = Geod(ellps='WGS84') lon_min = self.lonw lon_max = self.lone lat_min = self.lats lat_max = self.latn lon = (lon_min+lon_max)/2 lat = (lat_min+lat_max)/2 sn = g.inv (lon, lat_min, lon, lat_max, radians=False)[2] we = g.inv (lon_min, lat, lon_max, lat, radians=False)[2] return (sn, we)
def midpoint_utm(self,p1,p2): """ calculates midpoint between 2 points on earths surface input: p1,p2 location in the form (lon,lat) return: m midpoint in the form (lon,lat) """ g = Geod(ellps='WGS84') l = g.npts(p1[0],p1[0],p1[1],p1[1],1) m = l[0] # print 'm: ', m return m
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 zero_padding(self, outfname, component, evlo, evla, dt, minV=1.5, iter0=None, iterf=None, diter=None, verbose=True): # - Some initialisations. ------------------------------------------------------------------ g = Geod(ellps='WGS84') dset = h5py.File(outfname) dset.attrs.create(name = 'theta_max', data=self.attrs["theta_max"], dtype='f') dset.attrs.create(name = 'theta_min', data=self.attrs["theta_min"], dtype='f') dset.attrs.create(name = 'phi_min', data=self.attrs["phi_min"], dtype='f') dset.attrs.create(name = 'phi_max', data=self.attrs["phi_max"], dtype='f') lat_min = 90.0 - self.attrs["theta_max"]*180.0/np.pi lat_max = 90.0 - self.attrs["theta_min"]*180.0/np.pi lon_min = self.attrs["phi_min"]*180.0/np.pi lon_max = self.attrs["phi_max"]*180.0/np.pi dset.attrs.create(name = 'lat_min', data=lat_min, dtype='f') dset.attrs.create(name = 'lat_max', data=lat_max, dtype='f') dset.attrs.create(name = 'lon_min', data=lon_min, dtype='f') dset.attrs.create(name = 'lon_max', data=lon_max, dtype='f') dset.attrs.create(name = 'depth', data=self.attrs['depth'], dtype='f') dset.attrs.create(name = 'n_procs', data=self.attrs['n_procs'], dtype='f') dset.attrs.create(name = 'rotation_axis', data=self.attrs['rotation_axis'], dtype='f') dset.attrs.create(name = 'rotation_angle', data=self.attrs['rotation_angle'], dtype='f') group = dset.create_group( name = component ) in_group= self[component] # - Loop over processor boxes and check if depth falls within the volume. ------------------ try: iterArr=np.arange(iter0 ,iterf+diter, diter, dtype=int) except: iterArr = in_group.keys() for iteration in iterArr: try: in_subgroup = in_group[str(iteration)] except KeyError: continue subgroup=group.create_group(name=str(iteration)) if verbose: print 'Zero padding snapshot for iteration =',iteration time = float(iteration) * dt; mindist = time * minV for iproc in in_subgroup.keys(): in_subdset = in_subgroup[iproc] field = in_subdset.value theta = in_subdset.attrs['theta'] phi = in_subdset.attrs['phi'] lat = 90.-theta/np.pi*180.; lon = phi/np.pi*180. lats, lons = np.meshgrid(lat, lon, indexing = 'ij') evlaArr = evla * np.ones(lats.shape); evloArr = evlo * np.ones(lats.shape) az, baz, distevent = g.inv(lons, lats, evloArr, evlaArr) distevent=distevent/1000. index_padding = distevent < mindist field[index_padding] = 0 subdset = subgroup.create_dataset(name=iproc, shape=field.shape, data=field) subdset.attrs.create(name = 'theta', data=theta, dtype='f') subdset.attrs.create(name = 'phi', data=phi, dtype='f') dset.close() return
def calculate_distances(d): g = Geod(ellps='WGS84') far_left_lat = d['elevation_latlon_list'][0][0] far_left_lon = d['elevation_latlon_list'][1][0] for i, v in d['twod_vertices'].iteritems(): pt_lat = v[0] pt_lon = v[1] az1, az2, dist = g.inv(far_left_lon, far_left_lat, pt_lon, pt_lat) km_dist = dist / 1000.0 d['twod_vertices'][i] = [v[0], v[1], v[2], km_dist] d['gps_dist'] = [] for pt_lat, pt_lon in zip(d['gps_lat'], d['gps_lon']): az1, az2, dist = g.inv(far_left_lon, far_left_lat, pt_lon, pt_lat) km_dist = dist / 1000.0 d['gps_dist'].append(km_dist)
def __init__(self, width=800, height=None, bgcol=DEFAULT_BG, proj='eqc', cols=DEFAULT_COLS, line_width=1, gc_resolution=100): ''' Create an object for turning coordinate pairs into an image. Parameters height the height of the resultant image width the width of the resultant image bgcol the background color of the image, as an (r,g,b) triple proj the projection name as a string (passed to pyproj) cols a function which takes one fractional argument and returns a color (r,g,b) triple line_width the width of lines drawn gc_resolution the number of straight line segments used to approximate each great-circle curve Once the object is initialized, call set_data to add data. ''' if height is None: height = width / 2 self.height = height self.width = width self.bgcol = bgcol self.proj = proj self.line_width = line_width self.gc_resolution = gc_resolution self.cols = cols self.geo = Geod(a=1)
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 okada_synthetics(strike,dip,rake,length,width,lon_source,lat_source, depth_source,lon_obs,lat_obs,mu): ''' Calculate neu synthetics for a subfault using Okada analytical solutions ''' from okada_wrapper import dc3dwrapper from numpy import array,cos,sin,deg2rad,zeros from pyproj import Geod theta=strike-90 theta=deg2rad(theta) #Rotaion matrices since okada_wrapper is only for east striking fault R=array([[cos(theta),-sin(theta)],[sin(theta),cos(theta)]]) R2=array([[cos(-theta),-sin(-theta)],[sin(-theta),cos(-theta)]]) #position of point from lon/lat to x/y assuming subfault center is origin P=Geod(ellps='WGS84') az,baz,dist=P.inv(lon_source,lat_source,lon_obs,lat_obs) dist=dist/1000. x_obs=dist*sin(deg2rad(az)) y_obs=dist*cos(deg2rad(az)) #Calculate on rotated position xy=R.dot(array([x_obs, y_obs])) #Get Okada displacements lamb=mu alpha = (lamb + mu) / (lamb + 2 * mu) ss_in_m=1.0*cos(deg2rad(rake)) ds_in_m=1.0*sin(deg2rad(rake)) success, u, grad_u = dc3dwrapper(alpha, [xy[0], xy[1], 0.0],depth_source,dip, [-length/2., length/2.], [-width/2., width/2], [ss_in_m, ds_in_m, 0.0]) #Rotate output urot=R2.dot(array([[u[0]], [u[1]]])) u[0]=urot[0] u[1]=urot[1] #output n=u[1] e=u[0] z=u[2] return n,e,z
def get_stats(self, start_date=None, end_date=None): link_time = 0 move_time = 0 stay_time = 0 distance = 0 qs = self.positions.all() if start_date: qs = qs.filter(date__gte=start_date) if end_date: qs = qs.filter(date__lte=end_date) prev_p = None from pyproj import Geod g = Geod(ellps='clrk66') for p in qs: if not prev_p: prev_p = p continue time_delta = (p.date - prev_p.date).seconds if time_delta == 0: prev_p = p continue if time_delta < settings.MIN_LINK_TIMEOUT: link_time += time_delta try: angle, angle2, dist = g.inv(prev_p.point.x, prev_p.point.y, p.point.x, p.point.y) except ValueError: # except for 'may be' antipodal points continue if p.speed == None: avg_speed = float(dist) / float(time_delta) avg_speed = avg_speed * 10 / 36. if avg_speed < settings.STAY_AVG_SPEED: stay_time += time_delta elif p.speed < settings.STAY_AVG_SPEED: stay_time += time_delta distance += dist prev_p = p move_time = link_time - stay_time return { 'link_time': link_time, 'move_time': move_time, 'stay_time': stay_time, 'distance': distance, }
def lat_lon_grid_deltas(longitude, latitude, **kwargs): r"""Calculate the delta between grid points that are in a latitude/longitude format. Calculate the signed delta distance between grid points when the grid spacing is defined by delta lat/lon rather than delta x/y Parameters ---------- longitude : array_like array of longitudes defining the grid latitude : array_like array of latitudes defining the grid kwargs Other keyword arguments to pass to :class:`~pyproj.Geod` Returns ------- dx, dy: 2D arrays of signed deltas between grid points in the x and y direction Notes ----- Accepts, 1D or 2D arrays for latitude and longitude Assumes [Y, X] for 2D arrays """ # Inputs must be the same number of dimensions if latitude.ndim != longitude.ndim: raise ValueError( 'Latitude and longitude must have the same number of dimensions.') # If we were given 1D arrays, make a mesh grid if latitude.ndim < 2: longitude, latitude = np.meshgrid(longitude, latitude) geod_args = {'ellps': 'sphere'} geod_args.update(**kwargs) g = Geod(**geod_args) forward_az, _, dy = g.inv(longitude[:-1, :], latitude[:-1, :], longitude[1:, :], latitude[1:, :]) dy[(forward_az < -90.) | (forward_az > 90.)] *= -1 forward_az, _, dx = g.inv(longitude[:, :-1], latitude[:, :-1], longitude[:, 1:], latitude[:, 1:]) dx[(forward_az < 0.) | (forward_az > 180.)] *= -1 return dx * units.meter, dy * units.meter
def __init__(self, peg_lat, peg_lon, peg_heading, distance, peg_h=0., mode='center', ellps='WGS84', radians=False): """Initialize with a peg-point and a heading and a distance. mode: 'center', 'start', or 'end'. The peg-point location in the path. ellps: ellipsoid. """ self.peg_lat = peg_lat self.peg_lon = peg_lon self.peg_heading = peg_heading self.distance = distance self.peg_h = peg_h self.mode = mode self.geod = Geod(ellps=ellps) if mode == 'start': lat0 = peg_lat lon0 = peg_lon lon1, lat1, hdg = self.geod.fwd(lon0, lat0, peg_heading, distance) elif mode == 'end': lat1 = peg_lat lon1 = peg_lon hdg = (peg_heading + 180.) % 360. lon0, lat0, hdg = self.geod.fwd(lon1, lat1, hdg, distance) else: hdg = (peg_heading + 180.) % 360. lon0, lat0, hdg = self.geod.fwd(peg_lon, peg_lat, hdg, distance / 2.) lon1, lat1, hdg = self.geod.fwd(peg_lon, peg_lat, peg_heading, distance / 2.) GeodeticPath.__init__(self, lon0, lat0, lon1, lat1, ellps=ellps, radians=False)
def test_geod_cities(): # specify the lat/lons of some cities. boston_lat = 42.0 + (15.0 / 60.0) boston_lon = -71.0 - (7.0 / 60.0) portland_lat = 45.0 + (31.0 / 60.0) portland_lon = -123.0 - (41.0 / 60.0) g1 = Geod(ellps="clrk66") g2 = Geod(ellps="WGS84") az12, az21, dist = g1.inv(boston_lon, boston_lat, portland_lon, portland_lat) print("distance between boston and portland, clrk66:") print("%7.3f %6.3f %12.3f" % (az12, az21, dist)) assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3) print("distance between boston and portland, WGS84:") az12, az21, dist = g2.inv(boston_lon, boston_lat, portland_lon, portland_lat) assert_almost_equal((az12, az21, dist), (-66.530, 75.654, 4164074.239), decimal=3) print("%7.3f %6.3f %12.3f" % (az12, az21, dist)) print("testing pickling of Geod instance") with temporary_directory() as tmpdir: with open(os.path.join(tmpdir, "geod1.pickle"), "wb") as gp1w: pickle.dump(g1, gp1w, -1) with open(os.path.join(tmpdir, "geod2.pickle"), "wb") as gp2w: pickle.dump(g2, gp2w, -1) with open(os.path.join(tmpdir, "geod1.pickle"), "rb") as gp1: g3 = pickle.load(gp1) with open(os.path.join(tmpdir, "geod2.pickle"), "rb") as gp2: g4 = pickle.load(gp2) az12, az21, dist = g3.inv(boston_lon, boston_lat, portland_lon, portland_lat) assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3) print("distance between boston and portland, clrk66 (from pickle):") print("%7.3f %6.3f %12.3f" % (az12, az21, dist)) az12, az21, dist = g4.inv(boston_lon, boston_lat, portland_lon, portland_lat) print("distance between boston and portland, WGS84 (from pickle):") print("%7.3f %6.3f %12.3f" % (az12, az21, dist)) assert_almost_equal((az12, az21, dist), (-66.530, 75.654, 4164074.239), decimal=3) g3 = Geod("+ellps=clrk66") # proj4 style init string print("inverse transform") 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) az12, az21, dist = g3.inv(lon1pt, lat1pt, lon2pt, lat2pt) print("%7.3f %6.3f %12.3f" % (az12, az21, dist)) assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3)
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
def kml_trackers(request): trackers = Tracker.objects.filter(Q(view_users=request.user) | Q(creator=request.user)) placemarks = "" g = Geod(ellps='clrk66') added_tracker_pks = [] for tr in trackers: if tr.pk in added_tracker_pks: continue added_tracker_pks.append(tr.pk) pos_qs = Position.objects.filter(tracker=tr).order_by('-date') count = pos_qs.count() if not count: continue pos_qs = pos_qs.order_by('-date') pos = pos_qs[0] p = pos.point p_prev = None angle = 0.0 stay = None if datetime.datetime.now() - pos.date > datetime.timedelta(seconds=settings.MIN_LINK_TIMEOUT): stay = True elif pos.speed != None: stay = pos.speed <= settings.STAY_AVG_SPEED if count > 1: pos_prev = pos_qs[1] p_prev = pos_prev.point angle, angle2, dist = g.inv(p_prev.x, p_prev.y, p.x, p.y) if stay == None: avg_speed = dist/float((pos.date-pos_prev.date).seconds) avg_speed = avg_speed*10/36. logger.debug("avg_speed: %s" % avg_speed) stay = avg_speed <= settings.STAY_AVG_SPEED if stay == None: stay = True if stay: image_url = settings.MEDIA_URL + 'images/icons/busstop.png' graphic = 'circle' angle = 0.0 else: image_url = settings.MEDIA_URL + 'images/icons/bus.png' graphic = 'bus' marker_color = tr.marker_color if tr.marker_color else '00ff00' placemarks += """<Placemark><name>%s</name><description>%s</description><angle>%1.4f</angle><image>%s</image><graphic>%s</graphic><marker_color>#%s</marker_color><Point><coordinates>%1.6f,%1.6f</coordinates></Point></Placemark>""" % (tr.name, tr.description, angle, image_url, graphic, marker_color, p.x, p.y) kml = """<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.2"><Document>%s</Document></kml>""" % placemarks return HttpResponse(kml)
def distances_from_cross_section(cross): """Calculate the distances in the x and y directions along a cross-section. Parameters ---------- cross : `xarray.DataArray` The input DataArray of a cross-section from which to obtain geometeric distances in the x and y directions. Returns ------- x, y : tuple of `xarray.DataArray` A tuple of the x and y distances as DataArrays """ if (CFConventionHandler.check_axis(cross.metpy.x, 'lon') and CFConventionHandler.check_axis(cross.metpy.y, 'lat')): # Use pyproj to obtain x and y distances from pyproj import Geod g = Geod(cross.metpy.cartopy_crs.proj4_init) lon = cross.metpy.x lat = cross.metpy.y forward_az, _, distance = g.inv(lon[0].values * np.ones_like(lon), lat[0].values * np.ones_like(lat), lon.values, lat.values) x = distance * np.sin(np.deg2rad(forward_az)) y = distance * np.cos(np.deg2rad(forward_az)) # Build into DataArrays x = xr.DataArray(x, coords=lon.coords, dims=lon.dims, attrs={'units': 'meters'}) y = xr.DataArray(y, coords=lat.coords, dims=lat.dims, attrs={'units': 'meters'}) elif (CFConventionHandler.check_axis(cross.metpy.x, 'x') and CFConventionHandler.check_axis(cross.metpy.y, 'y')): # Simply return what we have x = cross.metpy.x y = cross.metpy.y else: raise AttributeError('Sufficient horizontal coordinates not defined.') return x, y
def test_geometry_area_perimeter__polygon__holes(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_area_perimeter( Polygon( LineString( [Point(1, 1), Point(1, 10), Point(10, 10), Point(10, 1)]), holes=[LineString([Point(1, 2), Point(3, 4), Point(5, 2)])], )), (-944373881400.3394, 3979008.0359657984), decimal=2, )
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
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 __azdist(sacobj, ellps): """ Return forward/backazimuth and distance using pyproj (proj4 bindings) """ from pyproj import Geod g = Geod(ellps=ellps) stla, stlo = sacobj.stla, sacobj.stlo evla, evlo = sacobj.evla, sacobj.evlo az, baz, dist = g.inv(evlo, evla, stlo, stla) # convert units so that they show the same as SAC if az < 0: az += 360 if baz < 0: baz += 360 dist /= 1000 return az, baz, dist
def fitANN(act, hlayers, hunits, lr, epochs, x_train_scale, y_train, x_test_scale, y_test, foldername, workinghome): plt.style.use("classic") sns.set_context("poster") sns.set_style('whitegrid') g = Geod(ellps='clrk66') mpl.rcParams['font.size'] = 22
def process_nexrad(fn, f): sweep = 0 try: az = np.array([ray[0].az_angle for ray in f.sweeps[sweep]]) except: return np.array([]) # Format for NEXRAD files changed (byte string and index), try for both formats try: ref_hdr = f.sweeps[sweep][0][4][b'REF'][0] ref_range = np.arange( ref_hdr.num_gates) * ref_hdr.gate_width + ref_hdr.first_gate ref = np.array([ray[4][b'REF'][1] for ray in f.sweeps[sweep]]) except: ref_hdr = f.sweeps[sweep][0][1]['REF'][0] ref_range = np.arange( ref_hdr.num_gates) * ref_hdr.gate_width + ref_hdr.first_gate ref = np.array([ray[1]['REF'][1] for ray in f.sweeps[sweep]]) data_hdr = f.sweeps[sweep][0][1] data = ma.array(ref) data[data == 0] = ma.masked g = Geod(ellps='clrk66') try: center_lat = np.ones([len(az), len(ref_range)]) * data_hdr.lat center_lon = np.ones([len(az), len(ref_range)]) * data_hdr.lon except: # Pulled from values in PyArt if not available center_lat = np.ones([len(az), len(ref_range)]) * 41.60444 center_lon = np.ones([len(az), len(ref_range)]) * -88.08472 az2D = np.ones_like(center_lat) * az[:, None] rng2D = np.ones_like(center_lat) * np.transpose(ref_range[:, None]) * 1000 lon, lat, back = g.fwd(center_lon, center_lat, az2D, rng2D) # Create timestamp in epoch (without milliseconds) for datetime later ts = datetime.strptime( re.search(r'\d{8}_\d{6}', fn).group(), '%Y%m%d_%H%M%S') # Get epoch (without milliseconds), subtracting 5 hours to convert from GMT to CST time_epoch = time.mktime(ts.timetuple()) - (5 * 3600) ts_arr = np.ones([len(az), len(ref_range)]) * time_epoch # Reducing dimensionality into rows of timestamp, lat, lon, and data arr_rows = np.dstack((ts_arr, lon, lat, data)) arr_simp = arr_rows.reshape(-1, 4) # Remove any nan values to reduce size return arr_simp[~np.isnan(arr_simp).any(1)]
def test_ellps_name_round_trip(self): # this could be done in a parameter fashion for ellps_name in pj_ellps: # skip tests, these ellipses NWL9D and WGS66 are the same if ellps_name in ("NWL9D", "WGS66"): continue p = Geod(ellps=ellps_name) expected = f"Geod(ellps='{ellps_name}')" self.assertEqual(repr(p), expected)
def test_geometry_length__polygon__radians(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_length( Polygon( LineString( [ Point(math.radians(1), math.radians(2)), Point(math.radians(3), math.radians(4)), Point(math.radians(5), math.radians(2)), ] ) ), radians=True, ), 1072185.2103813463, decimal=2, )
def test_ellps_name_round_trip(self): # this could be done in a parameter fashion for ellps_name in pj_ellps: # skip tests, these ellipses NWL9D and WGS66 are the same if ellps_name in ('NWL9D', 'WGS66'): continue p = Geod(ellps=ellps_name) expected = "pyproj.Geod(ellps='{0}')".format(ellps_name) self.assertEqual(repr(p), expected)
def nearest_station(lon, lat): with open('data/nexrad_stations.json') as f: stations = json.load(f) g = Geod(ellps='WGS84') min_dist = 1e10 min_k = stations.keys()[0] for k in stations.keys(): s = stations[k] lon_s = s['lon'] lat_s = s['lat'] az1, az2, dist = g.inv(lon, lat, lon_s, lat_s) #print k, dist/1e3 if dist < min_dist: min_dist = dist min_k = k return min_k, min_dist
def ellipsoidal_distance(a, b): # set the ellipsoid to be used - EXPLAIN WHY THIS ONE # this one is a pretty safe bet for global stuff g = Geod(ellps='WGS84') # extract nodes take the id of the nodes to be measured (a and b) use the grpah.nodes (data = True) function of # networkx to retrieve a list of nodes in the graph data=True means that the node list contains the data stored # inside each node, including coords, rather than just a list of ids extract the specific nodes in which we are # interested using [a] and [b] to retrieve the node with the corresponding id from the nodes list start = graph.nodes(data=True)[a] end = graph.nodes(data=True)[b] # compute forward and back azimuths, plus distance azf, azb, distance = g.inv(start['x'], start['y'], end['x'], end['y']) # return only the distance we are only interested in the distance return distance
def test_geometry_area_perimeter__polygon__radians(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_area_perimeter( Polygon( LineString( [ Point(math.radians(1), math.radians(2)), Point(math.radians(3), math.radians(4)), Point(math.radians(5), math.radians(2)), ] ) ), radians=True, ), (-49187690467.58623, 1072185.2103813463), decimal=2, )
def to_graph(link_path, node_path): adjacency_list = defaultdict(list) with fiona.open(link_path) as link_collection,\ fiona.open(node_path) as node_collection: nodes_coordinates = [] nodes_ids = [] for rec in node_collection: nodes_coordinates.append(rec['geometry']['coordinates']) nodes_ids.append(rec['properties']['id']) kdtree = KDTree(nodes_coordinates) geod = Geod(ellps="WGS84") for rec in link_collection: direction = rec['properties']['dir'] vel_AB = rec['properties']['VEL_AB'] vel_BA = rec['properties']['VEL_BA'] length = geod.geometry_length(shape(rec['geometry'])) time_AB = length / vel_AB * (60/1000) * 60 time_BA = length / vel_BA * (60/1000) * 60 start_point = rec['geometry']['coordinates'][0] end_point = rec['geometry']['coordinates'][-1] start_distance, start_pos = kdtree.query(start_point) end_distance, end_pos = kdtree.query(end_point) start_id = nodes_ids[start_pos] end_id = nodes_ids[end_pos] if direction == 1: adjacency_list[start_id].append((time_AB, end_id)) elif direction == -1: adjacency_list[end_id].append((time_BA, start_id)) elif direction == 0: adjacency_list[start_id].append((time_AB, end_id)) adjacency_list[end_id].append((time_BA, start_id)) else: raise ValueError(direction) return adjacency_list
class Binner: def __init__(self, city): self.geo = Geod(ellps='clrk66') # files self.base_dir = '../data/dataset/{:s}/'.format(city) limits = np.loadtxt(self.base_dir + '/box.txt') self.top_left = limits[0] self.bottom_right = limits[1] # resolution in meters and in grid units res_m = 25.0 # meters _, _, self.width_m = self.geo.inv(self.top_left[1], self.top_left[0], self.bottom_right[1], self.top_left[0]) _, _, self.height_m = self.geo.inv(self.top_left[1], self.top_left[0], self.top_left[1], self.bottom_right[0]) self.n_bins_x = self.width_m / res_m self.n_bins_y = self.height_m / res_m self.res_lat = abs(self.top_left[0] - self.bottom_right[0]) / self.n_bins_y self.res_lng = abs(self.top_left[1] - self.bottom_right[1]) / self.n_bins_x # bins self.n_bins_x = np.ceil(self.n_bins_x).astype(int) self.n_bins_y = np.ceil(self.n_bins_y).astype(int) self.n_bins = self.n_bins_x * self.n_bins_y def get_bin_id(self, lat, lng): nx = np.floor((lng-self.top_left[1]) / self.res_lng).astype(int) ny = np.floor((self.top_left[0]-lat) / self.res_lat).astype(int) idx = ny * self.n_bins_x + nx if(nx >= self.n_bins_x) or (ny >= self.n_bins_y) or (nx < 0) or (ny < 0): idx = -1 return idx def get_bin_loc(self, bin_id): ny = bin_id / self.n_bins_x nx = bin_id % self.n_bins_x lat = self.top_left[0] - (ny+0.5)*self.res_lat lng = self.top_left[1] + (nx+0.5)*self.res_lng return lat, lng def calc_distance(self, lat0, lng0, lat1, lng1): _, _, d = self.geo.inv(lng0, lat0, lng1, lat1) return d
def get_line(turnpoints, tol=0.001, min_t=5): """returns line segment extremes and bisecting segment extremes """ if not (turnpoints[-1].shape == 'line'): return [] from pyproj import Geod clon, clat = turnpoints[-1].lon, turnpoints[ -1].lat # center point of the line ln = turnpoints[-1].radius t = max(ln * tol, min_t) g = Geod(ellps="WGS84") for tp in reversed(list(turnpoints)): if not (tp.lat == clat and tp.lon == clon): flon, flat = tp.lon, tp.lat az1, az2, d = g.inv(clon, clat, flon, flat) lon1, lat1, az = g.fwd(clon, clat, az1 - 90, ln) lon2, lat2, az = g.fwd(clon, clat, az1 + 90, ln) lon3, lat3, az = g.fwd(clon, clat, az1, t) lon4, lat4, az = g.fwd(clon, clat, az2, ln + t) # print(f'Line: {lat1}, {lon1} - {lat2}, {lon2}') return [ Turnpoint(lat1, lon1, 0, 'optimised', 'optimised', 'optimised'), Turnpoint(lat2, lon2, 0, 'optimised', 'optimised', 'optimised'), Turnpoint(lat3, lon3, 0, 'optimised', 'optimised', 'optimised'), Turnpoint(lat4, lon4, 0, 'optimised', 'optimised', 'optimised') ] ''' if all waypoints have same coordinates, returns a north-south line''' lon1, lat1, az = g.fwd(clon, clat, 0, ln) lon2, lat2, az = g.fwd(clon, clat, 180, ln) lon3, lat3, az = g.fwd(clon, clat, 90, t) lon4, lat4, az = g.fwd(clon, clat, 270, ln + t) return [ Turnpoint(lat1, lon1, 0, 'optimised', 'optimised', 'optimised'), Turnpoint(lat2, lon2, 0, 'optimised', 'optimised', 'optimised'), Turnpoint(lat3, lon3, 0, 'optimised', 'optimised', 'optimised'), Turnpoint(lat4, lon4, 0, 'optimised', 'optimised', 'optimised') ]
def geodesic(crs, start, end, steps): r"""Construct a geodesic path between two points. This function acts as a wrapper for the geodesic construction available in `pyproj`. Parameters ---------- crs: `cartopy.crs` Cartopy Coordinate Reference System to use for the output start: (2, ) array_like A latitude-longitude pair designating the start point of the geodesic (units are degrees north and degrees east). end: (2, ) array_like A latitude-longitude pair designating the end point of the geodesic (units are degrees north and degrees east). steps: int, optional The number of points along the geodesic between the start and the end point (including the end points). Returns ------- `numpy.ndarray` The list of x, y points in the given CRS of length `steps` along the geodesic. See Also -------- cross_section """ import cartopy.crs as ccrs from pyproj import Geod # Geod.npts only gives points *in between* the start and end, and we want to include # the endpoints. g = Geod(crs.proj4_init) geodesic = np.concatenate([ np.array(start[::-1])[None], np.array(g.npts(start[1], start[0], end[1], end[0], steps - 2)), np.array(end[::-1])[None] ]).transpose() points = crs.transform_points(ccrs.Geodetic(), *geodesic)[:, :2] return points
def test_integrate(lat1, lon1, lat2, lon2): g = Geod(ellps='sphere') distance1 = g.inv(lon1, lat1, lon2, lat2)[2] / 1000.0 points = g.npts(lon1, lat1, lon2, lat2, int(distance1) // 1) distance2 = 0 distance3 = 0 res = 0 for i in range(len(points) - 1): lo1, la1, lo2, la2 = points[i] + points[i + 1] p1 = sphere2cartesian(90 - la1, 180 - lo1) * 6371 p2 = sphere2cartesian(90 - la2, 180 - lo2) * 6371 distance2 += np.linalg.norm(p1 - p2) az, baz, d = g.inv(lo1, la1, lo2, la2) distance3 += d res += abs(abs(az - baz) - 180) distance3 /= 1000.0 res /= len(points) print(distance1, distance2, distance3) print(res)
def __init__(self, census_apikey="ca22eb30af97c6b471419d7fe22b9ce9a5d1fe8d", db=None): # to lookup populations by census tract self.census = Census(census_apikey) # for distance calculations on the earth's surface self.geod = Geod(ellps='WGS84') # mongodb with loaded GENZ2010 cartographic boundary files if db == None: connection = pymongo.MongoClient( 'mongodb://*****:*****@eg-mongodb.bucknell.edu/ym015') self.db = connection.get_default_database() else: self.db = db # use the database of summary level 140 = state-county-census tract self.col = self.db['GENZ2010_140'] self.census_col = self.db['CENSUS2010_SF1']
def geodetic_azimuth_distance(p_start, p_end, ellipsoid=PYPROJ_WGS84_ELLIPSOID): """Compute geodetic azimuth, backazimuth, and distance from two (lat, lon) points. Assume WGS84 ellipsoid. p_start: (lat_1, lon_1) p_end: (lat_2, lon_2) """ g = Geod(ellps=ellipsoid) azimuth, backazimuth, dist = g.inv(p_start[1], p_start[0], p_end[1], p_end[0]) distance_km = dist / 1000 distance_degrees = central_angle_degrees_from_distance(distance_km) return (azimuth, backazimuth, distance_degrees, distance_km)
def __compute_velocity(data: DataFrame) -> DataFrame: """Output has units of meters per second.""" geodetic = Geod(ellps='WGS84') unique_datetimes = numpy.unique(data['datetime']) for datetime_index, unique_datetime in enumerate(unique_datetimes): unique_datetime_indices = numpy.where( numpy.asarray(data['datetime']) == unique_datetime)[0] for unique_datetime_index in unique_datetime_indices: if unique_datetime_indices[-1] + 1 < len(data['datetime']): dt = (data['datetime'].iloc[unique_datetime_indices[-1] + 1] - data['datetime'].iloc[unique_datetime_index]) forward_azimuth, inverse_azimuth, distance = geodetic.inv( data['longitude'].iloc[unique_datetime_indices[-1] + 1], data['latitude'].iloc[unique_datetime_indices[-1] + 1], data['longitude'].iloc[unique_datetime_index], data['latitude'].iloc[unique_datetime_index], ) else: dt = ( data['datetime'].iloc[unique_datetime_index] - data['datetime'].iloc[unique_datetime_indices[0] - 1]) forward_azimuth, inverse_azimuth, distance = geodetic.inv( data['longitude'].iloc[unique_datetime_indices[0] - 1], data['latitude'].iloc[unique_datetime_indices[0] - 1], data['longitude'].iloc[unique_datetime_index], data['latitude'].iloc[unique_datetime_index], ) speed = distance / (dt / timedelta(seconds=1)) bearing = inverse_azimuth % 360 data['speed'].iloc[unique_datetime_index] = speed data['direction'].iloc[unique_datetime_index] = bearing data['speed'] = data['speed'].astype('float', copy=False) data['direction'] = data['direction'].astype('float', copy=False) return data
def overground_distance(self, point: (float, float)) -> float: """ horizontal distance over ellipsoid :param point: (x, y) point :return: distance in ellipsodal units """ if not isinstance(point, numpy.ndarray): point = numpy.array(point) coordinates = numpy.stack([self.coordinates[:2], point], axis=0) if self.crs.is_projected: return numpy.hypot(*numpy.sum(numpy.diff(coordinates, axis=0), axis=0)) else: ellipsoid = self.crs.datum.to_json_dict()["ellipsoid"] geodetic = Geod( a=ellipsoid["semi_major_axis"], rf=ellipsoid["inverse_flattening"] ) return geodetic.line_length(coordinates[:, 0], coordinates[:, 1])
def rbf_cosine(self,cntr,x,y,tpr=None): ''' Calculate cosine basis function ''' length=self.sbf_dx width=self.sbf_dy strike = self.strike cntrx,cntry=cntr #print length, cntrx,cntry g = Geod(ellps='WGS84') cbf = np.zeros(x.shape) lt2k = 6371.*mt.pi/180. ln2k = lt2k*mt.cos(mt.radians(cntry)) #print ln2k rmax = mt.hypot(length,width) tmp = np.where(np.hypot((x-cntrx)*ln2k,(y-cntry)*lt2k) < rmax) cst = 1#mt.cos(mt.radians(sbf.strike)) sst = 1#mt.sin(mt.radians(sbf.strike)) # Take average of lat and lon grid interval dgrd = 0.5*((x[0,1]-x[0,0])*ln2k + (y[1,0]-y[0,0])*lt2k) if tpr is None: tpr = 7.5 for iy,ix in zip(tmp[0],tmp[1]): if True: az,baz,dist = g.inv(cntrx,cntry,x[iy,ix],y[iy,ix]) xp = abs(0.001*dist*mt.cos(mt.radians(az-strike))) yp = abs(0.001*dist*mt.sin(mt.radians(az-strike))) else: xp = abs( (x[iy,ix]-cntrx)*ln2k*sst + (y[iy,ix]-cntry)*lt2k*cst) yp = abs(-(x[iy,ix]-cntrx)*ln2k*cst + (y[iy,ix]-cntry)*lt2k*sst) xbf = 1. if xp > 0.5*length + tpr: xbf = 0. elif xp > 0.5*length - tpr: xbf = xbf*0.5*(1.+mt.cos(mt.pi*((xp-0.5*length+tpr)/(2.*tpr)))) if yp > 0.5*width + tpr: xbf = 0. elif yp > 0.5*width - tpr: xbf = xbf*0.5*(1.+mt.cos(mt.pi*((yp-0.5*width+tpr)/(2.*tpr)))) #if xbf != 0.: # print '##%7.3f %7.3f %7.2f %7.2f %g' % (x[iy,ix],y[iy,ix],xp,yp,xbf) cbf[iy,ix] = xbf return cbf
def _plot_circles(ax, evlon, evlat, maxdist, ncircles=5): geodetic_transform = ccrs.PlateCarree() g = Geod(ellps='WGS84') ax.plot(evlon, evlat, marker='*', markersize=20, markeredgewidth=1, markeredgecolor='white', color='k', transform=geodetic_transform, zorder=10) step = _round(maxdist / ncircles) if step == 0: step = 1 texts = [] for dist in np.arange(step, maxdist + step, step): azimuths = np.arange(0, 360, 1) circle = np.array( [g.fwd(evlon, evlat, az, dist * 1e3)[0:2] for az in azimuths]) p0 = circle[np.argmax(circle[:, 1])] ax.plot(circle[:, 0], circle[:, 1], color='#777777', linestyle='--', transform=geodetic_transform) dist_text = '{} km'.format(int(dist)) t = ax.text(p0[0], p0[1], dist_text, size=8, weight='bold', verticalalignment='center', horizontalalignment='center', clip_on=True, transform=geodetic_transform, zorder=10) t.set_path_effects([ PathEffects.Stroke(linewidth=0.8, foreground='white'), PathEffects.Normal() ]) texts.append(t) return texts