SerpentineZoneSampling / geo_tools.py
dilithjay's picture
Set label format to use starting letters of sites
c424639
raw
history blame
3.32 kB
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