Skip to content

Commit

Permalink
Merge f53e563 into 76291a0
Browse files Browse the repository at this point in the history
  • Loading branch information
Xintong Xia committed Mar 22, 2019
2 parents 76291a0 + f53e563 commit 86cadc8
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 12 deletions.
20 changes: 19 additions & 1 deletion docs/layers/icon-layer.md
Expand Up @@ -156,6 +156,24 @@ given pre-packed `iconAtlas`.

Icon size multiplier.

##### `sizeUnits` (String, optional)

* Default: `pixels`

The units of the size specified by `getSize`, one of `'meters'`, `'pixels'`. When zooming in and out, meter sizes scale with the base map, and pixel sizes remain the same on screen.

##### `sizeMinPixels` (Number, optional)

* Default: `1`

The minimum size in pixels.

##### `sizeMaxPixels` (Number, optional)

* Default: `Number.MAX_SAFE_INTEGER`

The maximum size in pixels.

##### `fp64` (Boolean, optional)

- Default: `false`
Expand Down Expand Up @@ -195,7 +213,7 @@ Method called to retrieve the position of each object, returns `[lng, lat, z]`.

- Default: `1`

The height of each object, in pixels.
The height of each object, in units specified by `sizeUnits` (default pixels).

- If a number is provided, it is used as the size for all objects.
- If a function is provided, it is called on each object to retrieve its size.
Expand Down
20 changes: 19 additions & 1 deletion docs/layers/text-layer.md
Expand Up @@ -62,6 +62,24 @@ Inherits from all [Base Layer](/docs/api-reference/layer.md) and [CompositeLayer

Text size multiplier.

##### `sizeUnits` (String, optional)

* Default: `pixels`

The units of the size specified by `getSize`, one of `'meters'`, `'pixels'`. When zooming in and out, meter sizes scale with the base map, and pixel sizes remain the same on screen.

##### `sizeMinPixels` (Number, optional)

* Default: `1`

The minimum size in pixels.

##### `sizeMaxPixels` (Number, optional)

* Default: `Number.MAX_SAFE_INTEGER`

The maximum size in pixels.

##### `fp64` (Boolean, optional)

* Default: `false`
Expand Down Expand Up @@ -117,7 +135,7 @@ Method called to retrieve the location of each text label.

* Default: `32`

The font size of each text label, in pixels.
The font size of each text label, in units specifies by `sizeUnits` (default pixels).

* If a number is provided, it is used as the size for all objects.
* If a function is provided, it is called on each object to retrieve its size.
Expand Down
2 changes: 1 addition & 1 deletion examples/experimental/bezier/webpack.config.js
Expand Up @@ -9,7 +9,7 @@ const CONFIG = {
mode: 'development',

entry: {
app: resolve('./app.js')
app: resolve('./src/app.js')
},

module: {
Expand Down
13 changes: 11 additions & 2 deletions modules/layers/src/icon-layer/icon-layer-vertex.glsl.js
Expand Up @@ -35,6 +35,8 @@ attribute vec2 instanceOffsets;
uniform float sizeScale;
uniform vec2 iconsTextureDim;
uniform float sizeMinPixels;
uniform float sizeMaxPixels;
varying float vColorMode;
varying vec4 vColor;
Expand All @@ -50,12 +52,19 @@ vec2 rotate_by_angle(vec2 vertex, float angle) {
void main(void) {
vec2 iconSize = instanceIconFrames.zw;
// convert size in meters to pixels, then scaled and clamp
float sizeScalePixels = clamp(
project_scale(instanceSizes * sizeScale),
sizeMinPixels, sizeMaxPixels
);
// scale icon height to match instanceSize
float instanceScale = iconSize.y == 0.0 ? 0.0 : instanceSizes / iconSize.y;
float instanceScale = iconSize.y == 0.0 ? 0.0 : sizeScalePixels / iconSize.y;
// scale and rotate vertex in "pixel" value and convert back to fraction in clipspace
vec2 pixelOffset = positions / 2.0 * iconSize + instanceOffsets;
pixelOffset = rotate_by_angle(pixelOffset, instanceAngles) * sizeScale * instanceScale;
pixelOffset = rotate_by_angle(pixelOffset, instanceAngles) * instanceScale;
pixelOffset.y *= -1.0;
gl_Position = project_position_to_clipspace(instancePositions, instancePositions64xyLow, vec3(0.0));
Expand Down
11 changes: 9 additions & 2 deletions modules/layers/src/icon-layer/icon-layer.js
Expand Up @@ -56,6 +56,9 @@ const defaultProps = {
iconMapping: {type: 'object', value: {}, async: true},
sizeScale: {type: 'number', value: 1, min: 0},
fp64: false,
sizeUnits: 'pixels',
sizeMinPixels: {type: 'number', min: 0, value: 0}, // min point radius in pixels
sizeMaxPixels: {type: 'number', min: 0, value: Number.MAX_SAFE_INTEGER}, // max point radius in pixels

getPosition: {type: 'accessor', value: x => x.position},
getIcon: {type: 'accessor', value: x => x.icon},
Expand Down Expand Up @@ -171,16 +174,20 @@ export default class IconLayer extends Layer {
/* eslint-enable max-statements, complexity */

draw({uniforms}) {
const {sizeScale} = this.props;
const {sizeScale, sizeMinPixels, sizeMaxPixels, sizeUnits} = this.props;
const {iconManager} = this.state;
const {viewport} = this.context;

const iconsTexture = iconManager.getTexture();
if (iconsTexture) {
this.state.model.render(
Object.assign({}, uniforms, {
iconsTexture,
iconsTextureDim: [iconsTexture.width, iconsTexture.height],
sizeScale
sizeScale:
sizeScale * (sizeUnits === 'pixels' ? viewport.distanceScales.metersPerPixel[2] : 1),
sizeMinPixels,
sizeMaxPixels
})
);
}
Expand Down
Expand Up @@ -37,6 +37,8 @@ attribute vec2 instanceOffsets;
attribute vec2 instancePixelOffset;
uniform float sizeScale;
uniform float sizeMinPixels;
uniform float sizeMaxPixels;
uniform vec2 iconsTextureDim;
uniform float gamma;
uniform float opacity;
Expand All @@ -56,13 +58,20 @@ vec2 rotate_by_angle(vec2 vertex, float angle) {
void main(void) {
vec2 iconSize = instanceIconFrames.zw;
// convert size in meters to pixels, then scaled and clamp
float sizeScalePixels = clamp(
project_scale(instanceSizes * sizeScale),
sizeMinPixels, sizeMaxPixels
);
// scale icon height to match instanceSize
float instanceScale = iconSize.y == 0.0 ? 0.0 : instanceSizes / iconSize.y;
float instanceScale = iconSize.y == 0.0 ? 0.0 : sizeScalePixels / iconSize.y;
// scale and rotate vertex in "pixel" value and convert back to fraction in clipspace
vec2 pixelOffset = positions / 2.0 * iconSize + instanceOffsets;
pixelOffset = rotate_by_angle(pixelOffset, instanceAngles) * sizeScale * instanceScale;
pixelOffset = rotate_by_angle(pixelOffset, instanceAngles) * instanceScale;
pixelOffset += instancePixelOffset;
pixelOffset.y *= -1.0;
Expand Down
9 changes: 9 additions & 0 deletions modules/layers/src/text-layer/text-layer.js
Expand Up @@ -58,6 +58,9 @@ const FONT_SETTINGS_PROPS = ['fontSize', 'buffer', 'sdf', 'radius', 'cutoff'];
const defaultProps = {
fp64: false,
sizeScale: 1,
sizeUnits: 'pixels',
sizeMinPixels: 0,
sizeMaxPixels: Number.MAX_SAFE_INTEGER,

characterSet: DEFAULT_CHAR_SET,
fontFamily: DEFAULT_FONT_FAMILY,
Expand Down Expand Up @@ -246,6 +249,9 @@ export default class TextLayer extends CompositeLayer {
fp64,
sdf,
sizeScale,
sizeUnits,
sizeMinPixels,
sizeMaxPixels,
transitions,
updateTriggers
} = this.props;
Expand All @@ -267,6 +273,9 @@ export default class TextLayer extends CompositeLayer {
getPixelOffset: this._getAccessor(getPixelOffset),
fp64,
sizeScale: sizeScale * scale,
sizeUnits,
sizeMinPixels: sizeMinPixels * scale,
sizeMaxPixels: sizeMaxPixels * scale,

transitions: transitions && {
getPosition: transitions.getPosition,
Expand Down
66 changes: 63 additions & 3 deletions test/render/test-cases.js
Expand Up @@ -551,10 +551,8 @@ export const TEST_CASES = [
renderingTimes: 2,
layers: [
new IconLayer({
id: 'icon-lnglat-64',
id: 'icon-lnglat-auto',
data: dataSamples.points,
iconAtlas: ICON_ATLAS,
iconMapping: dataSamples.iconAtlas,
sizeScale: 12,
coordinateSystem: COORDINATE_SYSTEM.LNGLAT_DEPRECATED,
fp64: true,
Expand All @@ -577,6 +575,40 @@ export const TEST_CASES = [
],
goldenImage: './test/render/golden-images/icon-lnglat.png'
},
{
name: 'icon-meters',
viewState: {
latitude: 37.751537058389985,
longitude: -122.42694203247012,
zoom: 11.5,
pitch: 0,
bearing: 0
},
// rendering times
renderingTimes: 2,
layers: [
new IconLayer({
id: 'icon-meters',
data: dataSamples.points,
iconAtlas: ICON_ATLAS,
iconMapping: dataSamples.iconAtlas,
sizeScale: 256,
sizeUnits: 'meters',
getPosition: d => d.COORDINATES,
getColor: d => [64, 64, 72],
getIcon: d => (d.PLACEMENT === 'SW' ? 'marker' : 'marker-warning'),
getSize: d => (d.RACKS > 2 ? 2 : 1),
opacity: 0.8,
pickable: true
})
],
onAfterRender: ({layers, done}) => {
if (layers[0].state.iconManager.getTexture()) {
done();
}
},
goldenImage: './test/render/golden-images/icon-lnglat.png'
},
{
name: 'geojson-lnglat',
viewState: {
Expand Down Expand Up @@ -1003,6 +1035,34 @@ export const TEST_CASES = [
],
goldenImage: './test/render/golden-images/text-layer.png'
},
{
name: 'text-layer-meters',
viewState: {
latitude: 37.751537058389985,
longitude: -122.42694203247012,
zoom: 11.5,
pitch: 0,
bearing: 0
},
layers: [
new TextLayer({
id: 'text-layer',
data: dataSamples.points.slice(0, 50),
fontFamily: 'Arial',
getText: x => `${x.PLACEMENT}-${x.YR_INSTALLED}`,
getPosition: x => x.COORDINATES,
getColor: x => [153, 0, 0],
getSize: x => 16,
getAngle: x => 0,
sizeScale: 21,
sizeUnits: 'meters',
getTextAnchor: x => 'start',
getAlignmentBaseline: x => 'center',
getPixelOffset: x => [10, 0]
})
],
goldenImage: './test/render/golden-images/text-layer.png'
},
{
name: 'gpu-grid-lnglat',
viewState: {
Expand Down

0 comments on commit 86cadc8

Please sign in to comment.