Skip to content

Commit

Permalink
Merge pull request #4006 from plotly/mapbox-raster-layer
Browse files Browse the repository at this point in the history
Add support for raster and image mapbox layers
  • Loading branch information
etpinard authored Jul 2, 2019
2 parents f5bc2e4 + 0b17b62 commit b69cf4b
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 12 deletions.
14 changes: 12 additions & 2 deletions src/plots/mapbox/layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function isVisible(opts) {

return opts.visible && (
Lib.isPlainObject(source) ||
(typeof source === 'string' && source.length > 0)
((typeof source === 'string' || Array.isArray(source)) && source.length > 0)
);
}

Expand Down Expand Up @@ -193,7 +193,10 @@ function convertOpts(opts) {
break;
}

return { layout: layout, paint: paint };
return {
layout: layout,
paint: paint
};
}

function convertSourceOpts(opts) {
Expand All @@ -206,9 +209,16 @@ function convertSourceOpts(opts) {
field = 'data';
} else if(sourceType === 'vector') {
field = typeof source === 'string' ? 'url' : 'tiles';
} else if(sourceType === 'raster') {
field = 'tiles';
sourceOpts.tileSize = 256;
} else if(sourceType === 'image') {
field = 'url';
sourceOpts.coordinates = opts.coordinates;
}

sourceOpts[field] = source;

return sourceOpts;
}

Expand Down
18 changes: 14 additions & 4 deletions src/plots/mapbox/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,11 @@ var attrs = module.exports = overrideAll({
},
sourcetype: {
valType: 'enumerated',
values: ['geojson', 'vector'],
values: ['geojson', 'vector', 'raster', 'image'],
dflt: 'geojson',
role: 'info',
description: [
'Sets the source type for this layer.',
'Support for *raster*, *image* and *video* source types is coming soon.'
'Sets the source type for this layer.'
].join(' ')
},

Expand All @@ -134,7 +133,7 @@ var attrs = module.exports = overrideAll({

type: {
valType: 'enumerated',
values: ['circle', 'line', 'fill', 'symbol'],
values: ['circle', 'line', 'fill', 'symbol', 'raster'],
dflt: 'circle',
role: 'info',
description: [
Expand All @@ -145,6 +144,17 @@ var attrs = module.exports = overrideAll({
].join(' ')
},

coordinates: {
valType: 'any',
role: 'info',
description: [
'Sets the coordinates array contains [longitude, latitude] pairs',
'for the image corners listed in clockwise order:',
'top left, top right, bottom right, bottom left.',
'Only has an effect for *image* `sourcetype`.'
].join(' ')
},

// attributes shared between all types
below: {
valType: 'string',
Expand Down
22 changes: 18 additions & 4 deletions src/plots/mapbox/layout_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var Lib = require('../../lib');
Expand Down Expand Up @@ -52,12 +51,27 @@ function handleLayerDefaults(layerIn, layerOut) {
var visible = coerce('visible');
if(visible) {
var sourceType = coerce('sourcetype');
var mustBeRasterLayer = sourceType === 'raster' || sourceType === 'image';

coerce('source');

if(sourceType === 'vector') coerce('sourcelayer');
if(sourceType === 'vector') {
coerce('sourcelayer');
}

if(sourceType === 'image') {
coerce('coordinates');
}

var typeDflt;
if(mustBeRasterLayer) typeDflt = 'raster';

// maybe add smart default based off GeoJSON geometry?
var type = coerce('type');
var type = coerce('type', typeDflt);

if(mustBeRasterLayer && type !== 'raster') {
type = layerOut.type = 'raster';
Lib.log('Source types *raster* and *image* must drawn *raster* layer type.');
}

coerce('below');
coerce('color');
Expand Down
Binary file modified test/image/baselines/mapbox_layers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 32 additions & 2 deletions test/image/mocks/mapbox_layers.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@
"#7570b3"
]
}
},
{
"type": "scattermapbox",
"subplot": "mapbox2"
}
],
"layout": {
"mapbox": {
"domain": {"x": [0, 0.48], "y": [0, 1]},
"style": "light",
"center": {
"lon": -73.59194521800514,
Expand Down Expand Up @@ -547,8 +552,33 @@
}
]
},

"mapbox2": {
"domain": {"x": [0.52, 1], "y": [0, 1]},
"style": "mapbox://styles/mapbox/light-v10",
"zoom": 4.5,
"center": {"lon": -74.5, "lat": 42},
"layers": [
{
"sourcetype": "raster",
"source": [
"https://img.nj.gov/imagerywms/Natural2015?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=256&height=256&layers=Natural2015"
],
"below": "aeroway-line"
},
{
"sourcetype": "image",
"coordinates": [
[-80.425, 46.437],
[-71.516, 46.437],
[-71.516, 37.936],
[-80.425, 37.936]
],
"source": "https://docs.mapbox.com/mapbox-gl-js/assets/radar.gif"
}
]
},
"height": 450,
"width": 1100,
"autosize": true
"width": 900
}
}
46 changes: 46 additions & 0 deletions test/jasmine/tests/mapbox_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,52 @@ describe('mapbox defaults', function() {
expect(layoutOut.mapbox.layers[3].circle).toBeUndefined();
});

it('should not allow to set layer type other than *raster* for sourcetype value *raster* and *image*', function() {
spyOn(Lib, 'log');

layoutIn = {
mapbox: {
layers: [{
sourcetype: 'raster',
source: 'url',
type: 'circle'
}, {
sourcetype: 'image',
source: 'url',
type: 'fill'
}]
}
};
supplyLayoutDefaults(layoutIn, layoutOut, fullData);

expect(Lib.log).toHaveBeenCalledTimes(2);
expect(Lib.log).toHaveBeenCalledWith('Source types *raster* and *image* must drawn *raster* layer type.');

expect(layoutOut.mapbox.layers[0].type).toBe('raster');
expect(layoutOut.mapbox.layers[1].type).toBe('raster');
});

it('should default layer with sourcetype *raster* and *image* to type *raster', function() {
spyOn(Lib, 'log');

layoutIn = {
mapbox: {
layers: [{
sourcetype: 'raster',
source: 'url'
}, {
sourcetype: 'image',
source: 'url'
}]
}
};
supplyLayoutDefaults(layoutIn, layoutOut, fullData);

expect(Lib.log).toHaveBeenCalledTimes(0);
expect(layoutOut.mapbox.layers[0].type).toBe('raster');
expect(layoutOut.mapbox.layers[1].type).toBe('raster');
});

it('should set *layout.dragmode* to pan while zoom is not available', function() {
var gd = {
data: fullData,
Expand Down

0 comments on commit b69cf4b

Please sign in to comment.