Spaces:
Sleeping
Sleeping
| import cv2 | |
| import fiona | |
| from pyproj import Transformer | |
| import numpy as np | |
| from tqdm import tqdm | |
| from grid_optim import get_optimal_grid | |
| def shapefile_to_latlong(file_path: str): | |
| c = fiona.open(file_path) | |
| contours = [] | |
| transformer = Transformer.from_crs(c.crs, 4326, always_xy=True) | |
| for poly in c: | |
| coords = poly["geometry"].coordinates | |
| for coord_set in coords: | |
| contours.append( | |
| np.array( | |
| list( | |
| transformer.itransform( | |
| coord_set[0] if len(coord_set) == 1 else coord_set | |
| ) | |
| ) | |
| ) | |
| ) | |
| return contours | |
| def mask_shapefile_to_grid_indices( | |
| file_path: str, side_len_m: float = 100, meters_per_px: float = 10 | |
| ): | |
| c = fiona.open(file_path, "r") | |
| all_indices = [] | |
| all_labels = [] | |
| city_counts = {} | |
| side_len = side_len_m / meters_per_px | |
| for poly in c: | |
| coords = poly["geometry"].coordinates | |
| city = poly["properties"]["City"] | |
| if city not in city_counts: | |
| city_counts[city] = 0 | |
| for coord_set in tqdm(coords): | |
| contour = np.array(coord_set[0] if len(coord_set) == 1 else coord_set) | |
| cmin = contour.min(axis=0) | |
| contour -= cmin | |
| cmax = int(contour.max() / meters_per_px) | |
| contour = contour // meters_per_px | |
| if cmax < side_len: | |
| continue | |
| mask = np.zeros((cmax, cmax), dtype="uint8") | |
| mask = cv2.drawContours( | |
| mask, | |
| [contour.reshape((-1, 1, 2)).astype(np.int32)], | |
| -1, | |
| (255), | |
| thickness=cv2.FILLED, | |
| ) | |
| indices = np.array(get_optimal_grid(mask, side_len=side_len)[0]) | |
| indices = indices * meters_per_px + cmin | |
| all_indices += sorted(indices.tolist(), key=lambda x: x[1]) | |
| all_labels += [ | |
| f"{city[0]}-{city_counts[city] + i}" for i in range(len(indices)) | |
| ] | |
| city_counts[city] += len(indices) | |
| transformer = Transformer.from_crs(c.crs, 4326, always_xy=True) | |
| all_indices = list(transformer.itransform(all_indices)) | |
| return np.array(all_indices), all_labels | |
| def points_to_shapefile(points: np.ndarray, labels: list, file_path: str): | |
| schema = {"geometry": "Point", "properties": [("ID", "int"), ("Name", "str")]} | |
| # open a fiona object | |
| pointShp = fiona.open( | |
| file_path, | |
| mode="w", | |
| driver="ESRI Shapefile", | |
| schema=schema, | |
| crs="EPSG:4326", | |
| ) | |
| # iterate over each row in the dataframe and save record | |
| for i, (x, y) in enumerate(points): | |
| rowDict = { | |
| "geometry": {"type": "Point", "coordinates": (x, y)}, | |
| "properties": {"ID": i, "Name": labels[i]}, | |
| } | |
| pointShp.write(rowDict) | |
| # close fiona object | |
| pointShp.close() | |
| def get_cached_grid_indices(file_path: str): | |
| c = fiona.open(file_path, "r") | |
| all_indices = [] | |
| all_labels = [] | |
| for poly in c: | |
| all_indices.append(poly["geometry"].coordinates) | |
| if "Name" in poly["properties"]: | |
| all_labels.append(poly["properties"]["Name"]) | |
| return np.array(all_indices), all_labels | |