Quantcast
Channel: maps for developers - Medium
Viewing all 2230 articles
Browse latest View live

Come hang with us at FOSS4GNA this week!

$
0
0

We’re in Raleigh this week for FOSS4G NA, and we are so excited to hang out and chat Mapbox with friends both old and new. Be sure to come check out our sessions and say hi!

You can see the full schedule over at the FOSS4G NA site. Can’t wait to see you there!


Fast geodesic approximations with Cheap Ruler

$
0
0

Geodesic calculations are an important building block of many geospatial applications. Examples include finding distance between two locations, length of a road, direction of a road segment, area of a polygon, or closest point to a road.

At Mapbox, we rely on these calculations to process telemetry data from our SDKs so we can infer unmapped streets, road speeds, turn lanes, turn restrictions, and areas to prioritize for satellite imagery updates.

We typically use Turf for these calculations — it’s a simple, fast, modular JavaScript library for geospatial analysis. However, the amount of telemetry data grows bigger with every day, and so is the computational challenge of processing it. Every bit of performance we can squeeze in this process pays off.

To optimize processing, I built Cheap Ruler, a JavaScript library for ultra-fast geodesic calculations on a city scale. It’s not a replacement for Turf — it implements only a fraction of its methods, has certain limitations, and is only meant to be used in performance-sensitive applications. But where it fits, it can be 100 times faster than using conventional methods. Let’s explore how it works.

Measuring distances

To get the distance for two points on a flat plane, we use the Pythagorean theorem:

image

This doesn’t work for locations on the earth because latitude and longitude values don’t directly map to units of distance. If you were standing near one of the poles, 360 degrees of longitude could equal a few miles, and on the equator, the same 360 degrees would be 24,900 miles.

Second, the Earth is not a flat place — it’s spherical! Luckily, mathematicians found a way to measure distances on a sphere — first using spherical law of cosines, and then improving on this with the Haversine formula which is used in Turf and most geo apps.

Unfortunately, Earth is not even a sphere — it’s an oblate ellipsoid. Consequently, the Haversine formula can result in an error of up to 0.5%. To address this, Thaddeus Vincenty developed a very complicated formula that is accurate up to 0.5mm, making it the ultimate geodesic formula for all serious scientific purposes.

Both formulas rely on many trigonometric calculations, which are computationally expensive. How can we avoid them?

Euclidean geodesic approximations

Most of the performance-sensitive measurements we need are on the city block scale — in telemetry, we typically measure distances up to a few dozen miles, not thousands. For small distances like this, we can pretend that the Earth is flat, and avoid most of the complex calculations without a noticeable precision loss.

image

Left: meridian (line of longitude), right: parallels (circle of latitude).

To approximate the distance between two latitudes (the “vertical” component of the distance), we could scale it proportionally to the length of the meridian (about 12,430 miles), since it’s approximately the same for any longitude:

\[\partial y = 12430 \frac{ \left| lat_{1} - lat_{2} \right|}{180}\]

For longitude differences, the length of the parallels (a 360 degree circle) depends on its latitude, starting with equator length (24,901 miles) and scaling with the latitude’s cosine:

\[\partial x = 24901 \frac{\left| lng_{1} - lng_{2} \right|}{360}\; \cos (lat)\]

We can then combine the two formulas with the Pythagorean theorem to do a Euclidean approximation of the distance between two locations, using the latitude in the middle for longitude correction:

\[\partial y = 12430 \frac{ \left| lat_{1} - lat_{2} \right|}{180}\] \[\partial x = 24901 \frac{\left| lng_{1} - lng_{2} \right|}{360}\; \cos \left( \frac{lat_{1} + lat_{2}}{2} \right)\] \[d = \sqrt{\partial x^{2} + \partial y^{2}}\]

The resulting formula has just one trigonometric call, making it much faster than the trigonometry-heavy Haversine formula.

But there’s one more consideration. Let’s say we’re doing calculations in a specific city area (e.g. within a zoom 14 tile). The cosine of coordinate latitudes won’t vary much within a small area, so we can use the same longitude correction multiplier for all these calculations without a noticeable precision loss. So we calculate cosine once for an area, and then avoid trigonometric calculations completely, leading to a huge speedup.

For a simple benchmark of a typical zoom 14 tile with OpenStreetMap roads, calculating road lengths with this approximation is 30 times faster than doing the same with Turf line-distance.

Improving approximation precision

Such an approximation is by definition less precise than conventional methods. But how much less precise exactly?

I wrote a small script to measure this and here’s a table showing the margin of error between the Euclidean approximation described above and the precise Vincenty formula for various distances (in miles) and latitudes:

lat 10° 20° 30° 40° 50° 60° 70° 80°
1mi 0.29% 0.27% 0.22% 0.13% 0.02% 0.1% 0.21% 0.3% 0.36%
100mi 0.3% 0.28% 0.22% 0.13% 0.02% 0.09% 0.2% 0.28% 0.27%
500mi 0.31% 0.29% 0.24% 0.17% 0.08% 0.01% 0.01% 0.22% 1.82%
1000mi 0.36% 0.35% 0.32% 0.28% 0.27% 0.35% 0.66% 1.81% 8.75%
2000mi 0.56% 0.57% 0.63% 0.76% 1.06% 1.73% 3.39% 8.6% 81.87%

As you can see, it's not a good idea to approximate distances for thousands of kilometers. But if you measure things within a few hundred, the error is pretty small — under 0.5%.

Now let’s see the errors for the Haversine formula (not dependent on distance):

10° 20° 30° 40° 50° 60° 70° 80°
0.26% 0.24% 0.18% 0.09% 0.02% 0.14% 0.25% 0.34% 0.4%

If you only measure distances up to a few hundred miles, the errors for the flat Earth approximation are only slightly bigger than for the Haversine formula, which is suitable for most applications.

But what’s more, there’s a way to make it much more precise while retaining the same performance by using the formula prescribed by the FCC for ellipsoidal Earth projected to a plane:

\[K_{1} = 111.13209-0.56605\cos \left( 2 lat \right)+0.0012\cos \left( 4 lat \right)\] \[K_{2} = 111.41513\cos \left( lat \right)-0.09455\cos \left( 3 lat \right)+0.00012\cos \left( 5 lat \right)\] \[d = \sqrt{\left( K_{1} \left( lat_{1} - lat_{2}\right)\right)^{2} + \left( K_{2} \left( lng_{1} - lng_{2}\right)\right)^{2}}\]

It’s very similar to previously described approach, except we use coefficients for both latitude and longitude. Moreover, we can use Chebyshev’s method for calculating cosine of angle multiples, reducing the number of cosine calculations from five to one. Let’s look at the errors:

lat 10° 20° 30° 40° 50° 60° 70° 80°
1mi 0% 0% 0% 0% 0% 0% 0% 0% 0%
100mi 0% 0% 0% 0% 0% 0.01% 0.01% 0.02% 0.09%
500mi 0.01% 0.02% 0.02% 0.04% 0.06% 0.11% 0.22% 0.52% 2.17%

For values under a few hundred miles, this method is both much faster and more precise than the Haversine formula.

Meet the Cheap Ruler

I’ve taken the approximation approach above and expanded it to most of the measuring methods available in Turf. The result is a JavaScript module called cheap-ruler.

Here’s a short list of what it can do along with the speedup you get over Turf (running these benchmarks on Node v6):

  • distance: ~31x faster
  • bearing: ~3.6x faster
  • destination: ~7.2x faster
  • lineDistance: ~31x faster
  • area: ~3.4x faster
  • along: ~31x faster
  • pointOnLine: ~78x faster
  • lineSlice: ~60x faster

In addition, I’ve implemented several utility functions that don’t directly mirror Turf modules, but do very fast approximations of common tasks that are usually done with a combination of Turf calls:

  • lineSliceAlong: slices a line between the given distances along the line; ~285x faster than turf.lineSlice(turf.along(...
  • bufferPoint: given a buffer distance, creates a bounding box around a point; ~260x faster than creating a bounding box with two diagonal turf.destination calls
  • bufferBBox: ~260x faster (likewise)
  • insideBBox: ~19x faster than turf.inside(turf.point(p), turf.bboxPolygon(bbox))

The usage is like this — first you create a ruler object with a certain latitude (around the area where you do calculation in) and units (e.g. miles):

varruler=cheapRuler(35.05,'miles');

If you don’t know the latitude before hand, you can create a separate ruler for each feature (e.g. using latitude of a first point of a road).

For convenience, you can also create a ruler from tile coordinates (y and z):

varruler=cheapRuler.fromTile(1567,12,'kilometers');

Then you use the ruler object just like you would use Turf, except you pass coordinates directly instead of wrapping them as GeoJSON features:

vardistance=ruler.distance([30.51,50.32],[30.52,50.312]);

Avoiding feature wrappers and input validation allows us to additionally squeeze some more performance. The library is for advanced uses where performance is critical, and we’re not targeting regular users, so this is fine.

One small additional benefit of cheap-ruler is that it’s under 200 lines of code— great for using on web pages that you want to keep as light as possible, and easy to port to other programming languages.

Enjoy the library, and don’t hesitate to hit me up on Twitter if you have any suggestions or comments. Thanks!

Mapping complex features in JOSM using relations

$
0
0

Relations are one of the more advanced feature types to map in OpenStreetMap. Most geographic features in OpenStreetMap are represented either by points (called nodes in OpenStreetMap terminology – for example, a single tree) or lines & areas (called ways– for example, a road or park). For some more complicated features, a single node or way is not enough, and that’s when we need relations.

This building has two holes for the courtyards. How do we map them?

Imagine a building with courtyards. We can trace the building exterior as a single way, and the courtyards as two additional ways. But all three ways are part of a single building; the courtyards are “holes” within the outer polygon. This is called a multipolygon. Relations are used to model these kinds of logical or geographic relationships between features in OpenStreetMap.

Here’s how you can add a multipolygon relation in the Java OpenStreetMap Editor (JOSM):

  1. Draw the exterior and courtyard shapes. In this example, you would draw three ways, one outer, and two inner polygons.
  2. Click the presets menu, select the relations sub-menu and click multipolygon from the drop down. Click add new relation.
  3. You will see the relation window. Select all three polygons. You can select multiple objects by holding shift and clicking on each of them.
  4. Define the Roles for each way. You must define the exterior polygon as outer and you must define the two courtyard polygons as inner. Add tags building=yesand type=multipolygon in the upper panel.
  5. Click OK the multipolygon relation is complete.

Relations are also used for routes, boundaries, and turn restrictions. You can read more about them on the OpenStreetMap wiki, and reach out if you have any questions or tips on relations.

Introducing data-driven styling in Mapbox GL JS

$
0
0

Today we’re introducing data-driven styling capabilities in Mapbox GL JS with property functions. Property functions allow you to style map features based on their properties. As of Mapbox GL JS v0.17.0, you can use property functions with the circle-radius and circle-color style properties. Over the coming months, we plan to roll out support for property functions across all style properties, Mapbox Mobile, and Mapbox Studio.

The map below uses property functions for circle-style and circle-color to visualize the volume of pedestrian foot traffic at intersections in Toronto:

The variable size and color of the circles add a dimension to the data. You can see how neighborhood centers tend to have higher foot traffic than the surrounding intersections. With maps like this, retailers can better decide where to put their next store and urban planners can assess what areas of their cities draw the most crowds.

Style based on zoom

You may already be familiar with zoom functions which allow the appearance of a map feature to be a function of the map’s zoom. The pedestrian foot traffic map uses zoom functions to create the illusion of depth and control data density. Circles have a radius of 1px at zoom level 8, a radius of 6px at zoom level 11, and a radius of 40px at zoom level 16.

'circle-radius':{stops:[[8,1],[11,6],[16,40]]}

Map with a zoom function

Style based on a property

The pedestrian foot traffic map uses property functions to make the color of each circle a function of its sqrt property. When sqrt is 0 or less, the circle is colored #f1f075. When sqrt is 250 or more, the circle is colored #e55e5e. When sqrt is between 0 and 250, the circle color is proportionally interpolated between those two colors.

'circle-color':{property:'sqrt',stops:[[0,'#f1f075'],[250,'#e55e5e']]}

Map with a property function

Style based on zoom and a property

You can style based on both zoom and data property in the same function.

'circle-radius':{property:'sqrt',stops:[[{zoom:8,value:0},0],[{zoom:8,value:250},1],[{zoom:11,value:0},0],[{zoom:11,value:250},6],[{zoom:16,value:0},0],[{zoom:16,value:250},40]]}

Map with a zoom-and-property function

Make a map!

We would love to see the maps you’re building with data-driven styling! If you have something to share, tweet at @Mapbox.

Mapping highway exit numbers on OpenStreetMap

$
0
0

Exit numbers are an essential part of guidance in navigation systems. To reach your desired destination, your navigation system should be able to guide you to the correct exit when driving on highways.

Image source: crosscountryroads.com

We collaborated with the community to inspect the coverage of exit numbers on OpenStreetMap and add missing ones in 9 states in the US. We chose these states based on the density and availability of Mapillary street photographs. Depending on the data present in the Mapillary images, we added the ref=<exit_number> tag to motorway junctions that have exit numbers and we added the noref=yes tag to junctions that lack an exit number.

After working on this project for two weeks using the checkautopista2 tool and reviewing more than 220 highways, we found that exit numbers are already well-mapped on OpenStreetMap. In total, we added 63 exit numbers (ref tags) and 219 noref tags in California, Florida, New Jersey, Maryland/DC, Pennsylvania, Washington, Colorado, Texas, and Illinois using Mapillary imagery, Wikipedia, and the state DOT documents.

Map showing the exit numbers added by the team. The pink dots represent ref=* tags and the blue dots represent noref=yes tags added by the team.

Join the mapping!

If you are interested in adding exit numbers in your state, read our guide on adding exit numbers and Your first steps with JOSM to get warmed up, then jump into our exit number mapping project.

If you have questions or more ideas for mapping exit numbers, find me on OpenStreetMap or Twitter.

Better OpenStreetMap data with iD's new imagery offset tool

$
0
0

The iD editor makes adding features to OpenStreetMap as easy as tracing on the map. But background imagery doesn’t always match up perfectly with the real world. Camera distortions, atmospheric conditions on the day the picture was taken, or the shape of the ground may cause imagery to appear shifted from where it should be.

How can you trust that the background imagery is accurate? The guidance in this post and the newly improved imagery offset tool, built by Kushan, can help.

Adjust the imagery offset

First, consider existing features on the map, including any available GPS traces. If the area is well mapped, but the background looks shifted, the imagery is probably inaccurate.

Press B to open the “Background pane” and check the list of available imagery for the current location. Try switching sources to see which is the most accurate.

At the bottom of the “Background pane” is a control for fine-tuning the imagery offset. Drag anywhere in the grey target area to align the background imagery perfectly with the map data.

For more tips on editing with iD, find Kushan and me on Twitter.

Our Geocoder 💙 Wikipedia

$
0
0

The Mapbox geocoder has always been able to tell you where a place is. Today we’re adding Wikidata IDs to geocoding responses, unlocking the ability to answer other questions about a location.

The Wikidata project adds structure to data in Wikipedia, providing IDs and connections between them that work across all versions of Wikipedia. This makes it possible to extract information from a Wikipedia article in a reliable way. It also enables connections to other datasets outside of Wikipedia. Just like Wikipedia, anyone can edit Wikidata. You can find the Wikidata item link in any Wikipedia article sidebar. The resulting data is completely open.

You can find Wikidata IDs in the new wikidata entries of a response’s properties and context sections. We’ve added Wikidata IDs for all country and region features, as well as more than 22,000 place features in the U.S. and Canada.

Below is an example showing how our geocoder can be combined with a couple of SPARQL queries to display locations' population, official websites, seals, and even some related movies. You can try these queries and explore building your own at the Wikidata Query Service.

This example is just for fun — the narrative location property isn’t among the most heavily-populated parts of Wikidata. But it forms a link to IMDb’s universe of identifiers, giving a glimpse of what’s possible when datasets are connected together. Integration with Wikidata means that Mapbox geocoding results can now be used to find capital cities, GDP, or even lists of famous people born nearby. The possibilities are endless. And if data is missing, anyone can add it, benefiting everyone. It’s open data at its best.

We’ll be deploying Wikidata identifiers for the rest of the world’s place features in the coming weeks. Check out the documentation and also let us know what you build with them!

Qt Framework officially supported

$
0
0

Mapbox GL Native now officially supports Qt, an open-source cross-platform application framework designed to write once, deploy everywhere. Qt is widely used in many industries, including mobile, automotive, avionics and much more due to its fast development cycle, extensive documentation and big community.

Mapbox Qt QML example

We are committed to Qt and Mapbox GL Native now welcomes it as a first-class platform. Mapbox Qt SDK provides QMapboxGL and QQuickMapboxGL.

QMapboxGL and QQuickMapboxGL solve different problems. The former is a low-level implementation that can be used on previous versions of Qt and is easily integrated into pure C++ environments. The latter takes advantage of Qt Quick’s modern user interface technology, and is the perfect tool for adding navigation maps on embedded platforms.

Grab our open source code on GitHub and join us at QtCon this September in Berlin.


Voice generated directions in Android apps

$
0
0

Add voice generated directions to your Android app using the Mapbox Android SDK, Mapbox Android Services, and the Android Speech To Text API.

To demonstrate how this works, we built an Android app called Go Where I Say that helps users find their way around the city of Seattle. Users generate local directions based on their starting point, Pike Place Market, by saying their destination, for example “Space Needle”.

Assembling the pieces

The app makes use of the Android SpeechRecognizer, which has been supported universally in AOSP since API 8, to turn the user’s voice command into a String. From there, we’re able to use the Mapbox Geocoding API (via Mapbox Android Services) to turn this String into geo coordinates called GeocodingFeature.

    // Use MapboxGeocoding To Get Geo Coordinates For String From SpeechRecognizer
    String speechText = "Space Needle";
    // Starting Place at Pike Place Market to give Geocoder context for producing local results
    LatLng pikePlace = new LatLng(47.60865, -122.34052);

    MapboxGeocoding geocodingClient = new MapboxGeocoding.Builder()
                .setAccessToken(getString(R.string.mapbox_access_token))
                .setLocation(speechText)
                .setProximity(Position.fromCoordinates(pikePlace.getLongitude(), pikePlace.getLatitude()))
                .build();

    geocodingClient.enqueueCall(new Callback<GeocodingResponse>() {
        @Override
        public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
            GeocodingFeature spaceNeedleGeoData = response.body().getFeatures().get(0);
            // Now We Can Generate Directions
        }
    }

Now that we have the GeocodingFeature we can use it to generate directions using the Mapbox Directions API (again via Mapbox Android Services).

    // Use MapboxDirections To Get Directions Using GeocodingFeature
    final ArrayList<Position> points = new ArrayList<>();
    // Starting at Pike Place Market
    points.add(Position.fromCoordinates(pikePlace.getLongitude(), pikePlace.getLatitude()));
    // Ending at Space Needle
    points.add(spaceNeedleGeoData.asPosition());

    MapboxDirections directionsClient = new com.mapbox.services.directions.v5.MapboxDirections.Builder()
        .setAccessToken(getString(R.string.mapbox_access_token))
        .setCoordinates(points)
        .setProfile(DirectionsCriteria.PROFILE_DRIVING)
        .build();

    directionsClient.enqueueCall(new Callback<DirectionsResponse>() {
        @Override
        public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
            DirectionsRoute routeFromPikePlaceMarketToSpaceNeedle = response.body().getRoutes().get(0);
            // Use this data to draw the route!
        }
    }

Drawing the Route

From DirectionsRoute data we can draw the route by creating a LineString and then adding it the map.

    // MapboxMap
    MapboxMap mapboxMap = ...

    // show route
    PolylineOptions polylineOptions = new PolylineOptions();
    polylineOptions.color(ContextCompat.getColor(this, R.color.colorAccent));
    polylineOptions.alpha(0.5f);

    LineString lineString = LineString.fromPolyline(route.getGeometry(), Constants.OSRM_PRECISION_V5);
    List<Position> coordinates = lineString.getCoordinates();
    for (int lc = 0; lc < coordinates.size(); lc++) {
        polylineOptions.add(new LatLng(coordinates.get(lc).getLatitude(), coordinates.get(lc).getLongitude()));
    }

    polylineOptions.width(getResources().getDimension(R.dimen.line_width_route));
    mapboxMap.addPolyline(polylineOptions);

Route From Pike Place Market to the Space Needle

Getting started

The Mapbox Android SDK and Mapbox Android Services library can be combined in many different ways to power your app. Dive into the Go Where I Say source code for a closer look at how we’ve used them here. If you have questions about how to build location based apps or want to share what you’re working on, hit me up on Twitter @bradleege.

Vector maps in Cocoa applications on OS X

$
0
0

The Mapbox OS X SDK is a community-maintained port of Mapbox GL Native. The same library that powers interactive, customizable vector maps on iOS, Android, and the cross-platform Qt framework runs just as fluidly in native Cocoa applications on OS X.

If you’ve developed a Mapbox-powered iOS application using our “First steps” guide, you can create a native companion application for OS X largely by repeating the same process. An MGLMapView control can be embedded in a standard Cocoa window using Objective-C, Swift, or Interface Builder storyboards. Your application will benefit from tight platform integration, from Cocoa’s popovers and visual effect views to its support for multitouch gestures like pinching and rotating. Meanwhile, the striking styles you design in Mapbox Studio will look identical across every platform, from the Web to the Mac.

The Mapbox iOS SDK directly benefits from any contributions to the OS X SDK by Mac developers. Not only do the iOS and OS X SDKs share a cross-platform core written in C++ and OpenGL, but they also share thousands of lines of Objective-C source code and unit tests that form the majority of the OS X SDK.

The Mapbox OS X SDK is open source, powered by open data, so your contributions are always welcome. Find it in the mapbox-gl-native repository on GitHub.

Mapbox Streets and Terrain now follow Vector Tile Specification version 2

$
0
0

We upgraded billions of our tiles in Mapbox Streets and Terrain* to follow the updated Mapbox Vector Tile Specification, which are now 100% compatible with our faster GL triangulation library, earcut. Polygons are guaranteed to be OGC valid and have clearly defined winding-orders for exterior and interior polygons, which means decoders like Mapbox GL Native and Mapbox GL JS have less work to do when rendering these v2 tiles.

Re-encoding the complex geometries of our base layers, like the hillshading multipolygons of Mapbox Terrain, exposed a lot of edge-case bugs in our clipping and encoding algorithms in mapnik-vector-tile and node-mapnik. We’re confident now that our encoder can handle very challenging source data and still produce valid v2 tiles.

Hillshading polygons of mapbox terrain in the British Columbia

We’ve also integrated the new vector tile v2 work into our Uploads API, so all of your tilesets that you create in Mapbox Studio or Mapbox Studio Classic will be earcut-ready too. If you uploaded your data in the last two weeks or you use Mapbox Terrain or Mapbox Streets in your maps, then you are already using v2 tiles.

Stay tuned for announcements on the earcut speed improvements in our client libraries and APIs, and let us know on Twitter how we can help you build faster and cleaner maps with these new v2 tiles.


* The specific source ids are mapbox://mapbox-streets-v5, mapbox://mapbox-streets-v6, mapbox://mapbox-streets-v7 and mapbox://mapbox-terrain-v2. Streets v4 and terrain v1 will be upgraded to the new vector tile specification soon.

See you at the Open Data Camp happy hour!

CityMaps2Go launches offline maps

$
0
0

citymapsorange

CityMaps2Go just launched their new travel and offline map guides on iOS using our mobile SDK and Mapbox Streets.

You can now browse maps or search for a specific country, province or city to download for offline use. While offline, the app still allows you to search for streets or points of interest and bookmark your favorite spots. Which is perfect for off the beaten path adventures or exploring cities with bad broadband connections.

Upgrade your Citymaps2Go app or go download it to get started with offline! Say hello on Twitter or drop me a note at hurlock@mapbox.com if you want to talk offline maps.

See you next week at Google I/O

$
0
0

We’ll be down in Mountain View next week for Google I/O 2016, Google’s annual developer event, learning about what’s new in the next version of Android, attending workshops, and answering any questions you have about our Android SDK, and the recent Mapbox Android Services release.

Find us at Google I/O, we’ll be wearing Mapbox T-shirts, or reach out on Twitter to chat with Antonio (@zugaldia), Brad (@bradleege), Tyler (@twbell), Molly (@mollymerp), Kajari (@kajari_ghosh), and Jesse (@boundsj). If you won’t be in Mountain View, look for Cameron (@cameronmace10) at Google I/O Extended in on May, 18th in Baltimore.

Updated terrain in Mapbox Outdoors

$
0
0

This week we launched our redesigned maps and announced that our streets and terrain data now follow Vector Tile Specification v2. These two releases come together in the new Mapbox Outdoors map, which overlays curated datasets tailored to hiking, biking, and adventuring on top of our lightning fast new terrain layer. Look for a detailed post on Mapbox Outdoors next week, but for now, explore the map and get started building today!

Mid-zoom view of the Christchurch, NZ area.

Area around the ancient waterworks of Dujiangyan, China.

The Colorado River's Hoover Dam, on the border between Arizona and Nevada.

Mapbox Streets redesign

$
0
0

This week we launched a redesign of all our maps across all our Mapbox GL APIs, SDKs, and tools. It’s been just over a year since the last significant redesign of our flagship map, Mapbox Streets, and we’re excited to share some details about its most recent evolution.

Like its predecessor, the new Mapbox Streets is a highly detailed, general use map featuring everything from hillshading to landuse to points of interest to buildings. What’s different in this redesigned map is more emphasis on road and transit networks, to aid in navigation and to give the map a stronger visual hierarchy.

We’ve continued to upgrade our data and styling for complex road systems, including improved visibility of major road networks at low zoom levels:

Major road networks in the Midwestern United States.

We recently added more support for displaying localized highway shields and subway icons. In this redesign, we’ve refined our custom icons to be more prominent, recognizable, and crisp at any resolution:

National and state highways in Kolkata.

National rail, tube, and DLR stations in London.

In addition, we’ve added more relevant high-zoom-level features, to help you get from A to B. For drivers, we’ve added motorway exits and junctions, and turning circles:

Motorway exits in Los Angeles, CA.

Turning circles in Foster City, CA.

For pedestrians, we’ve added pedestrian plazas and squares, as well as distinct styling for stairs – both important links for walking routes in urban areas:

The Spanish Steps, Rome.

In order to focus the visual complexity of the map on key features, we’ve edited out some details from the previous Mapbox Streets, including contour lines. For use cases where these features are important context, we designed an alternative general use map: Mapbox Outdoors.

Explore Mapbox Streets further, and start building with it today!

Whiskey distilleries by state with the Mapbox Studio dataset editor

$
0
0

Recently I’ve been working to understand the number of whiskey distilleries in the United States. Thanks to this handy blog post, I’ve been able to use the Mapbox dataset editor to visualize the number of distilleries by state. Take a look below to see how many distilleries are in your home state.

Using the dataset editor to add the number of distilleries to states

1-5
6-10
11-15
16-25
26-45
46-60
A simple map styled from the dataset

We hope to do a public beta of the dataset editor in July! Stay tuned for more updates, and ask me anything on twitter @mcwhittemore.

The end of CartoCSS

$
0
0

This begins with a short story, you can skip to the demo if you want.

In late 2010, I started on a map rendering language called CartoCSS. We were working on TileMill, our first-generation map editing application, and wanted a fast language hosted in JavaScript that worked with Mapnik, our original map renderer. Following in the tradition of Cascadenik, we made the language similar to CSS. Drawing from the lineage of less, we added constants and other features to the language.

CartoCSS is the language Mapbox created for TileMill and Mapbox Studio Classic - a CSS-like syntax that renders static maps, and did so quite well. We’re incredibly proud that it also became a successful open source project, being used by other applications and companies.

Vector maps have been one of the largest leaps in Mapbox’s history. We built a map renderer from the ground up. We created the industry standard for distributing vector map tiles, the Mapbox Vector Tile spec, which has also been adopted by other companies, including Esri. We keep improving every detail of the system, from size efficiency to text rendering and animations, and building an ecosystem around Mapbox GL JS, the Mapbox iOS SDK, and the Mapbox Android SDK.

As part of this transition, we created a new language: the Mapbox GL Style Specification. It is the realization of the lessons we learned creating CartoCSS, and it is the next step in cartographic styling. Like the Mapbox Vector Tile specification, it’s an open standard and we’re seeing other organizations starting to adopt it.

I’ve had a minor role in the development of the Mapbox GL Style Specification. People like Lucas have worked for months building each part of the specification from the ground up. Last week, he introduced the first bits of data-driven styling in the spec & Mapbox GL JS.

I want to share with you why this is so important, and why I couldn’t be happier to see a successor to CartoCSS that leaps beyond its limitations and is built on powerful simplicity.

The problems with CSS syntax

You can see it in the name: CartoCSS is CSS-like. We wanted to create a language that was friendly to designers, and we thought CSS syntax would help. We built CartoCSS on less.js, a CSS parser with extra, non-standard CSS syntax, and we decided to keep some of it, like constants.

This was a mistake.

First, we invented a new syntax, and one that’s quite difficult to parse. Even worse, once it’s parsed, we never wrote the stringify step: you can process CartoCSS into an abstract representation, but never back into CartoCSS.

Second, the CSS model doesn’t quite work. You can see it in the way that it’s difficult to arrange layers top-to-bottom with CartoCSS: CSS is a language designed to style a document with an existing drawing order - HTML. But instead, CartoCSS is creating Mapnik Symbolizers once it is compiled to Mapnik XML, and those symbolizer can draw in any order - and any number of times. Hence the complexity of attachments, a way to draw the same data multiple times.

The Mapbox GL Style Specification is JSON and JavaScript

We decided to build the Mapbox GL Style Specification on JSON.

Up-front: JSON can be more intimidating to newcomers than CSS-like syntax. There are more quotes, commas instead of semicolons, and the language doesn’t permit comments. But something much, much more important is at stake.

Mapbox GL styles are dynamic styles. Our color switcher example is just a few lines of code because Mapbox GL Styles actually become JavaScript objects that can be manipulated by methods on the Mapbox GL JS style object.

But you don’t even need Mapbox GL JS to manipulate styles: unlike CartoCSS, JSON can be parsed, manipulated, and produced by nearly every programming language in existence. Applications can generate Mapbox GL styles as easily as they generate other API responses: without the complexity of syntax and its sophisticated interpretation, styling maps is accessible to every line of code. Parsing, generating, and validating JSON is a solved problem.

Mapbox GL styles are designed to be created and manipulated by hand, with editors like Mapbox Studio, and by computers themselves.

The visualization problem

The CartoCSS model for visualizations was never quite there. The fundamental thing you use in CartoCSS to style things differently is the filter: to create a choropleth map, you might write:

#volume [number_of_cases <= 434] {
  marker-fill: #BD0026;
}
#volume [number_of_cases <= 183] {
  marker-fill: #F03B20;
}
#volume [number_of_cases <= 130] {
  marker-fill: #FD8D3C;
}
#volume [number_of_cases <= 90] {
  marker-fill: #FECC5C;
}
#volume [number_of_cases <= 50] {
  marker-fill: #FFFFB2;
}

Now, over time we created a shorthand for this case: you could, instead, write:

#volume {
  [number_of_cases <= 434] {
    marker-fill: #BD0026;
  }
  [number_of_cases <= 183] {
    marker-fill: #F03B20;
  }
  [number_of_cases <= 130] {
    marker-fill: #FD8D3C;
  }
  [number_of_cases <= 90] {
    marker-fill: #FECC5C;
  }
  [number_of_cases <= 50] {
    marker-fill: #FFFFB2;
  }
}

The second example is fewer characters, but it creates the same layers to be rendered. You can see the issue for both of these: not only is the syntax verbose, it’s also inefficient, creating as many layers as you have bins in your visualization.

If you dabble with visualization technology, this isn’t the way it’s done: if you were writing this example in d3, for instance, you might write:

var colorScale = d3.scale.linear()
    .domain([434, 183, 130, 90, 50])
    .range(['BD0026', 'F03B20', 'FECC5C', 'FFFFB2']);

d3.selectAll('#volume')
  .attr('marker-fill', colorScale);

Note the lack of if statements, and that I don’t create multiple layers for each different color bin: instead we simply assign colors to the appropriate elements. Not only is this pattern clearer, it’s also much more efficient.

Data-driven styles

Data-driven styles have been one of the biggest tasks in Mapbox GL’s history, but they stand to change everything. Right now we just support data-driven styles for Mapbox GL JS, and only for circle-radius and circle-color.

We chose to do this the hard way. We want the default way people create visualizations to also be the easiest way, and also be the fastest way. We will make it easy to fall into the pit of success.

So what this means is that data-driven styles give you a syntax to define a function, just like in d3, that creates visualizations based on data. It does this by loading just the dependent data - just the variables you’re referring to in your visualization - and loading that data into WebGL, where it can be rendered instantly by shaders.

With data-driven styles, visualizations are fast enough to render in real-time with Mapbox GL JS. And the flexibility of mapping data to representation is just like d3: both simple to understand and powerful enough to represent all kinds of data without putting colors and other styling information in your source data.

The goods

This is a flashy map demo. But it’s also extremely simple: I hope you glance at the code and see what I mean.

Fin

You cannot get a simple system by adding simplicity to a complex system. -Richard O'Keefe

The Mapbox GL Style Specification both simplifies and superpowers styling maps, and lets algorithms join in on the fun. It’s the realization of what we learned about CartoCSS and the future of dynamic vector maps.

See you at the Understanding Risk Forum 2016

$
0
0

Join me along with Heather Leason of the Humanitarian OpenSteetMap Team and Nama Raj Budhathoki of the Kathmandu Living Labs to talk about how OpenStreetMap and digital humanitarians support crisis response at the 2016 Understanding Risk (UR2016) Forum in Venice this week.

UR2016 is a biennial forum organized by the World Bank’s Global Facility for Disaster Reduction (GDFRR) that brings together experts and practitioners from around the globe to discuss the field of disaster risk assessment and communication.

Heather, Nama and I will share the role of the OpenStreetMap community in providing critical information to disaster responders throughcrowdsourcing and community mapping during and after the Gorkha Earthquake that struck Nepal last April 2015.

You can see the full schedule over at the UR2016 site. Can’t wait to see you there!

Members of the Disaster Assistance Response Team (DART) discusses with local officials during a reconnaissance patrol in the framework of assistance to earthquake victims in Nepal by Government of Canada, 2 May 2015 Photo: Sgt Yannick Bédard, Canadian Forces Combat Camera

Angelina Calderon joins Mapbox!

$
0
0

Angelina Calderon has joined the Mapbox team in San Francisco! As a member of our customer success team, Angelina helps Mapbox customers get the most out of the platform.

Prior to joining Mapbox, Angelina helped startups grow through strategic recruiting at The Sourcery. Welcome to the team, Angelina!

Viewing all 2230 articles
Browse latest View live