Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CircularGreenSimCity
CircularGreenSimCity
Compare Revisions
923449bed0a4049fd9d93e7094eb63c293f5ca52...f1ef4381ab93e77b1e17e0b4b90dd77f1ee9eb64
Commits (2)
More info
· 361b1885
Eric Duminil
authored
Mar 26, 2024
361b1885
More info from tabs
· f1ef4381
Eric Duminil
authored
Mar 26, 2024
f1ef4381
Hide whitespace changes
Inline
Side-by-side
python_scripts/add_trees_to_open_street_map/add_trees.py
View file @
f1ef4381
...
...
@@ -99,7 +99,7 @@ def set_plot(bounds, to_local_coordinates):
return
ax
def
place_trees
(
forest
,
ways
,
region
,
to_local
,
tree_distance
,
min_distance_2
):
def
place_trees
(
forest
,
ways
,
region
,
to_local
,
tree_distance
,
min_distance_2
)
->
Forest
:
local_region
=
transform
(
to_local
.
transform
,
region
)
for
way
in
ways
:
...
...
@@ -136,15 +136,19 @@ def place_trees(forest, ways, region, to_local, tree_distance, min_distance_2):
y
=
potential_tree
.
y
if
local_region
.
contains
(
geometry
.
Point
(
x
,
y
)):
forest
.
add_tree_if_possible
(
min_distance_2
,
x
,
y
,
color
=
'red'
,
description
=
'fake_tree'
color
=
'#DFFF00'
,
type
=
'Fake Tree'
,
description
=
'Tilia tomentosa'
radius
=
3
)
return
forest
.
xs_ys
return
forest
def
plot_trees
(
bounds
,
tree_xs
,
tree_ys
,
tree_distance
):
plt
.
scatter
(
tree_xs
,
tree_ys
,
s
=
2
,
c
=
'green'
)
def
plot_trees
(
bounds
,
forest
,
tree_distance
)
->
None
:
print
(
"Exporting diagram..."
)
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
}
\n
Tree distance :
{
tree_distance
}
m"
)
...
...
@@ -153,25 +157,25 @@ def plot_trees(bounds, tree_xs, tree_ys, tree_distance):
SCRIPT_DIR
/
f
"
{
get_basename
(
bounds
)
}
.png"
,
bbox_inches
=
'tight'
,
dpi
=
300
)
def
export_map
(
bounds
,
tree_xs
,
tree_ys
,
epsg_id
):
def
export_map
(
bounds
,
forest
,
epsg_id
)
->
None
:
print
(
"Exporting Map..."
)
to_wgs84
=
Transformer
.
from_crs
(
f
"EPSG:
{
epsg_id
}
"
,
"EPSG:4326"
,
always_xy
=
True
)
interactive_map
=
folium
.
Map
()
interactive_map
.
fit_bounds
([(
bounds
.
S
,
bounds
.
W
),
(
bounds
.
N
,
bounds
.
E
)])
radius
=
2
# [m]
for
x
,
y
in
zip
(
tree_xs
,
tree_ys
):
lon
,
lat
=
to_wgs84
.
transform
(
x
,
y
)
for
tree
in
forest
:
lon
,
lat
=
to_wgs84
.
transform
(
tree
.
x
,
tree
.
y
)
folium
.
Circle
(
location
=
[
lat
,
lon
],
radius
=
radius
,
radius
=
tree
.
radius
or
2
,
# [m], when defined
color
=
"black"
,
weight
=
1
,
fill_opacity
=
0.9
,
opacity
=
1
,
fill_color
=
"#00ff15"
,
fill_color
=
tree
.
color
,
fill
=
False
,
# gets overridden by fill_color
popup
=
"{} meters"
.
format
(
radius
),
tooltip
=
"I am a tree in street STREET"
,
popup
=
repr
(
tree
),
tooltip
=
str
(
tree
)
,
).
add_to
(
interactive_map
)
folium
.
TileLayer
(
...
...
@@ -183,23 +187,25 @@ def export_map(bounds, tree_xs, tree_ys, epsg_id):
).
add_to
(
interactive_map
)
interactive_map
.
save
(
f
"
{
get_basename
(
bounds
)
}
_trees.html"
)
print
(
" DONE!"
)
def
export_csv
(
bounds
,
tree_xs
,
tree_ys
,
wkt_polygon
,
tree_distance
,
min_distance
,
epsg_id
):
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
:
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
\n
"
)
csv
.
write
(
"# [m]; [m]
\n
"
)
for
x
,
y
in
zip
(
tree_xs
,
tree_ys
)
:
csv
.
write
(
f
"
{
x
}
;
{
y
}
\n
"
)
csv
.
write
(
"# X; Y
; Type; Description; Radius
\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
"
)
print
(
"DONE!"
)
print
(
"
DONE!"
)
def
main
(
wkt_polygon
,
epsg_id
,
tree_distance
,
min_distance
,
import_tree_shp
):
def
main
(
wkt_polygon
,
epsg_id
,
tree_distance
,
min_distance
,
import_tree_shp
)
->
None
:
region
,
bounds
=
load_region
(
wkt_polygon
)
ways
=
get_osm_roads
(
bounds
)
...
...
@@ -213,12 +219,12 @@ def main(wkt_polygon, epsg_id, tree_distance, min_distance, import_tree_shp):
to_local
=
Transformer
.
from_crs
(
"EPSG:4326"
,
f
"EPSG:
{
epsg_id
}
"
,
always_xy
=
True
)
set_plot
(
bounds
,
to_local
)
tree_xs
,
tree_ys
=
place_trees
(
existing_forest
,
ways
,
region
,
to_local
,
tree_distance
,
min_distance
**
2
)
print
(
repr
(
existing_forest
)
)
forest
=
place_trees
(
existing_forest
,
ways
,
region
,
to_local
,
tree_distance
,
min_distance
**
2
)
print
(
existing_forest
)
plot_trees
(
bounds
,
tree_xs
,
tree_ys
,
tree_distance
)
export_map
(
bounds
,
tree_xs
,
tree_ys
,
epsg_id
)
export_csv
(
bounds
,
tree_xs
,
tree_ys
,
wkt_polygon
,
plot_trees
(
bounds
,
forest
,
tree_distance
)
export_map
(
bounds
,
forest
,
epsg_id
)
export_csv
(
bounds
,
forest
,
wkt_polygon
,
tree_distance
,
min_distance
,
epsg_id
)
...
...
python_scripts/add_trees_to_open_street_map/import_existing_trees.py
View file @
f1ef4381
...
...
@@ -4,7 +4,14 @@ from tree import Tree, Forest
def
get_existing_forest
(
shp_input
):
print
(
f
"Importing
{
shp_input
}
"
)
df
=
gpd
.
read_file
(
shp_input
)
trees
=
[
Tree
(
p
.
x
,
p
.
y
)
for
p
in
df
.
geometry
]
trees
=
[]
for
tree_row
in
df
.
itertuples
():
point
=
tree_row
.
geometry
trees
.
append
(
Tree
(
point
.
x
,
point
.
y
,
description
=
tree_row
.
Bezeichnun
,
radius
=
tree_row
.
Kroneradi
,
type
=
tree_row
.
Baumart
))
return
Forest
(
trees
)
if
__name__
==
"__main__"
:
...
...
python_scripts/add_trees_to_open_street_map/tree.py
View file @
f1ef4381
from
dataclasses
import
dataclass
from
collections
import
UserList
import
kdtree
...
...
@@ -9,8 +10,8 @@ class Tree:
z
:
float
=
0
height
:
float
=
None
radius
:
float
=
None
description
:
str
=
None
type
:
str
=
None
description
:
str
=
'?'
color
:
str
=
'green'
def
__len__
(
self
):
...
...
@@ -19,32 +20,36 @@ class Tree:
def
__getitem__
(
self
,
i
):
return
[
self
.
x
,
self
.
y
][
i
]
def
__str__
(
self
):
return
f
"
{
self
.
type
}
(
{
self
.
description
}
),
{
self
.
radius
or
'?'
}
m (X=
{
self
.
x
:.
1
f
}
, Y=
{
self
.
y
:.
1
f
}
)"
class
Forest
:
class
Forest
(
UserList
)
:
def
__init__
(
self
,
existing_trees
=
[]):
if
existing_trees
:
self
.
kd_tree
=
kdtree
.
create
(
existing_trees
,
dimensions
=
2
)
else
:
self
.
kd_tree
=
kdtree
.
create
([(
0
,
0
)],
dimensions
=
2
)
self
.
trees
=
existing_trees
self
.
data
=
existing_trees
def
add_tree_if_possible
(
self
,
min_distance_2
,
x
,
y
,
**
kparams
):
_nearest_tree
,
distance_2
=
self
.
kd_tree
.
search_nn
((
x
,
y
))
if
distance_2
>
min_distance_2
:
self
.
kd_tree
.
add
((
x
,
y
))
self
.
trees
.
append
(
Tree
(
x
,
y
,
**
kparams
))
self
.
append
(
Tree
(
x
,
y
,
**
kparams
))
@
property
def
xs_ys
(
self
):
xs
,
ys
=
[],
[]
for
tree
in
self
.
trees
:
def
xs_ys
_cs
(
self
):
xs
,
ys
,
colors
=
[],
[],
[]
for
tree
in
self
:
xs
.
append
(
tree
.
x
)
ys
.
append
(
tree
.
y
)
return
xs
,
ys
colors
.
append
(
tree
.
color
)
return
xs
,
ys
,
colors
def
__str__
(
self
):
return
f
"Forest with
{
len
(
self
.
trees
)
}
trees."
return
f
"Forest with
{
len
(
self
)
}
trees."
def
__repr__
(
self
):
return
"
\n
"
.
join
([
str
(
self
)]
+
[
str
(
tree
)
for
tree
in
self
.
trees
])
return
"
\n
"
.
join
([
str
(
self
)]
+
[
str
(
tree
)
for
tree
in
self
])