## Sesc Av. Paulista
# Ilustração com mapas, dados georeferenciados e programação - Aula 2
### `hackmd.io/@sesc-av-paulista/ilustra-mapas-2025-a2` - [índice](https://hackmd.io/@sesc-av-paulista/ilustra-mapas-2025)
- Funções da biblioteca `osmnx` https://osmnx.readthedocs.io/en/stable/user-reference.html#module-osmnx.features
- Tags no OpenStreetMap https://wiki.openstreetmap.org/wiki/Map_features
```python=
import py5 # biblioteca de desenho
import osmnx as ox # para pegar dados do OSM
# Obter tupla (lat, long) de um endereço (geocofing)
sé = ox.geocode('Praça da Sé, São Paulo, SP, Brasil')
# Obter GeoDataFrame de um local (place)
municipio = ox.geocode_to_gdf('São Paulo, Brasil')
# municipio.geometry[0] shapely.Polygon
def setup():
py5.size(600, 600)
# Calculo para caber na tela usando .total_bounds do GDF
x_min, y_min, x_max, y_max = municipio.total_bounds
map_w, map_h = (x_max - x_min), (y_max - y_min)
x_scale = y_scale = py5.height / map_h
# Aplicar uma tranformação (encolher pra caber na tela) inverte Y
translate_and_scale_gdf(municipio, -x_min, -y_min, x_scale, -y_scale)
# Desenhar na tela
forma = municipio.geometry[0]
py5.shape(forma, 0, 600) # conversão implícita de shapely.Polygon em Py5Shape
# Salvar um PNG
# py5.save_frame('são paulo.png')
def translate_and_scale_gdf(gdf, x, y, x_scale, y_scale):
gdf['geometry'] = gdf.geometry.translate(x, y)
gdf['geometry'] = gdf.geometry.scale(
xfact=x_scale, yfact=y_scale, origin=(0, 0))
py5.run_sketch(block=False)
```
# Águas
```python=
import py5 # biblioteca de desenho
import osmnx as ox # para pegar dados do OSM em geopandas.GeoDatFrama
import shapely # biblioteca de geometria usada pelo geopandas
ox.settings.log_console = True
# Obter tupla (lat, long) de um endereço (geocofing)
sé = ox.geocode('Praça da Sé, São Paulo, SP, Brasil')
# Obter GeoDataFrame de um local (place)
municipio = ox.geocode_to_gdf('São Paulo, Brasil')
# muciopio.geometry[0] shapely.Polygon
aguas = ox.features.features_from_place(
'São Paulo, Brasil',
tags={'water': True}
)
def setup():
py5.size(600, 600)
# Calculo para caber na tela usando .total_bounds do GDF
x_min, y_min, x_max, y_max = municipio.total_bounds
map_w, map_h = (x_max - x_min), (y_max - y_min)
x_scale = y_scale = py5.height / map_h
# Aplicar uma tranformação (encolher pra caber na tela) inverte Y
translate_and_scale_gdf(municipio, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(aguas, -x_min, -y_min, x_scale, -y_scale)
# Desenhar na tela
py5.no_stroke()
forma = municipio.geometry[0] # pegando a primeira geometria
py5.fill(240)
py5.shape(forma, 0, py5.height) # conversão implícita de shapely.Polygon em Py5Shape
py5.fill(0, 0, 100) # azul escuro
geometrias = shapely.GeometryCollection(list(aguas.geometry))
py5.shape(geometrias, 0, py5.height)
# Salvar um PNG
# py5.save_frame('são paulo.png')
def translate_and_scale_gdf(gdf, x, y, x_scale, y_scale):
gdf['geometry'] = gdf.geometry.translate(x, y)
gdf['geometry'] = gdf.geometry.scale(
xfact=x_scale, yfact=y_scale, origin=(0, 0))
py5.run_sketch(block=False)
```
## Prédios no entorno do Pátio do Colégio
Ruas não ficaram legais
```python=
import py5 # biblioteca de desenho
import osmnx as ox # para pegar dados do OSM em geopandas.GeoDatFrama
import shapely # biblioteca de geometria usada pelo geopandas
ox.settings.log_console = True
# Obter tupla (lat, long) de um endereço (geocofing)
ponto = ox.geocode('Patío do Colégio, São Paulo, SP, Brasil')
# Obter GeoDataFrame de um local (place)
# muciopio.geometry[0] shapely.Polygon
predios = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'building': True},
dist=1000
)
aguas = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'water': True},
dist=1000
)
ruas = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'streets': True},
dist=1000
)
def setup():
py5.size(800, 800)
# Calculo para caber na tela usando .total_bounds do GDF
x_min, y_min, x_max, y_max = predios.total_bounds
map_w, map_h = (x_max - x_min), (y_max - y_min)
x_scale = y_scale = py5.height / map_h
# Aplicar uma tranformação (encolher pra caber na tela) inverte Y
translate_and_scale_gdf(predios, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(ruas, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(aguas, -x_min, -y_min, x_scale, -y_scale)
# Desenhar na tela predios
py5.stroke_weight(0.5)
py5.stroke(0) # cor do traço
py5.fill(100) # cinza escuro
geometria_predios = shapely.GeometryCollection(list(predios.geometry))
py5.shape(geometria_predios, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar ruas
py5.no_stroke()
py5.fill(240) # cinza escuro
geometria_ruas = shapely.GeometryCollection(list(ruas.geometry))
py5.shape(geometria_ruas, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar aguas
py5.no_stroke()
py5.fill(0, 0, 200) # cinza escuro
geometria_aguas = shapely.GeometryCollection(list(aguas.geometry))
py5.shape(geometria_aguas, 0, py5.height) # desenhar começando na parte de baixo da tela
def translate_and_scale_gdf(gdf, x, y, x_scale, y_scale):
gdf['geometry'] = gdf.geometry.translate(x, y)
gdf['geometry'] = gdf.geometry.scale(
xfact=x_scale, yfact=y_scale, origin=(0, 0))
py5.run_sketch(block=False) # tirar block=False no MacOS
```
### Usando grafo dos caminhos - predios com cores
```python=
import py5 # biblioteca de desenho
import osmnx as ox # para pegar dados do OSM em geopandas.GeoDatFrama
import shapely # biblioteca de geometria usada pelo geopandas
DIST = 1000
ox.settings.log_console = True
# Obter tupla (lat, long) de um endereço (geocofing)
ponto = ox.geocode('Patío do Colégio, São Paulo, SP, Brasil')
# Obter GeoDataFrame de um local (place)
predios = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'building': True},
dist=DIST
)
aguas = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'water': True},
dist=DIST
)
graph = ox.graph_from_point(
ponto, network_type='all', dist=DIST
)
gdf_nodes, caminhos = ox.graph_to_gdfs(
graph,
nodes=True, edges=True,
node_geometry=True,
fill_edge_geometry=False
)
def setup():
py5.size(800, 800)
py5.begin_record(py5.PDF, 'mapa.pdf')
py5.background(0) # branco
# Calculo para caber na tela usando .total_bounds do GDF
x_min, y_min, x_max, y_max = predios.total_bounds
map_w, map_h = (x_max - x_min), (y_max - y_min)
x_scale = y_scale = py5.height / map_h
# Aplicar uma tranformação (encolher pra caber na tela) inverte Y
translate_and_scale_gdf(predios, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(caminhos, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(aguas, -x_min, -y_min, x_scale, -y_scale)
# Desenhar na tela predios
py5.stroke_weight(0.1)
py5.stroke(0) # cor do traço
py5.fill(100) # cinza escuro
grupo_predios = py5.create_shape(py5.GROUP)
for geometria_predio in predios.geometry:
py5.fill(py5.random(255), py5.random(255), py5.random(255))
grupo_predios.add_child(py5.convert_shape(geometria_predio))
py5.shape(grupo_predios, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar ruas
py5.stroke('#96E9CD') # cor de traço das ruas
py5.stroke_weight(1.5)
py5.fill(240) # cinza escuro
geometria_caminhos = shapely.GeometryCollection(list(caminhos.geometry))
py5.shape(geometria_caminhos, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar aguas
py5.no_stroke()
py5.fill(0, 0, 200) # azul escuro R, G, B de 0 a 255
geometria_aguas = shapely.GeometryCollection(list(aguas.geometry))
py5.shape(geometria_aguas, 0, py5.height) # desenhar começando na parte de baixo da tela
py5.end_record()
def translate_and_scale_gdf(gdf, x, y, x_scale, y_scale):
gdf['geometry'] = gdf.geometry.translate(x, y)
gdf['geometry'] = gdf.geometry.scale(
xfact=x_scale, yfact=y_scale, origin=(0, 0))
py5.run_sketch(block=False) # tirar block=False no MacOS
```
### Coloridão Saturado
```python=
import py5 # biblioteca de desenho
import osmnx as ox # para pegar dados do OSM em geopandas.GeoDatFrama
import shapely # biblioteca de geometria usada pelo geopandas
DIST = 1000
ox.settings.log_console = True
# Obter tupla (lat, long) de um endereço (geocofing)
ponto = ox.geocode('Patío do Colégio, São Paulo, SP, Brasil')
# Obter GeoDataFrame de um local (place)
predios = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'building': True},
dist=DIST
)
aguas = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'water': True},
dist=DIST
)
graph = ox.graph_from_point(
ponto, network_type='all', dist=DIST
)
gdf_nodes, caminhos = ox.graph_to_gdfs(
graph,
nodes=True, edges=True,
node_geometry=True,
fill_edge_geometry=False
)
def setup():
py5.size(800, 800)
py5.begin_record(py5.PDF, 'mapa.pdf')
py5.color_mode(py5.HSB) # Hue (Matiz), Saturation, Brightness
py5.background(0) # preto
# Calculo para caber na tela usando .total_bounds do GDF
x_min, y_min, x_max, y_max = predios.total_bounds
map_w, map_h = (x_max - x_min), (y_max - y_min)
x_scale = y_scale = py5.height / map_h
# Aplicar uma tranformação (encolher pra caber na tela) inverte Y
translate_and_scale_gdf(predios, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(caminhos, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(aguas, -x_min, -y_min, x_scale, -y_scale)
# Desenhar na tela predios
py5.stroke_weight(0.1)
py5.stroke(0) # cor do traço
py5.fill(100) # cinza escuro
grupo_predios = py5.create_shape(py5.GROUP)
for geometria_predio in predios.geometry:
py5.fill(py5.random(255), 255, 255) # Hue, Sat, Bri
grupo_predios.add_child(py5.convert_shape(geometria_predio))
py5.shape(grupo_predios, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar ruas
py5.stroke(255) # cor de traço das ruas
py5.stroke_weight(1.5)
py5.fill(240) # cinza escuro
geometria_caminhos = shapely.GeometryCollection(list(caminhos.geometry))
py5.shape(geometria_caminhos, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar aguas
py5.no_stroke()
py5.fill(0, 0, 200) # cinza 200
geometria_aguas = shapely.GeometryCollection(list(aguas.geometry))
py5.shape(geometria_aguas, 0, py5.height) # desenhar começando na parte de baixo da tela
py5.end_record()
def translate_and_scale_gdf(gdf, x, y, x_scale, y_scale):
gdf['geometry'] = gdf.geometry.translate(x, y)
gdf['geometry'] = gdf.geometry.scale(
xfact=x_scale, yfact=y_scale, origin=(0, 0))
py5.run_sketch(block=False) # tirar block=False no MacOS
```
### Brasília
```python=
import py5 # biblioteca de desenho
import osmnx as ox # para pegar dados do OSM em geopandas.GeoDataFrame
import shapely # biblioteca de geometria usada pelo geopandas
DIST = 7000
ox.settings.log_console = True
# Obter tupla (lat, long) de um endereço (geocoding)
ponto = ox.geocode('Brasília, DF, Brasil')
# Obter GeoDataFrame de um local (place)
predios = ox.features.features_from_point(
ponto, # tupla de cooredenadas
tags={'building': True},
dist=DIST
)
aguas = ox.features.features_from_point(
ponto, # tupla de cooedenadas
tags={'water': True},
dist=DIST
)
graph = ox.graph_from_point(
ponto, network_type='walk', dist=DIST
)
gdf_nodes, caminhos = ox.graph_to_gdfs(
graph,
nodes=True, edges=True,
node_geometry=True,
fill_edge_geometry=False
)
def setup():
py5.size(800, 800)
# começa a gravar um pdf
py5.begin_record(py5.PDF, 'mapa-bsb.pdf')
py5.color_mode(py5.HSB) # Hue (Matiz), Saturation, Brightness
py5.background(0) # preto
# Calculo para caber na tela usando .total_bounds do GDF
x_min, y_min, x_max, y_max = caminhos.total_bounds
map_w, map_h = (x_max - x_min), (y_max - y_min)
x_scale = y_scale = py5.height / map_h
# Aplicar tranformação nos GDFs (encolher pra caber na tela) inverte Y
translate_and_scale_gdf(predios, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(caminhos, -x_min, -y_min, x_scale, -y_scale)
translate_and_scale_gdf(aguas, -x_min, -y_min, x_scale, -y_scale)
# Desenhar aguas
py5.no_stroke()
py5.fill(0, 0, 200) # cinza 200
geometria_aguas = aguas.geometry.union_all()
py5.shape(geometria_aguas, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar na tela predios
py5.stroke_weight(0.1)
py5.stroke(0) # cor do traço
grupo_predios = py5.create_shape(py5.GROUP)
for geometria_predio in predios.geometry:
py5.fill(py5.random(255), 255, 255) # Matiz/Hue aleatório, Sat max, Brilho max
grupo_predios.add_child(py5.convert_shape(geometria_predio))
py5.shape(grupo_predios, 0, py5.height) # desenhar começando na parte de baixo da tela
# Desenhar ruas
py5.stroke(255) # cor de traço das ruas
py5.stroke_weight(0.5)
geometria_caminhos = caminhos.geometry.union_all()
py5.shape(geometria_caminhos, 0, py5.height) # desenhar começando na parte de baixo da tela
# termina de gravar o PDF
py5.end_record()
def translate_and_scale_gdf(gdf, x, y, x_scale, y_scale):
gdf['geometry'] = gdf.geometry.translate(x, y)
gdf['geometry'] = gdf.geometry.scale(
xfact=x_scale, yfact=y_scale, origin=(0, 0))
py5.run_sketch(block=False) # remove block=False if on MacOS
```
