3D models | Urbi Documentation
MapGL JS API

3D models

The map supports rendering of 3D models of the glTF/GLB format. These models allow you to improve the esthetics of the map view, highlight certain objects, and increase the level of details.

3D models

To add models to the map, you need to configure a layer in the Style editor and prepare data. Examples below show styling of city sights, where each sight has a unique model.

For optimal map performance and correct display of 3D models on the map, follow the requirements and recommendations.

Mandatory requirements:

  • Format: glTF/GLB (.gltf, .glb files).

  • Mesh: it is preferred that the model contains one mesh (a geometric object on the scene). Using models with multiple meshes slightly reduces map performance.

  • Texture:

    • A mesh can have a texture or a fill with one color.
    • The texture resolution must be a power of two (2, 4, 8, 16, 32, 64, 128, and 256).
    • The supported image formats for textures are .png, .jpg, and .bmp.
    • Texture compression and the texture properties emissiveTexture and normalTexture are not supported.
  • Instantiation: extensions for instantiation are not supported.


Usage and performance recommendations:

  • Size: the optimal size for unique models is less than 20,000 vertices; for typical models (e.g., trees), it is from 200 to 2000 vertices.
  • Texture: the optimal texture size for unique models is 256×256; for typical models, it is 64×64.
  • Colors: if you do not customize your own map styles and only load models, it is recommended to match the texture colors of the models with the colors of the Urbi map.
  • Matrix animations: supported, but using them slightly reduces map performance.
  • PBR lighting model: supported, but using them slightly reduces map performance.
  • Local transformations: local transformations (translations, rotations, and scaling) are supported but slightly reduce map performance. It is recommended to use them only in rare cases. For optimal performance, models should not contain local transformations.
  1. Open the Style editor.

  2. Add a new layer and select the 3D model layer type.

  3. On the Data tab, scroll down and select JSON - add manually.

  4. Copy and paste the following code snippet:

    [
        "match",
        [
            "get",
            "layerType"
        ],
        [
            "SightModels"
        ],
        true,
        false
    ]
    
  5. Switch to the Style tab and set the following parameters using JSON (click Edit JSON):

    Parameter Value
    Model source ["get", "url"]
    Scale ["get", "scale"]
    Rotation ["get", "rotation"]
    Offset ["get", "translate"]

    Because the URL and exact location of models will be defined in the geodata, you need to link parameters of a model with its attributes using get expressions in the style layer.

  6. Place the resulting style layer after layers with POI and before layers with 3D buildings so that models do not overlay captures and icons:

    Order of style layers

  7. In the editor toolbar, select Share and copy the style ID to be used later:

    Style ID

Set the location of each model and its positioning configuration in a GeoJSON file:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "url": 'https://disk.2gis.com/digital-twin/models_s3/docs/kingdomcentre.glb',
                "layerType": "SightModels",
                "scale": [1, 1, 1],
                "rotation": [0, 0, 0],
                "translate": [0, 0, 0],
            },
            "geometry": {
                "type": "Point",
                "coordinates": [61.284307, 55.177358]
            }
        }
    ]
}

Parameters:

  • "type": "Feature" - common Feature object of GeoJSON.

  • properties:

    • url - URL to load a model.
    • "layerType": "SightModels" - enables the map to match a data object to a created style layer.
    • scale - initial scale setting.
    • rotation - initial rotation setting.
    • translate - initial offset setting.

    You can edit transformation settings later, after checking the model position on the map.

  • geometry:

    • "type": "Point" - point object.
    • coordinates - object center coordinates. In the given example, the object will be displayed in the 61.284307, 55.177358 point.

Note

Instead of manually selecting the model positioning settings (coordinates, rotation, and scale), use the tool for positioning models on the map. You can position the model and copy settings values: see the instruction on placing models on the map.

When the model data and the style layer are ready, you can evaluate an intermediate result:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Quickstart with 2GIS Map API" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [46.674137, 24.711404],
                zoom: 17,
                rotation: 174,
                pitch: 45,
                key: 'Your API access key',
                style: '18d586c4-4c36-4455-a60f-a4366f1fb17f'
            });

            map.on('click', function (ev) {
                console.log(ev);
            });

            const modelSource = new mapgl.GeoJsonSource(map, {
                data: {
                    "type": "FeatureCollection",
                    "features": [
                        {
                            "type": "Feature",
                            "properties": {
                                "scale": [1, 1, 1],
                                "rotation": [0, 0, 0],
                                "translate": [0, 0, 0],
                                "layerType": "SightModels",
                                "url": "https://disk.2gis.com/digital-twin/models_s3/docs/kingdomcentre.glb",
                                "idsToHide": []
                            },
                            "geometry": {
                                "type": "Point",
                                "coordinates": [46.674137, 24.711404]
                            }
                        }
                    ]
                }    
            })
            </script>
    </body>
</html>

You can see that the model is displayed on the map but is shown incorrectly. You need to configure its rotation and offset and hide a 3D building currently located in the model place.

To correctly position the model, open the example with the intermediate result and edit values of the scale, rotation, and translate object parameters. To correctly display the model above, specify the following values:

"scale": [0.98, 0.98, 0.98],
"rotation": [0, 0, 23],
"translate": [22, -6, 0],

Details about 3D model positioning

3D models support transformations in three-dimensional space defined by x-, y-, and z-axes.

Coordinate system

Scale transformation is done in the local coordinate system (Local in the picture above). Other transformations are performed in the World Coordinate System (World), where the x-axis faces east, the y-axis faces north, and the z-axis points upwards.

The scale is set in relative units based on the initial model size.

In most cases, you should change the model scale in all three axes at once. Otherwise, a model will look stretched and distorted.

The rotation is set in degrees.

The most common case is rotating a model around the z-axis. Rotation around other axes may lead to model distortion.

The offset is set in meters relatively to the initial model location.

You should define the offset in x- and y-axes only to prevent a model from "hanging in the air".

To hide an object on the map that overlays the model:

  1. Get the object identifier:

    1. To subscribe to the click event on the map and make it return to the console, add the following snippet to your application source code:

      map.on('click', function (ev) {
          console.log(ev);
      });
      
    2. Open the browser Developer Tools (press F12) and click the object to be hidden. Copy the identifier from the target.id field of the event, for example:

      Click event in the console

  2. Specify the received object identifier to the idsToHide field of the GeoJSON data:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "idsToHide": ["2111697998173735"],
                ...
            },
            ...
        }
    ]
}
  1. Specify this filed in the Linked ids parameter of the style layer:
Parameter Value
Linked ids ["get", "idsToHide"]

You can also check style layer settings in a prepared style. To access the settings, log into the Style editor and select Create a copy.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>2GIS Map API</title>
        <meta name="description" content="Quickstart with 2GIS Map API" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [46.674137, 24.711404],
                zoom: 16.5,
                rotation: 174,
                pitch: 45,
                key: 'Your API access key',
                style: '18d586c4-4c36-4455-a60f-a4366f1fb17f',
                enableTrackResize: true
            });

            map.on('click', function (ev) {
                console.log(ev);
            });

            const modelSource = new mapgl.GeoJsonSource(map, {
                data: {
                    "type": "FeatureCollection",
                    "features": [
                        {
                            "type": "Feature",
                            "properties": {
                                "scale": [0.98, 0.98, 0.98],
                                "rotation": [0, 0, 23],
                                "translate": [22, -6, 0],
                                "layerType": "SightModels",
                                "url": "https://disk.2gis.com/digital-twin/models_s3/docs/kingdomcentre.glb",
                                "idsToHide": ["70030076256609771"]
                            },
                            "geometry": {
                                "type": "Point",
                                "coordinates": [46.674137, 24.711404]
                            }
                        }
                    ]
                }    
            })
            </script>
    </body>
</html>