Skip to content

Commit

Permalink
edit quantization strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsmrynk committed Nov 11, 2023
1 parent d3477a5 commit e8c8cd5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 75 deletions.
5 changes: 3 additions & 2 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,9 @@ def main():
gdfs_grid = []
grid_iterations = len(config.aggregation.tile_size)

for index, tile_size_meters in enumerate(config.aggregation.tile_size):
gdfs_grid.append(grid_generator.get_grid(tile_size_meters=tile_size_meters))
for index, tile_size in enumerate(config.aggregation.tile_size):
gdfs_grid.append(grid_generator.get_grid(tile_size=tile_size,
quantize=False))
logger.info(f'Grid {index + 1} / {grid_iterations} created')
# endregion

Expand Down
3 changes: 2 additions & 1 deletion src/utils/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def get_valid_coordinates(self,

grid_generator = GridGenerator(bounding_box=bounding_box,
epsg_code=epsg_code)
grid_gdf = grid_generator.get_grid(tile_size_meters=settings.IMAGE_SIZE_METERS)
grid_gdf = grid_generator.get_grid(tile_size=settings.IMAGE_SIZE_METERS,
quantize=True)

intersections = list(grid_gdf['geometry'].intersects(boundary_gdf['geometry'][0]))
valid_coordinates = [coordinates_element for (coordinates_element, valid) in zip(coordinates, intersections)
Expand Down
107 changes: 35 additions & 72 deletions src/utils/grid_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import geopandas as gpd
from shapely.geometry import Polygon

import src.utils.settings as settings
import numpy as np
from shapely.geometry import box as Box # PEP8 compliant


class GridGenerator:
Expand All @@ -11,95 +10,59 @@ def __init__(self,
"""
| Constructor method
:param (int, int, int, int) bounding_box: bounding box (x_1, y_1, x_2, y_2)
:param (int, int, int, int) bounding_box: bounding box (x_min, y_min, x_max, y_max)
:param int epsg_code: epsg code of the coordinate reference system
:returns: None
:rtype: None
"""
self.bounding_box = bounding_box
self.x_min, self.y_min, self.x_max, self.y_max = bounding_box
self.epsg_code = epsg_code

def get_coordinates(self, tile_size_meters):
def get_coordinates(self,
tile_size,
quantize):
"""
| Returns the coordinates of the top left corner of each tile in the area of the bounding box.
The bounding box is quantized to the image size in meters.
| Returns the coordinates of the bottom left corner of each tile.
:param int tile_size_meters: tile size in meters
:returns: coordinates (x, y) of each tile
:rtype: list[(int, int)]
:param int tile_size: tile size in meters
:param bool quantize: if True, the bounding box is quantized to the tile_size
:returns: coordinates (x_min, y_min) of each tile
:rtype: np.ndarray[np.int32]
"""
coordinates = []

bounding_box = (self.bounding_box[0] - (self.bounding_box[0] % settings.IMAGE_SIZE_METERS),
self.bounding_box[1] - (self.bounding_box[1] % settings.IMAGE_SIZE_METERS),
self.bounding_box[2],
self.bounding_box[3])

columns = (bounding_box[2] - bounding_box[0]) // tile_size_meters
if (bounding_box[2] - bounding_box[0]) % tile_size_meters:
columns += 1
if quantize:
x_min = self.x_min - (self.x_min % tile_size)
y_min = self.y_min - (self.y_min % tile_size)
else:
x_min = self.x_min
y_min = self.y_min

rows = (bounding_box[3] - bounding_box[1]) // tile_size_meters
if (bounding_box[3] - bounding_box[1]) % tile_size_meters:
rows += 1
coordinates_x, coordinates_y = np.meshgrid(np.arange(x_min, self.x_max, tile_size),
np.arange(y_min, self.y_max, tile_size))

for row in range(rows):
for column in range(columns):
coordinates.append((bounding_box[0] + column * tile_size_meters,
bounding_box[1] + (row + 1) * tile_size_meters))
coordinates = np.concatenate((coordinates_x.reshape(-1)[..., np.newaxis],
coordinates_y.reshape(-1)[..., np.newaxis]),
axis=-1).astype(np.int32)

return coordinates

@staticmethod
def get_bounding_box(coordinates, tile_size_meters):
"""
| Returns the bounding box of a tile given its coordinates of the top left corner.
:param (int, int) coordinates: coordinates (x, y)
:param int tile_size_meters: tile size in meters
:returns: bounding box (x_1, y_1, x_2, y_2)
:rtype: (int, int, int, int)
"""
bounding_box = (coordinates[0],
coordinates[1] - tile_size_meters,
coordinates[0] + tile_size_meters,
coordinates[1])
return bounding_box

@staticmethod
def get_polygon(coordinates, tile_size_meters):
"""
| Returns the polygon of a tile given its coordinates of the top left corner.
:param (int, int) coordinates: coordinates (x, y)
:param int tile_size_meters: tile size in meters
:returns: polygon
:rtype: Polygon
"""
bounding_box = GridGenerator.get_bounding_box(coordinates=coordinates,
tile_size_meters=tile_size_meters)
polygon = Polygon([[bounding_box[0], bounding_box[1]],
[bounding_box[2], bounding_box[1]],
[bounding_box[2], bounding_box[3]],
[bounding_box[0], bounding_box[3]]])
return polygon

def get_grid(self, tile_size_meters):
def get_grid(self,
tile_size,
quantize):
"""
| Returns a geodataframe of the grid.
:param int tile_size_meters: tile size in meters
:returns: geodataframe
:param int tile_size: tile size in meters
:param bool quantize: if True, the bounding box is quantized to the tile_size
:returns: grid
:rtype: gpd.GeoDataFrame
"""
coordinates = self.get_coordinates(tile_size_meters=tile_size_meters)
coordinates = self.get_coordinates(tile_size=tile_size,
quantize=quantize)

polygons = []
polygons = [Box(x_min, y_min, x_min + tile_size, y_min + tile_size)
for x_min, y_min in coordinates]

for coordinates_element in coordinates:
polygon = self.get_polygon(coordinates=coordinates_element,
tile_size_meters=tile_size_meters)
polygons.append(polygon)
gdf = gpd.GeoDataFrame(geometry=polygons,
crs=f'EPSG:{self.epsg_code}')

gdf = gpd.GeoDataFrame(geometry=polygons, crs=f'EPSG:{self.epsg_code}')
return gdf

0 comments on commit e8c8cd5

Please sign in to comment.