Skip to content

[Feat] IconLayer - Add support for sizing and scaling icons by height or width #9694

Open
@rjwats

Description

@rjwats

Target Use Case

Currently we can configure the size of an icon based on its height. Height is also the basis of the behaviour of the sizeMinPixels, sizeMaxPixels properties which can constrain the minimum and maximum screen height of all icons in the IconLayer where necessary.

We have use cases where we require fixed-width, variable-height icons which this doesn't currently support. We are currently working around with our own copy of IconLayer to which we've added a sizeBasis property to select which dimension to consider as the basis for the size/scaling of the icons.

For more background, here's an example where we display road signs in one layer with optional "supplementary plates" in a second. The signs are offset using anchorY so the plates can be rendered below where applicable:

Image

We use sizeMaxPixels/sizeMinPixels to ensure these signs stay sensible sizes when zoomed in/out, and using a fixed width can ensure both layers scale together proportionally:

Image

Without the capability to set which dimension of is used to set the size/scaling for the icon we end up with the layers scaling at different zoom levels:

Image

We've explored many ways of making this work, a change to IconLayer seems to be the cleanest solution, see proposal.

Does this sound too niche a requirement, or would you be open to a PR?

P.S. Thanks for all of the amazing work which has gone into this project - it is truly remarkable.

Proposal

Adding a "sizeBasis" or "sizeDimension" prop which can be set to "width" but defaults to "height" which is the current behaviour:

const signLayer = new IconLayer<Sign>({
  id: 'sign-layer',
  data: signData,
  sizeUnits: 'meters',
  getSize: 1,
  sizeMinPixels: 20,
  sizeMaxPixels: 100,
  sizeBasis: "width", // new property
  // ... other props
}

A small adjustment to the shader as follows:

// Choose correct constraint based on the 'sizeBasis' value (0.0 = width, 1.0 = height)
float iconConstraint = icon.sizeBasis == 0.0 ? iconSize.x : iconSize.y;
float instanceScale = iconConstraint == 0.0 ? 0.0 : sizePixels / iconConstraint;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions