Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

update default tile/style endpoints for mapbox styles #1317

Merged
merged 16 commits into from
Mar 10, 2020
16 changes: 13 additions & 3 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
'use strict';

module.exports = {
HTTP_URL: 'http://a.tiles.mapbox.com/v4',
HTTPS_URL: 'https://a.tiles.mapbox.com/v4',
HTTP_URL: 'http://api.mapbox.com',
HTTPS_URL: 'https://api.mapbox.com',
FORCE_HTTPS: true,
REQUIRE_ACCESS_TOKEN: true
REQUIRE_ACCESS_TOKEN: true,
TEMPLATE_STYLES: {
'mapbox.dark': 'mapbox/dark-v10',
'mapbox.light': 'mapbox/light-v10',
'mapbox.osm-bright': 'mapbox/bright-v9',
'mapbox.outdoors': 'mapbox/outdoors-v11',
'mapbox.satellite': 'mapbox/satellite-v9',
'mapbox.streets': 'mapbox/streets-v11',
'mapbox.streets-basic': 'mapbox/basic-v9',
'mapbox.streets-satellite': 'mapbox/satellite-streets-v11'
}
};
10 changes: 9 additions & 1 deletion src/format_url.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var config = require('./config'),
warn = require('./util').warn,
version = require('../package.json').version;

module.exports = function(path, accessToken) {
Expand Down Expand Up @@ -38,7 +39,14 @@ module.exports.tileJSON = function(urlOrMapID, accessToken) {
if (urlOrMapID.indexOf('/') !== -1)
return urlOrMapID;

var url = module.exports('/v4/' + urlOrMapID + '.json', accessToken);
var url;
if (urlOrMapID in config.TEMPLATE_STYLES) {
url = module.exports('/styles/v1/' + config.TEMPLATE_STYLES[urlOrMapID], accessToken);
} else {
warn('Warning: this implementation is loading a Mapbox Studio Classic style (' + urlOrMapID + '). ' +
'Studio Classic styles are scheduled for deprecation: https://blog.mapbox.com/deprecating-studio-classic-styles-c65a744140a6');
url = module.exports('/v4/' + urlOrMapID + '.json', accessToken);
}

// TileJSON requests need a secure flag appended to their URLs so
// that the server knows to send SSL-ified resource references.
Expand Down
8 changes: 8 additions & 0 deletions src/load_tilejson.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ module.exports = {
_loadTileJSON: function(_) {
if (typeof _ === 'string') {
_ = format_url.tileJSON(_, this.options && this.options.accessToken);
var isGLStyle = _.indexOf('/styles/v1/') !== -1;

request(_, L.bind(function(err, json) {
if (err) {
util.log('could not load TileJSON at ' + _);
this.fire('error', {error: err});
} else if (json && isGLStyle) {
// In order to preserve compatibility, 256x256 tiles are requested by default
// If you would like better resolution & fewer network requests, use a styleLayer instead
json.tiles = [ format_url('/styles/v1/' + json.owner + '/' + json.id + '/tiles/256/{z}/{x}/{y}', this.options.accessToken) ];
this._setTileJSON(json);
this.fire('ready');
} else if (json) {
this._setTileJSON(json);
this.fire('ready');
Expand Down
3 changes: 2 additions & 1 deletion src/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ var LMap = L.Map.extend({
this._mapboxLogoControl._setTileJSON(json);

if (!this._loaded && json.center) {
var zoom = this.getZoom() !== undefined ? this.getZoom() : json.center[2],
var defaultZoom = (json.zoom) ? json.zoom : json.center[2];
var zoom = this.getZoom() !== undefined ? this.getZoom() : defaultZoom,
center = L.latLng(json.center[1], json.center[0]);

this.setView(center, zoom);
Expand Down
9 changes: 8 additions & 1 deletion src/tile_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ var TileLayer = L.TileLayer.extend({

var templated = L.Util.template(url, tilePoint);
if (!templated || !this.options.format) {
return templated;
var tileURL;
if (L.Browser.retina && url.indexOf('/styles/v1') !== -1) {
tileURL = templated.replace('?', '@2x?');
} else {
tileURL = templated;
}

return tileURL
} else {
return templated.replace(formatPattern,
(L.Browser.retina ? this.scalePrefix : '.') + this.options.format);
Expand Down
11 changes: 11 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ function contains(item, list) {
return false;
}

var warnOnceHistory = {};

module.exports = {
idUrl: function(_, t) {
if (_.indexOf('/') === -1) t.loadID(_);
Expand All @@ -19,6 +21,15 @@ module.exports = {
typeof console.error === 'function') {
console.error(_);
}
},
warn: function(_) {
// avoid cluttering the console with duplicative warnings
if (warnOnceHistory[_]) return;
if (typeof console === 'object' &&
typeof console.warn === 'function') {
warnOnceHistory[_] = true;
console.warn(_);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context this is being used may cause hundreds of duplicate warnings to be printed — maybe worth adopting something like warnOnce from GL JS?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point, implemented in 5a25f62

/* eslint-enable no-console */
},
strict: function(_, type) {
Expand Down
25 changes: 25 additions & 0 deletions test/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,31 @@ helpers.tileJSON_noformat = {
"tiles":["http://domain.example/path/{z}/{x}/{y}"]
};

helpers.styleJSON = {
"version": 8,
"name": "Bright",
"tiles": ['https://api.mapbox.com/styles/v1/mapbox/bright-v9/tiles/256/{z}/{x}/{y}?access_token=key'],
"sources": {
"mapbox": {
"url": "mapbox://mapbox.mapbox-streets-v7",
"type": "vector"
}
},
"center": [
-118.2518,
34.0442
],
"zoom": 15,
"sprite": "mapbox://sprites/mapbox/bright-v9",
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
"created": "1970-01-01T00:00:00.000Z",
"modified": "1970-01-01T00:00:00.000Z",
"owner": "mapbox",
"id": "bright-v9",
"draft": false,
"visibility": "public"
};

helpers.geoJson = {
type: 'FeatureCollection',
features: [{
Expand Down
19 changes: 19 additions & 0 deletions test/manual/default-style-retina.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'/>
<link rel="stylesheet" href="../../dist/mapbox.css"/>
<meta name='viewport' content='initial-scale=1.0 maximum-scale=1.0'>
<link rel="stylesheet" href="embed.css"/>
<script src="../../dist/mapbox.js"></script>
<script src="access_token.js"></script>
</head>
<body>
<div id='map'></div>
<script type='text/javascript'>
L.Browser.retina = true;
L.mapbox.map('map', 'mapbox.outdoors')
.setView([36.1257, -112.0586], 12);
</script>
</body>
</html>
18 changes: 11 additions & 7 deletions test/spec/format_url.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ describe("format_url", function() {
});

it('returns a v4 URL with access_token parameter', function() {
expect(internals.url('/v4/user.map.json')).to.equal('https://a.tiles.mapbox.com/v4/user.map.json?access_token=key')
expect(internals.url('/v4/user.map.json')).to.equal('https://api.mapbox.com/v4/user.map.json?access_token=key')
});

it('uses provided access token', function() {
expect(internals.url('/v4/user.map.json', 'token')).to.equal('https://a.tiles.mapbox.com/v4/user.map.json?access_token=token')
expect(internals.url('/v4/user.map.json', 'token')).to.equal('https://api.mapbox.com/v4/user.map.json?access_token=token')
});

it('throws an error if no access token is provided', function() {
Expand All @@ -39,27 +39,31 @@ describe("format_url", function() {
internals.config.FORCE_HTTPS = true;
internals.config.HTTPS_URL = 'https://api-maps-staging.tilestream.net/v4';
expect(internals.url('/v4/ludacris.map.json')).to.equal('https://api-maps-staging.tilestream.net/v4/ludacris.map.json?access_token=key');
internals.config.HTTPS_URL = 'https://a.tiles.mapbox.com';
internals.config.HTTPS_URL = 'https://api.mapbox.com';
});

describe('.tileJSON', function() {
it('returns the input when passed a URL', function() {
expect(internals.url.tileJSON('http://a.tiles.mapbox.com/v3/user.map.json')).to.equal('http://a.tiles.mapbox.com/v3/user.map.json')
expect(internals.url.tileJSON('http://api.mapbox.com/v3/user.map.json')).to.equal('http://api.mapbox.com/v3/user.map.json')
});

it('returns a v4 URL with access_token parameter, uses https and appends &secure', function() {
expect(internals.url.tileJSON('user.map')).to.equal('https://a.tiles.mapbox.com/v4/user.map.json?access_token=key&secure');
expect(internals.url.tileJSON('user.map')).to.equal('https://api.mapbox.com/v4/user.map.json?access_token=key&secure');
});

it('returns a styles/v1 URL for default mapbox style ids', function() {
expect(internals.url.tileJSON('mapbox.streets')).to.equal('https://api.mapbox.com/styles/v1/mapbox/streets-v11?access_token=key&secure')
});

it('does not append &secure and uses http when FORCE_HTTPS is set to false', function() {
internals.config.FORCE_HTTPS = false;
expect(internals.url.tileJSON('user.map')).to.equal('http://a.tiles.mapbox.com/v4/user.map.json?access_token=key');
expect(internals.url.tileJSON('user.map')).to.equal('http://api.mapbox.com/v4/user.map.json?access_token=key');
});
});

describe('.style', function() {
it('returns a style url with access_token parameter', function() {
expect(internals.url.style('mapbox://styles/bobbysud/cifr15emd00007zlzxjew2rar')).to.equal('https://a.tiles.mapbox.com/styles/v1/bobbysud/cifr15emd00007zlzxjew2rar?access_token=key')
expect(internals.url.style('mapbox://styles/bobbysud/cifr15emd00007zlzxjew2rar')).to.equal('https://api.mapbox.com/styles/v1/bobbysud/cifr15emd00007zlzxjew2rar?access_token=key')
});
});
});
26 changes: 13 additions & 13 deletions test/spec/geocoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,47 +13,47 @@ describe('L.mapbox.geocoder', function() {
it('supports multiple arguments', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL(['austin', 'houston']))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key');
});

it('supports proximity', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL({query: ['austin', 'houston'], proximity: [10, 15]}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&proximity=15,10');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&proximity=15,10');
});

it('supports country option', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL({query: ['austin', 'houston'], country: 'us'}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&country=us');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&country=us');
});

it('supports bbox option', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL({query: ['austin', 'houston'], bbox: [ -104.0458814, 26.0696823, -93.7347459, 36.4813628 ]}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&bbox=-104.0458814,26.0696823,-93.7347459,36.4813628');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&bbox=-104.0458814,26.0696823,-93.7347459,36.4813628');
});

it('supports autocomplete option', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL({query: ['austin', 'houston'], country: 'us', autocomplete: false}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&country=us&autocomplete=false');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&country=us&autocomplete=false');
});

it('rounds proximity params correctly', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL({query: ['austin', 'houston'], proximity: L.latLng(-10.12345, 15.67890)}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&proximity=15.679,-10.123');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&proximity=15.679,-10.123');
});

it('rounds reverse ')

it('supports types', function() {
var g = L.mapbox.geocoder('mapbox.places');
expect(g.queryURL({query: ['austin', 'houston'], types: 'place'}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&types=place');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&types=place');
expect(g.queryURL({query: ['austin', 'houston'], types: ['place', 'address']}))
.to.eql('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&types=place,address');
.to.eql('https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key&types=place,address');
});
});

Expand All @@ -62,7 +62,7 @@ describe('L.mapbox.geocoder', function() {
var g = L.mapbox.geocoder('mapbox.places');

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/austin;houston.json?access_token=key',
[200, { 'Content-Type': 'application/json' }, JSON.stringify(helpers.geocoderBulk)]);

g.query(['austin', 'houston'], function(err, res) {
Expand All @@ -77,7 +77,7 @@ describe('L.mapbox.geocoder', function() {
var g = L.mapbox.geocoder('mapbox.places');

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/austin.json?access_token=key',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderAustin)]);

g.query('austin', function(err, res) {
Expand All @@ -93,7 +93,7 @@ describe('L.mapbox.geocoder', function() {
var g = L.mapbox.geocoder('mapbox.places');

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/nonesuch.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/nonesuch.json?access_token=key',
[200, { 'Content-Type': 'application/json' }, JSON.stringify({"type":"FeatureCollection","query":["nonesuch"],"features":[]})]);

g.query('nonesuch', function(err, res) {
Expand All @@ -110,7 +110,7 @@ describe('L.mapbox.geocoder', function() {
var g = L.mapbox.geocoder('mapbox.places');

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/-97.7%2C30.3.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/-97.7%2C30.3.json?access_token=key',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderReverse)]);

g.reverseQuery({ lat: 30.3, lng: -97.7 }, function(err, res) {
Expand All @@ -125,7 +125,7 @@ describe('L.mapbox.geocoder', function() {
var g = L.mapbox.geocoder('mapbox.places');

server.respondWith('GET',
/https:\/\/a\.tiles\.mapbox\.com\/geocoding\/v5\/mapbox.places\/[\-\d\.]+(%2C|,)[\-\d\.]+\.json\?access_token=key/,
/https:\/\/api\.mapbox\.com\/geocoding\/v5\/mapbox.places\/[\-\d\.]+(%2C|,)[\-\d\.]+\.json\?access_token=key/,
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderReverseRounded)]);

g.reverseQuery({ lat: 30.1234567890, lng: -97.0987654321 }, function(err, res) {
Expand Down
16 changes: 8 additions & 8 deletions test/spec/geocoder_control.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('L.mapbox.geocoderControl', function() {
expect(control instanceof L.mapbox.GeocoderControl).to.eql(true);

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/austin.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/austin.json?access_token=key',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderAustin)]);

control._input.value = 'austin';
Expand All @@ -32,7 +32,7 @@ describe('L.mapbox.geocoderControl', function() {
control = L.mapbox.geocoderControl('mapbox.places', { proximity: false }).addTo(map);

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderWhiteHouse)]);

control._input.value = 'white house';
Expand All @@ -51,7 +51,7 @@ describe('L.mapbox.geocoderControl', function() {
}).addTo(map);

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderWhiteHouse)]);

control._input.value = 'white house';
Expand All @@ -74,7 +74,7 @@ describe('L.mapbox.geocoderControl', function() {
}).addTo(map);

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key&country=us&autocomplete=false',
'https://api.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key&country=us&autocomplete=false',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderWhiteHouse)]);

control._input.value = 'white house';
Expand All @@ -95,7 +95,7 @@ describe('L.mapbox.geocoderControl', function() {
map.setView([0, 0], 14);

server.respondWith('GET',
'https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key',
'https://api.mapbox.com/geocoding/v5/mapbox.places/white%20house.json?access_token=key',
[200, { "Content-Type": "application/json" }, JSON.stringify(helpers.geocoderWhiteHouse)]);

control._input.value = 'white house';
Expand All @@ -108,12 +108,12 @@ describe('L.mapbox.geocoderControl', function() {

it('sets url based on an id', function() {
var control = L.mapbox.geocoderControl('mapbox.places');
expect(control.getURL()).to.equal('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/{query}.json?access_token=key');
expect(control.getURL()).to.equal('https://api.mapbox.com/geocoding/v5/mapbox.places/{query}.json?access_token=key');
});

it('supports custom access token', function() {
var control = L.mapbox.geocoderControl('mapbox.places', {accessToken: 'custom'});
expect(control.getURL()).to.equal('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/{query}.json?access_token=custom');
expect(control.getURL()).to.equal('https://api.mapbox.com/geocoding/v5/mapbox.places/{query}.json?access_token=custom');
});

it('#setURL', function() {
Expand All @@ -125,7 +125,7 @@ describe('L.mapbox.geocoderControl', function() {
it('#setID', function() {
var control = L.mapbox.geocoderControl('mapbox.places');
expect(control.setID('mapbox.places')).to.eql(control);
expect(control.getURL()).to.equal('https://a.tiles.mapbox.com/geocoding/v5/mapbox.places/{query}.json?access_token=key');
expect(control.getURL()).to.equal('https://api.mapbox.com/geocoding/v5/mapbox.places/{query}.json?access_token=key');
});

it('is by default in the top left', function() {
Expand Down
Loading