Esempio n. 1
0
 def get_incremental_distance(self):
     from mapping.geotools.geodetic import spherical_distance
     lons, lats = np.array(self.lons), np.array(self.lats)
     lons1, lats1 = lons[:-1], lats[:-1]
     lons2, lats2 = lons[1:], lats[1:]
     cum_len = spherical_distance(lons1, lats1, lons2, lats2)
     return np.hstack(([0], cum_len))
Esempio n. 2
0
 def get_mean_strike(self):
     import mapping.geotools.geodetic as geodetic
     from mapping.geotools.angle import Azimuth
     lons, lats = np.array(self.lons), np.array(self.lats)
     lons1, lats1 = lons[:-1], lats[:-1]
     lons2, lats2 = lons[1:], lats[1:]
     distances = geodetic.spherical_distance(lons1, lats1, lons2, lats2)
     azimuths = geodetic.spherical_azimuth(lons1, lats1, lons2, lats2)
     azimuths = Azimuth(azimuths, 'deg')
     weights = distances / np.add.reduce(distances)
     mean_strike = azimuths.mean(weights).deg()
     return mean_strike
Esempio n. 3
0
	def set_mask_from_distance_to_data_points(self, data_points, max_dist):
		"""
		Mask grid depending on minimum distance to data points

		:param data_points:
			instance of :class:`MultiPointData` or :class:`UnstructuredGrid`
		:param max_dist:
			float, maximum distance to consider as valid grid cell
			Grid cells with larger minimum distance to data points
			will be masked
			If :param:`data_points` is instance of :class:`MultiPointData`,
			distance is expressed in meters
			If :param:`data_points` is instance of :class:`UnstructuredGrid`,
			distance is expressed in fractional degrees latitude

		:return:
			None, mask will be applied in-place
		"""
		from mapping.geotools.geodetic import spherical_distance
		mask = np.zeros_like(self.values, dtype=np.bool)
		if isinstance(data_points, MultiPointData):
			for r in range(self.nrows):
				for c in range(self.ncols):
					lon, lat = self.lons[r,c], self.lats[r,c]
					distances = spherical_distance(lon, lat, data_points.lons, data_points.lats)
					if np.min(distances) >= max_dist:
						mask[r,c] = True
		elif isinstance(data_points, UnstructuredGridData):
			## max_dist is distance in degrees
			max_lon_dist = max_dist / np.cos(np.radians(max_dist))
			for r in range(self.nrows):
				for c in range(self.ncols):
					lon, lat = self.lons[r,c], self.lats[r,c]
					extent = (lon - max_lon_dist, lon + max_lon_dist,
							lat - max_dist, lat + max_dist)
					close_data_points = data_points.confine_to_extent(extent)
					if len(close_data_points) == 0:
						mask[r,c] = True

		self.apply_mask(mask)
Esempio n. 4
0
	def to_mesh_grid_data(self, num_cells, cell_size=None,
						extent=(None, None, None, None),
						interpolation_method='cubic', max_dist=5.):
		"""
		Convert to meshed grid data

		:param num_cells:
			int or tuple of ints, number of grid cells in lon and lat
			direction
		:param cell_size:
			float or tuple of floats, cell width in lon and lat direction
			If specified, takes precedence over :param:`num_cells`
			(default: None)
		:param extent:
			(lonmin, lonmax, latmin, latmax) tuple of floats
			(default: (None, None, None, None)
		:param interpolation_method:
			str, interpolation method supported by griddata, either
			"linear", "nearestN" (with N number of neighbors to consider),
			"cubic" or "idwP" (with P power to raise distances to)
			(default: "cubic")
		:param max_dist:
			float, maximum interpolation distance (in km)
			Only relevant for "nearestN" and "idwP" methods
			(default: 5.)

		:return:
			instance of :class:`MeshGridData`
		"""
		assert num_cells or cell_size

		lonmin, lonmax, latmin, latmax = extent
		if lonmin is None:
			lonmin = self.lonmin()
		if lonmax is None:
			lonmax = self.lonmax()
		if latmin is None:
			latmin = self.latmin()
		if latmax is None:
			latmax = self.latmax()

		if cell_size:
			if isinstance(cell_size, int):
				cell_size = (cell_size, cell_size)
			num_lons = int(round((lonmax - lonmin) / cell_size[0])) + 1
			num_lats = int(round((latmax - latmin) / cell_size[1])) + 1
		else:
			if isinstance(num_cells, int):
				num_cells = (num_cells, num_cells)
			num_lons, num_lats = num_cells

		lons = np.linspace(lonmin, lonmax, num_lons)
		lats = np.linspace(latmin, latmax, num_lats)
		mesh_lons, mesh_lats = np.meshgrid(lons, lats)

		max_dist *= 1000  ## km --> m

		if (interpolation_method in ('linear', 'cubic') or
			interpolation_method[:7] == 'nearest'):
			from scipy.interpolate import griddata
			from mapping.geotools.coordtrans import lonlat_to_meter
			## Convert geographic to cartesian coordinates
			ref_lat = np.mean([latmin, latmax])
			x, y = lonlat_to_meter(self.lons, self.lats, ref_lat=ref_lat)
			mesh_x, mesh_y = lonlat_to_meter(mesh_lons, mesh_lats, ref_lat=ref_lat)

			if interpolation_method[:7] == 'nearest':
				from scipy.spatial import cKDTree
				tree = cKDTree(zip(x, y))
				num_neighbors = 1
				if len(interpolation_method) > 7:
					num_neighbors = int(interpolation_method[7:])
				d, idxs = tree.query(zip(mesh_x.flatten(), mesh_y.flatten()),
						k=num_neighbors, eps=0, distance_upper_bound=max_dist)
				if num_neighbors == 1:
					## When k == 1, the last dimension of the output is squeezed
					idxs.shape += (1,)
				if max_dist == np.inf:
					mesh_values = self.values[idxs]
				else:
					mesh_values = np.ones_like(idxs) * np.nan
					for i in range(idxs.shape[0]):
						i_idxs = idxs[i]
						## Missing neighbors are indicated with index = len(tree)
						i_idxs = i_idxs[i_idxs < len(self.lons)]
						mesh_values[i,:len(i_idxs)] = self.values[idxs[i,:len(i_idxs)]]
				mesh_values = np.nanmean(mesh_values, axis=-1)
				mesh_values.shape = mesh_lons.shape
			else:
				mesh_values = griddata((x, y), self.values,
							(mesh_x, mesh_y), method=interpolation_method)

		elif interpolation_method[:3] == 'idw':
			from mapping.geotools.geodetic import spherical_distance
			pow = 1
			if len(interpolation_method) > 3:
				pow = int(interpolation_method[3:])
			mesh_values = np.ones_like(mesh_lons) * np.nan
			for i in range(num_lons):
				lon = lons[i]
				for j in range(num_lats):
					lat = lats[j]
					d = spherical_distance(lon, lat, self.lons, self.lats)
					idxs = (d <= max_dist)
					weights = 1. / d[idxs]
					if pow != 1:
						weights **= pow
					if np.sum(weights):
						mesh_values[j, i] = np.average(self.values[idxs], weights=weights)

		return MeshGridData(mesh_lons, mesh_lats, mesh_values)
Esempio n. 5
0
 def get_nearest_index_to_point(self, pt):
     import mapping.geotools.geodetic as geodetic
     distances = geodetic.spherical_distance(pt.lon, pt.lat, self.lons,
                                             self.lats)
     return np.argmin(distances)