Skip to content

Commit

Permalink
Merge 2ccc8cb into c482053
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Jan 6, 2020
2 parents c482053 + 2ccc8cb commit 685282f
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 6 deletions.
4 changes: 3 additions & 1 deletion docs/api-reference/map-view.md
Expand Up @@ -11,7 +11,9 @@ import {MapView} from '@deck.gl/core';
const view = new MapView({id, ...});
```

`MapView` takes the same parameters as the [View](/docs/api-reference/view.md) superclass constructor.
`MapView` takes the same parameters as the [View](/docs/api-reference/view.md) superclass constructor, plus the following:

- `repeat` (`Boolean`) - Whether to render multiple copies of the map at low zoom levels. Default `false`.

## View State

Expand Down
12 changes: 9 additions & 3 deletions modules/core/src/passes/layers-pass.js
Expand Up @@ -30,12 +30,16 @@ export default class LayersPass extends Pass {
// Update context to point to this viewport
onViewportActive(viewport);

props.viewport = viewport;
props.view = view;

// render this viewport
const stats = this._drawLayersInViewport(gl, props);
renderStats.push(stats);
const subViewports = viewport.subViewports || [viewport];
for (const subViewport of subViewports) {
props.viewport = subViewport;

const stats = this._drawLayersInViewport(gl, props);
renderStats.push(stats);
}
});
return renderStats;
}
Expand Down Expand Up @@ -92,6 +96,8 @@ export default class LayersPass extends Pass {
const uniforms = Object.assign({}, layer.context.uniforms, {layerIndex});
const layerParameters = this.getLayerParameters(layer, layerIndex);

// overwrite layer.context.viewport with the sub viewport
_moduleParameters.viewport = viewport;
layer.drawLayer({
moduleParameters: _moduleParameters,
uniforms,
Expand Down
42 changes: 40 additions & 2 deletions modules/core/src/viewports/web-mercator-viewport.js
Expand Up @@ -32,6 +32,7 @@ import {

// TODO - import from math.gl
import * as vec2 from 'gl-matrix/vec2';
import {Matrix4} from 'math.gl';

export default class WebMercatorViewport extends Viewport {
/**
Expand All @@ -50,7 +51,10 @@ export default class WebMercatorViewport extends Viewport {
bearing = 0,
nearZMultiplier = 0.1,
farZMultiplier = 1.01,
orthographic = false
orthographic = false,

repeat = false,
worldOffset = 0
} = opts;

let {width, height, altitude = 1.5} = opts;
Expand All @@ -77,14 +81,19 @@ export default class WebMercatorViewport extends Viewport {
// shader (cheap) which gives a coordinate system that has its center in
// the layer's center position. This makes rotations and other modelMatrx
// transforms much more useful.
const viewMatrixUncentered = getViewMatrix({
let viewMatrixUncentered = getViewMatrix({
height,
pitch,
bearing,
scale,
altitude
});

if (worldOffset) {
const viewOffset = new Matrix4().translate([512 * worldOffset, 0, 0]);
viewMatrixUncentered = viewOffset.multiplyLeft(viewMatrixUncentered);
}

const viewportOpts = Object.assign({}, opts, {
// x, y,
width,
Expand Down Expand Up @@ -118,10 +127,39 @@ export default class WebMercatorViewport extends Viewport {

this.orthographic = orthographic;

this._subViewports = repeat ? [] : null;

Object.freeze(this);
}
/* eslint-enable complexity, max-statements */

get subViewports() {
if (this._subViewports && !this._subViewports.length) {
// Cache sub viewports so that we only calculate them once
const topLeft = this.unproject([0, 0]);
const topRight = this.unproject([this.width, 0]);
const bottomLeft = this.unproject([0, this.height]);
const bottomRight = this.unproject([this.width, this.height]);

const minLon = Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]);
const maxLon = Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]);

const minOffset = Math.floor((minLon + 180) / 360);
const maxOffset = Math.ceil((maxLon - 180) / 360);

for (let x = minOffset; x <= maxOffset; x++) {
const offsetViewport = x
? new WebMercatorViewport({
...this,
worldOffset: x
})
: this;
this._subViewports.push(offsetViewport);
}
}
return this._subViewports;
}

/**
* Add a meter delta to a base lnglat coordinate, returning a new lnglat array
*
Expand Down
34 changes: 34 additions & 0 deletions test/modules/core/viewports/web-mercator-viewport.spec.js
Expand Up @@ -242,6 +242,40 @@ test('WebMercatorViewport.getFrustumPlanes', t => {
t.end();
});

test('WebMercatorViewport.subViewports', t => {
let viewport = new WebMercatorViewport(TEST_VIEWPORTS[0]);
t.deepEqual(viewport.subViewports, null, 'gets correct subViewports');

viewport = new WebMercatorViewport({...TEST_VIEWPORTS[0], repeat: true});
t.deepEqual(viewport.subViewports, [viewport], 'gets correct subViewports');

viewport = new WebMercatorViewport({
width: 800,
height: 400,
longitude: 0,
latitude: 0,
zoom: 0,
repeat: true
});
const {subViewports} = viewport;
t.is(subViewports.length, 3, 'gets correct subViewports');
t.deepEqual(
subViewports[0].project([0, 0]),
[400 - 512, 200],
'center offset in subViewports[0]'
);
t.deepEqual(subViewports[1].project([0, 0]), [400, 200], 'center offset in subViewports[1]');
t.deepEqual(
subViewports[2].project([0, 0]),
[400 + 512, 200],
'center offset in subViewports[2]'
);

t.is(viewport.subViewports, subViewports, 'subViewports are cached');

t.end();
});

function getCulling(p, planes) {
let outDir = null;
p = new Vector3(p);
Expand Down
Binary file added test/render/golden-images/map-repeat.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions test/render/test-cases.js
Expand Up @@ -9,6 +9,7 @@ import {
} from '@deck.gl/aggregation-layers';
import {
COORDINATE_SYSTEM,
MapView,
OrbitView,
OrthographicView,
FirstPersonView,
Expand Down Expand Up @@ -1984,5 +1985,25 @@ export const TEST_CASES = [
})
],
goldenImage: './test/render/golden-images/binary.png'
},
{
name: 'map-repeat',
views: new MapView({repeat: true}),
viewState: {
latitude: 0,
longitude: 0,
zoom: 0,
pitch: 0,
bearing: 0
},
layers: [
new ScatterplotLayer({
data: h3.getRes0Indexes(),
getPosition: d => h3.h3ToGeo(d).reverse(),
radiusMinPixels: 4,
getFillColor: [255, 0, 0]
})
],
goldenImage: './test/render/golden-images/map-repeat.png'
}
];

0 comments on commit 685282f

Please sign in to comment.