Commit a1cb6c53 authored by Eric Duminil's avatar Eric Duminil
Browse files

Able to export Shapefile now

parent a5b79d6b
cache
*.html
*.csv
*.png
\ No newline at end of file
cache
\ No newline at end of file
......@@ -17,6 +17,8 @@ import overpy
from pyproj import Transformer
from shapely import LineString, geometry, wkt
from shapely.ops import transform
import pandas as pd
import geopandas as gpd
from tree import Forest
from import_existing_trees import get_existing_forest
......@@ -47,11 +49,13 @@ IGNORE_ROADS = set(['primary', 'unclassified', 'secondary',
SCRIPT_DIR = Path(__file__).resolve().parent
OUTPUT_DIR = SCRIPT_DIR / 'output'
Bounds = namedtuple("Bounds", "W S E N")
def load_region(wkt_polygon):
region = wkt.loads(wkt_polygon)
bounds = namedtuple("Bounds", "W S E N")(*region.bounds)
bounds = Bounds(*region.bounds)
return region, bounds
......@@ -140,22 +144,23 @@ def place_trees(forest, ways, region, to_local, tree_distance, min_distance_2) -
color='#DFFF00',
type='Fake Tree',
description='Tilia tomentosa',
diameter=6
diameter=6,
source='add_trees.py'
)
return forest
def plot_trees(bounds, forest, tree_distance) -> None:
def plot_trees(bounds: Bounds, forest: Forest, tree_distance: float) -> None:
print("Exporting diagram...")
tree_xs, tree_ys, colors = forest.xs_ys_c6
tree_xs, tree_ys, colors = forest.xs_ys_cs
plt.scatter(tree_xs, tree_ys, s=2, c=colors)
plt.grid(True)
plt.title(f"{bounds}\nTree distance : {tree_distance} m")
plt.gcf().set_size_inches(15, 10)
plt.savefig(
SCRIPT_DIR / f"{get_basename(bounds)}.png", bbox_inches='tight', dpi=300)
OUTPUT_DIR / f"{get_basename(bounds)}.png", bbox_inches='tight', dpi=300)
print(" DONE!")
......@@ -188,27 +193,49 @@ def export_map(bounds, forest, epsg_id) -> None:
control=True
).add_to(interactive_map)
interactive_map.save(f"{get_basename(bounds)}_trees.html")
interactive_map.save(OUTPUT_DIR / f"{get_basename(bounds)}_trees.html")
print(" DONE!")
def export_csv(bounds, forest, wkt_polygon, tree_distance, min_distance, epsg_id) -> None:
print("Exporting CSV...")
with open(SCRIPT_DIR / f"{get_basename(bounds)}_trees.csv", "w") as csv:
with open(OUTPUT_DIR / f"{get_basename(bounds)}_trees.csv", "w") as csv:
csv.write(f"# Fake trees for; {wkt_polygon}\n")
csv.write(f"# Tree distance along roads; {tree_distance}; [m]\n")
csv.write(f"# Minimum allowed distance between trees; {min_distance}; [m]\n")
csv.write(f"# EPSG; {epsg_id}\n")
csv.write("# X; Y; Type; Description; Radius\n")
csv.write("# [m]; [m]; [?]; [?]; [m]\n")
csv.write("# X; Y; Type; Description; Radius; Source\n")
csv.write("# [m]; [m]; [-]; [-]; [m]; [-]\n")
for tree in forest:
csv.write(f"{tree.x};{tree.y};{tree.type};{tree.description};{tree.radius}\n")
csv.write(f"{tree.x};{tree.y};{tree.type};{tree.description};{tree.radius};{tree.source}\n")
print(" DONE!")
def export_shapefile(bounds, forest, tree_distance, epsg_id):
def export_shapefile(bounds: Bounds, forest: Forest, tree_distance: float, epsg_id: str) -> None:
print("Exporting shapefile")
data = [{
'x': t.x, 'y': t.y,
'Bezeichnun': t.description, 'Baumart': t.type,
'Baumhöhe': t.height, 'Kronenbrei': t.diameter,
'Quelle': t.source,
}
for t in forest]
df = pd.DataFrame.from_dict(data)
gdf = gpd.GeoDataFrame(
df.drop(columns=['x', 'y']),
geometry=gpd.points_from_xy(df.x, df.y), crs=epsg_id
)
print(gdf)
basename = get_basename(bounds)
shp_dir = OUTPUT_DIR / basename
shp_dir.mkdir(exist_ok=True)
gdf.to_file(shp_dir / f"trees.shp")
print(" DONE!")
......
from pathlib import Path
import geopandas as gpd
from tree import Tree, Forest
......@@ -11,7 +12,8 @@ def get_existing_forest(shp_input):
description=tree_row.Bezeichnun,
diameter=tree_row.Kronenbrei,
type=tree_row.Baumart,
trunk_diameter=tree_row.Stammumfan
trunk_diameter=tree_row.Stammumfan,
source=Path(shp_input).name
))
return Forest(trees)
......
*.png
*.html
*.csv
*.cpg
*.dbf
*.shp
*.prj
*.shx
*.geojson
\ No newline at end of file
......@@ -13,6 +13,7 @@ class Tree:
trunk_diameter: float = None
type: str = None
description: str = '?'
source: str = '?'
color: str = 'green'
def __len__(self):
......@@ -26,7 +27,7 @@ class Tree:
return self.diameter / 2
def __str__(self):
return f"{self.type} ({self.description}), {self.radius or '?'} m (X={self.x:.1f}, Y={self.y:.1f})"
return f"{self.type} ({self.description}), {self.radius} m (X={self.x:.1f}, Y={self.y:.1f})"
class Forest(UserList):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment