Skip to content

Commit

Permalink
Merge pull request #12 from Sydney-Informatics-Hub/refactor-testing
Browse files Browse the repository at this point in the history
Refactor testing
  • Loading branch information
hlydecker authored Feb 26, 2024
2 parents c3bb485 + 2b24051 commit 6616edc
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
79 changes: 79 additions & 0 deletions aigis/convert/tiles.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,97 @@
# -*- coding: utf-8 -*-
import json
import glob
import itertools
import logging
import os

import rasterio as rio
import rasterio.windows as riow
from shapely.geometry import Polygon, box
from pyproj import Proj, transform

"""A collection of functions for manipulating raster tiles."""


log = logging.getLogger(__name__)


def create_grid_geojson(bbox, tile_size):
"""
Create a GeoJSON representation of a grid of tiles within the given bounding box.
Parameters:
bbox (tuple): A tuple containing the minimum and maximum longitude and latitude values of the bounding box.
tile_size (float): The size of each tile in degrees.
Returns:
str: A JSON string representing the GeoJSON feature collection.
"""
min_lon, min_lat, max_lon, max_lat = bbox

# Transform the coordinates to EPSG:3857 (Web Mercator) for easier calculations
in_proj = Proj(init='epsg:4326')
out_proj = Proj(init='epsg:3857')
min_lon, min_lat = transform(in_proj, out_proj, min_lon, min_lat)
max_lon, max_lat = transform(in_proj, out_proj, max_lon, max_lat)

# Calculate the number of tiles in x and y directions
num_tiles_x = int((max_lon - min_lon) / tile_size)
num_tiles_y = int((max_lat - min_lat) / tile_size)

features = []

for i in range(num_tiles_x):
for j in range(num_tiles_y):
# Calculate the coordinates of the current tile
tile_min_lon = min_lon + i * tile_size
tile_max_lon = min_lon + (i + 1) * tile_size
tile_min_lat = min_lat + j * tile_size
tile_max_lat = min_lat + (j + 1) * tile_size

# Convert the coordinates back to EPSG:4326
tile_min_lon, tile_min_lat = transform(out_proj, in_proj, tile_min_lon, tile_min_lat)
tile_max_lon, tile_max_lat = transform(out_proj, in_proj, tile_max_lon, tile_max_lat)

# Create a polygon for the current tile
tile_polygon = box(tile_min_lon, tile_min_lat, tile_max_lon, tile_max_lat)

# Create a GeoJSON feature for the current tile
feature = {
"type": "Feature",
"properties": {
"id": i * num_tiles_y + j,
"left": tile_min_lon,
"top": tile_max_lat,
"right": tile_max_lon,
"bottom": tile_min_lat,
"row_index": i,
"col_index": j
},
"geometry": {
"type": "Polygon",
"coordinates": [list(tile_polygon.exterior.coords)]
}
}

features.append(feature)

# Create a GeoJSON feature collection
feature_collection = {
"type": "FeatureCollection",
"name": "GSU_grid_1",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::3857"
}
},
"features": features
}

return json.dumps(feature_collection)


def get_tiles(
geotiff: rio.DatasetReader,
tile_width: int = 2000,
Expand Down
27 changes: 25 additions & 2 deletions scripts/coco2geojson.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,5 +486,28 @@ def main(args=None):
polygons_df.to_parquet(geopardquet_path)


if __name__ == "__main__":
main()
if len(tiles_list) == 1:
# Handle single input tile
single_tile_df = tiles_df.loc[tiles_df["tile_name"] == os.path.basename(tiles_list[0]).split(".")[0]]
if single_tile_df.empty:
log.warning("No annotations found for the single input tile.")
else:
single_tile_polygons_df = merge_class_polygons_shapely([single_tile_df], crs)
single_tile_polygons_df = multipolygon_to_polygons(single_tile_polygons_df)
single_tile_polygons_df["geometry"] = single_tile_polygons_df["geometry"].progress_apply(
lambda x: shape_regulariser(
x, simplify_tolerance, minimum_rotated_rectangle, orthogonalisation
)
)
single_tile_polygons_df = single_tile_polygons_df.to_crs(original_crs)
single_tile_polygons_df.Name = meta_name

if geojson_path is not None:
single_tile_polygons_df.to_file(geojson_path, driver="GeoJSON")
if geopardquet_path is not None:
single_tile_polygons_df.to_parquet(geopardquet_path)
else:
log.warning("Multiple input tiles detected. The code will handle overlapping and adjacent tiles by default.")

if __name__ == "__main__":
main()

0 comments on commit 6616edc

Please # to comment.