def get_circle_centers(b1, b2, radius): """ the function covers the area within the bounds with circles :param b1: south-west bounds [lat, lng] :param b2: north-east bounds [lat, lng] :param radius: specified radius, adapt for high density areas :return: list of circle centers that cover the area between lower/upper """ sw = Point(b1) ne = Point(b2) # north/east distances dist_lat = geodesic(Point(sw[0], sw[1]), Point(ne[0], sw[1])).meters dist_lng = geodesic(Point(sw[0], sw[1]), Point(sw[0], ne[1])).meters circles = cover_rect_with_cicles(dist_lat, dist_lng, radius) cords = [ GeodesicDistance(meters=c[0]).destination( GeodesicDistance(meters=c[1]).destination(point=sw, bearing=90), bearing=0)[:2] for c in circles ] return cords
def interpolation_radius(self, lat, lon): distance = GeodesicDistance() d = (distance.measure((np.amin(lat), np.amin(lon)), (np.amax(lat), np.amax(lon))) * 1000 / 8.0) if d == 0: d = 50000 d = np.clip(d, 20000, 50000) return d
def start_points_and_displacements_to_endpoints(start_latitudes_deg, start_longitudes_deg, scalar_displacements_metres, geodetic_bearings_deg): """Computes endpoint from each start point and displacement. :param start_latitudes_deg: numpy array with latitudes (deg N) of start points. :param start_longitudes_deg: equivalent-size numpy array with longitudes (deg E) of start points. :param scalar_displacements_metres: equivalent-size numpy array of scalar displacements. :param geodetic_bearings_deg: equivalent-size numpy array of geodetic bearings (from start point to end point, measured clockwise from due north). :return: end_latitudes_deg: equivalent-size numpy array with latitudes (deg N) of endpoints. :return: end_longitudes_deg: equivalent-size numpy array with longitudes (deg E) of endpoints. """ error_checking.assert_is_valid_lat_numpy_array(start_latitudes_deg, allow_nan=False) start_longitudes_deg = lng_conversion.convert_lng_positive_in_west( start_longitudes_deg, allow_nan=False) error_checking.assert_is_numpy_array(start_longitudes_deg, exact_dimensions=numpy.array( start_latitudes_deg.shape)) error_checking.assert_is_geq_numpy_array(scalar_displacements_metres, 0.) error_checking.assert_is_numpy_array(scalar_displacements_metres, exact_dimensions=numpy.array( start_latitudes_deg.shape)) error_checking.assert_is_geq_numpy_array(geodetic_bearings_deg, 0.) error_checking.assert_is_leq_numpy_array(geodetic_bearings_deg, 360.) error_checking.assert_is_numpy_array(geodetic_bearings_deg, exact_dimensions=numpy.array( start_latitudes_deg.shape)) end_latitudes_deg = numpy.full(start_latitudes_deg.shape, numpy.nan) end_longitudes_deg = numpy.full(start_latitudes_deg.shape, numpy.nan) num_points = start_latitudes_deg.size for i in range(num_points): this_start_point_object = geopy.Point(start_latitudes_deg.flat[i], start_longitudes_deg.flat[i]) this_end_point_object = GeodesicDistance( meters=scalar_displacements_metres.flat[i]).destination( this_start_point_object, geodetic_bearings_deg.flat[i]) end_latitudes_deg.flat[i] = this_end_point_object.latitude end_longitudes_deg.flat[i] = this_end_point_object.longitude end_longitudes_deg = lng_conversion.convert_lng_positive_in_west( end_longitudes_deg, allow_nan=False) return end_latitudes_deg, end_longitudes_deg
def walk(longitude, latitude, bearing, distance): """ longitude, latitude - point to walk from bearing - direction of the walk in bearing degrees distance_proj - distance to walk in meters returns longitude, latitude of arrival point """ origin = geopy.Point(longitude=longitude, latitude=latitude) destination = GeodesicDistance(meters=distance).destination( origin, bearing) return destination.longitude, destination.latitude
def _path_to_points(points, n, intimes=None): if intimes is None: intimes = [0] * len(points) tuples = list(zip(points, points[1::], intimes, intimes[1::])) d = GeodesicDistance() dist_between_pts = [] for pair in tuples: dist_between_pts.append(d.measure(pair[0], pair[1])) total_distance = np.sum(dist_between_pts) distances = [] target_lat = [] target_lon = [] bearings = [] times = [] for idx, tup in enumerate(tuples): npts = int(np.ceil(n * (dist_between_pts[idx] / total_distance))) if npts < 2: npts = 2 p0 = geopy.Point(tup[0]) p1 = geopy.Point(tup[1]) p_dist, p_lat, p_lon, b = points_between(p0, p1, npts) if len(distances) > 0: distances.extend(np.add(p_dist, distances[-1])) else: distances.extend(p_dist) target_lat.extend(p_lat) target_lon.extend(p_lon) bearings.extend([b] * len(p_dist)) times.extend([ tup[2] + i * (tup[3] - tup[2]) / (npts - 1) for i in range(0, npts) ]) return distances, times, target_lat, target_lon, bearings
def points_between(start, end, numpoints, constantvalue=False): distance = [] latitude = [] longitude = [] lat0 = start.latitude lon0 = start.longitude lat1 = end.latitude lon1 = end.longitude if constantvalue and np.isclose(lat0, lat1): latitude = np.ones(numpoints) * lat0 longitude = np.linspace(lon0, lon1, num=numpoints) for lon in longitude: distance.append(geodesic(start, geopy.Point(lat0, lon)).km) if lon1 > lon0: b = 90 else: b = -90 elif constantvalue and np.isclose(lon0, lon1): latitude = np.linspace(lat0, lat1, num=numpoints) longitude = np.ones(numpoints) * lon0 for lat in latitude: distance.append(geodesic(start, geopy.Point(lat, lon0)).km) if lat1 > lat0: b = 0 else: b = 180 else: total_distance = geodesic(start, end).km distance = np.linspace(0, total_distance, num=numpoints) b = bearing(lat0, lon0, lat1, lon1) for d in distance: p = GeodesicDistance().destination(start, b, d) latitude.append(p.latitude) longitude.append(p.longitude) return list(map(np.array, [distance, latitude, longitude, b]))
def points_between(start, end, numpoints): distance = GeodesicDistance() distances = [] latitudes = [] longitudes = [] lat0 = start.latitude lon0 = start.longitude lat1 = end.latitude lon1 = end.longitude if np.isclose(lat0, lat1): # Constant latitude latitudes = np.ones(numpoints) * lat0 longitudes = np.linspace(lon0, lon1, num=numpoints) for lon in longitudes: distances.append(distance.measure(start, geopy.Point(lat0, lon))) if lon1 > lon0: b = 90 else: b = -90 elif np.isclose(lon0, lon1): # Constant longitude latitudes = np.linspace(lat0, lat1, num=numpoints) longitudes = np.ones(numpoints) * lon0 for lat in latitudes: distances.append(distance.measure(start, geopy.Point(lat, lon0))) if lat1 > lat0: b = 0 else: b = 180 else: # Great Circle total_distance = distance.measure(start, end) distances = np.linspace(0, total_distance, num=numpoints) b = bearing(lat0, lon0, lat1, lon1) for d in distances: p = distance.destination(start, b, d) latitudes.append(p.latitude) longitudes.append(p.longitude) return distances, latitudes, longitudes, b
def _transect_plot(self, values, depths, plotTitle, vmin, vmax, cmapLabel, unit, cmap): self.__fill_invalid_shift(values) dist = np.tile(self.transect_data["distance"], (values.shape[0], 1)) # Plot the data c = plt.pcolormesh( dist, depths.transpose(), values, cmap=cmap, shading="gouraud", # Smooth shading vmin=vmin, vmax=vmax, ) ax = plt.gca() ax.set_title(plotTitle, fontsize=14) # Set title of subplot ax.invert_yaxis() if self.depth_limit is None or (self.depth_limit is not None and self.linearthresh < self.depth_limit): plt.yscale("symlog", linthresh=self.linearthresh) ax.yaxis.set_major_formatter(ScalarFormatter()) # Mask out the bottom plt.fill_between( self.bathymetry["x"], self.bathymetry["y"] * -1, plt.ylim()[0], facecolor="dimgray", hatch="xx", ) ax.set_facecolor("dimgray") plt.xlabel(gettext("Distance (km)")) plt.ylabel(gettext("Depth (m)")) plt.xlim([ self.transect_data["distance"][0], self.transect_data["distance"][-1] ]) # Tighten the y-limits if self.depth_limit: plt.ylim(self.depth_limit, 0) else: deep = np.amax(self.bathymetry["y"] * -1) l = 10**np.floor(np.log10(deep)) plt.ylim(np.ceil(deep / l) * l, 0) ticks = sorted( set(list(plt.yticks()[0]) + [self.linearthresh, plt.ylim()[0]])) if self.depth_limit is not None: ticks = [y for y in ticks if y <= self.depth_limit] plt.yticks(ticks) # Show the linear threshold plt.plot( [ self.transect_data["distance"][0], self.transect_data["distance"][-1] ], [self.linearthresh, self.linearthresh], "k:", alpha=1.0, ) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) bar = plt.colorbar(c, cax=cax) # Append variable units to color scale label bar.set_label(cmapLabel + " (" + utils.mathtext(unit) + ")") if len(self.points) > 2: station_distances = [] current_dist = 0 d = GeodesicDistance() for idx, p in enumerate(self.points): if idx == 0: station_distances.append(0) else: current_dist += d.measure(p, self.points[idx - 1]) station_distances.append(current_dist) ax2 = ax.twiny() ax2.set_xticks(station_distances) ax2.set_xlim([ self.transect_data["distance"][0], self.transect_data["distance"][-1] ]) ax2.tick_params("x", length=0, width=0, pad=-3, labelsize="xx-small", which="major") ax2.xaxis.set_major_formatter(StrMethodFormatter("$\u25bc$")) cax = make_axes_locatable(ax2).append_axes("right", size="5%", pad=0.05) bar2 = plt.colorbar(c, cax=cax) bar2.remove() return divider