Text and images on 3D models

A 3D model can carry surfaces: flat areas such as a bus's destination blind, a shelter's name board, an advert panel or an equipment ID plate. Icon Map draws your data onto those surfaces, so each model on the map shows its own values: the bus on route 25 shows "25 Ilford", the shelter shows its stop name, the advert panel shows the poster for that site.

Surfaces work on the 3D models layer and on the Vehicle tracker when its markers are 3D models. A surface can show text, an image, or rotating images, and the content can come from a column of your data.

Where to find it

Open the layer's settings and choose a model. If the model has surfaces, a Text and images on model section appears below the Model picker, with one row per surface.

If the section does not appear, the model has no surfaces. See Adding surfaces to your own model.

When a layer uses a different model per category, each row shows how many of the models have that surface (for example 2 of 3 models). Rows for the other models simply have nothing to draw.

Choosing what a surface shows

Each surface has a content setting:

Setting What it shows Example
Field The value of one column, for each row stop_name
Template Text built from several columns. Put column names in braces. A missing value shows as blank. {route} {destination}
Fixed text The same text on every model Not in service
Image One image: a fixed address, or {column} to take it from your data https://cdn.example.com/poster.png or {advert}
Rotating images A list of images shown in turn, a few seconds each, or one picked at random per model three poster URLs
Off Nothing. The setting is kept, so you can switch it back on.

Rotating images hold still for anyone whose device is set to reduce motion: each model keeps showing one of its images instead of changing every few seconds.

Some models suggest a binding for a surface, for example a destination blind that expects {route} {destination}. When you first choose such a model and your data has those columns, the suggestion is applied for you; otherwise the row offers it as Use suggested. Opening an existing layer never changes your settings.

Surfaces meant for pictures, such as advert panels, offer only Image, Rotating images and Off.

Text, images or SVG from a column

With Field, choose what the column holds under Column holds:

  • Text (the default): the value is drawn as text.
  • An image (URL, OneLake path or SVG): each value is an image.
  • Text or an image, per row: Icon Map decides for each row. A value is treated as an image when it is SVG markup, a data:image/... URI, or an address starting with https://, http:// or onelake://. Anything else is drawn as text. A plain file name such as poster.png stays text, because there is nowhere to load it from.

An image value can be any of:

Value Example Notes
An image URL https://cdn.example.com/ads/gym.png The server must allow cross-origin requests (CORS). Azure Blob storage with CORS enabled, and most CDNs, do. Without it the surface stays blank. Each viewer's browser requests the image from that server directly, including readers of an embedded map, so only use servers you trust. Icon Map does not send which map is being viewed.
A OneLake file onelake://<workspace-id>/<item-id>/Files/ads/coffee.png OneLake https://…onelake.dfs.fabric.microsoft.com/… addresses work too. Read with the viewer's own permissions. Not shown in embedded maps.
A data URI data:image/png;base64,iVBORw0… The image travels inside the row.
SVG markup <svg viewBox="0 0 400 200">…</svg> Starts with <svg. Good for generated signs, badges and simple charts.

SVG notes:

  • Give the SVG a viewBox. Its size is taken from that, so it is drawn sharply at the right shape.
  • Scripts in an SVG never run: it is drawn as a picture.
  • SVGs containing <foreignObject> (embedded HTML) are not drawn. Browsers forbid using them as textures on a 3D model.

Styling

Select Style (the brush button) on a surface's row.

  • Text: text color, a panel behind the text and its color, alignment, and uppercase.
  • Images: Fit (Fill the surface crops to fill, Show all letterboxes, Stretch distorts to fit) and Mirror left to right.
  • Lit display / Backlit: on by default, so the surface glows at night and is not darkened by the sun, like a real LED blind or lightbox. Turn it off for a painted sign.

A column set to Text or an image, per row shows both sets of options.

The default text style is amber on a dark panel, the look of an LED destination display.

When surfaces appear

Text and images are only legible close up, so they are hidden below a zoom level. Set it with Show surfaces from zoom below the surface rows. The default is 16, roughly street level.

Surfaces are drawn at the display's real size, so the model's size must be in meters. A 3D models layer sized in pixels shows no surfaces.

Embedded maps

When you embed a map, surfaces work as they do in Fabric, with one exception: OneLake images taken from your data (a onelake:// path in a column, or {column} in an Image or Rotating images setting) are blank in the embedded map.

This is because an embedded map can only read files that were copied into the publish folder when you published. A fixed OneLake image, typed into the surface's settings, is copied and does show. A path that sits in your data is only known row by row, so it is not copied.

For data-driven images in an embedded map, put an https:// URL, a data:image/... URI or SVG markup in the column instead.

Adding surfaces to your own model

None of the built-in models have surfaces. To add them to your own glTF/GLB model, in Blender or any other 3D tool:

  1. Add a flat rectangle (a plane) where the content should go, lying on the model's face. Icon Map lifts the content very slightly off it, so it never flickers against the model.
  2. Name the object surface:<name>, for example surface:blind or surface:advert. The part after the colon is the name shown in Icon Map. (text:<name> also works.)
  3. Make sure the plane faces outwards. Content is drawn on the side its face normal points to; if a surface stays blank, flip the normal.
  4. Export as GLB without Draco compression. Compressed meshes are skipped when Icon Map looks for surfaces.

Text is drawn upright relative to the model's up direction.

Optional, for model authors: a surface node's glTF extras can carry an iconmap:text object that gives the surface a friendly label, a suggested binding (suggest, for example "{route} {destination}"), and default styling (color, background, align, uppercase, emissive, and for picture surfaces fit and mirror). Setting fit marks the surface as a picture surface.

With Icon Map AI

Coming soon

Icon Map AI is on the Icon Map Platform roadmap. This section describes how it will work; it is not yet generally available in the private preview.

Instead of building a model and binding each surface by hand, you'll be able to describe what you want to your AI assistant through Icon Map AI. For example:

"Make a London bus shelter with a name board above the opening and an advert panel on the end wall. Put one at every stop in my stops table, show the stop name on the board, and rotate our three campaign posters on the panels."

Generating a model with surfaces

Icon Map AI includes model forge, which builds low-poly 3D models from a description. When the real object carries changing text or pictures, model forge adds each display to the model as a surface:

  • At its real size and position, facing the side people read it from, so there is nothing to measure or flip yourself.
  • Named for what it is (blind, route_number, advert). Where there are many, they are numbered in reading order: shelf tickets label_b1_s1_p1, label_b1_s1_p2 and so on, left to right and top to bottom.
  • With a suggested binding and a default style: an amber LED blind, a white-on-blue aisle header, a backlit advert panel.

The assistant shows you a preview image of the model and changes it as you comment ("make the blind wider", "put the advert on the other end").

Setting up the layer

When the model looks right, the assistant:

  1. Saves the model into your workspace's OneLake.
  2. Adds a 3D models or Vehicle tracker layer that uses it, or updates an existing one.
  3. Binds each surface to your data: a column, a template such as {route} {destination}, a fixed image or a rotating set. It also sets the zoom from which surfaces appear.
  4. Renders a preview of the map, so you can check the text reads correctly before the map is saved.

The result is an ordinary Icon Map layer. Open it in the editor and the Text and images on model section shows every binding, ready to change by hand.

Shaping your data

A surface reads from the row of the model it sits on: one row per bus, per shelter, per shelving unit. When one model carries many labels, such as a shelving unit with 40 price tickets, each label needs its own column, named after its surface. If your data has one row per label instead, the assistant can write the query that reshapes it. Because the model's surfaces suggest exactly those column names, every label then binds without further setup.

What the assistant will tell you

  • Size is real. A bus blind reads from street-level zoom; a shelf ticket a few centimeters tall reads only in close, eye-level views. The assistant does not enlarge a display to make it readable from further away.
  • Embedded maps need web or SVG images. For a map you plan to embed, it puts web URLs or SVG in your data rather than OneLake paths (see Embedded maps).

Next steps

  • 3D models: place a model at each point in your data.
  • Vehicle tracker: live fleets, with destination blinds that update as the data does.
  • Embedding maps: put a published map on your own page.