The result of making a map album of Italy honeymoon in Python and sharing it

I went to Italy for my honeymoon a while ago. I took a weekly tour of Milan, Venice, Florence, Pisa, Rome and Pompeii, and when I noticed, I took about 1000 photos. I had some free time and took a walk for about 10,000 steps every day, so I wanted to keep a record including the route, so I made a map album ...!

Visualization

The whole picture looks like this. I'm using a map from OpenStreetMap.

From here, for example, if you zoom in on Venice, you can see the walking route like this. It is color-coded according to the date, and since I stayed overnight in Venice, there is a two-color route. And the marker is the point where you took the picture, click it and the picture will pop up.

This is the original photo. Since I took it during the gondola tour, the marker is also on the waterway. I was looking forward to Venice as a sanctuary of "ARIA", but it was a far more fantastic city of water than I expected. I will do my best to recommend it.

This is the Spanish Steps, the sanctuary of the timeless masterpiece "Roman Holiday". I saw it on the plane to go (Oi)

This is a cat watching over Pompeii, which was destroyed by the eruption. Cats appear here. It was a cat. Nice to meet you

reaction

I shared it with my family and friends, and it was great because I was able to share my memories while following the journey and showing photos. I went through this stall street, had a supper at this shop, and ran this road, and it was just before the meeting time. However, since I shared the HTML file that exported the Jupyter Lab notebook as it is, the engineers started reading the Python code, and there was a problem that it was hard to hear this story w

procedure

I wrote about 50 lines of Python code on JupyterLab and did the following: I'm starting to use Folium for business, but it's very easy.

--Read the image file with Pillow. --Extract the latitude / longitude information from the Exif of the image. --Extract the rotation / inversion information from the Exif of the image and apply it. --Draw a route by feeding Folium with a column of latitude and longitude. --Folium is fed with latitude / longitude and Base64-encoded image to hit a marker. --HTML output with JupterLab.

I can pass an image tag to the Folium marker, but it seems that I can't refer to the local file, so I'm using the trick of encoding to Base64. Thanks to that, it is easy to share because it can output a single independent HTML file, but even though it is reduced, it has about 1000 images, so it became an HTML file of about 100 MB ... … W

code

import base64
import folium
import glob
import pandas as pd
from io import BytesIO
from matplotlib import pyplot as plt
from PIL import ExifTags, Image, ImageOps
def to_deg(v, ref, pos):
    d = float(v[0][0]) / float(v[0][1])
    m = float(v[1][0]) / float(v[1][1])
    s = float(v[2][0]) / float(v[2][1])
    return (d + (m / 60.0) + (s / 3600.0)) * (1 if ref == pos else -1)
to_trans_methods = {
    1: [],
    2: [Image.FLIP_LEFT_RIGHT],
    3: [Image.ROTATE_180],
    4: [Image.FLIP_TOP_BOTTOM],
    5: [Image.FLIP_LEFT_RIGHT, Image.ROTATE_90],
    6: [Image.ROTATE_270],
    7: [Image.FLIP_LEFT_RIGHT, Image.ROTATE_270],
    8: [Image.ROTATE_90]
}
files = glob.glob('/path/to/*.jpg')
rows = []
for file in files:
    with Image.open(file) as im:
        exif = {ExifTags.TAGS[k]: v for k, v in im.getexif().items() if k in ExifTags.TAGS}
        if 'GPSInfo' in exif:
            gps = {ExifTags.GPSTAGS[k]: v for k, v in exif['GPSInfo'].items() if k in ExifTags.GPSTAGS}
            lat = to_deg(gps['GPSLatitude'], gps['GPSLatitudeRef'], 'N')
            lon = to_deg(gps['GPSLongitude'], gps['GPSLongitudeRef'], 'E')
            im.thumbnail((192, 192))
            for method in to_trans_methods[exif.get('Orientation', 1)]:
                im = im.transpose(method)
            buf = BytesIO()
            im.save(buf, format="png")
            rows.append([lat, lon, exif['DateTimeOriginal'], base64.b64encode(buf.getvalue()).decode()])

df = pd.DataFrame(rows, columns=['lat', 'lon', 'dt', 'base64'])
df['dt'] = pd.to_datetime(df['dt'], format='%Y:%m:%d %H:%M:%S')
df = df.sort_values('dt')
fmap = folium.Map(location=[df['lat'].mean(), df['lon'].mean()], zoom_start=6)
hsv=[plt.get_cmap('hsv', 12)(i) for i in range(12)]
fmap.add_child(folium.ColorLine(zip(df['lat'], df['lon']), colors=df['dt'].dt.day, colormap=hsv, weight=4))
for _, row in df.iterrows():
    fmap.add_child(folium.Marker([row['lat'], row['lon']], popup=f'<img src="data:image/png;base64,{row["base64"]}">'))
fmap

Execution environment

$ python --version
Python 3.7.4

$ pip list | grep -e folium -e jupyter -e matplotlib -e pandas -e Pillow
folium               0.10.1    
jupyter-client       5.3.3     
jupyter-core         4.5.0     
jupyterlab           1.1.4     
jupyterlab-server    1.0.6     
matplotlib           3.1.2     
pandas               1.0.1     
Pillow               7.0.0     

Reference link

Let's find out the shooting location from the GPS information embedded in the photo with Python | Mynavi News Processed with PIL considering EXIF Orientation tag | Qiita View image on popup | python-visualization/folium

Recommended Posts

The result of making a map album of Italy honeymoon in Python and sharing it
The process of making Python code object-oriented and improving it
Convert the result of python optparse to dict and utilize it
The result of installing python in Anaconda
Find the white Christmas rate by prefecture with Python and map it to a map of Japan
[Python] The role of the asterisk in front of the variable. Divide the input value and assign it to a variable
Enclose the cat result in double quotes and put it in a variable
Open an Excel file in Python and color the map of Japan
Get the caller of a function in Python
View the result of geometry processing in Python
Make a copy of the list in Python
Compare the speed of Python append and map
Output in the form of a python array
A discussion of the strengths and weaknesses of Python
[Python / Jupyter] Translate the comment of the program copied to the clipboard and insert it in a new cell
How to pass the execution result of a shell command in a list in Python
What I investigated in the process of expressing (schematicizing) containers in a nested frame with Jupyter and making it
A reminder about the implementation of recommendations in Python
If you define a method in a Ruby class and define a method in it, it becomes a method of the original class.
[Python3] Take a screenshot of a web page on the server and crop it further
[Python] Change the text color and background color of a specific keyword in print output
[Selenium] Open the link in a new tab and move it [Python / Chrome Driver]
It is easy to execute SQL with Python and output the result in Excel
Find out the apparent width of a string in python
Measure the execution result of the program in C ++, Java, Python.
Temporarily save a Python object and reuse it in another Python
The result of Java engineers learning machine learning in Python www
Get the number of specific elements in a python list
[Note] Import of a file in the parent directory in Python
[Tips] Problems and solutions in the development of python + kivy
Find the eigenvalues of a real symmetric matrix in Python
Recursively get the Excel list in a specific folder with python and write it to Excel.
An easy way to view the time taken in Python and a smarter way to improve it
How to pass the execution result of a shell command in a list in Python (non-blocking version)
The story of Python and the story of NaN
How to determine the existence of a selenium element in Python
Save the result of the life game as a gif with python
Scraping the schedule of Hinatazaka46 and reflecting it in Google Calendar
[Python] Let's reduce the number of elements in the result in set operations
How to check the memory size of a variable in Python
Delete a particular character in Python if it is the last
Read the standard output of a subprocess line by line in Python
The story of making a standard driver for db with python.
How to check the memory size of a dictionary in Python
A function that measures the processing time of a method in python
The story of making a module that skips mail with python
Get the title and delivery date of Yahoo! News in Python
Get the number of readers of a treatise on Mendeley in Python
A simple reason why the return value of round (2.675,2) is 2.67 in python (it should be 2.68 in reality ...)
Note that I understand the algorithm of the machine learning naive Bayes classifier. And I wrote it in Python.
[Rails 6] Embed Google Map in the app and add a marker to the entered address. [Confirmation of details]
Set up a dummy SMTP server in Python and check the operation of sending from Action Mailer
The story of making a tool to load an image with Python ⇒ save it as another name
[Python] How to save the installed package and install it in a new environment at once Mac environment
How to input a character string in Python and output it as it is or in the opposite direction.
Get a capture of the entire web page in Selenium Python VBA
The story of making a university 100 yen breakfast LINE bot with Python
If you want a singleton in python, think of the module as a singleton
Predict the amount of electricity used in 2 days and publish it in CSV
[Python] Sweet Is it sweet? About suites and expressions in the official documentation
Comparing the basic grammar of Python and Go in an easy-to-understand manner