The Mapillary Blog


Privacy Policy and Terms

by Jan Erik Solem, Posted on 13 Sep 2014

Jan Erik Solem

Six months after our launch it is now time for an update of our policies. While our previous terms regulated what we can do with photos contributed to Mapillary we decided that more clarity and detail would be helpful on things like how you are allowed to use the service, your rights to photos, how we handle your personal data, copyright infringement and more.

In an international context we need to be explicit about what behaviour is acceptable and what rights you have as users. We are therefore adding a privacy policy and updating our terms today.

Our privacy policy

Full text here. The privacy policy declares how we collect, store and use information from you when you use Mapillary. It also mentions our use of cookies (an EU requirement).

Our updated terms

Full text here (same URL as before). Our intentions are best described in the opening paragraph:

To better serve the Mapillary community, promote transparency, and minimize disputes, we have prepared these Terms of Use. We wish to clearly set out our rights and your rights, in furtherance of building a strong Mapillary community. We would like to assure the community that nothing in these Terms requires transfer of your ownership of photos taken with the Mapillary App, and that photos contributed by the Mapillary community are made publicly available by us in accordance with these Terms.

New points are:

  • Commercial vs Non-commercial use
  • Inappropriate behaviour
  • Limitations on liability
  • Account termination
  • Copyright DMCA notices

The rights we give to OpenStreetMap and CreativeCommons as described on our legal page are now clearly referenced throughout the text under the term “Outbound Terms”. Nothing has changed there. Our use of incoming photos has not changed either but we are clearer on the point that you don’t transfer ownership by submitting a photo.

Feedback

We take your personal data and your rights seriously. If you have any questions or thoughts, please send them to us directly by email.


Now Supporting Panoramas and Photo Spheres

by Jan Erik Solem, Posted on 10 Sep 2014

Jan Erik Solem

Uploading panoramas

Today we are adding support for uploading panoramas to Mapillary. With the advance of 360 degree (action) cameras and smartphone cameras widely supporting panoramas, this is a natural step for us.

Uploading panoramas works in the web uploader as well as with upload scripts*. Group them into sequences, just like you would do with regular photos.

Any panorama conforming to the Photo Sphere XMP Metadata standard will work. In addition to those, we are also supporting iOS camera panoramas and some other apps. See below for some examples of what works.

Supported:

  • Apple iOS panoramas from the camera app
  • Android Photo Spheres from the camera app
  • 360 cameras, like the Ricoh Theta, that save photos in the Photo Sphere format (assuming they have GPS)
  • Many popular panorama apps like Sphere, and DMD Panorama.

Not supported:

  • Google PhotoSphere iOS app. They remove the GPS locations when saving the photos. (If you can add back the GPS in Exif it will work)

Viewing panoramas

Panoramas are viewed in the same interface as regular photos, the difference is that now you can pan around by dragging the photo**. To show that you are looking at a panorama, the aspect ratio of the viewer changes to a wider view.

Panorama viewer
A panorama in the viewer. The same navigation contols as for regular photos are there.

Here's an example sequence of panoramas taken with the regular iOS camera.

Stitching panoramas

Starting today, we are also stitching Mapillary photos into panoramas. Our viewer already gives you a dynamically generated panorama if you zoom out from a photo with lots of overlap but many asked for a high res stitched photo compilation. Sequences taken in panorama mode, are now stitched and you can switch between the regular photo view and panorama view.

Dynamically stitched
Zooming out on a photo generates our dynamic panorama. Here you can apply filters and the panorama changes accordingly. Clicking the panorama button changes the view to the stitched version.

Statically stitched
The stitched panorama is one large image. Click 'Exit Panorama' to go back to the regular view.

Hope you will enjoy these new features (many of you requested panorama support). Let us know what you think and report any issues you find.

/Jan Erik

*) The web uploader does not work directly from iOS devices due to the image picker stripping photos of the GPS data. **) Works best on browsers that support WebGL. In Safari you can turn that on under the Develop menu.


Mapillary iD Editor for OpenStreetMap

by Peter Neubauer, Posted on 19 Aug 2014

Peter Neubauer

We have been working closely with the OpenStreetMap community in order to find the best way to leverage all the fantastic coverage that is starting to emerge on Mapillary to improve OpenStreetMap data.

With our latest effort, with the guidance and input of @jfire and @mvexel, we are proud to present a first version of the Mapillary - OSM integration for editing here.

alt image with links

Main integration features of Mapillary-iD, taken from Malmö

Basically, we did 3 additions to iD:

  • Added an optional layer to the main map view to display Mapillary sequences (the red lines)
  • Upon mouse clicks on the map, fetch and display the closest image in the inspector sidebar and link to the full view on Mapillary
  • Indicate the position and view direction of that image on the map, so the editing person can find the relevant features on the map

With a bit of feedback, maybe this can get merged into the main branch and be available on the main iD site. Now, if you are mapping for OpenStreetmap, feel free to take pictures with Mapillary and you will enhance both projects.

Try it out and let us know what you think!

/peter


jq - JSON Power For The Terminal

by Peter Neubauer, Posted on 12 Aug 2014

Peter Neubauer

Do you find yourself sometimes writing small scripts just to introspect some JSON? Say we want to get some image from the Mapillary API, the URL for getting GeoJSON from an image search is http://api.mapillary.com/v1/im/search?min-lat=55.611&max-lat=55.613&min-lon=12.994&max-lon=12.995&max-results=3&geojson=true:

curl http://api.mapillary.com/v1/im/search\?min-lat\=55.611\&max-lat\=55.613\&min-lon\=12.994\&max-lon\=12.995\&max-results\=3\&geojson\=true
{"features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[12.99455273,55.61112242]},"properties":{"location":"Beijerskajen, Malmö","marker-color":"#707070","marker-size":"medium","image":"https://d1cuyjsrcm0gby.cloudfront.net/BjoCtrQEPlLbj-qM-CKt4Q/thumb-320.jpg","key":"BjoCtrQEPlLbj-qM-CKt4Q","compass_direction":"2","ca":90.8944244384766}},{"type":"Feature","geometry":{"type":"Point","coordinates":[12.994548972049,55.6111892340047]},"properties":{"location":"Beijerskajen, Malmö","marker-color":"#707070","marker-size":"medium","image":"https://d1cuyjsrcm0gby.cloudfront.net/XSPgbXcjLkIgOIfn-9C-ow/thumb-320.jpg","key":"XSPgbXcjLkIgOIfn-9C-ow","compass_direction":"7","ca":334.037878787879}},{"type":"Feature","geometry":{"type":"Point","coordinates":[12.994737,55.611425]},"properties":{"location":"Beijerskajen, Malmö","marker-color":"#707070","marker-size":"medium","image":"https://d1cuyjsrcm0gby.cloudfront.net/UsOg_TQgsuPfNJTOjwHmuA/thumb-320.jpg","key":"UsOg_TQgsuPfNJTOjwHmuA","compass_direction":"6","ca":275.6486}}],"type":"FeatureCollection"}

Pretty awkward to find anything here right?

I recently discovered jq, the most awesome tool to look at JSON fast. To install, just do the familiar

brew install jq

And we are ready to look at the JSON we pipe into jq, just pretty-formatting the output (for the prompt coloring and git branch magic - I'm using oh-my-zsh):

curl http://api.mapillary.com/v1/im/search\?min-lat\=55.611\&max-lat\=55.613\&min-lon\=12.994\&max-lon\=12.995\&max-results\=3\&geojson\=true | jq '.'

alt image with links

Nice colors 'n' all!

Nice, the GeoJSON is a map with a features array with maps in it. Let's count the length by piping the features array into a length filter, much along the lines of data flow frameworks, giving 3 as the result:

➜  mapillary_api (master) ✗) curl http://api.mapillary.com/v1/im/search\?min-lat\=55.611\&max-lat\=55.613\&min-lon\=12.994\&max-lon\=12.995\&max-results\=3\&geojson\=true | jq '.features | length' 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1076    0  1076    0     0   3368      0 --:--:-- --:--:-- --:--:--  3373
3

Now, let's drill down into the first images longitude with:

  mapillary_api (master) ✗) curl http://api.mapillary.com/v1/im/search\?min-lat\=55.611\&max-lat\=55.613\&min-lon\=12.994\&max-lon\=12.995\&max-results\=3\&geojson\=true | jq '.features[0].geometry.coordinates[0]'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1076    0  1076    0     0   3187      0 --:--:-- --:--:-- --:--:--  3183
12.99455273

However, jq can do almost arbitrary transformations on JSON, much like awk and sed for textfiles. Say we want to just list certain attributes like the key and ca of every image in a line-style fashion, we just apply some pipes and output literal strings with something like jq '.features[] | "key: \(.properties.key), ca: \(.properties.ca)"':

➜  mapillary_api (master) ✗) curl http://api.mapillary.com/v1/im/search\?min-lat\=55.611\&max-lat\=55.613\&min-lon\=12.994\&max-lon\=12.995\&max-results\=3\&geojson\=true | jq '.features[] | "key: \(.properties.key), ca: \(.properties.ca)"'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1076    0  1076    0     0   5853      0 --:--:-- --:--:-- --:--:--  5879
"key: BjoCtrQEPlLbj-qM-CKt4Q, ca: 90.8944244384766"
"key: XSPgbXcjLkIgOIfn-9C-ow, ca: 334.037878787879"
"key: UsOg_TQgsuPfNJTOjwHmuA, ca: 275.6486"

This certainly makes my days with the terminal more enjoyable when dealing with REST APIs like Mapillary, ElasticSearch, Neo4j, AWS and many others. How about you?

/peter


Time Filtering and Web Interface Improvements

by Kamil Nikel, Posted on 07 Aug 2014

Kamil Nikel

Filtering & Interface Improvements

Today we released couple of new features. In the past few weeks we have been working hard on them and we were so excited, that we decided to release them slightly earlier. So, let me walk you through what we have this time.

Filtering the map

As there are more and more sequences being uploaded to Mapillary, we were thinking about new ways to interact with them. As we want everyone to enjoy all the data that's available at Mapillary, we decided to go with filtering.

Filter tab folded

Filter tab folded

Filter tab expanded

The new filter tab

Would you like to see all sequences taken in spring in Malmö? No problem - search for Malmö, head to the new Filter tab and select seasonal spring filter. All the sequences have been color coded for your convenience.

Maybe you're interested in sequences taken between 20th of September, 2013 and 14th of July, 2014 (just because you find these dates interesting)? We have you covered - adjust the histogram's handles accordingly and you're set. The histogram also shows the amount of sequences taken per week/month in the currently visible area. So if at any time you zoom-in/out, it will update with new values.

Histogram with a filter applied

Histogram with w filter applied

Perhaps you're more of a social person, or just curious about commented pictures? From now on you can also toggle comments on the map, from within the filter tab too.

Comments enabled on the map

Comments enabled on the map

Last thing. There might be situations, when you are looking at an image, but it happens to be outside of the filter you have applied; in that case the image will appear faded. You will still be able to go to next/previous image in that sequence.

The UI Improvements

Filtering isn't the only new thing. We gave a slight visual overhaul to the main map/image view. In Mapillary, the image is the core of what Mapillary is, but the location gives it the context. We wanted to explore that concept in the new interface as well, and push it even further. Therefore now, the image and its location are embedded in the map. However, we have a varied user base who have different needs, who have different browsing habits, and this brings us to the next point…

Toggling image size

Sometimes the image might not need to be that important to you to see it at all times, like e.g. while browsing the map. So from now on you have a possibility to change its size whenever you need it. As you will see, opening the filter tab gives a better glance at the map, and toggles the image. However, as soon as you fold the filter tab, image returns to its standard size. In case you'd like to have the image retain the smaller size at all time, you can toggle it here. This is what we call a 'manual toggle', which means if you expand/fold the filter tab again, the image will remember its size.

Here you can toggle the image

Here you can toggle the image

Manual toggle applied

Manual toggle applied

Related Images

From now on users have possibility to see related images to the one they see at the given time. The images are taken from adjacent sequences.

Related Images

Related Images

Screencast

Here you can find a brief overview of what's new out there.

The time filtering UI from Mapillary on Vimeo.

Have a look, browse around, spread the word. Let us know what you think on Twitter and report any problems you find!

Happy exploring!

/Kamil & The Mapillary Team


Upload Scripts

by Jan Erik Solem, Posted on 21 Jul 2014

Jan Erik Solem

Here's a post for those of you who upload from a computer, because you use other cameras like GoPro or Garmin Virb, or because you offload photos when your phone is getting full. In our Mapillary Tools repository we have the tools you need. Just clone or download to get started.

There are two cases and two different kinds of uploads. The first is when you upload photos taken with the Mapillary app. The second is when you upload photos from other cameras. Let's look at each of them.

Photos from the Mapillary app

This is the easy case. Because the apps embed all information needed in the photo's EXIF information (inside the Image Description tag) all you need to do is to get the photo to the right server. Since the photos are self-contained it doesn't matter who does the uploading. You can collect photos from many users to one computer and upload all at once. They will be correctly sorted in sequences and assigned the right photographer.

Just run the script upload.py with the folder containing your photos as argument, like this:

$ python upload.py path

After successful upload the photo will be moved to a subfolder of where you run the script (named 'success'). This is so that in case you loose your connection or have to abort, you can just start again and not worry about uploading the same photo twice. Tip: run the script from a separate folder.

Photos from other cameras

With photos from other cameras, the photos don't contain all the information we need. For example, there is no sequence id indicating which photos belong together, and there is no information on which user took the photos.

One option is to use the web uploader and select photos sequence-by-sequence. Since you are logged in to the Mapillary website, and select which photos go together, we have everything that's needed. Using the web uploader is a liitle cumbersome if you have a lot of photos.

The second option is to use the upload_with_authentication.py script. As the name says, you need to authenticate so Mapillary can see who uploaded. To do this, you first need to go to this page while you are logged in in your browser. Then take the two hashes and save them as environment variables together with your Mapillary username. For example:

$ export MAPILLARY_SIGNATURE_HASH="your signature hash"
$ export MAPILLARY_PERMISSION_HASH="your permission hash"
$ export MAPILLARY_USERNAME="jesolem"

Next you need to group the photos into folders of sequences. Just copy manually or use the time_split.py script, also part of the tools you downloaded. See here on how to use that.

Finally, you can upload each sequence by supplying the path to the folder. Like this:

$ python upload_with_authentication.py path

The photos are also moved to a subfolder 'success' after sucessful upload.

Dependencies

In both scripts there are checks for the necessary EXIF tags. You will have to install the exifread module. For example using pip:

$ pip install exifread

Happy mapping with your GoPros and Garmins!

/Jan Erik


Introducing Places and Regional Stats

by Johan Gyllenspetz, Posted on 24 Jun 2014

Johan Gyllenspetz

We are continuing our work on showing all the great data that we have. Recently we added connections and notifications to connect mappers.

We have now added a new places page on our website with stats on who's mapping and where. We have so many great contributors and this is a nice way to show who is mapping a particular region.

The map looks like this:

alt toplists

From the main map you can drill down by clicking a specific region, for example Italy:

alt italy

Some countries have sub-regions, for example Germany, Sweden, and the United States. We will add more sub-regions when a region has enough data for that to make sense. Every country and region has its own url so you can share and bookmark.

For each of these views, we are also showing who the top contributors are. For example, for Italy:

alt fulltoplists

The number one contributor also gets a special spot on the map too.

Take a moment and browse around, see whos active in areas you care about and look at their fantastic contributions.


Making Connections and New Profile Pages

by Jan Erik Solem, Posted on 22 Jun 2014

Jan Erik Solem

At Mapillary, our main task is connecting the many photos uploaded to the service. We do this all the time, in the background, using computer vision and reasoners.

Besides showing connections when you are actively looking at a photo and navigating, we haven't really exposed this data. That is changing now.

Weekly Connections

Some of you may have noticed the weekly activity email that went out last week. At the top there are stats on how many new photos you added, how many new connections were made between your contributions and others', and your ranking on some relevent top lists of contributors. Then there is a section called "Close and similar to yours", these are the new connections between you and other mappers made in that week.

alt similar

In the screenshot above, you can see that my uploads were matched to other users' uploads. In the top row, the other photo (from a bus camera) is from a later point in time. You can see that the building under construction has several floors added. On the second row, you see a difference in seasons for two photos taken at the same exact spot.

Connections on Profile Pages

Johan made a major update to the profile pages. These show your bio and your basic stats at the top, just like before. Then, next to your uploads, are the connections. Here we are showing which users you are connected to through your uploads. The counter next to the name is how many connections you have. Click a user and the view expands so you can see all the connections.

alt profile

Now you can easily see who else is mapping where you are. Who knows, you might make new friends or new rivals this way ;)

We love this way of connecting our contributors, not just the photos. You are not alone out there. When your uploads become connected with others and become part of something bigger, we want to let you know. Hopefully you will find that as rewarding as we do.

/Jan Erik


Using an Action Camera with GPS

by Jan Erik Solem, Posted on 16 Jun 2014

Jan Erik Solem

Here's another workflow posts for you, this time about action cameras that have GPS. I have had my eyes on the Garmin Virb after seeing it at bike races and finally gave it a try.

We have written about flying drones, about working with GoPro cameras, where you have to sync the photos to locations recorded with an external GPS or phone. (There is a script for that, see this post.)

With a GPS enabled action camera you can skip all that. I'll use a bike handle bar as example.

alt bike
A Garmin Virb attached to a bike with the GoPro bike mount.

Here's the process:

  • Attach the camera (I like the GoPro bike mount kit, you can also try 3D printing these).
  • Check the preview to see that the photos are straight and the horizon is where you want it (I like mine in the middle).
  • Set the camera to 2s interval time lapse. On the Garmin Virb, you can turn on wide angle straightening, this is a good idea.
  • Start riding and start the camera.
  • Stop and start when it makes sense to do so, at natual sequence gaps or when there is sometheing you don't want to capture.
  • When you are done riding, copy the photos over to your computer. Look through them quickly and delete the bad ones.
  • Before uploading the photos using the web uploader, it is useful to organize them in sequences since the uploader needs all photos in a sequence at the same time. I made a script for that, just download it here. Run it like this:
$ python time_split.py virb_test 
Organizing into 15 groups.
Moved 32 photos to virb_test/0
Moved 42 photos to virb_test/1
Moved 10 photos to virb_test/2
Moved 36 photos to virb_test/3
Moved 46 photos to virb_test/4
Moved 30 photos to virb_test/5
Moved 11 photos to virb_test/6
Moved 25 photos to virb_test/7
Moved 154 photos to virb_test/8
Moved 54 photos to virb_test/9
Moved 29 photos to virb_test/10
Moved 84 photos to virb_test/11
Moved 70 photos to virb_test/12
Moved 59 photos to virb_test/13
Moved 27 photos to virb_test/14
Done grouping photos.
  • With photos captured in time lapse mode the script automatically finds the cutoff points and copies the photos into subfolders for you.
  • Open the web uploader, click "Choose Files" and select everything in one of those folders. You will then see them on a map, where you can check that everything is ok and remove unwanted photos. alt uploader
  • Click "Upload To Server" and when all markers are green, push to Mapillary.
  • Repeat until all folders are uploaded.

Hope this is useful for our bikers and motorcyclists out there. If you have other workflow tips, blog, tweet or email us.

/Jan Erik


Privacy Blurring - Now in the Editor

by Johan Gyllenspetz, Posted on 25 May 2014

Johan Gyllenspetz

At Mapillary we do a lot of things with the photos you upload. One thing we do is to automatically blur license plates and peoples faces for privacy purposes. No license plate detector or face detector is perfect and sometimes we will incorrectly blur areas, sometimes we will miss important areas that needed blurring.


Example of incorrect blurring

Enabling manual correction of blurring is one of the most requested features that we have had so far. It is a great thing that our users are concerned about privacy. We promised to do something about it and now we have.

As of now, any user can manually add and remove blur in the editor. This is how it works (a video says more than a thousand words):

Blurring/Unblurring Mapillary from Mapillary on Vimeo.

That means that even though our automatic detectors sometimes fail, together we can make Mapillary a place where privacy is respected.

This looks like an easy feature to build but we actually had to make deep changes in how we handle the results of the detectors for blurring. We are very happy to finally have the feature out and we hope you will like it too.

/johan


Flying Drones, Capturing Mapillary Tracks

by Peter Neubauer, Posted on 20 May 2014

Peter Neubauer

The task

A few days ago, we tested what it would take to capture tracks using professional equipment like the awesome drones by Intuitive Aerial in Linköping, Sweden.

The hardware

For the flight, we used a smaller variant of the drone, and attached a normal cell phone to capture the GPS position while flying with a GoPro camera, following the same technique as described in Craig Taverner's blog post for time lapsed GoPro pictures.

The quadcopter was a lesser variant of the real devices produced by the company, with an Ardupilot central unit and for propellers. Thank you Torkel Danielsson of Intuitive Aerial for taking the time to make this possible!


Torkel Danielsson of Intuitive Aerials and his quadcopter

Also, we had the fortune to have a prototype of a stabilizing handheld wig for GoPro available, big thanks to Patrick St-Arnaud from Shape for spending the time to makes this possible!

Patrick St-Arnaud demoing the GoPro stabilization device

The process

Now, it is "just" a matter of directing the drone automatically along GPX tracks, or manually control it to take the desired footage in GoPro sequence mode.


The Quadcopter rig flying

The resulting pictures are transferred from the GoPro to a computer together with the GPX track form the phone, and then correlated and uploaded to Mapillary.

Here is the result - aerial coverage around the university of Linköping!

Summary:

With the right equipment, it is entirely possible to capture aerial footage using drones and Mapillary, and without big effort this can be scaled up for a municipality or infrastructure company. This experiment took about 2 hours - not a lot of time considering this was the first time.

Safe flying,

/peter


A Mapillary Windows Phone App!

by Tommy Ovesen, Posted on 15 May 2014

Tommy Ovesen

Today Mapillary - the project to provide a street level view of the world - arrived at the Windows Phone platform with the first release of the app for Windows Phone 8 / 8.1.

This is not an official app from Mapillary, but it was developed by me in cooperation with the Mapillary team.

The Windows Phone app is quite similar to the iPhone and Android apps. Here are a few screenshots:


The Welcome Screen


The Camera View.


Edit/Delete pictures before upload.


Upload pictures.

The Mapillary app for Windows Phone can be downloaded for free here:

Mapillary for Windows Phone is developed by Ovesen.net. The person behind Ovesen.net is me, Tommy Ovesen, an experienced senior software developer from Bodø, Norway. I develop apps for the Windows 8 and Windows Phone platform as a hobby besides my full time job as a developer.

Please try out the app if you have a Windows Phone. If you have any suggestions or issues with the Windows Phone app, contact me at my Facebook page

Your community member

Tommy Ovesen


A Capture Workflow

by Jan Erik Solem, Posted on 15 May 2014

Jan Erik Solem

This past weekend we captured some data for the upcoming Traffic Jam Session hackathon here in Malmö. Since the event is about hacking public transportation data, we mapped some of the local bus lines. We used six Android phones running the Mapillary app that captured a total of 50GB of photos.

alt devices
The red things are TI Sensor Tags that recorded some additional data.

With this blog post I just wanted to share the workflow we used for this type of organized "large scale" capture session.

  • Meet up with all devices charged and plan who goes where. In our case we had coffee and waited for the rain to clear.
  • Turn off automatic syncing if you use Android.
  • Go out and capture. Depending on your mode of transportation, hold the phone in your hand, use a mount, whatever works in the situation. For vertical windows like a bus or tram, double-sided tape directly against the window works great.
  • Empty the phones at regular intervals. If you want to capture 10-20GB per device, you most likely will have to do it in several sessions and copy your photos over to a laptop.
    • On iOS you can do this in iTunes. Open the Apps tab and scroll down until you see the Mapillary app at the bottom. You can copy the photos from there.
    • On Android you can access the files over USB cable or if they are on an external SD card, you can put the card in a reader on your laptop.
  • Review the photos. When you are done capturing and have collected all photos it is much easier to go over thousands of photos on your laptop on a good screen. Just delete all photos you don't want.
  • Upload. The easiest way is to run our command line upload script. Just point it at the folder with all your photos and it should do the rest. If you cannot run the script, you can also copy photos back to the app and upload from there but that's a little messy. Don't worry about giving credit to the right photographer, all capture information is contained in the photo's EXIF. Anyone can upload a photo you took from anywhere, it will show as your upload.

The same process applies if you capture over long times with no WiFi to upload. Just copy the photos over to a laptop at regular intervals and review them in peace before bulk uploading.

Here's one of the routes. alt route

Here's a photo of Peter and a happy busdriver. alt devices


Weekend Hack - a Mapillary GoPro Bike Mount

by Peter Neubauer, Posted on 05 May 2014

Peter Neubauer

After we sent out the car mounts after our survey, we received a lot of positive feedback. However, there are not many mounts for bikes that are suitable for Mapillary.

So, last weekend's project was to start building one. First, my friend Martin Wolff did a great first iteration with a 3D printer:

alt test

There are many interested Mapillary users wanting to import images from GoPro cameras. I thought it might be a good idea to build on that ecosystem and design a bicycle phone mount that is compatible with the GoPro accessories.

Searching at Thingiverse, I found this nice starting point. Loading it into OpenSCAD, I got

alt test

Cool! So, I could use the GoPro 2-legged mount and edited Martins Phone-mount, corrected for my Sony Xperia Z1, resulting in this code:

use <gopro_mounts_mooncactus.scad>
include <write.scad>

// Create a "triple" gopro connector
translate([0,-10.5,0])
gopro_connector("double");


ph_width     = 147;
ph_height    = 74;
ph_thick     = 9.5;
wall             = 2;
camera_hole_to_top_edge = 11.5;
camera_hole_to_side_edge = 10;
camera_hole_diameter = 15;
side_edge_to_screen = 10;
bottom_edge_to_screen = 10;
lift_holes_diameter= 20;


color([0.6,0.6,0.6])
translate([-ph_thick/2,0,-ph_width/2])
difference (){
    union() {
        cube([ph_thick+wall*2,ph_height+wall*2,ph_width+wall*2]);

    }
    union() {
        translate([wall,wall,wall])
        //phone body
        cube([ph_thick,ph_height+10,ph_width]);

        //camera hole
        translate([0,ph_height-camera_hole_to_top_edge,ph_width-camera_hole_to_side_edge]) {
            rotate([90,0,90])   cylinder(3*wall,d=camera_hole_diameter,center=true);
        }

        rotate([90,0,90])   cylinder(30,d=lift_holes_diameter,center=true);
        translate([0,0,ph_width]) {
            rotate([90,0,90]) cylinder(30,d=lift_holes_diameter,center=true);
            translate([0, ph_height/2, -ph_height])
            rotate([270,270,90])
                write("Mapillary",h=10,t=wall/2,center=true);
        }
        translate([wall*2+ph_thick/2,side_edge_to_screen,bottom_edge_to_screen]) cube([wall*6,ph_height*0.8,ph_width*0.8]);



    }
}

Which looks something like:

alt test

The code is here, feel free to fork and improve, and adjust the dimensions to your phone model. Once it is good enough, we will upload it to Thingiverse.

This took about two hours (I am a bit slow on CAD, just starting). After that, just export the STL file and print it on your nearest 3D printer - I went to my local hacker space STPLN where we printed the mount in ABS on a RepRap variant:

alt test

The walls are a bit thin, and I printed with only 40% material fill which is wrong but the dimensions seem to work:

alt test

alt test

So, next iteration will be on a printshop-printer, printing the GoPro handlebar-mount, and off we go!

/peter


License Update: Now Creative Commons Share Alike

by Jan Erik Solem, Posted on 29 Apr 2014

Jan Erik Solem

It has been six weeks since we announced that we were licensing our photos with Creative Commons. The license we chose was the Creative Commons Attribution-NonCommercial 4.0 License (CC BY-NC). Our reasoning was explained in the accompanying blog post.

Today we are making modifications to the license and are switching to a Creative Commons Attribution-ShareAlike 4.0 License (CC BY-SA).

Creative Commons License

Our updated legal summary page has the details.

This now means we have a true open data license and that we are welcoming people to use our photos. Our guiding principle remains the same: maximize sharing and use of all our photos without totally compromising us building a sustainable business.

We are in this to build something great and we have many cool features to come. As a commercial business we are still in the early phases but we plan to build some great products on these photos and the data we create using our algorithms. Stay tuned.

Now let's map this world.

/Jan Erik

If you came here without knowing what Mapillary is, take a look at our manifesto.


Bulk Editing Compass Angles - Yay!

by Peter Neubauer, Posted on 28 Apr 2014

Peter Neubauer

Today, we finally got around to implement one of the most requested editing operations for Mapillary - the bulk-straightening for all images in a sequence.

When you take pictures in cars, busses and other vehicles, the phones compass directions tends to be off by non-trivial angles. Now, in the editor, you can just click on the button "Camera was pointing forward" and we will make a changeset for all pictures in the sequence with their compass direction pointing to the next picture as calculated from the GPS positions instead of the phones data. Very handy and being applicable in 95% of all sequences in Riding mode!

Here is a few seconds video showing this:

Happy editing!

/peter


A Startup Dashboard with Google Spreadsheet

by Peter Neubauer, Posted on 04 Apr 2014

Peter Neubauer

When you are a startup, you don't have much time. In our case, we want to track some of our KPIs, as the numbers of users, images and power users over time (lots of other historic KPIs like user retention too, but that's another blog). We also want have a nice dashboard but not build a system for that.

Since we needed a JSON API call anyway, we decided to implement a sliding backwards-scale JSON endpoint that looks something like

{
    "date":["12/19/2013","12/26/2013","01/02/2014","01/09/2014","01/16/2014","01/23/2014","01/30/2014","02/06/2014","02/13/2014","02/20/2014","02/27/2014","03/06/2014","03/13/2014","03/20/2014","03/27/2014","04/03/2014"],
    "users":[104,109,112,113,121,131,152,164,185,198,215,574,738,786,843,956],
    "photos":[24889,28435,34919,36599,40255,43388,51790,60306,68490,74641,78413,91207,120284,138000,165583,192208],
    "sequences":[923,1034,1171,1228,1358,1471,1776,2085,2483,2729,3177,3907,5034,5729,6635,8019],
    "edges":[128752,140619,181738,217009,247674,284711,315260,462161,612369,874701,1127074,1268489,1808776,2232907,2829353,3508281],
    "uploading_users":[31,34,36,38,39,41,45,51,53,61,66,110,154,181,203,234],
    "uploading_users_10":[26,29,30,32,33,35,37,42,43,49,53,76,108,133,154,181],
    "uploading_users_100":[14,15,17,17,17,18,18,21,24,29,31,44,56,62,74,100]
}

Now, you can build your own visualization on top of this with authentication, Heroku hosting and so on. However, there is Google Spreadsheet and Google AppScript, an extremely powerful and productive combination. In our case, we added a script to a Google Calc spreadsheet to interpret the JSON response and return an array of cell values:

function fetchStats() {

  var url = "https://api.mapillary.com/xxx";
  var urlFetch = UrlFetchApp.fetch(url, null);
  //fetch the data (with a secret token or authentication)
  var json = JSON.parse(urlFetch.getContentText());
  var cells = [];
  for (key in json) {
    var values = [];
    values.push(key)
    for (var i = 0; i < json[key].length; i++) {
      values.push(json[key][i]);
    }
    cells.push(values);
  }
  //the resulting 2-dimensional cell range
  return cells;
}

Once we have this, we can simply have a cell with =fetchStats() and have a cell range filled in from the endpoint anywhere in the spreadsheet. After that, diagrams and calculations are trivial. This could result in a spreadsheet like

alt trace

And we get the whole sharing, charting and other spreadsheet benefits instead of yet another system to maintain.

I like pragmatic - thought you might be interested.

/peter


The Disqus Integration is Working - Let's Start Talking!

by Peter Neubauer, Posted on 19 Mar 2014

Peter Neubauer

Hi there, you probably have seen the disqus footers under the Mapillary pictures. While this has been working for a while (we are talking days here :), we now have integrated a polling on new blog posts that will mail the photographer of the image with any new updates on the discussions.

In other words - you will now be notified when someone comments on your pictures. Start commenting and replying. Now the photographer can actually hear you!

/peter


An Angular.js Confirm Dialog Directive ftw!

by Peter Neubauer, Posted on 18 Mar 2014

Peter Neubauer

We got a complaint from a user who flagged an image by accident, see this issue. As we are now entering a phase of Complaint Driven Development, this morning I found a great little fix to this. Angular.js which we use for the web client, does not come with a built-in confirmation dialogue. However, here is a great little generic confirm-button directive that avoids the onClick method and can be reused.

This is how it turned out:

angular.module('mapapp')
  .directive 'ngConfirmClick', [() ->
    restrict: 'A'
    replace: false
    link: ($scope, $element, $attr) ->
      msg = $attr.ngConfirmClick || "Are you sure?"
      clickAction = $attr.confirmedClickAction;
      $element.bind('click',(event) ->
        if window.confirm(msg)
          $scope.$eval(clickAction)
      )
      ]

Having done this, we can now just change the HAML-template code from

%span.set_flag{'ng-show' => '!flagged', 'ng-click' => 'flagImage(nav.currentImage)'}

to something like

%span.set_flag{'ng-show' => '!flagged', 'confirmed-click-action' => 'flagImage(nav.currentImage)', 'ng-confirm-click'=>'Are you sure to flag this image?'}

Resulting in this:

Voilá, another closed issue :)

/peter


Mapillary Goes Creative Commons

by Jan Erik Solem, Posted on 17 Mar 2014

Jan Erik Solem

One thing we have been struggling with since starting Mapillary is the issue of licensing Mapillary photos.

On one hand, the reality of the situation is that we are a startup with a small hard-working team, trying to build something we think is important. With that comes operational cost for salaries, servers, office space etc. At the same time, we are strong proponents of Open Source and Open Data and feel we have a responsibility for sharing and contributing as much as we can.

In our discussions we went over many scenarios of users opting in, or opting out, to sharing specific photos or specific uploads. It never felt right. Complicated and contrived. Hard to explain.

We decided to go for something simple instead. Maximize sharing and use of all our photos without completely shooting us in the foot (head?) when it comes to making a sustainable future business. Something truly sustainable that will let us work on this challenging thing we love for many years to come.

Today we are happy to announce that all public photos on Mapillary are free to use for non-commercial work under the Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC).

Creative Commons License

Take a look at our legal summary page for the full details.

If you came here without knowing what Mapillary is, take a look at our manifesto.


Thanks!

While trying to sort out licensing, we have received a lot of feedback, questions, and comments over twitter, email, and our public GitHub issues, and really appreciated all of it. Lots of great advice from lots of smart people. Members of the Swedish and German OSM communities have been very supportive and helped a lot. Thanks everyone!

Now let's map this world.

Update: We are revising the license and going from CC-BY-NC to CC-BY-SA on April 29, 2014. See this blog post.


Embed a Mapillary View

by Johan Gyllenspetz, Posted on 04 Mar 2014

Johan Gyllenspetz

As Mapillary is starting to grow in popularity, we got a number of requests to be able to embed the Mapillary view into other web pages. So, we built it! This is how it goes - for details, see the developer page:

  • import the Mapillary Javascript lib
  • have a <div id='mapillary'>l tag somewhere on your site where you want the widget
  • initialize the Mapillary Javascript after the site is loaded fully.

The code is quite simple:

    <!-- pull in the script -->
    <script src="//dga406zepc8gy.cloudfront.net/javascripts/mapillary.js" type="text/javascript"></script>

    <!-- This is where the widget will appear-->
    <div id='mapillary'></div>

    <!-- Initialize the Widget with a start image and a width-->
    <script>
      (function() {
        Mapillary.init('mapillary', {image: 'RdGqCZOGpRTzFII4i7swYg', width: 320});
      })();
    </script>

With this, you can now start at any image you find on Mapillary. Of course, we want to add more things to it, like the ability to give a longitude/latitude to start with, but it's a start. Please let us know how you like it. As always, comment below, and report issues.

Looking forward to seeing Mapillary on a website near you!


Making the Static Dynamic

by Johan Gyllenspetz, Posted on 26 Feb 2014

Johan Gyllenspetz

The right stack for the job

Here at Mapillary we believe in dividing our services into small maintainable parts. We use the right stack at the right place. We force ourselves to write clear API:s between our services, no cheating. Our iPhone app uses the same API as our website. A feature developed in one of our server APIs can instantly be used by both our javascript front-end guy as well as our iPhone and Android developers.

The static problem

Our website http://mapillary.com uses the middleman framework and is hosted on heroku, this prevents us from cheating with the APIs. To communicate with our servers we use angularjs, the whole web page is static which is awesome.

However we just recently bumped into a problem. We want some of our links to be socially shareable. If a user finds a beautiful image in our archives (such as this one http://www.mapillary.com/map/im/pXA7tF-BIYMM2gStoOBMrQ) we want them to be able to share that link with their friends. This requires that we fill in our meta tags on the site accordingly. This is where rack is the best of friends.

Rack

Rack lets you write middlewares. A middleware is a piece of code that has access to everything in the HTML request by the user and the HTML response from the server. This is what we came up with. Add the following to your config.ru file.

    # Datamapper is awesome for accesing your database in ruby
    require 'data_mapper'

    # Create an Image object
    class Image
      include DataMapper::Resource
      property :k, String
      property :title, String
    end

    # Setup Database
    DataMapper.setup(:default, ENV['DATABASE_URL'])

    class DYNAMIC_META
      def initialize(app)
        @app = app
      end

      def call(env)
        status, headers, body = @app.call env

        # Check for request path
        if env['REQUEST_PATH']
          # Match it to our specific path
          match = env['REQUEST_PATH'].match(/^\/map\/im\/([^\/]*)$/)
          if match
            key = match[1]
            # If there is a match lookup up the image in our database
            image = Image.all(k: key).first
            if body
              body.each do |line|
                # Replace static content with dynamic content
                if line =~ /.*twitter:.*/
                  line.gsub!(/<meta content='' name='twitter:image:src'>/, "<meta content='https://example.com/#{key}/image.jpg' name='twitter:image:src'>")
                  line.gsub!(/<meta content='' name='twitter:title'>/, "<meta content='#{image.title}' name='twitter:title'>")
                  body = [line]
                end
              end
            end
          end
        end

        [status, headers, body]
      end
    end

    use DYNAMIC_META

Why is this piece of code so magical. Well its the easiest smallest piece of server side include I can think of. It enables us to use middleman and all of the features we love yet having a tiny part of our website to be dynamic.


Manual Upload

by Jan Erik Solem, Posted on 21 Feb 2014

Jan Erik Solem

One question we get a lot is if you can upload photos that you have taken with another camera, outside of our apps. Maybe you have some great street sequences taken with your DSLR or older photos that you would like to add.

Today we added manual uploads as an experimental feature. If you are signed in, you can find it in the drop down menu here:

alt upload menu

Just click the "Choose files" button and select all photos that should go together as a sequence. Once uploaded they will go through our regular pipeline.

We are working to support different EXIF tag formats. Right now we require latitude, longitude, image direction, and time.

alt upload menu
Example EXIF tags (photo from ubahnverleih)

Let us know if you have photos, EXIF, camera models that you would like us to support (twitter or email).


Mapillary to OpenStreetMap

by Johan Gyllenspetz, Posted on 20 Feb 2014

Johan Gyllenspetz

We have been working with the OpenStreetMap community lately and we wanted to investigate how Mapillary can be used as a tool for some serious mapping.

First of all I needed to find a possible candidate area for mapping. After some investigation I found this little park in West Hollywood, called West Hollywood park. The park was under construction on the Bing images in the Id editor and nobody has traced the park yet.

alt before map

I headed out a Saturday equiped with my iPhone and my Garmin GLO GPS connected with bluetooth for better GPS accuracy. After some (not too rigorous) testing we have found that the Garmin GLO gives really good accuracy.

alt garmin

I went around the park and used the Mapillary app to take photos of every path. When I came home I uploaded the images directly from the app over WiFi. When the upload finished, I went to My Uploads.

alt my uploads

Every sequence taken has a link where I can get the corresponding GPX file.

alt gpx

I downloaded all the gpx files and added them to the excellent application Adze. Here I can import several traces, merge them into one, and save the merged file.

alt editor

Next step was to locate the park in the Id editor and drag that file to the editor. Id will now show an overlay of my trace.

alt overlay

I traced the tracks and set them to be “walking path”.

alt trace

Press save button and, voila, a few minutes later the track was visible on openstreetmap.org.

alt done map

Check out the final result on Mapillary and on OpenStreetMap.

Some of these steps can probably be done more effectively, but this first test shows that we can easily use Mapillary for OpenStreetMap tracing. Try it yourself!


Photo Capture Modes

by Jan Erik Solem, Posted on 13 Feb 2014

Jan Erik Solem

With our latest update to the iPhone and Android apps today, we made some changes in how you capture photos. Where before, you selected "photo" or "sequences" when launching the camera, we now added three capture modes:

alt iphone modes

Walking

Walking mode is for when you are walking, or moving slow, and want to manually control when photos are taken. Take as many photos as you like and try to get lots of overlap between photos. When you turn or change direction, try to do it gradually, taking overlapping photos. That way the photos will be better connected and you get a nicer viewing experience.

Riding (bike/car)

In riding mode, photos are taken automatically in 2s intervals. Hold the camera straight and point it in the direction you are riding. Bikes are great for this! If you are in a car, make sure your view is clear of dashboards and other car parts.

Panorama

The panorama mode is for when you are in a location where you want people to be able to look around in many directions. For example, in fromt of landmarks, interesting buildings, at intersections, where there is a beautiful view. Stand in one place and take as many photos you like while panning the camera around. Make sure to get lots of overlap between photos.

alt screenshot alt screenshot
iPhone app in walking mode and Android app in riding mode.

In all modes, we recommend shooting with the camera in landscape orientation.

The reason for introducing these modes is that we want to help users take better photos. Some were confused when to use sequences before and we felt that although people did take panoramas, we wanted to handle panoramas differently. The capture mode will also determine how your photos are processed and what rules and reasoners are applied to the resulting data which also improves the end result.

We hope you will like our new apps. As always, send us your feedback on twitter or email.


Editing Uploads

by Johan Gyllenspetz, Posted on 31 Jan 2014

Johan Gyllenspetz

Starting out Mapillary with the idea of crowdsourcing street view photos using smartphones we were fully aware of the limitations of the devices used. Typically, your phone will at best give position within a few meters accuracy, sometimes a lot more than a few meters.

To help users take photos with good positioning, we added GPS icons to the camera view in the apps that would show when it is safe to take photos. We also prevent photo capture in the apps if the accuracy is too low. Despite this, things go wrong and we wanted the ability to crowdsource the correction of uploads.

Today we launched the next step in improving our data quality, editing of uploads.

When you are signed in and looking at a photo (or sequence) you will see an "Edit" button, like this:

alt edit button

Clicking that button will take you into edit mode where you can drag to change the position of photos and edit other details. Once you are done, review and save your edits. Once saved, your edits will generate a change set that is queued for approval by Mapillary users that have the extra powers to approve changes. We aim to update all incoming change sets within 24h.

alt edit before
An example with poor GPS accuracy.

alt edit after
The same after editing. (modified photos are marked with red)

Next time you see a Mapillary upload that has errors, we hope you will give editing a try. Not just on your own uploads, you can help improve everyone's uploads.

Have fun editing!


Mapillary for Android

by Jan Erik Solem, Posted on 24 Jan 2014

Jan Erik Solem

The number one thing people have been asking us during our short history is "when will you have an Android app"?

We are happy to announce that exactly 9 weeks after the Mapillary iPhone app went live on the App Store, we have now released Mapillary for Android!

The two apps are essentially the same. Android allows background activities so our Android app has automatic background upload when you connect to WiFi. There is also sharing of uploads, something we will add to the iPhone version soon.

alt android screenshot

With Android comes a wide range of devices to support. While we have tested on a few models (recent Samsung, HTC and Sony models), it is still a small sample set. Let us know if you find issues with your device so we can fix them. The easiest way is twitter or email.

Download Mapillary for Android and try it out!


A Graph of Images

by Jan Erik Solem, Posted on 21 Jan 2014

Jan Erik Solem

Yesterday we updated the site with some major changes. Some of you may have noticed that loading the photos after clicking the map took a long time for certain locations with lots of photos.

This is because internally, we are actually building up a connected model of how images relate to all their possible neighbors - both in terms of location, direction, overlap and time, amongst others. Our master database is Postgres - very robust and with great tooling, but poor on performance in smart rule-based traversals of our image graph.

Just a few days back, we internally launched a graph search service built on top of the awesome graph database neo4j - also lovingly built in Malmö, Sweden! This graph search service exposes an API that we are now using for the site and that we will open up for developers soon. Even with hundreds of images, the performance is now back to where it needs to be (<100ms, compared to 15s+ in some really bad cases on Postgres).

We will use this as a platform for building new features around browsing photos and navigation. Stay tuned for a number of cool things we can do now that the bottleneck of the database performance is removed.

alt image with links

A photo is connected to other photos based on location and image features. The arrows show the most important connections for user navigation.

What does this mean for you?

  • The site is faster
  • Your applications will have better and faster search
  • Later on, you will be able to do queries for photos in specific directions or with specific properties.

Right now it’s winter over here in Sweden - help take some sunny photos to brighten the database and the front page. Happy mapping!


Welcome to Mapillary!

by Jan Erik Solem, Posted on 01 Jan 2014

Jan Erik Solem

With this post we are starting our company blog to share long-form content on topics that we are passionate about and topics that relate to Mapillary. For announcements and short-style content, follow us on twitter.

Why are we doing this?

In short: we want to create a photo representation of the world, a map with photos of every place on earth.

A somewhat longer answer is that we want to collect street view and map photos and make them available for users and developers because we believe:

  • that in order to extend the coverage and improve the freshness and level of detail of today's street view and map photos, we need to move from a top-down model (cars with a rig on the roof) to a bottom-up model where users contribute.
  • that users are good at deciding what is important and useful to photograph. Local knowledge is hard to beat.
  • that there is no limit to the focus and depth of people's interests, and there should be no limit to the level of detail users can contribute.
  • that the best way to crowdsource is to make super simple apps for data collection and move the intelligence to the server side, away from the user.
  • that a crowdsourced solution should improve with every new photo contributed, immediately.
  • that users and customers using the data provide a natural prioritization of what areas to cover first and how.
  • that there is a place for an independent neutral provider of map photos.

What can you do?

Browse photos online at mapillary.com.

Download the app. Try it out. Take photos of your neighborhood, take photos on your next vacation, your next hike, your next bike ride.

Use the API to build something.

Send us your feedback. These days are early days and we appreciate all feedback that can help us understand what you need and how.

Join us! It will be an adventure.