Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Mayer
CircularGreenSimCity
Commits
361b1885
Commit
361b1885
authored
Mar 26, 2024
by
Eric Duminil
Browse files
More info
parent
923449be
Changes
2
Show whitespace changes
Inline
Side-by-side
python_scripts/add_trees_to_open_street_map/add_trees.py
View file @
361b1885
...
@@ -99,7 +99,7 @@ def set_plot(bounds, to_local_coordinates):
...
@@ -99,7 +99,7 @@ def set_plot(bounds, to_local_coordinates):
return
ax
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
)
local_region
=
transform
(
to_local
.
transform
,
region
)
for
way
in
ways
:
for
way
in
ways
:
...
@@ -136,15 +136,17 @@ def place_trees(forest, ways, region, to_local, tree_distance, min_distance_2):
...
@@ -136,15 +136,17 @@ def place_trees(forest, ways, region, to_local, tree_distance, min_distance_2):
y
=
potential_tree
.
y
y
=
potential_tree
.
y
if
local_region
.
contains
(
geometry
.
Point
(
x
,
y
)):
if
local_region
.
contains
(
geometry
.
Point
(
x
,
y
)):
forest
.
add_tree_if_possible
(
min_distance_2
,
x
,
y
,
forest
.
add_tree_if_possible
(
min_distance_2
,
x
,
y
,
color
=
'red'
,
color
=
'#DFFF00'
,
description
=
'fake_tree'
description
=
'Fake Tree'
,
radius
=
3
)
)
return
forest
.
xs_ys
return
forest
def
plot_trees
(
bounds
,
tree_xs
,
tree_ys
,
tree_distance
):
def
plot_trees
(
bounds
,
forest
,
tree_distance
)
->
None
:
plt
.
scatter
(
tree_xs
,
tree_ys
,
s
=
2
,
c
=
'green'
)
tree_xs
,
tree_ys
,
colors
=
forest
.
xs_ys_cs
plt
.
scatter
(
tree_xs
,
tree_ys
,
s
=
2
,
c
=
colors
)
plt
.
grid
(
True
)
plt
.
grid
(
True
)
plt
.
title
(
f
"
{
bounds
}
\n
Tree distance :
{
tree_distance
}
m"
)
plt
.
title
(
f
"
{
bounds
}
\n
Tree distance :
{
tree_distance
}
m"
)
...
@@ -153,25 +155,25 @@ def plot_trees(bounds, tree_xs, tree_ys, tree_distance):
...
@@ -153,25 +155,25 @@ def plot_trees(bounds, tree_xs, tree_ys, tree_distance):
SCRIPT_DIR
/
f
"
{
get_basename
(
bounds
)
}
.png"
,
bbox_inches
=
'tight'
,
dpi
=
300
)
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
)
to_wgs84
=
Transformer
.
from_crs
(
f
"EPSG:
{
epsg_id
}
"
,
"EPSG:4326"
,
always_xy
=
True
)
interactive_map
=
folium
.
Map
()
interactive_map
=
folium
.
Map
()
interactive_map
.
fit_bounds
([(
bounds
.
S
,
bounds
.
W
),
(
bounds
.
N
,
bounds
.
E
)])
interactive_map
.
fit_bounds
([(
bounds
.
S
,
bounds
.
W
),
(
bounds
.
N
,
bounds
.
E
)])
radius
=
2
# [m]
for
tree
in
forest
:
for
x
,
y
in
zip
(
tree_xs
,
tree_ys
):
lon
,
lat
=
to_wgs84
.
transform
(
tree
.
x
,
tree
.
y
)
lon
,
lat
=
to_wgs84
.
transform
(
x
,
y
)
folium
.
Circle
(
folium
.
Circle
(
location
=
[
lat
,
lon
],
location
=
[
lat
,
lon
],
radius
=
radius
,
radius
=
tree
.
radius
or
2
,
# [m], when defined
color
=
"black"
,
color
=
"black"
,
weight
=
1
,
weight
=
1
,
fill_opacity
=
0.9
,
fill_opacity
=
0.9
,
opacity
=
1
,
opacity
=
1
,
fill_color
=
"#00ff15"
,
fill_color
=
tree
.
color
,
fill
=
False
,
# gets overridden by fill_color
fill
=
False
,
# gets overridden by fill_color
popup
=
"{} meters"
.
format
(
radius
),
popup
=
repr
(
tree
),
tooltip
=
"I am a tree in street STREET"
,
tooltip
=
str
(
tree
)
,
).
add_to
(
interactive_map
)
).
add_to
(
interactive_map
)
folium
.
TileLayer
(
folium
.
TileLayer
(
...
@@ -183,9 +185,11 @@ def export_map(bounds, tree_xs, tree_ys, epsg_id):
...
@@ -183,9 +185,11 @@ def export_map(bounds, tree_xs, tree_ys, epsg_id):
).
add_to
(
interactive_map
)
).
add_to
(
interactive_map
)
interactive_map
.
save
(
f
"
{
get_basename
(
bounds
)
}
_trees.html"
)
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
:
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
"# Fake trees for;
{
wkt_polygon
}
\n
"
)
csv
.
write
(
f
"# Tree distance along roads;
{
tree_distance
}
; [m]
\n
"
)
csv
.
write
(
f
"# Tree distance along roads;
{
tree_distance
}
; [m]
\n
"
)
...
@@ -193,13 +197,13 @@ def export_csv(bounds, tree_xs, tree_ys, wkt_polygon, tree_distance, min_distanc
...
@@ -193,13 +197,13 @@ def export_csv(bounds, tree_xs, tree_ys, wkt_polygon, tree_distance, min_distanc
csv
.
write
(
f
"# EPSG;
{
epsg_id
}
\n
"
)
csv
.
write
(
f
"# EPSG;
{
epsg_id
}
\n
"
)
csv
.
write
(
"# X; Y
\n
"
)
csv
.
write
(
"# X; Y
\n
"
)
csv
.
write
(
"# [m]; [m]
\n
"
)
csv
.
write
(
"# [m]; [m]
\n
"
)
for
x
,
y
in
zip
(
tree_xs
,
tree_ys
)
:
for
tree
in
forest
:
csv
.
write
(
f
"
{
x
}
;
{
y
}
\n
"
)
csv
.
write
(
f
"
{
tree
.
x
}
;
{
tree
.
y
}
\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
)
region
,
bounds
=
load_region
(
wkt_polygon
)
ways
=
get_osm_roads
(
bounds
)
ways
=
get_osm_roads
(
bounds
)
...
@@ -213,12 +217,12 @@ def main(wkt_polygon, epsg_id, tree_distance, min_distance, import_tree_shp):
...
@@ -213,12 +217,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
)
to_local
=
Transformer
.
from_crs
(
"EPSG:4326"
,
f
"EPSG:
{
epsg_id
}
"
,
always_xy
=
True
)
set_plot
(
bounds
,
to_local
)
set_plot
(
bounds
,
to_local
)
tree_xs
,
tree_ys
=
place_trees
(
existing_forest
,
ways
,
region
,
to_local
,
tree_distance
,
min_distance
**
2
)
forest
=
place_trees
(
existing_forest
,
ways
,
region
,
to_local
,
tree_distance
,
min_distance
**
2
)
print
(
repr
(
existing_forest
)
)
print
(
existing_forest
)
plot_trees
(
bounds
,
tree_xs
,
tree_ys
,
tree_distance
)
plot_trees
(
bounds
,
forest
,
tree_distance
)
export_map
(
bounds
,
tree_xs
,
tree_ys
,
epsg_id
)
export_map
(
bounds
,
forest
,
epsg_id
)
export_csv
(
bounds
,
tree_xs
,
tree_ys
,
wkt_polygon
,
export_csv
(
bounds
,
forest
,
wkt_polygon
,
tree_distance
,
min_distance
,
epsg_id
)
tree_distance
,
min_distance
,
epsg_id
)
...
...
python_scripts/add_trees_to_open_street_map/tree.py
View file @
361b1885
from
dataclasses
import
dataclass
from
dataclasses
import
dataclass
from
collections
import
UserList
import
kdtree
import
kdtree
...
@@ -19,32 +20,36 @@ class Tree:
...
@@ -19,32 +20,36 @@ class Tree:
def
__getitem__
(
self
,
i
):
def
__getitem__
(
self
,
i
):
return
[
self
.
x
,
self
.
y
][
i
]
return
[
self
.
x
,
self
.
y
][
i
]
def
__str__
(
self
):
return
f
"
{
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
=
[]):
def
__init__
(
self
,
existing_trees
=
[]):
if
existing_trees
:
if
existing_trees
:
self
.
kd_tree
=
kdtree
.
create
(
existing_trees
,
dimensions
=
2
)
self
.
kd_tree
=
kdtree
.
create
(
existing_trees
,
dimensions
=
2
)
else
:
else
:
self
.
kd_tree
=
kdtree
.
create
([(
0
,
0
)],
dimensions
=
2
)
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
):
def
add_tree_if_possible
(
self
,
min_distance_2
,
x
,
y
,
**
kparams
):
_nearest_tree
,
distance_2
=
self
.
kd_tree
.
search_nn
((
x
,
y
))
_nearest_tree
,
distance_2
=
self
.
kd_tree
.
search_nn
((
x
,
y
))
if
distance_2
>
min_distance_2
:
if
distance_2
>
min_distance_2
:
self
.
kd_tree
.
add
((
x
,
y
))
self
.
kd_tree
.
add
((
x
,
y
))
self
.
trees
.
append
(
Tree
(
x
,
y
,
**
kparams
))
self
.
append
(
Tree
(
x
,
y
,
**
kparams
))
@
property
@
property
def
xs_ys
(
self
):
def
xs_ys
_cs
(
self
):
xs
,
ys
=
[],
[]
xs
,
ys
,
colors
=
[],
[],
[]
for
tree
in
self
.
trees
:
for
tree
in
self
:
xs
.
append
(
tree
.
x
)
xs
.
append
(
tree
.
x
)
ys
.
append
(
tree
.
y
)
ys
.
append
(
tree
.
y
)
return
xs
,
ys
colors
.
append
(
tree
.
color
)
return
xs
,
ys
,
colors
def
__str__
(
self
):
def
__str__
(
self
):
return
f
"Forest with
{
len
(
self
.
trees
)
}
trees."
return
f
"Forest with
{
len
(
self
)
}
trees."
def
__repr__
(
self
):
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
])
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment