Topónimo Quintana en Cataluña

Siguiendo el mismo esquema y código que hemos hecho en la Cataluña Mágica del post anterior, hemos publicado rápidamente los topónimos Quintana que hay en Cataluña.

Una Quintana o quintà hace referencia a la quinta parte que tenían que pagar los payeses en impuestos, y con el tiempo una Quintana acabó significando una masía y los campos de alrededor, es decir, lo que hoy llamamos una finca. De aquí viene el apellido Quintana, tanto en catalán como en castellano, que se escriben igual y viene directamente del latín. Mi apellido Quintana viene de la masía La Quintana de Oristà, que tuvimos la suerte de visitar hace unos años, con mis padres, hermanos, primos y familia. Los Quintana de Cabrianes vienen de esta casa de payés de Oristá. Mi bisabuelo (el abuelo de mi padre, acs) era de Cabrianes y se casó en Bagà. De aquí el apellido Quintana en Bagà, Guardiola y Berguedá. Jo soy de Barcelona, pero estas son mis raíces por parte de mi abuelo paterno.

Referencias:


Cataluña Mágica

Se ha publicado la web de la Cataluña Mágica: demonios, infierno, brujas y diablos, con información extraída de OpenStreetMap.

Hemos utiltzado OpenLayers 6.5.0 (con el paradigma de imports), y los tiles estandard de OSM y también TRESC, una capa de visualización que me gusta mucho. Los datos que se obtienen pueden ser nodos o vías, y ha habido un trabajo previo de limpiar un poco los datos, pero todo ha sido un proceso muy rápido.

Referencias:

Segmentos de ciclismo con la API de Strava

De la API de Strava me interesa sobretodo la parte de segmentos, que son trozos de rutas donde la gent se cronometra y se publican los rankings. Sin una subscripción Premium no se puede acceder a toda la información. Jugando un rato con la API de Strava he llegado a poder ver los segmentos que hay en una zona geográfica, y poder ver los puntos de este segmento, que se pueden representar en cualquier mapa.

Para acceder a la información de un segmento:

$ curl -X GET https://www.strava.com/api/v3/segments/229781 -H 'Authorization: Bearer *******************'

Y el resultado:

{"id":229781,"resource_state":3,"name":"Hawk Hill","activity_type":"Ride","distance":2684.82,"average_grade":5.8,"maximum_grade":10.9,"elevation_high":247.2,"elevation_low":92.0,"start_latlng":[37.833112,-122.483436],"end_latlng":[37.828072,-122.498139],"elevation_profile":"https://d3o5xota0a1fcr.cloudfront.net/v6/charts/KO5P7GCFLK5P5NF5GNUX3D6IVFLIEYRYD6JRBEGMXHOCPENJUQZXD5IIEJOYINQE2HX3XLZMYRTF5GHG5JLQ====","start_latitude":37.833112,"start_longitude":-122.483436,"end_latitude":37.828072,"end_longitude":-122.498139,"climb_category":1,"city":"San Francisco","state":"CA","country":"United States","private":false,"hazardous":false,"starred":false,"created_at":"2009-09-21T20:29:41Z","updated_at":"2021-03-13T09:01:33Z","total_elevation_gain":155.2,

"map":{"id":"s229781","polyline":"}g|eFnpqjVl@En@Md@HbAd@d@^h@Xx@VbARjBDh@OPQf@w@d@k@XKXDFPF\\CbGT`AV`@v@|@NTNb@?XOb@cAxAWLuE@eAFMBoAv@eBt@q@b@}@tAeAt@i@dAC`AFZj@dBA~@Yh@MbAVn@b@b@\\d@Ef@Qd@_@d@eB|@c@h@YfBI|AMpA?VF\\\\t@f@t@h@j@|@b@hCb@b@XTd@Bl@GtA?jAL`ALp@Tr@RXd@Rx@Pn@^Zh@Tx@Zf@`@FTCzDy@f@Yx@m@n@Op@VJr@","resource_state":3},

"effort_count":556805,"athlete_count":49100,"star_count":5022,"athlete_segment_stats":{"pr_elapsed_time":null,"pr_date":null,"pr_activity_id":null,"effort_count":0},"xoms":{"kom":"5:37","qom":"6:42","destination":{"href":"strava://segments/229781/leaderboard","type":"overall","name":"All-Time"}},"local_legend":{"athlete_id":54312907,"title":"Dalton Nonweiler","profile":"https://dgalywyr863hv.cloudfront.net/pictures/athletes/54312907/14907176/5/large.jpg","effort_description":"86 efforts in the last 90 days","effort_count":"86","effort_counts":{"overall":"86 efforts","female":"41 efforts"},"destination":"strava://segments/229781/local_legend?categories%5B%5D=overall"}}

Vemos que la polilinea está codificada en una cadena de texto. La podemos decodificar y obtener las coordenadas:

$ pip3 install polyline

$ python3
>> import polyline
>> #polyline.decode(summary_polyline)
>> polyline.decode("gxu{Fem|Kc@fAq@fAoApAMR[ZMXw@v@a@VQZi@j@sAhAk@hA_@f@oDxCiAhA_@j@a@~@{@pCC`@EFD^H`B?`@BNNZV@JGDMEqA@q@H]NOFSLo@t@eB^i@d@i@t@m@n@Yz@EHBR\\`AdDFdEJ`@RNHIVGf@ATH`At@VXDl@GJU@WY[e@YSKC_@GgA@YMKMc@eBYeBSWg@AUTSVa@|@[tAAPDb@Nr@@TCb@[bACd@BNJ^Xh@N^BNB`@Nn@DJTNZ\\Rn@?\\c@zAA^B\\JZHHh@NZDVHTRHJBNAb@I|@B\\Th@PTVf@F`@Cl@Sj@WJ{Ae@{@OKBSPOr@IvA[z@UTw@JWE_@]QUUKKCu@Hs@NMEIIi@kAOUGE]OUMGIGY?y@XiB@]E]U[SGU?c@XcA`Aw@|@i@~@WbASPK?IC_Au@q@_@SAI@g@Lo@XK?YB[MYOQSQYi@Y_@AK@CDg@X]Bg@KUMi@e@[k@GU@MHQb@a@DIFU@WIYg@u@]y@IqAP{ABq@Is@e@iB}@wAw@oBk@aAa@g@g@w@Km@Q{AYkB_AmCc@eB?]H]NWxAiBZq@JYFm@@m@C[G]OWa@k@eAu@o@k@iBkCm@k@SKc@CK@]LS@e@]]]E@GDEH@`@PZJd@CHEFI?OSMe@Uk@")

[(41.40436, 2.11683), (41.40454, 2.11647), (41.40479, 2.11611), (41.40519, 2.1157), (41.40526, 2.1156), (41.4054, 2.11546), (41.40547, 2.11533), 
...
(41.41868, 2.11667), (41.41859, 2.11653), (41.41853, 2.11634), (41.41855, 2.11629), (41.41858, 2.11625), (41.41863, 2.11625), (41.41871, 2.11635), (41.41878, 2.11654), (41.41889, 2.11676)]

Referències:

Gráficos interactivos con Jupyter Notebooks: tiro parabólico

Ahora que ya he empezado a hacer pruebas con Jupyter Notebook, el siguiente paso que quiero probar es hacer gráficos interactivos. Pues ha resultado ser más fácil y rápido de lo que pensaba.

Partimos de un script python que simula los datos experimentales de una trayectoria parabólica, y calcula la parábola que mejor se ajusta (regresión cuadrática). A partir de la ecuación de la parábola se puede deducir la constante g (=9,81 m/s2). Simulamos los datos experimentales introduciendo un error de ruido en los datos teóricos. Pues bien, con mi gráfico interactivo puedo jugar con el nivel de ruido y con el número de puntos del muestreo, tal com se ve en el video. El código queda de la siguiente forma:

%matplotlib inline
from ipywidgets import interactive
import numpy as np
import pylab as plt
from IPython.display import display, Math, Latex

# tir parabòlic: y = vy*t - .5gt^2
vy = 10 # 10m/s
g = 9.81 # m/s^2
t_max = 2*vy/g

def f(nivell_soroll, num_punts):
    t = np.linspace(0, t_max, num_punts)
    y_or = vy*t - .5*g*t**2
    noise = np.random.normal(0, nivell_soroll, num_punts) # simulem dades experimentals
    y = y_or + noise

    # ajustament a una paràbola
    z = np.polyfit(t, y, 2)
    g_exp = 2.0*z[0]

    t_ = np.linspace(0, t_max, 100)
    y_ = z[0]*t_**2 + z[1]*t_ + z[2]

    fig, ax = plt.subplots()
    plt.plot(t_, y_, t, y, 'bo')
    plt.suptitle("Tir parabòlic. Regressió quadràtica")
    plt.title("y = " + str(round(z[0],3)) + "t^2 + " + str(round(z[1],3)) + "t + " + str(round(z[2],3)) + " -> g exp = " + str(round(g_exp,3)) + " m/s^2")
    ax.set(xlabel='temps (s)', ylabel='y (m)')
    ax.grid()
    plt.show()
    
interactive_plot = interactive(f, nivell_soroll=(0.0, 2.0),  num_punts=(10, 50))
interactive_plot

Otra cosa que me interesa es la manera de exportar estos Jupyter Notebooks a una web, conservando las gráficas y las fórmulas en format Latex (aunque se pierda la interacció con las gráficas). Esto se consigue directamente exportando el Notebook a html:

$ jupyter nbconvert --execute tir_parabolic.ipynb --to html

e integrando este código en una web donde haya más texto y explicaciones, y con la librería Bootstrap.

Introducción a Jupyter Notebooks

Ya hace tiempo que tenía ganas de mirar qué es esto de Jupyter Notebook, del que se está hablando mucho y cada vez se hablará más. Este es el primer ejemplo que hago, la solución de la ecuación de 2o grado con python y la librería sympy, que he cogido de una página que me gusta mucho: arachnoid.com.

El siguiente paso será mirar Jupyter Lab, que proporciona una interfície más moderna, y tengo ganas de jugar con widgets y sliders para poder hacer cosas más interactivas. Ahora que estoy programando bastante con Python para preparar ejemplos para las clases de CNED en la UPC, hacerlo con las Notebooks de Jupyter sería una manera muy puntera de hacer clases interactivas.

Referencias:

Incendio en OVH Estrasburgo

Esta noche ha habido un incendio en los servidores de OVH en Estrasburgo, me he enterado por Twitter. Cuando me he levantado, he comprobado que la mediawiki de wiki.joanillo.org y este bloc de www.joanillo.org estaban activos. Sabía que mi máquina estaba en Francia, y ya me temía lo peor. Por suerte, he comprobado que mi máquina está en Gravelines, que es una localidad en el Pas de Calais. Suerte! De todas formas, tenía hecha una copia de seguridad de la wiki de hacía un par de días.

Esto nos tiene que hacer reflexionar sobre lo líquido y lo intangible de la información en la nube… Precisamente esta semana íbamos a contratar los servicios de OVH para alojar la web del instituto.

Extraer información de un track GPX

Estaba haciendo un pequeño script en NodeJS para extraer la información de mis tracks de BTT. Esta es la información básica que se puede extraer:

$ node xml_stats.js ../rutesgps/montnegreopenmtb_32.gpx
track: ../rutesgps/montnegreopenmtb_32.gpx
2020-11-05
29.4 Km (distància total)
02:25:40 (temps en moviment)
02:58:01 (temps total)
1121 m (desnivell acumulat)
886 m (desnivell acumulat amb filtre)
143m -> 650m (altitud min and max)

La dificultad principal está en entender qué significa y cómo se calcula el desnivel acumulado. Pongamos por ejemplo una excursión bastante plana com puede ser el Passeig de les Aigües de Barcelona. Teniendo en cuenta que la resolución de mi GPS es de 1 metro (sin decimales), el hecho de recorrer una superficie plana hace que se vaya acumulando los metros de desnivel de una manera exagerada (aunque el GPS tuviera más resolución también pasaría). Lo primero que haremos es recalcular las elevaciones de mi track con algún servicio online que dé las alturas exactas, y con algún decimal. Después, la solución pasa por filtrar los datos, hacer un suavizado, es decir, hacer una media. Por ejemplo, por cada punto cogemos el valor de la elevación haciendo la media entre el punto actual y los puntos anterior y posterior. Sería una media de tres puntos. Como cada punto se graba a los 4 segundos, sería una media de 12 segundos. Ahora bien, puedo hacer filtrados de 5, 7, 9 o 11 puntos, i da como resultado valores de pendient acumulado cada vez más pequeños. ¿Qué criterio seguir? El caso es que los diferentes sistemas (mi GPS, wikiloc, etc…) dan valores diferentes. Esto hace que medir la elevación acumulada en una excursión no sea una medida demasiado fiable. Este efecto no es demasiado problemático en las excursiones con bajadas y subidas largas y constantes. Por contra, con excursiones con zonas llanas y terreno irregular el efecto se acumula más.

Todos estos cálculos dan pie a programar otro script para calcular subidas donde podemos definir unas cronoescaladas, subidas que se van repitiendo en los entrenamientos y se podrá extraer información para comparar. De ello hablaremos en un próximo post…

Virtual Pinball basado en Superman (Atari, 1979)

Finalmente ya he acabado el virtual pinball de Superman que irá hacia el País Vasco. Esta vez he mejorado diversos aspectos en el proceso de fabricación: perfiles de acero inoxidable, fijación de la TV, monedero de Industrias Lorenzo, diseño de los vinilos, paletización de la máquina. Y también he incorporado el simulador VPX además del VP9. Pero qué queréis que os diga, no he notado especialmente las mejoras que supuestamente incorpora el VPX.

También he cogido unas cuantas ideas por si he de coger una nueva máquina, que creo que podría hacer más rápidamente que esta última, que se me ha alargado demasiado. Así que ya está, sólo hace falta enviarla.

Referencias:

Proyectar imágenes del móvil

Cogiendo una idea que encontré por Internet, me he construido este no tan pequeño mueble para proyectar imágenes del móvil hacia el papel, y así de manera rápida poder dibujar una imagen del móvil a papel.

La calidad no es nada buena porque la óptica de que dispongo tampoco lo es, pero es suficiente para poder hacer el dibujo. Una ventaja es que moviendo la distancia del móvil a la lente, y de la lente al papel, se puede conseguir diferentes tamaños, con un enfoque más o menos bueno.

Como se ve en la foto, dibujar un ciclista no es una tarea fácil, y con este sistema se puede hacer rápidamente y con las proporciones correctas.

Calas de Menorca

Con motivo del #30DAYMAPCHALLENGE (Noviembre de 2020), el día 16 toca hacer un mapa de una isla. Participo enviando al Twitter un mapa de las calas de la isla de Menorca.

I en este mapa tengo dos objetivos. El primero, utilizar un ángulo para pintar los labels de las calas, de forma que los nombres estén bien orientados alrededor de la isla; y también quiero que al hacer zoom, el font size de los labels sea más grande o más pequeño.

Para encontrar todas las calas he hecho una consulta a Overpass Turbo. La cosa no ha sido fàcil, pues las calas las he buscado con el tag «natural»=»beach», pero después he visto que también es importante el tag «natural»=»bay». Además, no sólo hay que buscar por Cala, sino también por Cales y Caló

La idea inicial era hacer un posicionamient y orientación automático de los nombres de las calas. Pero no es una cosa fácil y rápida, o sea que al final lo he hecho manualmente, y el resultado se puede ver en la foto.

El mapa se ha programado con OpenLayers sobre la base de los mapes de OpenStreetMap.

Referencias: