Skip to content

Commit

Permalink
Add sizeUnits option
Browse files Browse the repository at this point in the history
  • Loading branch information
Xintong Xia committed Mar 20, 2019
1 parent b786bfe commit 41af615
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 47 deletions.
8 changes: 7 additions & 1 deletion docs/layers/icon-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ given pre-packed `iconAtlas`.

Icon size multiplier.

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

* Default: `pixels`

One of `pixels` or `meters`.

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

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

- Default: `1`

The height of each object, in meters.
The height of each object, in 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
8 changes: 7 additions & 1 deletion docs/layers/text-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ Inherits from all [Base Layer](/docs/api-reference/layer.md) and [CompositeLayer

Text size multiplier.

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

* Default: `pixels`

One of `pixels` or `meters`.

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

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

* Default: `32`

The font size of each text label, in meters.
The font size of each text label, in 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
10 changes: 5 additions & 5 deletions examples/layer-browser/src/examples/core-layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ const IconLayerExample = {
getPosition: d => d.COORDINATES,
getColor: d => [64, 64, 72],
getIcon: d => (d.PLACEMENT === 'SW' ? 'marker' : 'marker-warning'),
getSize: d => (d.RACKS > 2 ? 40 : 20),
getSize: d => (d.RACKS > 2 ? 2 : 1),
sizeMinPixels: 1,
sizeMaxPixels: 2048,
sizeScale: 24,
sizeScale: 480,
sizeUnits: 'meters',
opacity: 0.8,
pickable: true
}
Expand Down Expand Up @@ -102,9 +103,7 @@ const IconLayerAutoPackingExample = {
mask: false
};
},
getSize: d => (d.RACKS > 2 ? 40 : 20),
sizeMinPixels: 1,
sizeMaxPixels: 2048,
getSize: d => (d.RACKS > 2 ? 2 : 1),
opacity: 0.8,
pickable: true
}
Expand Down Expand Up @@ -494,6 +493,7 @@ const TextLayerExample = {
autoHighlight: true,
pickable: true,
highlightColor: [0, 0, 128, 128],
sizeUnits: 'meters',
sizeMinPixels: 1,
sizeMaxPixels: 2048,
getText: x => x.LOCATION_NAME,
Expand Down
8 changes: 3 additions & 5 deletions examples/website/icon/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class App extends Component {

const {x, y, object} = info;
const z = info.layer.state.z;
const {showCluster} = this.props;
const {showCluster = true} = this.props;

let hoveredItems = null;

Expand Down Expand Up @@ -124,7 +124,7 @@ export class App extends Component {
data = DATA_URL,
iconMapping = 'data/location-icon-mapping.json',
iconAtlas = 'data/location-icon-atlas.png',
showCluster,
showCluster = true,
viewState
} = this.props;

Expand All @@ -137,9 +137,7 @@ export class App extends Component {
iconMapping,
onHover: this._onHover,
onClick: this._onClick,
sizeMinPixels: 0,
sizeMaxPixels: 2000000,
sizeScale: 1048576
sizeScale: 60
};

const size = viewState ? Math.min(Math.pow(1.5, viewState.zoom - 10), 1) : 0.1;
Expand Down
16 changes: 2 additions & 14 deletions examples/website/icon/icon-cluster-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,7 @@ export default class IconClusterLayer extends CompositeLayer {

renderLayers() {
const {z, version} = this.state;
const {
data,
iconAtlas,
iconMapping,
sizeMinPixels,
sizeMaxPixels,
sizeScale,
getPosition,
onHover,
onClick
} = this.props;
const {data, iconAtlas, iconMapping, sizeScale, getPosition, onHover, onClick} = this.props;

return new IconLayer(
this.getSubLayerProps({
Expand All @@ -74,8 +64,6 @@ export default class IconClusterLayer extends CompositeLayer {
iconAtlas,
iconMapping,
sizeScale,
sizeMinPixels,
sizeMaxPixels,
getPosition,
getIcon: d => d.zoomLevels[z] && d.zoomLevels[z].icon,
getSize: d => d.zoomLevels[z] && d.zoomLevels[z].size,
Expand Down Expand Up @@ -116,7 +104,7 @@ export default class IconClusterLayer extends CompositeLayer {
tree.load(data);

for (let z = 0; z <= 20; z++) {
const radius = sizeScale / Math.pow(2, 15) / Math.pow(2, z);
const radius = sizeScale / Math.sqrt(2) / Math.pow(2, z);

data.forEach(p => {
if (p.zoomLevels[z] === undefined) {
Expand Down
15 changes: 10 additions & 5 deletions modules/layers/src/icon-layer/icon-layer-vertex.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ uniform float sizeScale;
uniform vec2 iconsTextureDim;
uniform float sizeMinPixels;
uniform float sizeMaxPixels;
uniform bool sizeInMeters;
varying float vColorMode;
varying vec4 vColor;
Expand All @@ -53,12 +54,16 @@ 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 instanceScaledSizePixels = clamp(
project_scale(instanceSizes * sizeScale),
sizeMinPixels, sizeMaxPixels
);
float sizeScalePixels = instanceSizes * sizeScale;
if (sizeInMeters) {
sizeScalePixels = project_scale(sizeScalePixels);
}
sizeScalePixels = clamp(sizeScalePixels, sizeMinPixels, sizeMaxPixels);
// scale icon height to match instanceSize
float instanceScale = iconSize.y == 0.0 ? 0.0 : instanceScaledSizePixels / 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;
Expand Down
6 changes: 4 additions & 2 deletions modules/layers/src/icon-layer/icon-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ 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

Expand Down Expand Up @@ -173,7 +174,7 @@ export default class IconLayer extends Layer {
/* eslint-enable max-statements, complexity */

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

const iconsTexture = iconManager.getTexture();
Expand All @@ -184,7 +185,8 @@ export default class IconLayer extends Layer {
iconsTextureDim: [iconsTexture.width, iconsTexture.height],
sizeScale,
sizeMinPixels,
sizeMaxPixels
sizeMaxPixels,
sizeInMeters: sizeUnits === 'meters'
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ attribute vec2 instanceOffsets;
attribute vec2 instancePixelOffset;
uniform float sizeScale;
uniform bool sizeInMeters;
uniform float sizeMinPixels;
uniform float sizeMaxPixels;
uniform vec2 iconsTextureDim;
Expand All @@ -59,12 +60,15 @@ 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 instanceScaledSizePixels = clamp(
project_scale(instanceSizes * sizeScale),
sizeMinPixels, sizeMaxPixels
);
float sizeScalePixels = instanceSizes * sizeScale;
if (sizeInMeters) {
sizeScalePixels = project_scale(sizeScalePixels);
}
sizeScalePixels = clamp(sizeScalePixels, sizeMinPixels, sizeMaxPixels);
// scale icon height to match instanceSize
float instanceScale = iconSize.y == 0.0 ? 0.0 : instanceScaledSizePixels / 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const DEFAULT_GAMMA = 0.2;
const DEFAULT_BUFFER = 192.0 / 256;

const defaultProps = {
sizeUnits: 'pixels',
sizeMinPixels: 0,
sizeMaxPixels: Number.MAX_SAFE_INTEGER,

Expand Down Expand Up @@ -77,14 +78,15 @@ export default class MultiIconLayer extends IconLayer {
}

draw({uniforms}) {
const {sdf, sizeMinPixels, sizeMaxPixels} = this.props;
const {sdf, sizeUnits, sizeMinPixels, sizeMaxPixels} = this.props;
super.draw({
uniforms: Object.assign({}, uniforms, {
// Refer the following doc about gamma and buffer
// https://blog.mapbox.com/drawing-text-with-signed-distance-fields-in-mapbox-gl-b0933af6f817
buffer: DEFAULT_BUFFER,
gamma: DEFAULT_GAMMA,
sdf: Boolean(sdf),
sizeInMeters: sizeUnits === 'meters',
sizeMinPixels,
sizeMaxPixels
})
Expand Down
3 changes: 3 additions & 0 deletions modules/layers/src/text-layer/text-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const FONT_SETTINGS_PROPS = ['fontSize', 'buffer', 'sdf', 'radius', 'cutoff'];
const defaultProps = {
fp64: false,
sizeScale: 1,
sizeUnits: 'pixels',
sizeMinPixels: 0,
sizeMaxPixels: Number.MAX_SAFE_INTEGER,

Expand Down Expand Up @@ -248,6 +249,7 @@ export default class TextLayer extends CompositeLayer {
fp64,
sdf,
sizeScale,
sizeUnits,
sizeMinPixels,
sizeMaxPixels,
transitions,
Expand All @@ -271,6 +273,7 @@ export default class TextLayer extends CompositeLayer {
getPixelOffset: this._getAccessor(getPixelOffset),
fp64,
sizeScale: sizeScale * scale,
sizeUnits,
sizeMinPixels: sizeMinPixels * scale,
sizeMaxPixels: sizeMaxPixels * scale,

Expand Down

0 comments on commit 41af615

Please sign in to comment.