Ex3 - Apocalypse now
Introduction
You are working as a GIS specialist in an UN organization dealing with the Syrian conflict. Your boss gives you daily KML data on reported fights in the field (points) and territory definition (areas). He asks you to create nice visualization to prove that a surrounding technique is used to besiege the city of Ma‘baţlī.
You have already developed a fairly complex workspace. It reads all KML files and create images out of them. The images are centered on the city of Ma‘baţlī. You show the result to your boss, he is quite pleased, but he asks you to produce not only pictures, but also an animated movie.
Despite having many thousands of formats, FME can not directly export a movie. However, you know that with a litlle bit of python you could transform the images into a movie. After some research on the internet, the OpenCV package seems to be the perfect tool for that. Since it is not a build-in package, you need to use an external Python interpretor with FME. That will be the challenge of this exercise !
Objective
Create this movie :
Workspace description
As mentioned, this workspace is fairly complex. Here's a quick run-down of what it does.
First of all, dates are read and formatted.
We define the name and the color of the armed forces.
Like this, the name will be nicely displayed on the legend map, rather than the abbreviation from the dataset.
Then, the text of the legend is created :
Same thing with the color of the legend :
And the date is also added to the image:
And the position of the city of Ma‘baţlī :
Finally, the picture is created from the vector data and written on a local folder :
The MapnikRasterizer is a fairly complex transformer to rasterize vector features. Note that we used a "group by" option to create one picture per day, so as to not end with all the information in one single picture. The same parameter (and mechanism) has been used in the writer to export one picture file per day.
Exercise
1) Add the OpenCV python package
From a Windows comand prompt, localise your PIP installation folder, as below :
cd C:\Python365-64\Scripts
After that, install OpenCV
pip install opencv-python
This python package will help us to create a movie out of the pictures
Once installed, check the installation by typing :
cd ..
followed by :
python
And then :
import cv2
If there is no error or warning, it means the installation was successful.
2) Configure FME
As soon as python has been correctly installed on the computer, we need to tell FME to use this python interpreter. This can be done as follow :
- Select Tools > FME Options from the menubar
- Select the tab for "Translation“
- Change the preferred Python interpreter as follows :
Once this is done, FME will use the new python interpreter, and will be able to use the OpenCV package.
3) Change the Python Compatibility parameter
4) Shutdown script
The script that merges pictures into a movie must be, of course, run after all images have been written. We will therefore place the script in the Shutdown Python script:
First, let’s import the two following packages :
import cv2
import os
Next, we can define the paths :
# Path
folder_pictures = FME_MacroValues['DestDataset_PNGRASTER']
path_movie = os.path.join(folder_pictures, 'movie.mp4')
And now, let’s create a list of the pictures :
# List of pictures
images = []
for f in os.listdir(folder_pictures):
images.append(f)
Next step is to define the format of the movie using the first image
# Determine the width and height from the first image
image_path = os.path.join(folder_pictures, images[0])
frame = cv2.imread(image_path)
cv2.imshow('video', frame)
height, width, channels = frame.shape
And we define the codec and the object
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use lower case
out = cv2.VideoWriter(path_movie, fourcc, 1, (width, height))
Finally, pictures can be merged to create the movie
for image in images:
image_path = os.path.join(folder_pictures, image)
frame = cv2.imread(image_path)
out.write(frame) # Write out frame to video
And now, if you run the workspace, you will see a new file called movie.mp4 in the pictures folder.
Full code :
import cv2
import os
# Path
folder_pictures = FME_MacroValues['DestDataset_PNGRASTER']
path_movie = os.path.join(folder_pictures, 'movie.mp4')
# List of pictures
images = []
for f in os.listdir(folder_pictures):
images.append(f)
# Determine the width and height from the first image
image_path = os.path.join(folder_pictures, images[0])
frame = cv2.imread(image_path)
cv2.imshow('video', frame)
height, width, channels = frame.shape
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use lower case
out = cv2.VideoWriter(path_movie, fourcc, 1, (width, height))
for image in images:
image_path = os.path.join(folder_pictures, image)
frame = cv2.imread(image_path)
out.write(frame) # Write out frame to video
Optional advanced task
Having a script in the shutdown python parameter is not always ideal if you aren't working with FME on a regular basis - the functionality is kind of hidden away in the workspace. Another solution could be to use a FeatureWriter to write the picture files (rather than the normal writer) and move the movie generation code to a PythonCaller, which will be instantly visible in the workspace when you open it up.
Why don't you give it a go !