def get_distance_vincenty(gps_data): distance = 0 last_trkpt = [gps_data[0]['latitude'],gps_data[0]['longitude']] for trkpt in gps_data: curr_trkpt = [trkpt['latitude'],trkpt['longitude']] dist = VincentyDistance() distance = distance + dist.measure(last_trkpt,curr_trkpt) last_trkpt = curr_trkpt return distance
def points_between(start, end, numpoints): distance = VincentyDistance() 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 points_between(start, end, numpoints): distance = VincentyDistance() 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 interpolation_radius(self, lat, lon): distance = VincentyDistance() 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 interpolation_radius(self, lat, lon): distance = VincentyDistance() 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 _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 = VincentyDistance() 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 _path_to_points(points, n, intimes=None): if intimes is None: intimes = [0] * len(points) tuples = zip(points, points[1::], intimes, intimes[1::]) d = VincentyDistance() 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 _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', linthreshy=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 = VincentyDistance() 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
def load_data(self): if self.projection == 'EPSG:32661': blat = min(self.bounds[0], self.bounds[2]) blat = 5 * np.floor(blat / 5) self.basemap = basemap.load_map('npstere', (blat, 0), None, None) elif self.projection == 'EPSG:3031': blat = max(self.bounds[0], self.bounds[2]) blat = 5 * np.ceil(blat / 5) self.basemap = basemap.load_map('spstere', (blat, 180), None, None) else: distance = VincentyDistance() height = distance.measure( (self.bounds[0], self.centroid[1]), (self.bounds[2], self.centroid[1])) * 1000 * 1.25 width = distance.measure( (self.centroid[0], self.bounds[1]), (self.centroid[0], self.bounds[3])) * 1000 * 1.25 self.basemap = basemap.load_map('lcc', self.centroid, height, width) if self.basemap.aspect < 1: gridx = 500 gridy = int(500 * self.basemap.aspect) else: gridy = 500 gridx = int(500 / self.basemap.aspect) self.longitude, self.latitude = self.basemap.makegrid(gridx, gridy) with open_dataset(get_dataset_url(self.dataset_name)) as dataset: if self.time < 0: self.time += len(dataset.timestamps) self.time = np.clip(self.time, 0, len(dataset.timestamps) - 1) self.variable_unit = self.get_variable_units( dataset, self.variables)[0] self.variable_name = self.get_variable_names( dataset, self.variables)[0] scale_factor = self.get_variable_scale_factors( dataset, self.variables)[0] if self.cmap is None: if len(self.variables) == 1: self.cmap = colormap.find_colormap(self.variable_name) else: self.cmap = colormap.colormaps.get('speed') if len(self.variables) == 2: self.variable_name = self.vector_name(self.variable_name) if self.depth == 'bottom': depth_value = 'Bottom' else: self.depth = np.clip(int(self.depth), 0, len(dataset.depths) - 1) depth_value = dataset.depths[self.depth] data = [] allvars = [] for v in self.variables: var = dataset.variables[v] allvars.append(v) if self.filetype in ['csv', 'odv', 'txt']: d, depth_value = dataset.get_area(np.array( [self.latitude, self.longitude]), self.depth, self.time, v, return_depth=True) else: d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v) d = np.multiply(d, scale_factor) self.variable_unit, d = self.kelvin_to_celsius( self.variable_unit, d) data.append(d) if self.filetype not in ['csv', 'odv', 'txt']: if len(var.dimensions) == 3: self.depth_label = "" elif self.depth == 'bottom': self.depth_label = " at Bottom" else: self.depth_label = " at " + \ str(int(np.round(depth_value))) + " m" if len(data) == 2: data[0] = np.sqrt(data[0]**2 + data[1]**2) self.data = data[0] quiver_data = [] if self.quiver is not None and \ self.quiver['variable'] != '' and \ self.quiver['variable'] != 'none': for v in self.quiver['variable'].split(','): allvars.append(v) var = dataset.variables[v] quiver_unit = get_variable_unit(self.dataset_name, var) quiver_name = get_variable_name(self.dataset_name, var) quiver_lon, quiver_lat = self.basemap.makegrid(50, 50) d = dataset.get_area(np.array([quiver_lat, quiver_lon]), self.depth, self.time, v) quiver_data.append(d) self.quiver_name = self.vector_name(quiver_name) self.quiver_longitude = quiver_lon self.quiver_latitude = quiver_lat self.quiver_unit = quiver_unit self.quiver_data = quiver_data if all( map(lambda v: len(dataset.variables[v].dimensions) == 3, allvars)): self.depth = 0 contour_data = [] if self.contour is not None and \ self.contour['variable'] != '' and \ self.contour['variable'] != 'none': d = dataset.get_area(np.array([self.latitude, self.longitude]), self.depth, self.time, self.contour['variable']) contour_unit = get_variable_unit( self.dataset_name, dataset.variables[self.contour['variable']]) contour_name = get_variable_name( self.dataset_name, dataset.variables[self.contour['variable']]) contour_factor = get_variable_scale_factor( self.dataset_name, dataset.variables[self.contour['variable']]) contour_unit, d = self.kelvin_to_celsius(contour_unit, d) d = np.multiply(d, contour_factor) contour_data.append(d) self.contour_unit = contour_unit self.contour_name = contour_name self.contour_data = contour_data self.timestamp = dataset.timestamps[self.time] if self.variables != self.variables_anom: self.variable_name += " Anomaly" with open_dataset(get_dataset_climatology( self.dataset_name)) as dataset: data = [] for v in self.variables: var = dataset.variables[v] d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.timestamp.month - 1, v) data.append(d) if len(data) == 2: data = np.sqrt(data[0]**2 + data[1]**2) else: data = data[0] u, data = self.kelvin_to_celsius( dataset.variables[self.variables[0]].unit, data) self.data -= data # Load bathymetry data self.bathymetry = overlays.bathymetry(self.basemap, self.latitude, self.longitude, blur=2) if self.depth != 'bottom' and self.depth != 0: if len(quiver_data) > 0: quiver_bathymetry = overlays.bathymetry( self.basemap, quiver_lat, quiver_lon) self.data[np.where(self.bathymetry < depth_value)] = np.ma.masked for d in self.quiver_data: d[np.where(quiver_bathymetry < depth_value)] = np.ma.masked for d in self.contour_data: d[np.where(self.bathymetry < depth_value)] = np.ma.masked else: mask = maskoceans(self.longitude, self.latitude, self.data).mask self.data[~mask] = np.ma.masked for d in self.quiver_data: mask = maskoceans(self.quiver_longitude, self.quiver_latitude, d).mask d[~mask] = np.ma.masked for d in contour_data: mask = maskoceans(self.longitude, self.latitude, d).mask d[~mask] = np.ma.masked if self.area and self.filetype in ['csv', 'odv', 'txt', 'geotiff']: area_polys = [] for a in self.area: rings = [LinearRing(p) for p in a['polygons']] innerrings = [LinearRing(p) for p in a['innerrings']] polygons = [] for r in rings: inners = [] for ir in innerrings: if r.contains(ir): inners.append(ir) polygons.append(Poly(r, inners)) area_polys.append(MultiPolygon(polygons)) points = [ Point(p) for p in zip(self.latitude.ravel(), self.longitude.ravel()) ] indicies = [] for a in area_polys: indicies.append( np.where(map(lambda p, poly=a: poly.contains(p), points))[0]) indicies = np.unique(np.array(indicies).ravel()) newmask = np.ones(self.data.shape, dtype=bool) newmask[np.unravel_index(indicies, newmask.shape)] = False self.data.mask |= newmask self.depth_value = depth_value
def load_data(self): distance = VincentyDistance() height = distance.measure( (self.bounds[0], self.centroid[1]), (self.bounds[2], self.centroid[1])) * 1000 * 1.25 width = distance.measure( (self.centroid[0], self.bounds[1]), (self.centroid[0], self.bounds[3])) * 1000 * 1.25 if self.projection == 'EPSG:32661': near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = min(self.bounds[0], self.bounds[2]) blat = 5 * np.floor(blat / 5) if self.centroid[0] > 80 or near_pole or covers_pole: self.basemap = basemap.load_map( 'npstere', self.centroid, height, width, min(self.bounds[0], self.bounds[2])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) elif self.projection == 'EPSG:3031': near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = max(self.bounds[0], self.bounds[2]) blat = 5 * np.ceil(blat / 5) if ((self.centroid[0] < -80 or self.bounds[1] < -80 or self.bounds[3] < -80) or covers_pole): # is centerered close to the south pole self.basemap = basemap.load_map('spstere', (blat, 180), height, width) else: self.basemap = basemap.load_map( 'lcc', self.centroid, height, width, max(self.bounds[0], self.bounds[2])) elif abs(self.centroid[1] - self.bounds[1]) > 90: height_bounds = [self.bounds[0], self.bounds[2]] width_bounds = [self.bounds[1], self.bounds[3]] height_buffer = (abs(height_bounds[1] - height_bounds[0])) * 0.1 width_buffer = (abs(width_bounds[0] - width_bounds[1])) * 0.1 if abs(width_bounds[1] - width_bounds[0]) > 360: raise ClientError( gettext( "You have requested an area that exceads the width of the world. \ Thinking big is good but plots need to be less the 360 deg wide." )) if height_bounds[1] < 0: height_bounds[1] = height_bounds[1] + height_buffer else: height_bounds[1] = height_bounds[1] + height_buffer if height_bounds[0] < 0: height_bounds[0] = height_bounds[0] - height_buffer else: height_bounds[0] = height_bounds[0] - height_buffer new_width_bounds = [] new_width_bounds.append(width_bounds[0] - width_buffer) new_width_bounds.append(width_bounds[1] + width_buffer) if abs(new_width_bounds[1] - new_width_bounds[0]) > 360: width_buffer = np.floor( (360 - abs(width_bounds[1] - width_bounds[0])) / 2) new_width_bounds[0] = width_bounds[0] - width_buffer new_width_bounds[1] = width_bounds[1] + width_buffer if new_width_bounds[0] < -360: new_width_bounds[0] = -360 if new_width_bounds[1] > 720: new_width_bounds[1] = 720 self.basemap = basemap.load_map( 'merc', self.centroid, (height_bounds[0], height_bounds[1]), (new_width_bounds[0], new_width_bounds[1])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) if self.basemap.aspect < 1: gridx = 500 gridy = int(500 * self.basemap.aspect) else: gridy = 500 gridx = int(500 / self.basemap.aspect) self.longitude, self.latitude = self.basemap.makegrid(gridx, gridy) with open_dataset(get_dataset_url(self.dataset_name)) as dataset: if self.time < 0: self.time += len(dataset.timestamps) self.time = np.clip(self.time, 0, len(dataset.timestamps) - 1) self.variable_unit = self.get_variable_units( dataset, self.variables)[0] self.variable_name = self.get_variable_names( dataset, self.variables)[0] scale_factor = self.get_variable_scale_factors( dataset, self.variables)[0] if self.cmap is None: if len(self.variables) == 1: self.cmap = colormap.find_colormap(self.variable_name) else: self.cmap = colormap.colormaps.get('speed') if len(self.variables) == 2: self.variable_name = self.vector_name(self.variable_name) if self.depth == 'bottom': depth_value = 'Bottom' else: self.depth = np.clip(int(self.depth), 0, len(dataset.depths) - 1) depth_value = dataset.depths[self.depth] data = [] allvars = [] for v in self.variables: var = dataset.variables[v] allvars.append(v) if self.filetype in ['csv', 'odv', 'txt']: d, depth_value = dataset.get_area(np.array( [self.latitude, self.longitude]), self.depth, self.time, v, self.interp, self.radius, self.neighbours, return_depth=True) else: d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v, self.interp, self.radius, self.neighbours) d = np.multiply(d, scale_factor) self.variable_unit, d = self.kelvin_to_celsius( self.variable_unit, d) data.append(d) if self.filetype not in ['csv', 'odv', 'txt']: if len(var.dimensions) == 3: self.depth_label = "" elif self.depth == 'bottom': self.depth_label = " at Bottom" else: self.depth_label = " at " + \ str(int(np.round(depth_value))) + " m" if len(data) == 2: data[0] = np.sqrt(data[0]**2 + data[1]**2) self.data = data[0] quiver_data = [] # Store the quiver data on the same grid as the main variable. This # will only be used for CSV export. quiver_data_fullgrid = [] if self.quiver is not None and \ self.quiver['variable'] != '' and \ self.quiver['variable'] != 'none': for v in self.quiver['variable'].split(','): allvars.append(v) var = dataset.variables[v] quiver_unit = get_variable_unit(self.dataset_name, var) quiver_name = get_variable_name(self.dataset_name, var) quiver_lon, quiver_lat = self.basemap.makegrid(50, 50) d = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, v, self.interp, self.radius, self.neighbours, ) quiver_data.append(d) # Get the quiver data on the same grid as the main # variable. d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v, self.interp, self.radius, self.neighbours, ) quiver_data_fullgrid.append(d) self.quiver_name = self.vector_name(quiver_name) self.quiver_longitude = quiver_lon self.quiver_latitude = quiver_lat self.quiver_unit = quiver_unit self.quiver_data = quiver_data self.quiver_data_fullgrid = quiver_data_fullgrid if all( map(lambda v: len(dataset.variables[v].dimensions) == 3, allvars)): self.depth = 0 contour_data = [] if self.contour is not None and \ self.contour['variable'] != '' and \ self.contour['variable'] != 'none': d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.contour['variable'], self.interp, self.radius, self.neighbours, ) contour_unit = get_variable_unit( self.dataset_name, dataset.variables[self.contour['variable']]) contour_name = get_variable_name( self.dataset_name, dataset.variables[self.contour['variable']]) contour_factor = get_variable_scale_factor( self.dataset_name, dataset.variables[self.contour['variable']]) contour_unit, d = self.kelvin_to_celsius(contour_unit, d) d = np.multiply(d, contour_factor) contour_data.append(d) self.contour_unit = contour_unit self.contour_name = contour_name self.contour_data = contour_data self.timestamp = dataset.timestamps[self.time] if self.compare: self.variable_name += " Difference" with open_dataset(get_dataset_url( self.compare['dataset'])) as dataset: data = [] for v in self.compare['variables']: var = dataset.variables[v] d = dataset.get_area( np.array([self.latitude, self.longitude]), self.compare['depth'], self.compare['time'], v, self.interp, self.radius, self.neighbours, ) data.append(d) if len(data) == 2: data = np.sqrt(data[0]**2 + data[1]**2) else: data = data[0] u, data = self.kelvin_to_celsius( dataset.variables[self.compare['variables'][0]].unit, data) self.data -= data # Load bathymetry data self.bathymetry = overlays.bathymetry(self.basemap, self.latitude, self.longitude, blur=2) if self.depth != 'bottom' and self.depth != 0: if len(quiver_data) > 0: quiver_bathymetry = overlays.bathymetry( self.basemap, quiver_lat, quiver_lon) self.data[np.where(self.bathymetry < depth_value)] = np.ma.masked for d in self.quiver_data: d[np.where(quiver_bathymetry < depth_value)] = np.ma.masked for d in self.contour_data: d[np.where(self.bathymetry < depth_value)] = np.ma.masked else: mask = maskoceans(self.longitude, self.latitude, self.data).mask self.data[~mask] = np.ma.masked for d in self.quiver_data: mask = maskoceans(self.quiver_longitude, self.quiver_latitude, d).mask d[~mask] = np.ma.masked for d in contour_data: mask = maskoceans(self.longitude, self.latitude, d).mask d[~mask] = np.ma.masked if self.area and self.filetype in ['csv', 'odv', 'txt', 'geotiff']: area_polys = [] for a in self.area: rings = [LinearRing(p) for p in a['polygons']] innerrings = [LinearRing(p) for p in a['innerrings']] polygons = [] for r in rings: inners = [] for ir in innerrings: if r.contains(ir): inners.append(ir) polygons.append(Poly(r, inners)) area_polys.append(MultiPolygon(polygons)) points = [ Point(p) for p in zip(self.latitude.ravel(), self.longitude.ravel()) ] indicies = [] for a in area_polys: indicies.append( np.where(map(lambda p, poly=a: poly.contains(p), points))[0]) indicies = np.unique(np.array(indicies).ravel()) newmask = np.ones(self.data.shape, dtype=bool) newmask[np.unravel_index(indicies, newmask.shape)] = False self.data.mask |= newmask self.depth_value = depth_value
def load_data(self): distance = VincentyDistance() height = distance.measure( (self.bounds[0], self.centroid[1]), (self.bounds[2], self.centroid[1])) * 1000 * 1.25 width = distance.measure( (self.centroid[0], self.bounds[1]), (self.centroid[0], self.bounds[3])) * 1000 * 1.25 if self.projection == 'EPSG:32661': # north pole projection near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = min(self.bounds[0], self.bounds[2]) blat = 5 * np.floor(blat / 5) if self.centroid[0] > 80 or near_pole or covers_pole: self.basemap = basemap.load_map( 'npstere', self.centroid, height, width, min(self.bounds[0], self.bounds[2])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) elif self.projection == 'EPSG:3031': # south pole projection near_pole, covers_pole = self.pole_proximity(self.points[0]) blat = max(self.bounds[0], self.bounds[2]) blat = 5 * np.ceil(blat / 5) # is centerered close to the south pole if ((self.centroid[0] < -80 or self.bounds[1] < -80 or self.bounds[3] < -80) or covers_pole) or near_pole: self.basemap = basemap.load_map( 'spstere', self.centroid, height, width, max(self.bounds[0], self.bounds[2])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) elif abs(self.centroid[1] - self.bounds[1]) > 90: height_bounds = [self.bounds[0], self.bounds[2]] width_bounds = [self.bounds[1], self.bounds[3]] height_buffer = (abs(height_bounds[1] - height_bounds[0])) * 0.1 width_buffer = (abs(width_bounds[0] - width_bounds[1])) * 0.1 if abs(width_bounds[1] - width_bounds[0]) > 360: raise ClientError( gettext( "You have requested an area that exceeds the width of the world. \ Thinking big is good but plots need to be less than 360 deg wide." )) if height_bounds[1] < 0: height_bounds[1] = height_bounds[1] + height_buffer else: height_bounds[1] = height_bounds[1] + height_buffer if height_bounds[0] < 0: height_bounds[0] = height_bounds[0] - height_buffer else: height_bounds[0] = height_bounds[0] - height_buffer new_width_bounds = [] new_width_bounds.append(width_bounds[0] - width_buffer) new_width_bounds.append(width_bounds[1] + width_buffer) if abs(new_width_bounds[1] - new_width_bounds[0]) > 360: width_buffer = np.floor( (360 - abs(width_bounds[1] - width_bounds[0])) / 2) new_width_bounds[0] = width_bounds[0] - width_buffer new_width_bounds[1] = width_bounds[1] + width_buffer if new_width_bounds[0] < -360: new_width_bounds[0] = -360 if new_width_bounds[1] > 720: new_width_bounds[1] = 720 self.basemap = basemap.load_map( 'merc', self.centroid, (height_bounds[0], height_bounds[1]), (new_width_bounds[0], new_width_bounds[1])) else: self.basemap = basemap.load_map('lcc', self.centroid, height, width) if self.basemap.aspect < 1: gridx = 500 gridy = int(500 * self.basemap.aspect) else: gridy = 500 gridx = int(500 / self.basemap.aspect) self.longitude, self.latitude = self.basemap.makegrid(gridx, gridy) variables_to_load = self.variables[:] # we don't want to change self,variables so copy it if self.__load_quiver(): variables_to_load.append(self.quiver['variable']) with open_dataset(self.dataset_config, variable=variables_to_load, timestamp=self.time) as dataset: self.variable_unit = self.get_variable_units( dataset, self.variables)[0] self.variable_name = self.get_variable_names( dataset, self.variables)[0] if self.cmap is None: self.cmap = colormap.find_colormap(self.variable_name) if self.depth == 'bottom': depth_value_map = 'Bottom' else: self.depth = np.clip(int(self.depth), 0, len(dataset.depths) - 1) depth_value = dataset.depths[self.depth] depth_value_map = depth_value data = [] var = dataset.variables[self.variables[0]] if self.filetype in ['csv', 'odv', 'txt']: d, depth_value_map = dataset.get_area(np.array( [self.latitude, self.longitude]), self.depth, self.time, self.variables[0], self.interp, self.radius, self.neighbours, return_depth=True) else: d = dataset.get_area(np.array([self.latitude, self.longitude]), self.depth, self.time, self.variables[0], self.interp, self.radius, self.neighbours) data.append(d) if self.filetype not in ['csv', 'odv', 'txt']: if len(var.dimensions) == 3: self.depth_label = "" elif self.depth == 'bottom': self.depth_label = " at Bottom" else: self.depth_label = " at " + \ str(int(np.round(depth_value_map))) + " m" self.data = data[0] quiver_data = [] # Store the quiver data on the same grid as the main variable. This # will only be used for CSV export. quiver_data_fullgrid = [] if self.__load_quiver(): var = dataset.variables[self.quiver['variable']] quiver_unit = self.dataset_config.variable[var].unit quiver_name = self.dataset_config.variable[var].name quiver_x_var = self.dataset_config.variable[ var].east_vector_component quiver_y_var = self.dataset_config.variable[ var].north_vector_component quiver_lon, quiver_lat = self.basemap.makegrid(50, 50) x_vals = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, quiver_x_var, self.interp, self.radius, self.neighbours, ) quiver_data.append(x_vals) y_vals = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, quiver_y_var, self.interp, self.radius, self.neighbours, ) quiver_data.append(y_vals) mag_data = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, self.quiver['variable'], self.interp, self.radius, self.neighbours, ) self.quiver_magnitude = mag_data # Get the quiver data on the same grid as the main # variable. x_vals = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, quiver_x_var, self.interp, self.radius, self.neighbours, ) quiver_data_fullgrid.append(x_vals) y_vals = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, quiver_y_var, self.interp, self.radius, self.neighbours, ) quiver_data_fullgrid.append(y_vals) self.quiver_name = self.get_variable_names( dataset, [self.quiver['variable']])[0] self.quiver_longitude = quiver_lon self.quiver_latitude = quiver_lat self.quiver_unit = quiver_unit self.quiver_data = quiver_data self.quiver_data_fullgrid = quiver_data_fullgrid if all([ dataset.variables[v].is_surface_only() for v in variables_to_load ]): self.depth = 0 contour_data = [] if self.contour is not None and \ self.contour['variable'] != '' and \ self.contour['variable'] != 'none': d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.contour['variable'], self.interp, self.radius, self.neighbours, ) vc = self.dataset_config.variable[self.contour['variable']] contour_unit = vc.unit contour_name = vc.name contour_data.append(d) self.contour_unit = contour_unit self.contour_name = contour_name self.contour_data = contour_data self.timestamp = dataset.nc_data.timestamp_to_iso_8601(self.time) if self.compare: self.variable_name += " Difference" compare_config = DatasetConfig(self.compare['dataset']) with open_dataset(compare_config, variable=self.compare['variables'], timestamp=self.compare['time']) as dataset: data = [] for v in self.compare['variables']: var = dataset.variables[v] d = dataset.get_area( np.array([self.latitude, self.longitude]), self.compare['depth'], self.compare['time'], v, self.interp, self.radius, self.neighbours, ) data.append(d) data = data[0] self.data -= data # Load bathymetry data self.bathymetry = overlays.bathymetry(self.basemap, self.latitude, self.longitude, blur=2) if self.depth != 'bottom' and self.depth != 0: if quiver_data: quiver_bathymetry = overlays.bathymetry( self.basemap, quiver_lat, quiver_lon) self.data[np.where( self.bathymetry < depth_value_map)] = np.ma.masked for d in self.quiver_data: d[np.where(quiver_bathymetry < depth_value)] = np.ma.masked for d in self.contour_data: d[np.where(self.bathymetry < depth_value_map)] = np.ma.masked else: mask = maskoceans(self.longitude, self.latitude, self.data, True, 'h', 1.25).mask self.data[~mask] = np.ma.masked for d in self.quiver_data: mask = maskoceans(self.quiver_longitude, self.quiver_latitude, d).mask d[~mask] = np.ma.masked for d in contour_data: mask = maskoceans(self.longitude, self.latitude, d).mask d[~mask] = np.ma.masked if self.area and self.filetype in ['csv', 'odv', 'txt', 'geotiff']: area_polys = [] for a in self.area: rings = [LinearRing(p) for p in a['polygons']] innerrings = [LinearRing(p) for p in a['innerrings']] polygons = [] for r in rings: inners = [] for ir in innerrings: if r.contains(ir): inners.append(ir) polygons.append(Poly(r, inners)) area_polys.append(MultiPolygon(polygons)) points = [ Point(p) for p in zip(self.latitude.ravel(), self.longitude.ravel()) ] indicies = [] for a in area_polys: indicies.append( np.where( list(map(lambda p, poly=a: poly.contains(p), points)))[0]) indicies = np.unique(np.array(indicies).ravel()) newmask = np.ones(self.data.shape, dtype=bool) newmask[np.unravel_index(indicies, newmask.shape)] = False self.data.mask |= newmask self.depth_value_map = depth_value_map
def load_data(self): if self.projection == 'EPSG:32661': blat = min(self.bounds[0], self.bounds[2]) blat = 5 * np.floor(blat / 5) self.basemap = basemap.load_map('npstere', (blat, 0), None, None) elif self.projection == 'EPSG:3031': blat = max(self.bounds[0], self.bounds[2]) blat = 5 * np.ceil(blat / 5) self.basemap = basemap.load_map('spstere', (blat, 180), None, None) else: distance = VincentyDistance() height = distance.measure( (self.bounds[0], self.centroid[1]), (self.bounds[2], self.centroid[1]) ) * 1000 * 1.25 width = distance.measure( (self.centroid[0], self.bounds[1]), (self.centroid[0], self.bounds[3]) ) * 1000 * 1.25 self.basemap = basemap.load_map( 'lcc', self.centroid, height, width ) if self.basemap.aspect < 1: gridx = 500 gridy = int(500 * self.basemap.aspect) else: gridy = 500 gridx = int(500 / self.basemap.aspect) self.longitude, self.latitude = self.basemap.makegrid(gridx, gridy) with open_dataset(get_dataset_url(self.dataset_name)) as dataset: if self.time < 0: self.time += len(dataset.timestamps) self.time = np.clip(self.time, 0, len(dataset.timestamps) - 1) self.variable_unit = self.get_variable_units( dataset, self.variables )[0] self.variable_name = self.get_variable_names( dataset, self.variables )[0] scale_factor = self.get_variable_scale_factors( dataset, self.variables )[0] if self.cmap is None: if len(self.variables) == 1: self.cmap = colormap.find_colormap(self.variable_name) else: self.cmap = colormap.colormaps.get('speed') if len(self.variables) == 2: self.variable_name = self.vector_name(self.variable_name) if self.depth == 'bottom': depth_value = 'Bottom' else: self.depth = np.clip( int(self.depth), 0, len(dataset.depths) - 1) depth_value = dataset.depths[self.depth] data = [] allvars = [] for v in self.variables: var = dataset.variables[v] allvars.append(v) if self.filetype in ['csv', 'odv', 'txt']: d, depth_value = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v, return_depth=True ) else: d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, v ) d = np.multiply(d, scale_factor) self.variable_unit, d = self.kelvin_to_celsius( self.variable_unit, d) data.append(d) if self.filetype not in ['csv', 'odv', 'txt']: if len(var.dimensions) == 3: self.depth_label = "" elif self.depth == 'bottom': self.depth_label = " at Bottom" else: self.depth_label = " at " + \ str(int(np.round(depth_value))) + " m" if len(data) == 2: data[0] = np.sqrt(data[0] ** 2 + data[1] ** 2) self.data = data[0] quiver_data = [] if self.quiver is not None and \ self.quiver['variable'] != '' and \ self.quiver['variable'] != 'none': for v in self.quiver['variable'].split(','): allvars.append(v) var = dataset.variables[v] quiver_unit = get_variable_unit(self.dataset_name, var) quiver_name = get_variable_name(self.dataset_name, var) quiver_lon, quiver_lat = self.basemap.makegrid(50, 50) d = dataset.get_area( np.array([quiver_lat, quiver_lon]), self.depth, self.time, v ) quiver_data.append(d) self.quiver_name = self.vector_name(quiver_name) self.quiver_longitude = quiver_lon self.quiver_latitude = quiver_lat self.quiver_unit = quiver_unit self.quiver_data = quiver_data if all(map(lambda v: len(dataset.variables[v].dimensions) == 3, allvars)): self.depth = 0 contour_data = [] if self.contour is not None and \ self.contour['variable'] != '' and \ self.contour['variable'] != 'none': d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.time, self.contour['variable'] ) contour_unit = get_variable_unit( self.dataset_name, dataset.variables[self.contour['variable']]) contour_name = get_variable_name( self.dataset_name, dataset.variables[self.contour['variable']]) contour_factor = get_variable_scale_factor( self.dataset_name, dataset.variables[self.contour['variable']]) contour_unit, d = self.kelvin_to_celsius(contour_unit, d) d = np.multiply(d, contour_factor) contour_data.append(d) self.contour_unit = contour_unit self.contour_name = contour_name self.contour_data = contour_data self.timestamp = dataset.timestamps[self.time] if self.variables != self.variables_anom: self.variable_name += " Anomaly" with open_dataset( get_dataset_climatology(self.dataset_name) ) as dataset: data = [] for v in self.variables: var = dataset.variables[v] d = dataset.get_area( np.array([self.latitude, self.longitude]), self.depth, self.timestamp.month - 1, v ) data.append(d) if len(data) == 2: data = np.sqrt(data[0] ** 2 + data[1] ** 2) else: data = data[0] u, data = self.kelvin_to_celsius( dataset.variables[self.variables[0]].unit, data) self.data -= data # Load bathymetry data self.bathymetry = overlays.bathymetry( self.basemap, self.latitude, self.longitude, blur=2 ) if self.depth != 'bottom' and self.depth != 0: if len(quiver_data) > 0: quiver_bathymetry = overlays.bathymetry( self.basemap, quiver_lat, quiver_lon) self.data[np.where(self.bathymetry < depth_value)] = np.ma.masked for d in self.quiver_data: d[np.where(quiver_bathymetry < depth_value)] = np.ma.masked for d in self.contour_data: d[np.where(self.bathymetry < depth_value)] = np.ma.masked else: mask = maskoceans(self.longitude, self.latitude, self.data).mask self.data[~mask] = np.ma.masked for d in self.quiver_data: mask = maskoceans( self.quiver_longitude, self.quiver_latitude, d).mask d[~mask] = np.ma.masked for d in contour_data: mask = maskoceans(self.longitude, self.latitude, d).mask d[~mask] = np.ma.masked if self.area and self.filetype in ['csv', 'odv', 'txt', 'geotiff']: area_polys = [] for a in self.area: rings = [LinearRing(p) for p in a['polygons']] innerrings = [LinearRing(p) for p in a['innerrings']] polygons = [] for r in rings: inners = [] for ir in innerrings: if r.contains(ir): inners.append(ir) polygons.append(Poly(r, inners)) area_polys.append(MultiPolygon(polygons)) points = [Point(p) for p in zip(self.latitude.ravel(), self.longitude.ravel())] indicies = [] for a in area_polys: indicies.append(np.where( map( lambda p, poly=a: poly.contains(p), points ) )[0]) indicies = np.unique(np.array(indicies).ravel()) newmask = np.ones(self.data.shape, dtype=bool) newmask[np.unravel_index(indicies, newmask.shape)] = False self.data.mask |= newmask self.depth_value = depth_value
def get_center(request): tours = DBSession.query(Tour).all() for tour in tours: distance = 0 #get the total distance of tour for etappe in tour.etappes: for track in etappe.tracks: previous_trkpt = [ track.trackpoints[0].latitude, track.trackpoints[0].longitude ] for trkpt in track.trackpoints: curr_trkpt = [trkpt.latitude, trkpt.longitude] dist = VincentyDistance() distance = distance + dist.measure(previous_trkpt, curr_trkpt) previous_trkpt = curr_trkpt #log.debug('old : {0}, new: {1}'.format(old_distance, distance)) halfway = distance / 2 distance = 0 #find the trackpoint that is closest to distance/2 for etappe in tour.etappes: for track in etappe.tracks: previous_trkpt = [ track.trackpoints[0].latitude, track.trackpoints[0].longitude ] for trkpt in track.trackpoints: curr_trkpt = [trkpt.latitude, trkpt.longitude] dist = VincentyDistance() #log.debug(trkpt.timestamp) if distance <= halfway: distance = distance + dist.measure( previous_trkpt, curr_trkpt) previous_trkpt = curr_trkpt #center=[previous_trkpt[1], previous_trkpt[0]] log.debug(trkpt.latitude) log.debug(previous_trkpt[0]) center = trkpt.id #log.debug('{0}, distance: {1}, halfway {2}'.format(distance > halfway, distance,halfway)) tour.center_id = center #log.debug(center) etappes = DBSession.query(Etappe).all() for etappe in etappes: distance = 0 for track in etappe.tracks: previous_trkpt = [ track.trackpoints[0].latitude, track.trackpoints[0].longitude ] for trkpt in track.trackpoints: curr_trkpt = [trkpt.latitude, trkpt.longitude] dist = VincentyDistance() distance = distance + dist.measure(previous_trkpt, curr_trkpt) previous_trkpt = curr_trkpt #log.debug('old : {0}, new: {1}'.format(old_distance, distance)) halfway = distance / 2 distance = 0 for track in etappe.tracks: previous_trkpt = [ track.trackpoints[0].latitude, track.trackpoints[0].longitude ] for trkpt in track.trackpoints: curr_trkpt = [trkpt.latitude, trkpt.longitude] dist = VincentyDistance() #log.debug(trkpt.timestamp) if distance <= halfway: distance = distance + dist.measure(previous_trkpt, curr_trkpt) previous_trkpt = curr_trkpt #center=[previous_trkpt[1], previous_trkpt[0]] center = trkpt.id log.debug(trkpt.id) #log.debug('{0}, distance: {1}, halfway {2}'.format(distance > halfway, distance,halfway)) etappe.center_id = center tracks = DBSession.query(Track).all() for track in tracks: distance = 0 previous_trkpt = [ track.trackpoints[0].latitude, track.trackpoints[0].longitude ] for trkpt in track.trackpoints: curr_trkpt = [trkpt.latitude, trkpt.longitude] dist = VincentyDistance() distance = distance + dist.measure(previous_trkpt, curr_trkpt) previous_trkpt = curr_trkpt #log.debug('old : {0}, new: {1}'.format(old_distance, distance)) halfway = distance / 2 distance = 0 previous_trkpt = [ track.trackpoints[0].latitude, track.trackpoints[0].longitude ] for trkpt in track.trackpoints: curr_trkpt = [trkpt.latitude, trkpt.longitude] dist = VincentyDistance() #log.debug(trkpt.timestamp) if distance <= halfway: distance = distance + dist.measure(previous_trkpt, curr_trkpt) previous_trkpt = curr_trkpt center_old = [previous_trkpt[1], previous_trkpt[0]] center = trkpt.id track.center_id = center #DBSession.flush() return Response(str(center))
def _transect_plot(self, values, depths, name, vmin, vmax): self.__fill_invalid_shift(values) dist = np.tile(self.transect_data['distance'], (values.shape[0], 1)) c = plt.pcolormesh(dist, depths.transpose(), values, cmap=self.cmap, shading='gouraud', vmin=vmin, vmax=vmax) ax = plt.gca() 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', linthreshy=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_axis_bgcolor('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 = filter(lambda y: y <= self.depth_limit, ticks) 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=0.5) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) bar = plt.colorbar(c, cax=cax) bar.set_label( name + " (" + utils.mathtext(self.transect_data['unit']) + ")") if len(self.points) > 2: station_distances = [] current_dist = 0 d = VincentyDistance() 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(u"$\u25bc$")) cax = make_axes_locatable(ax2).append_axes( "right", size="5%", pad=0.05) bar2 = plt.colorbar(c, cax=cax) bar2.remove() return divider