def _mask_with_shp(cube, shapefilename, region_indices=None): """ Apply a Natural Earth land/sea mask. Apply a pre-made land or sea mask that is extracted form a Natural Earth shapefile (proprietary file format). The masking process is performed by checking if any given (x, y) point from the data cube lies within the desired geometries (eg land, sea) stored in the shapefile (this is done via shapefle vectorization and is fast). region_indices is a list of indices that the user will want to index the regions on (select a region by its index as it is listed in the shapefile). """ # Create the region regions = _get_geometries_from_shp(shapefilename) if region_indices: regions = [regions[idx] for idx in region_indices] # Create a mask for the data mask = np.zeros(cube.shape, dtype=bool) # Create a set of x,y points from the cube # 1D regular grids if cube.coord('longitude').points.ndim < 2: x_p, y_p = np.meshgrid( cube.coord(axis='X').points, cube.coord(axis='Y').points) # 2D irregular grids; spit an error for now else: msg = ("No fx-files found (sftlf or sftof)!" "2D grids are suboptimally masked with " "Natural Earth masks. Exiting.") raise ValueError(msg) # Wrap around longitude coordinate to match data x_p_180 = np.where(x_p >= 180., x_p - 360., x_p) # the NE mask has no points at x = -180 and y = +/-90 # so we will fool it and apply the mask at (-179, -89, 89) instead x_p_180 = np.where(x_p_180 == -180., x_p_180 + 1., x_p_180) y_p_0 = np.where(y_p == -90., y_p + 1., y_p) y_p_90 = np.where(y_p_0 == 90., y_p_0 - 1., y_p_0) for region in regions: # Build mask with vectorization if cube.ndim == 2: mask = shp_vect.contains(region, x_p_180, y_p_90) elif cube.ndim == 3: mask[:] = shp_vect.contains(region, x_p_180, y_p_90) elif cube.ndim == 4: mask[:, :] = shp_vect.contains(region, x_p_180, y_p_90) # Then apply the mask if isinstance(cube.data, np.ma.MaskedArray): cube.data.mask |= mask else: cube.data = np.ma.masked_array(cube.data, mask) return cube
def center_inside_cpu(self, gt_bboxes, anchors, anchor_in_gt=True, gt_in_anchor=True): gt_centers = torch.round(gt_bboxes[:, -2:]) gt_bboxes = gt_bboxes[:, :-2] # remove gt_centers intersects = gt_bboxes.new_zeros((gt_bboxes.size(0), anchors.size(0))) if gt_in_anchor: # compute gt center in anchor left_top = torch.sum(gt_centers[:, None] >= anchors[:, :2], dim=-1) right_bottom = torch.sum(gt_centers[:, None] <= anchors[:, -2:], dim=-1) intersects += ((left_top + right_bottom) == 4).float() # anchor center in gt if anchor_in_gt: intersects = intersects.cpu() gt_bboxes = gt_bboxes.cpu() anchor_center_x = torch.mean(anchors[:, 0::2], dim=1).cpu() anchor_center_y = torch.mean(anchors[:, 1::2], dim=1).cpu() for k in range(len(gt_bboxes)): gt_bbox = Polygon(gt_bboxes[k, :].reshape((-1, 2))) inside_gt = sv.contains(gt_bbox, x=anchor_center_x, y=anchor_center_y) intersects[k, :] += torch.FloatTensor(inside_gt) # 0 or 1 return intersects.cuda()
def verts_to_mask(verts): """ Based on the given vertices (and using the CCD size from semd.SEDM_CCD_SIZE) this create a weighted mask: - pixels outise of the vertices have 0 - pixels fully included within the vertices have 1 - pixels on the edge only have a fraction of 1 = Based on Shapely = Returns ------- [NxM] array (size of semd.SEDM_CCD_SIZE) """ from shapely.vectorized import contains verts = verts + np.asarray([0.5, 0.5]) xlim, ylim = np.asarray(np.round(np.percentile(verts, [0, 100], axis=0)), dtype="int").T + np.asarray([-1, 1]) polytrace = geometry.Polygon(verts) sqgrid = np.asarray( [[_BASEPIX + np.asarray([x_, y_]) for y_ in np.arange(*ylim)] for x_ in np.arange(*xlim)]).reshape( (ylim[1] - ylim[0]) * (xlim[1] - xlim[0]), *np.shape(_BASEPIX)) maskins = vectorized.contains(polytrace, *sqgrid.T).T maskfull = np.zeros(SEDM_CCD_SIZE) maskfull[xlim[0]:xlim[1],ylim[0]:ylim[1]] = \ (np.asarray([ 0 if not np.any(maskin_) else 1 if np.all(maskin_) else polytrace.intersection(geometry.Polygon(sq_)).area for maskin_,sq_ in zip(maskins,sqgrid)]).reshape(xlim[1]-xlim[0],ylim[1]-ylim[0])) return maskfull.T
def _get_ne_land_mask_cube(n_lats=1000, n_lons=2000): """Get Natural Earth land mask.""" ne_dir = os.path.join( os.path.dirname(os.path.realpath(esmvalcore.preprocessor.__file__)), 'ne_masks', ) ne_file = os.path.join(ne_dir, 'ne_10m_land.shp') reader = shapereader.Reader(ne_file) geometries = list(reader.geometries()) # Setup grid lat_coord = iris.coords.DimCoord( np.linspace(-90.0, 90.0, n_lats), var_name='lat', standard_name='latitude', long_name='latitude', units='degrees') lon_coord = iris.coords.DimCoord( np.linspace(-180.0, 180.0, n_lons), var_name='lon', standard_name='longitude', long_name='longitude', units='degrees') (lats, lons) = np.meshgrid(lat_coord.points, lon_coord.points) # Setup mask (1: land, 0: sea) mask = np.full(lats.shape, False, dtype=bool) for geometry in geometries: mask |= shp_vect.contains(geometry, lons, lats) land_mask = np.swapaxes(np.where(mask, 1, 0), 0, 1) # Setup cube cube = iris.cube.Cube(land_mask, var_name='land_mask', long_name='Land mask (1: land, 0: sea)', units='no_unit', dim_coords_and_dims=[(lat_coord, 0), (lon_coord, 1)]) return cube
def set_region_id(self): """ Set region_id attribute for every pixel or point """ lon_ne, lat_ne = self._ne_crs_xy() LOGGER.debug('Setting region_id %s points.', str(self.lat.size)) countries = get_country_geometries(extent=(lon_ne.min(), lon_ne.max(), lat_ne.min(), lat_ne.max())) self.region_id = np.zeros(lon_ne.size, dtype=int) for geom in zip(countries.geometry, countries.ISO_N3): select = contains(geom[0], lon_ne, lat_ne) self.region_id[select] = int(geom[1])
def victoria_check(coords_inp): x, y = coords_inp.split(' ') x = float(x) y = float(y) c_1 = Point(x, y) if sv.contains(vic_state_b_1.geometry[0], c_1.x, c_1.y).flat[0]: message = 'Yes' else: message = 'No' return message
def sample(polygon, count, factor=1.5, max_iter=10): """ Use rejection sampling to generate random points inside a polygon. Parameters ----------- polygon : shapely.geometry.Polygon Polygon that will contain points count : int Number of points to return factor : float How many points to test per loop max_iter : int Maximum number of intersection checks is: > count * factor * max_iter Returns ----------- hit : (n, 2) float Random points inside polygon where n <= count """ # do batch point-in-polygon queries from shapely import vectorized # get size of bounding box bounds = np.reshape(polygon.bounds, (2, 2)) extents = bounds.ptp(axis=0) hit = [] hit_count = 0 per_loop = int(count * factor) for i in range(max_iter): # generate points inside polygons AABB points = np.random.random((per_loop, 2)) points = (points * extents) + bounds[0] # do the point in polygon test and append resulting hits mask = vectorized.contains(polygon, *points.T) hit.append(points[mask]) # keep track of how many points we've collected hit_count += len(hit[-1]) # if we have enough points exit the loop if hit_count > count: break # stack the hits into an (n,2) array and truncate hit = np.vstack(hit)[:count] return hit
def covers_positions(self, x, y, z=0): """ Check which points are within boundary of mesh. """ assert self.boundary is not None, "Boundary of mesh has not been prepared by reader" # TODO: Check z coordinates logger.warning("z-coordinates are not bounds-checked") from shapely.vectorized import contains return contains(self.boundary, x, y)
def _no_speed_reward(self): x, y, u, v, t_x, t_y = self.get_state() dist = np.float64(10000000) dist = min(dist, np.linalg.norm([x - t_x, y - t_y])) vel = np.linalg.norm(np.array([u, v])) # Reward in base of the distance # if self.total_timestep % 20 == 0: # print('dist: ', np.array([dist]), ' vel: ', np.array([vel])) reward = 0 if dist < self.threshold_dist: reward = + POSITIVE_REWARD self.done = np.array([True]) # print('Target Found') self.n_done += 1 self.episode_success = True else: d2 = np.square(dist) reward = (- 0.01 * (d2 + 1) - 80) * self.dense_reward # Max Timestep if self.total_timestep >= self.max_timestep: reward -= TIME_NEGATIVE_REWARD self.oo_time += 1 self.done = np.array([True]) # print('Timeout') # Out of bounds check if x < self.map_min_x or y < self.map_min_y or x > self.map_max_x or y > self.map_max_y: reward += -OUT_OF_BOUNDS_REWARD self.oob += 1 self.done = np.array([True]) # print('Out of Bounds') # COLLISIONS check for obstacle in IT.compress(self.prep_obstacles, self.culled): if sv.contains(obstacle, x=x, y=y): reward += -OUT_OF_BOUNDS_REWARD # print('Crash') self.crashes += 1 self.done = np.array([True]) break reward = reward / REWARD_NORMALIZATION_FACTOR # print(reward) # Printing functions self.trajectory['vel'].append(vel) self.trajectory['dist'].append(dist) self.trajectory['reward'].append(reward) return reward
def medial_axis(polygon, resolution=.01, clip=None): """ Given a shapely polygon, find the approximate medial axis using a voronoi diagram of evenly spaced points on the boundary of the polygon. Parameters ---------- polygon : shapely.geometry.Polygon The source geometry resolution : float Distance between each sample on the polygon boundary clip : None, or (2,) float Clip the lower and upper bound of sample count to: [minimum number of samples, maximum number of samples] specifying a very fine resolution can cause the sample count to explode, so clip specifies a minimum and maximum number of samples to use per boundary region. To not clip, this can be specified as: [0, np.inf] Returns ---------- medial : Path2D object """ from scipy.spatial import Voronoi from .path import Path2D from .io.misc import edges_to_path # get evenly spaced points on the polygons boundaries samples = resample_boundaries(polygon=polygon, resolution=resolution, clip=clip) # stack the boundary into a (m,2) float array samples = stack_boundaries(samples) # create the voronoi diagram on 2D points voronoi = Voronoi(samples) # which voronoi vertices are contained inside the polygon contains = vectorized.contains(polygon, *voronoi.vertices.T) # ridge vertices of -1 are outside, make sure they are False contains = np.append(contains, False) # make sure ridge vertices is numpy array ridge = np.asanyarray(voronoi.ridge_vertices, dtype=np.int64) # only take ridges where every vertex is contained edges = ridge[contains[ridge].all(axis=1)] # line objects from edges medial = Path2D(**edges_to_path( edges=edges, vertices=voronoi.vertices)) return medial
def scipy_point_to_vertex_dist(vehicle_array, polygon_geom): """ Put a negative sign on the point contained by polygon https://github.com/geopandas/geopandas/issues/430#issuecomment-291003750 """ contain_array = sv.contains(polygon_geom, vehicle_array[:, 0], vehicle_array[:, 1]) ### vectorized contain contain_array = np.where(contain_array, -1, 1) ### translate contain to -1, not contain to 1 distance_array = scipy_point_to_vertex_distance_positive( vehicle_array, np.array(polygon_geom.exterior.coords)) distance_array = distance_array * contain_array return distance_array
def medial_axis(polygon, resolution=None, clip=None): """ Given a shapely polygon, find the approximate medial axis using a voronoi diagram of evenly spaced points on the boundary of the polygon. Parameters ---------- polygon : shapely.geometry.Polygon The source geometry resolution : float Distance between each sample on the polygon boundary clip : None, or (2,) int Clip sample count to min of clip[0] and max of clip[1] Returns ---------- edges : (n, 2) int Vertex indices representing line segments on the polygon's medial axis vertices : (m, 2) float Vertex positions in space """ from scipy.spatial import Voronoi from shapely import vectorized if resolution is None: resolution = np.reshape( polygon.bounds, (2, 2)).ptp(axis=0).max() / 100 # get evenly spaced points on the polygons boundaries samples = resample_boundaries(polygon=polygon, resolution=resolution, clip=clip) # stack the boundary into a (m,2) float array samples = stack_boundaries(samples) # create the voronoi diagram on 2D points voronoi = Voronoi(samples) # which voronoi vertices are contained inside the polygon contains = vectorized.contains(polygon, *voronoi.vertices.T) # ridge vertices of -1 are outside, make sure they are False contains = np.append(contains, False) # make sure ridge vertices is numpy array ridge = np.asanyarray(voronoi.ridge_vertices, dtype=np.int64) # only take ridges where every vertex is contained edges = ridge[contains[ridge].all(axis=1)] return edges, voronoi.vertices
def _compute_containment(point_metadata, point_id_field, polygon_metadata, polygon_metadata_field): from shapely.vectorized import contains points, lats, lons = zip(*[(point, point["latitude"], point["longitude"]) for point in point_metadata.values()]) for i, polygon in enumerate(polygon_metadata.values()): containment = contains(polygon["polygon"], lons, lats) for point, c in zip(points, containment): if c: point[polygon_metadata_field] = polygon[polygon_metadata_field] # fill in with None for point in point_metadata.values(): point[polygon_metadata_field] = point.get(polygon_metadata_field, None)
def grid_collisions_perception(self, x, y): point = np.array([x, y]).reshape((-1, 2)) PER = self.perception_matrix + point p_vector = np.zeros(PER.size // 2) # get only close objects to check the perception # culled = [as_point.distance(obstacle) < 1.5*PERCEPTION_DISTANCE for obstacle in self.obstacles] if self.obstacles: self.culled = fast_distance(point, self.obstacle_centers) < 3 * PERCEPTION_DISTANCE for obstacle in IT.compress(self.prep_obstacles, self.culled): # Vectorized p_i = sv.contains(obstacle, x=PER[:, 0], y=PER[:, 1]) p_vector = np.logical_or(p_vector, p_i) return p_vector
def assertContainsResults(self, geom, x, y): result = contains(geom, x, y) x = np.asanyarray(x) y = np.asanyarray(y) self.assertIsInstance(result, np.ndarray) self.assertEqual(result.dtype, np.bool) result_flat = result.flat x_flat, y_flat = x.flat, y.flat # Do the equivalent operation, only slowly, comparing the result # as we go. for idx in range(x.size): self.assertEqual(result_flat[idx], geom.contains(Point(x_flat[idx], y_flat[idx]))) return result
def bushfire_question(coords_inp): # if victoria_check(coords_inp)=='No': # dict_message = {} # list_message = [] # dict_message['message_key'] = '' # list_message.append(dict_message) # return dumps(list_message) x, y = coords_inp.split(' ') x = float(x) y = float(y) c_1 = Point(x, y) if sv.contains(inter_bush_neigh_dissolve_geom.geometry[0], c_1.x, c_1.y).flat[0]: message = 'Yes' else: message = 'No' return message
def assertContainsResults(self, geom, x, y): result = contains(geom, x, y) x = np.asanyarray(x) y = np.asanyarray(y) self.assertIsInstance(result, np.ndarray) self.assertEqual(result.dtype, np.bool) result_flat = result.flat x_flat, y_flat = x.flat, y.flat # Do the equivalent operation, only slowly, comparing the result # as we go. for idx in range(x.size): self.assertEqual(result_flat[idx], geom.contains(Point(x_flat[idx], y_flat[idx]))) return result
def _mask_edgepoints_shapely(mask, lon, lat, polygons, numbers, fill=np.NaN): import shapely.vectorized as shp_vect # not sure if this is really necessary lon, lat, numbers = _parse_input(lon, lat, polygons, fill, numbers) LON, LAT, out, shape = _get_LON_LAT_out_shape(lon, lat, fill) mask = mask.flatten() mask_unassigned = np.isnan(mask) # find points at -180°E/0°E if lon.min() < 0: LON_180W_or_0E = np.isclose(LON, -180.0) & mask_unassigned else: LON_180W_or_0E = np.isclose(LON, 0.0) & mask_unassigned # find points at -90°N LAT_90S = np.isclose(LAT, -90) & mask_unassigned borderpoints = LON_180W_or_0E | LAT_90S # return if there are no unassigned gridpoints at -180°E/0°E and -90°N if not borderpoints.any(): return mask.reshape(shape) # add a tiny offset to get a consistent edge behaviour LON = LON[borderpoints] - 1 * 10**-8 LAT = LAT[borderpoints] - 1 * 10**-10 # wrap points LON_180W_or_0E: -180°E -> 180°E and 0°E -> 360°E LON[LON_180W_or_0E[borderpoints]] += 360 # shift points at -90°N to -89.99...°N LAT[LAT_90S[borderpoints]] = -90 + 1 * 10**-10 # "mask[borderpoints][sel] = number" does not work, need to use np.where idx = np.where(borderpoints)[0] for i, polygon in enumerate(polygons): sel = shp_vect.contains(polygon, LON, LAT) mask[idx[sel]] = numbers[i] return mask.reshape(shape)
def _mask_shapely(lon, lat, polygons, numbers, fill=np.NaN): """ create a mask using shapely.vectorized.contains """ import shapely.vectorized as shp_vect lon, lat, numbers = _parse_input(lon, lat, polygons, fill, numbers) LON, LAT, out, shape = _get_LON_LAT_out_shape(lon, lat, fill) # add a tiny offset to get a consistent edge behaviour LON = LON - 1 * 10**-8 LAT = LAT - 1 * 10**-10 for i, polygon in enumerate(polygons): sel = shp_vect.contains(polygon, LON, LAT) out[sel] = numbers[i] return out.reshape(shape)
def get_pixels_in(self, polygon, invert=False): """ checks if the centroid of the pixel is in or out the given shapely polygon. Parameters ---------- polygon: [shapely.geometry] reference polygon invert: [bool] -optional- Get the pixel inside the polygon [invert=False] or outsite [invert=True] Returns ------- list of pixels and boolean mask """ from shapely import vectorized flagin = vectorized.contains(polygon, *self.pixels.T) if invert: flagin = ~flagin return self.pixels[flagin], flagin
def qidmask(poly, res, buff): """ Generate raster mask from rectangular lon, lat grid resolution and Shapely Polygon or MultiPolygon object. """ # Generate global lon and lat arrays, and meshgrid for vectorisation lons = np.arange(-180 + res / 2, 180 + res / 2, res) lats = np.arange(-90 + res / 2, 90 + res / 2, res) llons, llats = np.meshgrid(lons, lats) # Generate the mask, transpose, convert to DataArray and return it mask = shpv.contains(poly.buffer(buff), llons, llats) return xr.DataArray(mask, dims=['lat', 'lon'], coords={ 'lon': lons, 'lat': lats }, name='mask')
def overlap_to_verts(grid_1, vert_, buffer=2): """ """ poly_ = geometry.Polygon(vert_) lgrid, sgrid, _should_be_2 = np.shape(grid_1) weight_map = np.zeros(lgrid) # Are the grid corners inside the buffered poly corners_in = vectorized.contains(poly_.buffer(buffer), *grid_1.reshape(lgrid * sgrid, 2).T).reshape( lgrid, sgrid) corner_sum = np.sum(corners_in, axis=1) for i in np.argwhere(np.asarray(corner_sum, dtype="bool")).flatten(): # 300microsec poly_vert_ = geometry.Polygon(verts_flat[i]) if polygon.contains(poly_vert_): weight_map[i] = 1 else: weight_map[i] = poly_.intersection(poly_vert_).area return weight_map
def medial_axis(polygon, resolution=None, clip=None): """ Given a shapely polygon, find the approximate medial axis using a voronoi diagram of evenly spaced points on the boundary of the polygon. Parameters ---------- polygon : shapely.geometry.Polygon The source geometry resolution : float Distance between each sample on the polygon boundary clip : None, or (2,) int Clip sample count to min of clip[0] and max of clip[1] Returns ---------- edges : (n, 2) int Vertex indices representing line segments on the polygon's medial axis vertices : (m, 2) float Vertex positions in space """ # a circle will have a single point medial axis if len(polygon.interiors) == 0: # what is the approximate scale of the polygon scale = np.reshape(polygon.bounds, (2, 2)).ptp(axis=0).max() # a (center, radius, error) tuple fit = fit_circle_check(polygon.exterior.coords, scale=scale) # is this polygon in fact a circle if fit is not None: # return an edge that has the center as the midpoint epsilon = np.clip(fit['radius'] / 500, 1e-5, np.inf) vertices = np.array( [fit['center'] + [0, epsilon], fit['center'] - [0, epsilon]], dtype=np.float64) # return a single edge to avoid consumers needing to special case edges = np.array([[0, 1]], dtype=np.int64) return edges, vertices from scipy.spatial import Voronoi from shapely import vectorized if resolution is None: resolution = np.reshape(polygon.bounds, (2, 2)).ptp(axis=0).max() / 100 # get evenly spaced points on the polygons boundaries samples = resample_boundaries(polygon=polygon, resolution=resolution, clip=clip) # stack the boundary into a (m,2) float array samples = stack_boundaries(samples) # create the voronoi diagram on 2D points voronoi = Voronoi(samples) # which voronoi vertices are contained inside the polygon contains = vectorized.contains(polygon, *voronoi.vertices.T) # ridge vertices of -1 are outside, make sure they are False contains = np.append(contains, False) # make sure ridge vertices is numpy array ridge = np.asanyarray(voronoi.ridge_vertices, dtype=np.int64) # only take ridges where every vertex is contained edges = ridge[contains[ridge].all(axis=1)] # now we need to remove uncontained vertices contained = np.unique(edges) mask = np.zeros(len(voronoi.vertices), dtype=np.int64) mask[contained] = np.arange(len(contained)) # mask voronoi vertices vertices = voronoi.vertices[contained] # re-index edges edges_final = mask[edges] if tol.strict: # make sure we didn't screw up indexes assert (vertices[edges_final] - voronoi.vertices[edges]).ptp() < 1e-5 return edges_final, vertices
import numpy as np import pandas as pd from shapely import vectorized, geometry import geopandas as gpd import os bbox = (240.9375, 33.4375, 243.1875, 34.9375) step = 0.125 lats = (np.array(np.linspace(bbox[1], bbox[3], int(1 + (bbox[3] - bbox[1])/step)), dtype=np.float32)) lons = (np.array(np.linspace(bbox[0], bbox[2], int(1 + (bbox[2] - bbox[0])/step)), dtype=np.float32) - 360) homedir = os.path.expanduser('~') climzone = gpd.read_file('%s/Dropbox/CA_Building_Standards_Climate_Zones/CA_Building_Standards_Climate_Zones.shp' % homedir).to_crs(epsg=4326) latlon = np.vstack(np.dstack(np.meshgrid(lons, lats))) result = climzone['geometry'].apply(lambda x: np.where(vectorized.contains(x, latlon[:,0], latlon[:,1]))[0]) result = result[result.apply(len) > 0] # If you want the integer index -- as it would appear in np.meshgrid(lons, lats) zone_to_idx = pd.Series(np.concatenate(result.values), index=np.repeat(result.index.values, result.apply(len))) # If you want the x and y indices: idx_xy = zone_to_idx.apply(lambda x: np.unravel_index(x, (lons.size, lats.size))).apply(pd.Series).rename(columns={0: 'x', 1: 'y'})
def get_cell_masking(self, x, y): """ Returns a boolean masking for each polygon on weither or not it contains the given x, y points """ return np.asarray([vectorized.contains(s_, x, y) for s_ in self.grid])
# grabbing state polygon state = states_df.loc[states_df.iso_3166_2 == STATE] poly, points = generate_grid_in_polygon(SPACING_deg, state) # generating lon,lat meshgrid # lon/lat points corresponding to STATE lonlats = np.array(getLatLons( points[0], points[1])) # convert meshgrid to a list of lon/lat points. # The points may not all be within STATE due to the linearity of numpy meshgrid. # We now can trim off the points that do not fall withing the state boundary print('Checking to make sure points are withing the state boundary...') ind2keep = contains(poly, lonlats[:, 0], lonlats[:, 1]) lonlats = lonlats[ ind2keep == 1] ## Note: if ind2keep is a BOOLEAN array then " == 1" is optional # This is an array of shapely points points = np.array([Point(x, y) for x, y in lonlats], dtype=object) df, lr_df = RiskClassification(lonlats, data, alt_ft_agl=ALTITUDE, points=points) # saving results df.to_file('output/states/{}/alt_{}/spacing_{}/RiskClass.shp'.format(
def create_mask_vectorize( *, x_dim: xarray.DataArray = None, y_dim: xarray.DataArray = None, poly: gpd.GeoDataFrame = None, wrap_lons: bool = False, check_overlap: bool = False, ): """Create a mask with values corresponding to the features in a GeoDataFrame using vectorize methods. The returned mask's points have the value of the first geometry of `poly` they fall in. Parameters ---------- x_dim : xarray.DataArray X or longitudinal dimension of xarray object. y_dim : xarray.DataArray Y or latitudinal dimension of xarray object. poly : gpd.GeoDataFrame GeoDataFrame used to create the xarray.DataArray mask. wrap_lons : bool Shift vector longitudes by -180,180 degrees to 0,360 degrees; Default = False check_overlap: bool Perform a check to verify if shapes contain overlapping geometries. Returns ------- xarray.DataArray Examples -------- >>> import geopandas as gpd # doctest: +SKIP >>> import xarray as xr # doctest: +SKIP >>> from xclim.subset import create_mask_vectorize # doctest: +SKIP >>> ds = xr.open_dataset(path_to_tasmin_file) # doctest: +SKIP >>> polys = gpd.read_file(path_to_multi_shape_file) # doctest: +SKIP ... # Get a mask from all polygons in the shape file >>> mask = create_mask_vectorize(x_dim=ds.lon, y_dim=ds.lat, poly=polys) # doctest: +SKIP >>> ds = ds.assign_coords(regions=mask) # doctest: +SKIP ... # Operations can be applied to each regions with `groupby`. Ex: >>> ds = ds.groupby('regions').mean() # doctest: +SKIP ... # Extra step to retrieve the names of those polygons stored in another column (here "id") >>> region_names = xr.DataArray(polys.id, dims=('regions',)) # doctest: +SKIP >>> ds = ds.assign_coords(regions_names=region_names) # doctest: +SKIP """ if check_overlap: _check_has_overlaps(polygons=poly) if wrap_lons: warnings.warn("Wrapping longitudes at 180 degrees.") if len(x_dim.shape) == 1 & len(y_dim.shape) == 1: # create a 2d grid of lon, lat values lon1, lat1 = np.meshgrid(np.asarray(x_dim.values), np.asarray(y_dim.values), indexing="ij") dims_out = x_dim.dims + y_dim.dims coords_out = dict() coords_out[dims_out[0]] = x_dim.values coords_out[dims_out[1]] = y_dim.values else: lon1 = x_dim.values lat1 = y_dim.values dims_out = x_dim.dims coords_out = x_dim.coords # try vectorize mask = np.zeros(lat1.shape) + np.nan for pp in poly.index: for vv in poly[poly.index == pp].geometry.values: b1 = vectorized.contains(vv, lon1.flatten(), lat1.flatten()).reshape(lat1.shape) mask[b1] = pp mask = xarray.DataArray(mask, dims=dims_out, coords=coords_out) return mask
def run(self): ''' run function assigns vehicles to their regions and execute the main algorithm ''' max_queue = [] max_queue_time = 0.0 pbar = tqdm(self.vehicles_list.values(), bar_format="{l_bar}%s{bar}%s{r_bar}" % (Fore.GREEN, Fore.RESET)) pbar.set_description("Assigning vehicles to regions") # Assigning vehicles to their regions at each timestamp, the vehicles that don't belong to the specified areas are excluded for vehicle in pbar: for area in self.areas: for i, region in enumerate(area.regions): lista = np.where( contains(region.polygon, vehicle.utm_path.transpose()[0], vehicle.utm_path.transpose()[1]) == True)[0] idx = lista + int(round(vehicle.min_time / self.time_step)) for i in idx: if not region.vehicles.get(i): region.vehicles[i] = [] region.vehicles[i].append(vehicle.track_id) end_line_tolerance_squared = self.end_line_tolerance**2 max_idx = int(round(self.max_time / self.time_step)) + 1 pbar = tqdm(range(0, max_idx), bar_format="{l_bar}%s{bar}%s{r_bar}" % (Fore.BLACK, Fore.RESET)) pbar.set_description("Running") # Looping over time from zero to the maximum timestamp for t_idx in pbar: for area in self.areas: for i, region in enumerate(area.regions): if not region.vehicles.get(t_idx): continue # Sorting vehicles in each region in each area by distance to the stop line dist_list = [None] * len(region.vehicles[t_idx]) for v_idx, id in enumerate(region.vehicles[t_idx]): current_vehicle = self.vehicles_list[id] idx = t_idx - int( round(current_vehicle.min_time / self.time_step)) dist = (region.end_point[0] - current_vehicle.utm_path[idx, 0])**2 + ( region.end_point[1] - current_vehicle.utm_path[idx, 1])**2 dist_list[v_idx] = [dist, id] dist_list.sort() region.vehicles[t_idx] = list(zip(*dist_list))[1] queue_member_id = 0 # Looping over vehicles in each region, from the stop line to the start line for id in region.vehicles[t_idx]: # Fetching the vehicle object by its ID current_vehicle = self.vehicles_list[id] current_vehicle.region = region self.lateral_threshold = ( current_vehicle.vehicle_width / 2.0) idx = t_idx - int( round(current_vehicle.min_time / self.time_step)) # Executing the finite state machine on each vehicle # Not in a queue? if not current_vehicle.queuing_status: # At Rest or Decelerating? if current_vehicle.speed_trajectory[ idx] == 0 or current_vehicle.long_accel[ idx] < 0: preceding_vehicle = self.get_preceding_vehicle( region, current_vehicle, t_idx) # Preceding Vehicle? if preceding_vehicle: # Preceding Vehicle in Queue? if preceding_vehicle.queuing_status: self.add_to_queue( region, current_vehicle, preceding_vehicle.queue_idx) else: # At Rest? if current_vehicle.speed_trajectory[ idx] == 0: # Obtaining distance to stop line d = ((region.end_point[0] - current_vehicle.utm_path[idx, 0]) **2 + (region.end_point[1] - current_vehicle.utm_path[idx, 1]) **2) # At stop Line? if d < end_line_tolerance_squared: # Assign as Queue Head region.queue_list.append( [current_vehicle.track_id]) current_vehicle.queuing_status = 'Head' current_vehicle.queue_region = region current_vehicle.queue_idx = len( region.queue_list) - 1 # In A Queue? else: # Leaving The Region? if (region.vehicles.get(t_idx + 10) and not id in region.vehicles[t_idx + 10]): # Exit Queue self.remove_from_queue(current_vehicle) else: # Obtaining the preceding vehicle preceding_vehicle = self.get_preceding_vehicle( region, current_vehicle, t_idx) # Preceding vehicle exists? if preceding_vehicle: # Preceding vehicle is in queue? if preceding_vehicle.queuing_status: # Preceding vehicle is in the same queue of the current vehicle? if preceding_vehicle.queue_idx == current_vehicle.queue_idx: # Stay current_vehicle.queuing_status = 'Member' else: # Exit Queue self.remove_from_queue( current_vehicle) else: # Current vehicle is at rest? if current_vehicle.speed_trajectory[ idx] == 0: # Assign as Queue Head current_vehicle.queuing_status = 'Head' region.queue_list[ current_vehicle. queue_idx].remove(id) region.queue_list[ current_vehicle. queue_idx].insert(0, id) else: # Exit Queue self.remove_from_queue( current_vehicle) else: if current_vehicle.queuing_status == 'Member' or ( current_vehicle.queuing_status == 'Head' and current_vehicle. speed_trajectory[idx] >= 3): # Exit Queue self.remove_from_queue(current_vehicle) # Visualizing vehicles, the queue members are colored, the queue head is thick, while the non-queue members are thick and white if self.gui: r, color = 5, (255, 255, 255) if current_vehicle.queuing_status: color = self.gui.queues_color_code[ current_vehicle.queue_idx] r = 3 if current_vehicle.queuing_status == 'Member' else r # pygame.draw.circle(self.gui.screen, color, current_vehicle.pixels_path[idx], r) # Checking Spillback # Queue Head? if current_vehicle.queuing_status == 'Head': # At stop line? if region.traffic_sign: # Obtaining distance to stop line d = ( (region.end_point[0] - current_vehicle.utm_path[idx, 0])**2 + (region.end_point[1] - current_vehicle.utm_path[idx, 1])**2)**0.5 if d < 10: # Current region has a preceding traffic line? if i > 0: # Obtaining the preceding vehicle in the preceding region preceding_vehicle = self.get_preceding_vehicle( area.regions[i - 1], current_vehicle, t_idx) # Preceding vehicle exists and in queue? if preceding_vehicle and preceding_vehicle.queuing_status: p_idx = t_idx - int( round( preceding_vehicle.min_time / self.time_step)) # Obtaining distance to the preceding vehicle in the preceding region distance = ( (preceding_vehicle.utm_path[ p_idx, 0] - current_vehicle .utm_path[idx, 0])**2 + (preceding_vehicle.utm_path[ p_idx, 1] - current_vehicle .utm_path[idx, 1])**2)**0.5 if distance < 8: # Making sure that the spillback is new if not (region.spillbacks and id in list( zip(*region. spillbacks))[3] ): # Adding new spillback front_queue_length = area.regions[ i - 1].queue_list[ preceding_vehicle. queue_idx] rear_queue_length = region.queue_list[ current_vehicle. queue_idx] region.spillbacks.append([ t_idx * 0.04, area.id, region.id, id, front_queue_length + rear_queue_length ]) # Updating the maximum queues of each area with each timestamp area.update_max_queue(t_idx * 0.04) # updating GUI if self.gui and not self.gui.update(): del self.gui return # Closing GUI at the end if self.gui: del self.gui # Displaying results print('Results Report:') for i, area in enumerate(self.areas): print(' Area', i + 1, ':') print(' Color =', area.id) print(' Maximum Queue Length = ', len(area.max_queue)) print( ' Lane of Max Queue = ', self.vehicles_list[area.max_queue[0]].get_lane( area.max_queue_region, area.max_queue_time, self.time_step)) print( ' Coordinates of Max Queue = ', self.vehicles_list[area.max_queue[0]].gps_path[int( round(max_queue_time / 0.04))], self.vehicles_list[area.max_queue[-1]].gps_path[int( round(max_queue_time / 0.04))]) print(' Time of Max Queue = ', area.max_queue_time) print(' Spillbacks :') for j, region in enumerate(area.regions): for k, spillback in enumerate(region.spillbacks): print(' Region', j + 1, ':') print(' Spillback', k + 1, ':') print(' When?', spillback[0]) print(' Where?', spillback[1:3]) print(' Final Queue Length?', len(spillback[4])) print('\n')