Creating maps

We have the data that we need to begin building the map for our report. Our approach will be the following steps:

  • Enhancing the elevation and base map images with filters
  • Blending the images together to provide a hillshaded OSM map
  • Creating a translucent layer to draw the street route
  • Blending the route layer with the hillshaded map

These tasks will all be accomplished using the PIL Image and ImageDraw modules:

# Convert the numpy array back to an image
relief = Image.fromarray(shaded).convert("L")

# Smooth the image several times so it's not pixelated
for i in range(10):
    relief = relief.filter(ImageFilter.SMOOTH_MORE)

log.info("Creating map image")

# Increase the hillshade contrast to make
# it stand out more
e = ImageEnhance.Contrast(relief)
relief = e.enhance(2)

# Crop the image to match the SRTM image. We lose
# 2 pixels during the hillshade process
base = Image.open(osm_img + ".jpg").crop((0, 0, w-2, h-2))

# Enhance base map contrast before blending
e = ImageEnhance.Contrast(base)
base = e.enhance(1)

# Blend the the map and hillshade at 90% opacity
topo = Image.blend(relief.convert("RGB"), base, .9)

# Draw the GPX tracks
# Convert the coordinates to pixels
points = []
for x, y in zip(lons, lats):
    px, py = world2pixel(x, y, w, h, bbox)
    points.append((px, py))

# Crop the image size values to match the map
w -= 2
h -= 2

# Set up a translucent image to draw the route.
# This technique allows us to see the streets
# and street names under the route line.

track = Image.new('RGBA', (w, h))

track_draw = ImageDraw.Draw(track)

# Route line will be red at 50% transparency (255/2=127)
track_draw.line(points, fill=(255, 0, 0, 127), width=4)

# Paste onto the base map using the drawing layer itself
# as a mask.
topo.paste(track, mask=track)

# Now we'll draw start and end points directly on top
# of our map - no need for transparency
topo_draw = ImageDraw.Draw(topo)

# Starting circle
start_lon, start_lat = (lons[0], lats[0])
start_x, start_y = world2pixel(start_lon, start_lat, w, h, bbox)
start_point = [start_x-10, start_y-10, start_x+10, start_y+10]
topo_draw.ellipse(start_point, fill="lightgreen", outline="black")
start_marker = [start_x-4, start_y-4, start_x+4, start_y+4]
topo_draw.ellipse(start_marker, fill="black", outline="white")

# Ending circle
end_lon, end_lat = (lons[-1], lats[-1])
end_x, end_y = world2pixel(end_lon, end_lat, w, h, bbox)
end_point = [end_x-10, end_y-10, end_x+10, end_y+10]
topo_draw.ellipse(end_point, fill="red", outline="black")
end_marker = [end_x-4, end_y-4, end_x+4, end_y+4]
topo_draw.ellipse(end_marker, fill="black", outline="white")

# Save the topo map
topo.save("{}_topo.jpg".format(osm_img))

While not saved to the filesystem, the hillshaded elevation looks as follows:

Creating maps

The blended topographic map looks like the following screenshot:

Creating maps

While hillshade mapping gives us an idea of the elevation, it doesn't' give us any quantitative data. To get more details, we'll create a simple elevation chart.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset