MapKnitter - Using photo data to speed up aerial mapping

MapKnitter helps people turn balloon, kite, pole, and drone photographs into georeferenced maps. During Google Summer of Code, we worked on using EXIF data to give each image a useful starting position before manual alignment.

Visit MapKnitter

Project
MapKnitter
Organisation
Public Lab
Program
Google Summer of Code 2014
Aerial photograph being aligned over a reference map in MapKnitter

Overview

MapKnitter is an open-source tool from Public Lab for turning aerial photographs into maps. People can collect images with balloons, kites, poles, or drones, place them over a reference map, correct their position and perspective, and export the result for the web or GIS software.

This is useful when existing satellite imagery is too old, too coarse, or simply does not show the event a community wants to document. A local team can collect its own images and produce a map of a coastline, wetland, campus, construction site, neighbourhood, or area affected by an environmental event.

Each photograph still has to be connected to a real place. The mapper moves, rotates, scales, and distorts the image until roads, buildings, coastlines, and other visible features line up with the reference map. This is georeferencing: connecting points in a photograph to real locations on a map.

During Google Summer of Code in 2014, XO Research founder Vidhun Vinod worked with Public Lab on reducing the repetitive first part of that process. The contribution used EXIF metadata stored in photographs to place an image near where it was captured before the mapper began the careful alignment.

The goal was not to replace the person making the map. It was to give them a useful starting point instead of an empty canvas.

Why make your own aerial map?

Satellite maps are valuable, but they do not always match a community’s question at a particular moment. Available imagery may be months or years old, lack enough detail for a small site, or be limited by cloud cover, licensing, cost, and a provider’s update schedule.

A local group may care about a wetland edge, a changing construction site, or post-event conditions that are too specific for a commercial imagery programme. Balloon, kite, pole, and drone photography can collect recent images at relatively low cost. The people doing the work choose what to photograph and retain the source images.

That does not make amateur imagery automatically more accurate, and a MapKnitter export is not inherently survey-grade. MapKnitter makes the photographs useful by giving people a way to place them in geographic space and turn them into a map they can share or continue analysing.

From aerial photographs to a map

  1. Capture overlapping aerial photographs using a balloon, kite, pole, drone, or another camera platform.
  2. Upload the useful images to MapKnitter.
  3. Use available EXIF data to suggest an initial location and orientation.
  4. Place each photograph over a reference map.
  5. Drag, rotate, scale, and distort its four corners until visible features align.
  6. Repeat the process across the image set.
  7. Export the composition as a web map, GeoTIFF, TMS tiles, or a high-resolution image.

This remains a manual, visual workflow. The mapper decides which photographs are clear enough, how overlapping images should be stacked, which reference features are trustworthy, and when the alignment is good enough for the intended use. An obstructed or badly tilted image may be left out. MapKnitter is not a fully automatic photogrammetry system.

Architecture at a glance

Aerial photographs
        │
        ▼
Browser mapping interface
Leaflet + Leaflet.DistortableImage
        │
        ├── Read available EXIF metadata
        ├── Suggest an initial position
        ├── Drag, rotate, scale, and distort four corners
        │
        ▼
Ruby on Rails application
        │
        ├── Store maps and uploaded images
        ├── Store four geographic corner points
        ├── Keep placement history
        └── Estimate image resolution
        │
        ▼
MapKnitter exporter
GDAL + ImageMagick
        │
        ├── GeoTIFF
        ├── TMS tiles
        ├── High-resolution JPEG
        └── Web map

A mapping interface, an application, and an exporter

Public Lab describes MapKnitter as three connected parts. Keeping them separate lets the browser stay responsive while the server handles durable map state and the exporter does the heavier full-resolution image processing.

The browser interface

The editor is built on Leaflet. Leaflet.DistortableImage adds an image overlay whose position is represented by four geographic corners. Dragging moves the overlay. Rotation moves the corners around its centre. Scaling changes their distance from the centre. Distort mode lets each corner move independently.

That last operation is often called rubbersheeting: stretching, rotating, and distorting an image until visible features line up with a reference map. The plugin calculates a projective transform from the image’s rectangular pixel coordinates to the four map corners, then applies a CSS matrix3d transform. The mapper sees the change immediately without waiting for a server-rendered preview.

MapKnitter sends a medium-sized image to the editor while keeping the original image URL in the record returned to the client. That makes interactive editing lighter without discarding the full-resolution source needed for export.

The Rails application

The Ruby on Rails application stores users, maps, annotations, uploaded photographs, and placement data in MySQL. An uploaded photograph is a Warpable. Its nodes field keeps the identifiers of four Node records, each containing a latitude and longitude.

The Warpable JSON exposes both image URLs and the corner nodes so Leaflet.DistortableImage can restore the overlay after a page load. PaperTrail records changes to the nodes field, and the controller includes a revert action. The important stored state is not a screenshot of the editor; it is the original image plus the geographic geometry needed to reconstruct its placement.

The exporter

Browser distortion is useful for editing, but a final map needs the original images transformed and composited at export resolution. The interface posts the placed-image collection to a separate Sinatra service and receives the path of a status.json file. MapKnitter stores that status location and checks it while the export runs.

The service uses the MapKnitter exporter gem. ImageMagick applies the perspective distortion and masking to each source image. GDAL assigns geographic coordinates, warps the images, composites them, and generates map tiles. The result can include a GeoTIFF, TMS tiles and a zipped tileset, and a high-resolution JPEG.

A GeoTIFF is an image file containing geographic location information for GIS software. TMS is a directory of map tiles at different zoom levels, so a web map can load only the pieces visible on screen.

Giving each photograph a useful starting position

A camera may store more than pixels. Its EXIF metadata can include the GPS position where a photograph was captured, the direction the camera was facing, its orientation, and sometimes its altitude.

The current MapKnitter interface reads those tags in the browser with exif-js. GPS latitude and longitude are commonly stored as degrees, minutes, and seconds, so the code converts the three values into decimal coordinates. Latitude and longitude references determine whether the result is north or south, east or west. If usable coordinates are missing, the GPS-placement control is not offered and the image can still enter the normal manual workflow.

A new overlay already has four corners. MapKnitter finds its current centre, calculates the latitude and longitude difference to the EXIF position, and applies that difference to every corner. The image moves without changing its initial shape. If a true- or magnetic-north image-direction value exists, the interface converts that heading to a rotation. EXIF orientation values 6, 8, and 3 add quarter- or half-turn corrections for camera orientation.

Altitude is treated more cautiously. The current code subtracts estimated ground elevation from the EXIF altitude and tries to estimate image width using a fixed field-of-view value. Historical code also experimented with altitude and image dimensions. Both approaches are clues, not exact photogrammetry: altitude may be relative to sea level, and the footprint also depends on ground elevation, lens, field of view, camera angle, and terrain.

The result is an informed first placement, not a finished map. Roads, rooflines, coastlines, and other visible features still need to be aligned by a person.

A photograph needs four map coordinates

One GPS coordinate describes the camera’s approximate position. It does not describe the ground visible in the photograph. MapKnitter therefore represents a placed image with four corners, each holding latitude and longitude.

Moving the whole image translates the four corners together. Rotation moves them around the image centre. Scaling changes their distance from that centre. Perspective distortion lets each corner move independently, which helps align photographs taken at an angle rather than perfectly downward.

When an edit is saved, the browser serialises the four corner pairs and sends them to the Rails image endpoint. The controller creates four new Node records, stores their identifiers on the Warpable, recalculates resolution, and saves the record. PaperTrail versions the node relationship, allowing supported placements to be reverted later.

Estimating map resolution

Once an image has geographic corners and a known pixel width, MapKnitter estimates how much ground each pixel represents. The model projects the first two corners into spherical Mercator coordinates, measures the distance between them, converts metres to centimetres, and divides by image width.

The stored centimetres-per-pixel value is useful for choosing an export scale. It is still approximate: perspective and uneven terrain can make resolution vary across the same photograph, so it is not survey-grade ground sampling distance.

Where people have used MapKnitter

MapKnitter belongs to Public Lab and a broad open-source community. Its value is clearest in projects where people needed to make and inspect imagery themselves.

Documenting the Deepwater Horizon oil spill

After the 2010 Deepwater Horizon spill, volunteers across the five Gulf states attached cameras to balloons and kites and collected more than 10,000 aerial photographs. MapKnitter was used to assemble them into recent, detailed community-produced maps. News organisations used the imagery, lawyers requested copies for litigation, and Google Earth published the group’s maps.

This work predates Vidhun’s 2014 contribution. It demonstrates the wider value of MapKnitter, not an outcome caused by EXIF placement. The maps did not replace official geographic data; they gave local people a current view of conditions they could collect and inspect themselves.

Teaching mapping by making a map

At Western Carolina University, students used balloon photography and MapKnitter while building and updating a campus map. At Waterloo Collegiate Institute, high-school students flew a camera on a helium balloon, then stretched and aligned the resulting photographs into a composite with MapKnitter.

These projects turn mapping into something students construct rather than only consume. They encounter image selection, overlap, perspective, coordinate systems, and uncertainty in one real workflow, without needing professional aerial-survey equipment.

Creating an independent view of a place

MapKnitter was also used to assemble DIY aerial photographs of East Jerusalem. The project showed how people could produce and combine local imagery when available maps or imagery did not represent the view they needed. It is another example of the tool supporting independent observation without making the resulting map automatically authoritative.

What automatic placement cannot know

GPS normally records where the camera was, not the exact footprint visible on the ground. Even a complete EXIF record leaves important uncertainty:

  • Coordinates, compass direction, or the camera clock may be missing or wrong.
  • Altitude may be measured above sea level rather than above the ground.
  • Camera tilt, field of view, lens distortion, and terrain change the visible geometry.
  • Trees, water, shadows, clouds, and moving objects can hide reliable reference points.
  • Existing base imagery may itself be old or slightly misaligned.
  • Some photographs contain too few recognisable features for confident placement.

The feature removed repetitive setup. It did not remove the need for the mapper’s judgement, and it does not make the output legally authoritative or survey-grade.

Why this approach was practical

The contribution reused metadata already present in many photographs. It provided value without requiring a complete photogrammetry system, preserved the manual workflow, and allowed images without useful metadata to be placed normally. Users could disable the suggestion when they did not trust it.

The browser remained the place for final visual judgement. Rails stored the source image and map geometry, while the separate exporter handled full-resolution distortion, compositing, and geospatial files.

It was a small automation at the right point in the workflow: enough to remove repetitive work, but not so much that it hid uncertainty from the person making the map.

What we did

  • Mapping-workflow research
  • EXIF and GPS metadata parsing
  • GPS-assisted initial placement
  • Camera direction and orientation handling
  • Altitude-based scale experiments
  • Upload workflow improvements
  • Manual-placement fallback
  • JavaScript and Rails integration
  • Open-source testing and bug fixes
  • Community collaboration

Technology

Contribution

  • JavaScript
  • EXIF.js
  • GPS metadata
  • Ruby on Rails integration
  • Open-source development

MapKnitter platform

  • Leaflet
  • Leaflet.DistortableImage
  • Ruby on Rails
  • MySQL
  • Paperclip
  • PaperTrail
  • GDAL
  • ImageMagick
  • Sinatra exporter

Project approach

Automatic placement did not try to replace the cartographer. It removed the blank-canvas work so the person could spend time on the alignment that needed judgement.

Google Summer of Code
2014
Initial placement
EXIF + GPS
Manual alignment
4 corners
Map exports
GeoTIFF + TMS

Related projects

Building an AI chat product that remembers

AI product

FanChat lets people talk with AI characters in direct messages and group chats. It has reached 250,000+ users and more than one million messages, including students who use it to practise English.

Read more

Giving every Solana wallet an inbox

Messaging protocol

Jabber is an end-to-end encrypted messaging protocol that lets a person or application send a message directly to any valid Solana address.

Read more

Bring us the problem worth solving

Our office

  • Bangalore
    GoodWorks Infinity Park
    Electronics City