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
a1cb6c53
Commit
a1cb6c53
authored
Mar 26, 2024
by
Eric Duminil
Browse files
Able to export Shapefile now
parent
a5b79d6b
Changes
5
Show whitespace changes
Inline
Side-by-side
python_scripts/add_trees_to_open_street_map/.gitignore
View file @
a1cb6c53
cache
cache
*.html
*.csv
*.png
\ No newline at end of file
python_scripts/add_trees_to_open_street_map/add_trees.py
View file @
a1cb6c53
...
@@ -17,6 +17,8 @@ import overpy
...
@@ -17,6 +17,8 @@ import overpy
from
pyproj
import
Transformer
from
pyproj
import
Transformer
from
shapely
import
LineString
,
geometry
,
wkt
from
shapely
import
LineString
,
geometry
,
wkt
from
shapely.ops
import
transform
from
shapely.ops
import
transform
import
pandas
as
pd
import
geopandas
as
gpd
from
tree
import
Forest
from
tree
import
Forest
from
import_existing_trees
import
get_existing_forest
from
import_existing_trees
import
get_existing_forest
...
@@ -47,11 +49,13 @@ IGNORE_ROADS = set(['primary', 'unclassified', 'secondary',
...
@@ -47,11 +49,13 @@ IGNORE_ROADS = set(['primary', 'unclassified', 'secondary',
SCRIPT_DIR
=
Path
(
__file__
).
resolve
().
parent
SCRIPT_DIR
=
Path
(
__file__
).
resolve
().
parent
OUTPUT_DIR
=
SCRIPT_DIR
/
'output'
Bounds
=
namedtuple
(
"Bounds"
,
"W S E N"
)
def
load_region
(
wkt_polygon
):
def
load_region
(
wkt_polygon
):
region
=
wkt
.
loads
(
wkt_polygon
)
region
=
wkt
.
loads
(
wkt_polygon
)
bounds
=
namedtuple
(
"Bounds"
,
"W S E N"
)
(
*
region
.
bounds
)
bounds
=
Bounds
(
*
region
.
bounds
)
return
region
,
bounds
return
region
,
bounds
...
@@ -140,22 +144,23 @@ def place_trees(forest, ways, region, to_local, tree_distance, min_distance_2) -
...
@@ -140,22 +144,23 @@ def place_trees(forest, ways, region, to_local, tree_distance, min_distance_2) -
color
=
'#DFFF00'
,
color
=
'#DFFF00'
,
type
=
'Fake Tree'
,
type
=
'Fake Tree'
,
description
=
'Tilia tomentosa'
,
description
=
'Tilia tomentosa'
,
diameter
=
6
diameter
=
6
,
source
=
'add_trees.py'
)
)
return
forest
return
forest
def
plot_trees
(
bounds
,
f
orest
,
tree_distance
)
->
None
:
def
plot_trees
(
bounds
:
Bounds
,
forest
:
F
orest
,
tree_distance
:
float
)
->
None
:
print
(
"Exporting diagram..."
)
print
(
"Exporting diagram..."
)
tree_xs
,
tree_ys
,
colors
=
forest
.
xs_ys_c
6
tree_xs
,
tree_ys
,
colors
=
forest
.
xs_ys_c
s
plt
.
scatter
(
tree_xs
,
tree_ys
,
s
=
2
,
c
=
colors
)
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"
)
plt
.
gcf
().
set_size_inches
(
15
,
10
)
plt
.
gcf
().
set_size_inches
(
15
,
10
)
plt
.
savefig
(
plt
.
savefig
(
SCRIP
T_DIR
/
f
"
{
get_basename
(
bounds
)
}
.png"
,
bbox_inches
=
'tight'
,
dpi
=
300
)
OUTPU
T_DIR
/
f
"
{
get_basename
(
bounds
)
}
.png"
,
bbox_inches
=
'tight'
,
dpi
=
300
)
print
(
" DONE!"
)
print
(
" DONE!"
)
...
@@ -188,27 +193,49 @@ def export_map(bounds, forest, epsg_id) -> None:
...
@@ -188,27 +193,49 @@ def export_map(bounds, forest, epsg_id) -> None:
control
=
True
control
=
True
).
add_to
(
interactive_map
)
).
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!"
)
print
(
" DONE!"
)
def
export_csv
(
bounds
,
forest
,
wkt_polygon
,
tree_distance
,
min_distance
,
epsg_id
)
->
None
:
def
export_csv
(
bounds
,
forest
,
wkt_polygon
,
tree_distance
,
min_distance
,
epsg_id
)
->
None
:
print
(
"Exporting CSV..."
)
print
(
"Exporting CSV..."
)
with
open
(
SCRIP
T_DIR
/
f
"
{
get_basename
(
bounds
)
}
_trees.csv"
,
"w"
)
as
csv
:
with
open
(
OUTPU
T_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
"
)
csv
.
write
(
f
"# Minimum allowed distance between trees;
{
min_distance
}
; [m]
\n
"
)
csv
.
write
(
f
"# Minimum allowed distance between trees;
{
min_distance
}
; [m]
\n
"
)
csv
.
write
(
f
"# EPSG;
{
epsg_id
}
\n
"
)
csv
.
write
(
f
"# EPSG;
{
epsg_id
}
\n
"
)
csv
.
write
(
"# X; Y; Type; Description; Radius
\n
"
)
csv
.
write
(
"# X; Y; Type; Description; Radius
; Source
\n
"
)
csv
.
write
(
"# [m]; [m]; [
?
]; [
?
]; [m]
\n
"
)
csv
.
write
(
"# [m]; [m]; [
-
]; [
-
]; [m]
; [-]
\n
"
)
for
tree
in
forest
:
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!"
)
print
(
" DONE!"
)
def
export_shapefile
(
bounds
,
f
orest
,
tree_distance
,
epsg_id
)
:
def
export_shapefile
(
bounds
:
Bounds
,
forest
:
F
orest
,
tree_distance
:
float
,
epsg_id
:
str
)
->
None
:
print
(
"Exporting shapefile"
)
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!"
)
print
(
" DONE!"
)
...
...
python_scripts/add_trees_to_open_street_map/import_existing_trees.py
View file @
a1cb6c53
from
pathlib
import
Path
import
geopandas
as
gpd
import
geopandas
as
gpd
from
tree
import
Tree
,
Forest
from
tree
import
Tree
,
Forest
...
@@ -11,7 +12,8 @@ def get_existing_forest(shp_input):
...
@@ -11,7 +12,8 @@ def get_existing_forest(shp_input):
description
=
tree_row
.
Bezeichnun
,
description
=
tree_row
.
Bezeichnun
,
diameter
=
tree_row
.
Kronenbrei
,
diameter
=
tree_row
.
Kronenbrei
,
type
=
tree_row
.
Baumart
,
type
=
tree_row
.
Baumart
,
trunk_diameter
=
tree_row
.
Stammumfan
trunk_diameter
=
tree_row
.
Stammumfan
,
source
=
Path
(
shp_input
).
name
))
))
return
Forest
(
trees
)
return
Forest
(
trees
)
...
...
python_scripts/add_trees_to_open_street_map/output/.gitignore
0 → 100644
View file @
a1cb6c53
*.png
*.html
*.csv
*.cpg
*.dbf
*.shp
*.prj
*.shx
*.geojson
\ No newline at end of file
python_scripts/add_trees_to_open_street_map/tree.py
View file @
a1cb6c53
...
@@ -13,6 +13,7 @@ class Tree:
...
@@ -13,6 +13,7 @@ class Tree:
trunk_diameter
:
float
=
None
trunk_diameter
:
float
=
None
type
:
str
=
None
type
:
str
=
None
description
:
str
=
'?'
description
:
str
=
'?'
source
:
str
=
'?'
color
:
str
=
'green'
color
:
str
=
'green'
def
__len__
(
self
):
def
__len__
(
self
):
...
@@ -26,7 +27,7 @@ class Tree:
...
@@ -26,7 +27,7 @@ class Tree:
return
self
.
diameter
/
2
return
self
.
diameter
/
2
def
__str__
(
self
):
def
__str__
(
self
):
return
f
"
{
self
.
type
}
(
{
self
.
description
}
),
{
self
.
radius
or
'?'
}
m (X=
{
self
.
x
:
.
1
f
}
, Y=
{
self
.
y
:
.
1
f
}
)"
return
f
"
{
self
.
type
}
(
{
self
.
description
}
),
{
self
.
radius
}
m (X=
{
self
.
x
:
.
1
f
}
, Y=
{
self
.
y
:
.
1
f
}
)"
class
Forest
(
UserList
):
class
Forest
(
UserList
):
...
...
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