add ratio parameter to allow drawing rectangular maps

pull/105/head
Etienne Brodu 2023-01-12 23:12:24 +01:00
rodzic 3f3b8be923
commit cf192deca9
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6A66320245467CC0
7 zmienionych plików z 37 dodań i 17 usunięć

Wyświetl plik

@ -528,13 +528,21 @@ def create_background(
Tuple[BaseGeometry, float, float, float, float, float, float]: background geometry, bounds, width and height
"""
# Create background
background_pad = 1.1
# pad is the value with which to scale the perimeter to get the background.
# dilate is the value in metter to add to the perimeter to get the background.
# the pad scaling is applied after the dilate addition.
background_pad = 1
if "background" in style and "pad" in style["background"]:
background_pad = style["background"].pop("pad")
background_dilate = 0
if "background" in style and "dilate" in style["background"]:
background_dilate = style["background"].pop("dilate")
background = shapely.affinity.scale(
box(*
shapely.ops.unary_union(ox.project_gdf(gdfs["perimeter"]).geometry).bounds),
shapely.ops.unary_union(ox.project_gdf(gdfs["perimeter"]).geometry.buffer(background_dilate)).bounds),
background_pad,
background_pad,
)
@ -801,10 +809,12 @@ def plot(
update_preset=None,
# Custom postprocessing function on layers
postprocessing=None,
# Circular boundary? Default: square
# Circular boundary? Default: rectangular
circle=None,
# Radius for circular or square boundary
# Radius for circular or rectangular boundary
radius=None,
# Ratio width/height for rectangular boundary. Radius is the height of the rectangle. Default: square
ratio=1,
# Dilate boundary by this much
dilate=None,
# Whether to save result
@ -894,7 +904,7 @@ def plot(
layers = override_args(layers, circle, dilate)
# 4. Fetch geodataframes
gdfs = get_gdfs(query, layers, radius, dilate, -rotation)
gdfs = get_gdfs(query, layers, radius, ratio, dilate, -rotation)
# 5. Apply transformations to GeoDataFrames (translation, scale, rotation)
gdfs = transform_gdfs(gdfs, x, y, scale_x, scale_y, rotation)

Wyświetl plik

@ -57,8 +57,8 @@ def parse_query(query):
return "address"
# Get circular or square boundary around point
def get_boundary(query, radius, circle=False, rotation=0):
# Get circular or rectangular boundary around point
def get_boundary(query, radius, ratio, circle=False, rotation=0):
# Get point from query
point = query if parse_query(query) == "coordinates" else ox.geocode(query)
@ -70,15 +70,16 @@ def get_boundary(query, radius, circle=False, rotation=0):
if circle: # Circular shape
# use .buffer() to expand point into circle
boundary.geometry = boundary.geometry.buffer(radius)
else: # Square shape
else: # rectangular shape
x, y = np.concatenate(boundary.geometry[0].xy)
r = radius
dx = radius * ratio
dy = radius
boundary = GeoDataFrame(
geometry=[
rotate(
Polygon(
[(x - r, y - r), (x + r, y - r),
(x + r, y + r), (x - r, y + r)]
[(x - dx, y - dy), (x + dx, y - dy),
(x + dx, y + dy), (x - dx, y + dy)]
),
rotation,
)
@ -94,13 +95,13 @@ def get_boundary(query, radius, circle=False, rotation=0):
# Get perimeter from query
def get_perimeter(
query, radius=None, by_osmid=False, circle=False, dilate=None, rotation=0, **kwargs
query, radius=None, ratio=1, by_osmid=False, circle=False, dilate=None, rotation=0, **kwargs
):
if radius:
# Perimeter is a circular or square shape
# Perimeter is a circular or rectangular shape
perimeter = get_boundary(
query, radius, circle=circle, rotation=rotation)
query, radius, ratio, circle=circle, rotation=rotation)
else:
# Perimeter is a OSM or user-provided polygon
if parse_query(query) == "polygon":
@ -128,6 +129,7 @@ def get_gdf(
layer,
perimeter,
perimeter_tolerance=0,
dilate=0,
tags=None,
osmid=None,
custom_filter=None,
@ -143,12 +145,15 @@ def get_gdf(
**kwargs
):
if dilate == None:
dilate = 0
# Supress shapely deprecation warning
warnings.simplefilter("ignore", ShapelyDeprecationWarning)
# Apply tolerance to the perimeter
perimeter_with_tolerance = (
ox.project_gdf(perimeter).buffer(perimeter_tolerance).to_crs(4326)
ox.project_gdf(perimeter).buffer(dilate + perimeter_tolerance).to_crs(4326)
)
perimeter_with_tolerance = unary_union(
perimeter_with_tolerance.geometry).buffer(0)
@ -204,7 +209,7 @@ def get_gdf(
# Fetch GeoDataFrames given query and a dictionary of layers
def get_gdfs(query, layers_dict, radius, dilate, rotation=0) -> dict:
def get_gdfs(query, layers_dict, radius, ratio, dilate, rotation=0) -> dict:
perimeter_kwargs = {}
if "perimeter" in layers_dict:
@ -215,6 +220,7 @@ def get_gdfs(query, layers_dict, radius, dilate, rotation=0) -> dict:
perimeter = get_perimeter(
query,
radius=radius,
ratio=ratio,
rotation=rotation,
dilate=dilate,
**perimeter_kwargs

Wyświetl plik

@ -1 +1 @@
{"layers": {"perimeter": {"circle": false}, "streets": {"width": {"primary": 5, "secondary": 4, "tertiary": 3, "residential": 2, "footway": 1}}, "building": {"tags": {"building": true}}, "green": {"tags": {"landuse": ["grass", "village_green"], "leisure": "park"}}}, "style": {"background": {"fc": "#F2F4CB", "ec": "#dadbc1", "hatch": "ooo...", "zorder": -1}, "perimeter": {"fill": false, "lw": 0, "zorder": 0}, "green": {"fc": "#8BB174", "ec": "#2F3737", "hatch_c": "#A7C497", "hatch": "ooo...", "lw": 1, "zorder": 1}, "water": {"fc": "#a8e1e6", "ec": "#2F3737", "hatch_c": "#9bc3d4", "hatch": "ooo...", "lw": 1, "zorder": 3}, "streets": {"fc": "#2F3737", "ec": "#475657", "alpha": 1, "lw": 0, "zorder": 4}, "building": {"palette": ["#433633", "#FF5E5B"], "ec": "#2F3737", "lw": 0.5, "zorder": 5}}, "circle": null, "radius": 500, "dilate": 100}
{"layers": {"perimeter": {"circle": false}, "streets": {"width": {"primary": 5, "secondary": 4, "tertiary": 3, "residential": 2, "footway": 1}}, "building": {"tags": {"building": true}}, "green": {"tags": {"landuse": ["grass", "village_green"], "leisure": "park"}}}, "style": {"background": {"fc": "#F2F4CB", "ec": "#dadbc1", "hatch": "ooo...", "pad": 1.1, "zorder": -1}, "perimeter": {"fill": false, "lw": 0, "zorder": 0}, "green": {"fc": "#8BB174", "ec": "#2F3737", "hatch_c": "#A7C497", "hatch": "ooo...", "lw": 1, "zorder": 1}, "water": {"fc": "#a8e1e6", "ec": "#2F3737", "hatch_c": "#9bc3d4", "hatch": "ooo...", "lw": 1, "zorder": 3}, "streets": {"fc": "#2F3737", "ec": "#475657", "alpha": 1, "lw": 0, "zorder": 4}, "building": {"palette": ["#433633", "#FF5E5B"], "ec": "#2F3737", "lw": 0.5, "zorder": 5}}, "circle": null, "radius": 500, "dilate": 100}

Wyświetl plik

@ -69,6 +69,7 @@
},
"background": {
"fc": "#F2F4CB",
"pad": 1.1,
"zorder": -1
},
"green": {

Wyświetl plik

@ -69,6 +69,7 @@
},
"background": {
"fc": "#F2F4CB",
"pad": 1.1,
"zorder": -1
},
"green": {

Wyświetl plik

@ -59,6 +59,7 @@
"fc": "#F2F4CB",
"ec": "#dadbc1",
"hatch": "ooo...",
"pad": 1.1,
"zorder": -1
},
"perimeter": {

Wyświetl plik

@ -25,6 +25,7 @@
},
"background": {
"fc": "#fff",
"pad": 1.1,
"zorder": -1
},
"streets": {