Replies: 5 comments 18 replies
-
Yes, definitely, I'm interested in exploring map data and py5. I've wanted to do this for a long time but simply haven't had the time. Making progress with py5+shapely would be a step in the right direction, and make it easier for someone else to take the next step do something with mapping data. |
Beta Was this translation helpful? Give feedback.
-
If I had the time I would study @marceloprates's prettymaps code. |
Beta Was this translation helpful? Give feedback.
-
My crude explorations, some progress :) # Draws ways and buildings from data © OpenStreetMap contributors
import py5
from shapely import Polygon, MultiPolygon
from shapely import LineString, MultiLineString, LinearRing
from shapely import Point, MultiPoint
from shapely import GeometryCollection
from shapely.ops import transform
import osmnx as ox
ox.settings.log_console=True
ox.settings.use_cache=True
from geopandas import GeoDataFrame
bgcolor = '#343434'
edge_color = '#CCCCCC'
bldg_color = '#008888'
point = ox.geocode('Avenida Paulista, São Paulo, Brasil')
dist = 2000
bbox = ox.utils_geo.bbox_from_point(point, dist=dist)
fp = ox.features_from_point(point, tags={'building':True}, dist=dist)
G = ox.graph_from_point(point, network_type='walk', dist=dist, truncate_by_edge=True, retain_all=True)
nodes, edges = ox.graph_to_gdfs(G)
m_edges = edges.to_crs(epsg=3857)
m_fp = fp.to_crs(epsg=3857)
#m_edges = edges.set_crs('EPSG:4326').to_crs('EPSG:3857')
paulista = m_edges[m_edges['name'] == 'Avenida Paulista']
#selected_edges_gdf = gdf_meters[gdf_meters['edge_id'].isin(selected_edges)]
paulista_length = paulista.geometry.length.sum()
print(paulista_length) # value seems wrong!!!
# for debugging:
import matplotlib.pyplot as plt
fig, ax = ox.plot_graph(G, bgcolor=bgcolor, node_size=0, edge_color=edge_color, show=False)
fig, ax = ox.plot_footprints(fp, ax=ax, bbox=bbox, color=bldg_color, show=False) #, save=True)
paulista.plot(ax=ax, color='red')
# an then call plt.show() at the REPL...
def setup():
py5.size(800, 800)
py5.background(bgcolor)
#py5.translate(400, 400)
minx, miny, maxx, maxy = m_edges.total_bounds
scale_x = py5.width / (maxx - minx)
scale_y = py5.height / (maxy - miny)
translate_x = -minx * scale_x
translate_y = -miny * scale_y
matrix = [scale_x, 0, 0, scale_y, translate_x, translate_y]
screen_edges = m_edges['geometry'].affine_transform(matrix).apply(flip_y)
screen_buildings = m_fp['geometry'].affine_transform(matrix).apply(flip_y)
screen_paulista = paulista.affine_transform(matrix).apply(flip_y)
py5.no_stroke()
py5.fill(bldg_color)
draw_shapely(b for b in screen_buildings if b.area)
py5.stroke(edge_color)
draw_shapely(screen_edges)
py5.stroke(255, 0, 0)
draw_shapely(screen_paulista)
py5.save(f'{__file__[:-3]}.png')
def flip_y(geom):
return transform(lambda x, y: (x, -y + py5.height), geom)
def draw_shapely(shps, sketch: py5.Sketch=None):
"""
Draw most shapely objects with py5.
This will use the "current" py5 sketch as default.
"""
s = sketch or py5.get_current_sketch()
if isinstance(shps, (MultiPolygon, MultiLineString, GeometryCollection)):
for shp in shps.geoms:
draw_shapely(shp)
elif isinstance(shps, Polygon):
with s.begin_closed_shape():
s.vertices(shps.exterior.coords)
for hole in shps.interiors:
with s.begin_contour():
s.vertices(hole.coords)
elif isinstance(shps, (LineString, LinearRing)):
# no need to uses begin_closed_shape() because LinearRing repeats the start/end coordinates
with s.push_style():
s.no_fill()
with s.begin_shape():
s.vertices(shps.coords)
elif isinstance(shps, Point):
s.point(shps.x, shps.y)
elif isinstance(shps, MultiPoint):
s.points((p.x, p.y) for p in shps.geoms)
elif isinstance(shps, GeoDataFrame):
for shp in shps.geometry:
draw_shapely(shp)
else:
try:
for shp in shps:
draw_shapely(shp)
except TypeError as e:
print(f"Unable to draw: {shps}")
py5.run_sketch(block=False) |
Beta Was this translation helpful? Give feedback.
-
Hmm, I have some GPS data of my bicycle riding in a city park - may be it's time to build a map of bicycle routes.) |
Beta Was this translation helpful? Give feedback.
-
Here's a map made in py5 with prettymaps: Do you recognize the location? This is a prototype but it is in pretty good shape. While building this I found a bug in Processing and made a PR and also found a bug in py5's new shapely integration code. Working on this has been a useful test of the new py5 feature. @marceloprates , the plotter / vsketch mode seems to be commented out and is not working? I need to support the "background" functionality and maybe some other things I am missing. The py5 code is still a bit messy and I will make sure there are no bugs on my end before asking you to do anything. py5 does not have hatching so we'll want to make some presets that are well suited for py5. I'll enlist @villares and others for help with that when the prototype is ready for it. |
Beta Was this translation helpful? Give feedback.
-
I know it can sound a bit ridiculous, but, maybe if someone with the right skills comes by...
I noticed that geocoded data in a geodataframe can contain shapely geometry, and previously I have played with Unfolding Maps in Processing.py so, some geo/map viz would be great to have.
Beta Was this translation helpful? Give feedback.
All reactions