Skip to content

Commit

Permalink
updated tile buffering
Browse files Browse the repository at this point in the history
  • Loading branch information
kcartier-wri committed Nov 3, 2024
1 parent 3b243f7 commit 9ec0285
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 41 deletions.
44 changes: 19 additions & 25 deletions city_metrix/layers/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,13 @@ def write(self, bbox, output_path, tile_side_meters=None, buffer_meters=None, **
_write_tile_grid(unbuffered_tile_grid, output_path, 'tile_grid_unbuffered.geojson')


def _get_tile_boundaries(bbox, tile_degrees, buffer_meters):
has_buffer = True if buffer_meters is not None and buffer_meters != 0 else False
def _get_tile_boundaries(bbox, tile_side_meters, tile_buffer_meters):
has_buffer = True if tile_buffer_meters is not None and tile_buffer_meters != 0 else False
if has_buffer:
lon_degree_offset, lat_degree_offset = offset_degrees_for_bbox_centroid(bbox, buffer_meters)
tiles = create_fishnet_grid(*bbox, tile_degrees, lon_degree_offset, lat_degree_offset)
unbuffered_tiles = create_fishnet_grid(*bbox, tile_degrees)
tiles = create_fishnet_grid(*bbox, tile_side_meters, tile_buffer_meters)
unbuffered_tiles = create_fishnet_grid(*bbox, tile_side_meters)
else:
tiles = create_fishnet_grid(*bbox, tile_degrees)
tiles = create_fishnet_grid(*bbox, tile_side_meters)
unbuffered_tiles = None

tile_grid = []
Expand Down Expand Up @@ -258,20 +257,25 @@ def get_utm_zone_epsg(bbox) -> str:
return f"EPSG:{epsg}"


def create_fishnet_grid(min_lon, min_lat, max_lon, max_lat, cell_size_m, lon_degree_buffer=0, lat_degree_buffer=0):
def create_fishnet_grid(min_lon, min_lat, max_lon, max_lat, tile_side_meters, tile_buffer_meters=0):
lon_coord, lat_coord = (min_lon, min_lat)
geom_array = []

center_lat = (min_lat + max_lat) / 2
lon_cell_offset, lat_cell_offset = offset_meters_to_geographic_degrees(center_lat, cell_size_m)
lon_side_offset, lat_side_offset = offset_meters_to_geographic_degrees(center_lat, tile_side_meters)
if tile_buffer_meters == 0:
lon_buffer_offset = 0
lat_buffer_offset = 0
else:
lon_buffer_offset, lat_buffer_offset = offset_meters_to_geographic_degrees(center_lat, tile_buffer_meters)

# Polygon Size
while lat_coord < max_lat:
while lon_coord < max_lon:
cell_min_lon = lon_coord - lon_degree_buffer
cell_min_lat = lat_coord - lat_degree_buffer
cell_max_lon = lon_coord + lon_cell_offset + lon_degree_buffer
cell_max_lat = lat_coord + lat_cell_offset + lat_degree_buffer
cell_min_lon = lon_coord - lon_buffer_offset
cell_min_lat = lat_coord - lat_buffer_offset
cell_max_lon = lon_coord + lon_side_offset + lon_buffer_offset
cell_max_lat = lat_coord + lat_side_offset + lat_buffer_offset
geom = geometry.Polygon(
[
(cell_min_lon, cell_min_lat),
Expand All @@ -282,10 +286,10 @@ def create_fishnet_grid(min_lon, min_lat, max_lon, max_lat, cell_size_m, lon_deg
]
)
geom_array.append(geom)
lon_coord += lon_cell_offset
lon_coord += lon_side_offset
lon_coord = min_lon

lat_coord += lat_cell_offset
lat_coord += lat_side_offset

fishnet = gpd.GeoDataFrame(geom_array, columns=["geometry"]).set_crs("EPSG:4326")
fishnet["fishnet_geometry"] = fishnet["geometry"]
Expand Down Expand Up @@ -370,18 +374,8 @@ def write_dataarray(path, data):
else:
data.rio.to_raster(raster_path=path, driver="COG")


def offset_degrees_for_bbox_centroid(bbox, offset_meters):
min_lat = bbox[1]
max_lat = bbox[3]
center_lat = (min_lat + max_lat) / 2

lon_degree_offset, lat_degree_offset = offset_meters_to_geographic_degrees(center_lat, offset_meters)

return lon_degree_offset, lat_degree_offset


def offset_meters_to_geographic_degrees(decimal_latitude, length_m):
# TODO consider replacing this spherical calculation with ellipsoidal
earth_radius_m = 6378137
rad = 180/math.pi

Expand Down
20 changes: 4 additions & 16 deletions tests/test_methods.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import numpy as np
from city_metrix.layers.layer import create_fishnet_grid, offset_degrees_for_bbox_centroid, offset_meters_to_geographic_degrees
from city_metrix.layers.layer import create_fishnet_grid, offset_meters_to_geographic_degrees
from .conftest import (
LARGE_ZONES,
ZONES,
Expand Down Expand Up @@ -38,27 +38,15 @@ def test_fishnet():
min_y = -80.1
max_x = -38.2
max_y = -80.0
cell_size_m = 1000
lon_degree_buffer = 0.004
lat_degree_buffer = 0.004
tile_side_meters = 1000
tile_buffer_meters = 100
result_fishnet = (
create_fishnet_grid(min_x, min_y, max_x, max_y, cell_size_m, lon_degree_buffer, lat_degree_buffer))
create_fishnet_grid(min_x, min_y, max_x, max_y, tile_side_meters, tile_buffer_meters))

actual_count = result_fishnet.geometry.count()
expected_count = 24
assert actual_count == expected_count

def test_bbox_centroid_to_offset_degrees():
# random high-latitude location where long offset is > lat offset
bbox = (-38.355, -82.821, -38.338, -82.804)
offset_meters = 500
lon_degree_offset, lat_degree_offset = offset_degrees_for_bbox_centroid(bbox, offset_meters)

round_lon_degree_offset = round(lon_degree_offset, 4)
round_lat_degree_offset = round(lat_degree_offset, 4)

assert round_lon_degree_offset > round_lat_degree_offset
assert round_lon_degree_offset == 0.0359

def test_meters_to_offset_degrees():
decimal_latitude = 45
Expand Down

0 comments on commit 9ec0285

Please sign in to comment.