---
title: "Me and the world"
format:
html:
code-tools: true
title-block-banner: "#DD633F"
description: "Last updated: Apr. 2025"
resources:
- files/
include-in-header:
- text: |
<script src=https://unpkg.com/maplibre-gl@5.2.0/dist/maplibre-gl.js></script>
<link href=https://unpkg.com/maplibre-gl@5.2.0/dist/maplibre-gl.css rel="stylesheet" />
jupyter: base
---
## My Travel History
Click country shapes to see more information.
<iframe src="./files/my_travel_history.html" width="100%" height="400px" style="border: none;" scrolling="no"></iframe>
## My Flight Map
```{=html}
<div id="map" style="width: 100%; height: 400px;"></div>
<script>
const map = new maplibregl.Map({
container: "map", // the id of the div element
style: `https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json`,
zoom: 1, // starting zoom
center: [50, 40] // starting location [longitude, latitude]
});
map.on('load', () => {
map.addSource('airports', {
type: 'geojson',
data: './files/my_airports_gdf.geojson'
});
map.addLayer({
id: 'airports',
type: 'circle',
source: 'airports',
paint: {
'circle-radius': ["+",["get", "No. visit"], 3],
'circle-color': 'orange',
'circle-opacity': 0.6,
'circle-stroke-color': 'black',
'circle-stroke-width': 1
}
});
map.on('click', 'airports', (e) => {
const coordinates = e.features[0].geometry.coordinates.slice();
const { Name, 'No. visit': noVisit } = e.features[0].properties;
new maplibregl.Popup()
.setLngLat(coordinates)
.setHTML(`<strong>${Name}</strong><br>Total visit: ${noVisit}`)
.addTo(map);
});
map.on("mouseenter", "airports", () => {
map.getCanvas().style.cursor = "pointer";
});
map.on("mouseleave", "airports", () => {
map.getCanvas().style.cursor = "";
});
map.addSource('flights', {
type: 'geojson',
data: './files/my_flights_gdf.geojson'
});
map.addLayer({
id: 'flights',
type: 'line',
source: 'flights',
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': 'black',
'line-width': ["*", ["get", "No. flight"], 1.2]
}
});
map.on('click', 'flights', (e) => {
const coordinates = e.features[0].geometry.coordinates[0];
const { Route, 'No. flight': noFlight } = e.features[0].properties;
new maplibregl.Popup()
.setLngLat(coordinates)
.setHTML(`<strong>${Route}</strong><br>Total flight: ${noFlight}`)
.addTo(map);
});
map.on("mouseenter", "flights", () => {
map.getCanvas().style.cursor = "pointer";
});
map.on("mouseleave", "flights", () => {
map.getCanvas().style.cursor = "";
});
});
</script>
```
<!-- <iframe src="./files/my_flight_log.html" width="100%" height="400px" style="border: none;" scrolling="no"></iframe> -->
<!-- <iframe src="./files/mpl_test_flight.html" width="100%" height="400px" style="border: none;" scrolling="no"></iframe> -->
### Records
```{python}
#| echo: false
import pandas as pd
import requests
import geopandas as gpd
my_flights_gdf = gpd.read_file('./files/my_flights_gdf.geojson')
airlines_json = requests.get('https://cdn.jsdelivr.net/gh/besrourms/airlines@latest/airlines.json').json()
airlines = pd.read_json('https://cdn.jsdelivr.net/gh/besrourms/airlines@latest/airlines.json')
code2fullname = dict(zip(airlines.code, airlines.name))
code2logo = dict(zip(airlines.code, airlines.logo))
my_flights_gdf['Airlines'] = my_flights_gdf['Flight Number'].str[:2].apply(lambda x: code2fullname[x])
my_flights_gdf['Airlines logo'] = my_flights_gdf['Flight Number'].str[:2].apply(lambda x: code2logo[x])
my_flights_gdf.rename(columns={'Aircraft Registration': 'Tail', 'Flight Number': 'Flight', 'Departure': 'DEP', 'Arrival': 'ARR'}, inplace=True)
my_flights_df = my_flights_gdf[['Date', 'Airlines', 'Flight', 'DEP', 'ARR', 'Aircraft', 'Tail', 'Distance']]
my_flights_df.index += 1#my_flights_df.index
display(my_flights_df.to_html(escape=False))
```
::: {.grid}
::: {.g-col-4}
:::
::: {.g-col-4}
### Top Airlines
```{python}
#| echo: false
my_flights_gdf['Airlines logo'] = "<img src=\"" + my_flights_gdf['Airlines logo']+ " Logo\" width=\"25\" height=\"25\">"
airline_counts = my_flights_gdf.groupby('Airlines',as_index=False).count().iloc[:,[0,1]]
airline_counts.columns = [' ','Flights']
airline_counts['Airline'] = my_flights_gdf.groupby('Airlines',as_index=False).apply(lambda x : x['Airlines logo']).unique()
airline_counts = airline_counts.sort_values(by='Flights',ascending=False).set_index('Airline')
airline_counts.index.rename(None,inplace=True)
display(airline_counts.to_html(escape=False))
```
:::
::: {.g-col-4}
:::
:::
::: {.grid}
::: {.g-col-4}
:::
::: {.g-col-4}
### Top Aircrafts
```{python}
#| echo: false
aircraft_counts = my_flights_df.groupby('Aircraft',as_index=False).count().iloc[:,[0,1]]
aircraft_counts.columns = [' ','Flights']
com2con = {'Airbus':'eu', 'Boeing':'us', 'COMAC': 'cn'}
aircraft_counts['Aircraft'] = [com2con[i[0]] for i in aircraft_counts[' '].str.split()]
aircraft_counts['Aircraft'] = "<img src=\"https://flagicons.lipis.dev/flags/4x3/" + aircraft_counts['Aircraft'] + ".svg\" width=\"25\" height=\"25\">"
aircraft_counts = aircraft_counts.sort_values(by='Flights',ascending=False).set_index('Aircraft')
aircraft_counts.index.rename(None,inplace=True)
display(aircraft_counts.to_html(escape=False))
```
:::
::: {.g-col-4}
:::
:::