09 – Improving map quality with Raster Tiles

Tiles are just a way of dividing & displaying high-resolution images very efficiently. At each zoom level, the image is divided on a set of squared areas or tiles. The key idea is that all tiles have the same resolution (independently of the zoom level), which guarantees a constant real-size / image-resolution ratio on each tile.

Take for example the following image: for that zoom level, the floorplan is divided in 6 x 5 tiles of constant size (e.g., 512×512 pixels).

Indoor mapping
This image represents what the tiles would be for zoom 2

As we zoom in, we focus on a particular area, which is itself divided into squared tiled as well. Since these smaller areas also have the same resolution, we can in fact represent greater levels of detail. And since the mobile or web viewer downloads and displays only the required tiles for each particular area/zoom level, the whole process is really efficient & fast! We have an entry on Tiles in our blog, in which we go into more detail on the benefits of using tiles to represent floorplans.

Tip! If you want to enable Tiles in your buildings, please contact our support team

Displaying tiles on typical map providers #

Map providers such as Google Maps or Mapbox are able to retrieve & display (automatically) the tiles that correspond to the current camera view. To do so, you just need to pass them an URL in an standard format. Typically, this URL will be something like:

//Typical URL pattern to fetch tiles from a server
https://tiles.server.com/{z}/{x}/{y}.png

//Typical URI pattern to fetch tiles from a device's local folder
/path/to/my/folder/{z}/{x}/{y}.png

The templated parameters will be modified at runtime by your map provider to retrieve the tiles needed:

  • {z} – The tile’s zoom level, ranging from 0 to 23 (not all the venues will need to have generated all the zoom levels in the range). At zoom level 0, each tile covers the entire world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, 116 of the world, and so on.
  • {x} – The index of the tile along the map’s X axis according to Spherical Mercator projection. If the value is 0, the tile’s left edge corresponds to the 180th meridian west. If the value is 2z−1, the tile’s right edge corresponds to the 180th meridian east.
  • {y} – The index of the tile along the map’s y axis according to Spherical Mercator projection. If the value is 0, the tile’s tile edge corresponds to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value is 2z−1, the tile’s bottom edge corresponds to −arctan(sinh(π)), or approximately 85.0511 degrees south.

You will also need to know the resolution of each tile (typically, 512×512 pixels in our case).

Some useful links to know more about tiles in general and how to integrate them (the specifics will change depending on the provider you choose):

Getting tiles from Situm APIs #

Situm provides a standard URL so you can plug-it in your map implementation with your favourite map provider. For each floor, Situm provides an URL like:

https://dashboard.situm.com/uploads/tiles/{floorId}/{z}/{x}/{y}.png 

For example, if you want to display tiles from floor 1234, you should build an URL like this one:

https://dashboard.situm.com/uploads/tiles/1234/{z}/{x}/{y}.png 

Whenever the floor changes (e.g. your user selects a different floor to display), you will need to pass a new URL to your map provider. Please refer to our docs to know the floor_id to display.

Getting tiles from a local source #

Using the previous approach, the map provider downloads the tiles as the user visualizes different areas of the map. But… what if the smartphone does not have connectivity?

In this case, you can pre-download all the tiles using Situm SDK (Android, iOS and ReactNative). Tiles will be stored in a local storage folder with an URI such as:

/path/to/my/local/folder/{building_id}/{floor_id}/{z}/{x}/{y}.png 

Therefore, if you want to render tiles from building 9876 and floor 1234, you will need to pass this URI to your map provider:

/path/to/my/local/folder/9876/1234/{z}/{x}/{y}.png 

Please refer to our docs to know the building_id and the floor_id to display.

Code examples #

In this section, we provide some code examples that will help to clarify the concepts explained. We will start with a (mostly) complete React Native example using React Native Maps. Of course, you can use other languages/platforms/libraries but we found this one to be very educational:

import {MapLocalTile, URLTile ...} from "react-native-maps" 

//Sample component
export const TiledBuilding = () => {

//State variable to store the local folder's URI
const [offlineTilePath, setOfflineTilePath] = useState<String>("");
//In this example, floor id is fixed. However, if you have several floors you will need 
//to change this number accordingly (e.g. every time the user selects a new floor to display)
const SITUM_FLOOR_ID = 1234; 
...

// First download tiles (e.g. call this from an useEffect)
const getOfflineTiles = (building: any) => {
    SitumPlugin.fetchTilesFromBuilding(building,
      (result: any) => {

        //result.results contains the URI string with the local folder 
        //where tiles are stored for this building
        setOfflineTilePath(result.results);

      },
      (error: any) => {
        console.log("Fetch tiles from building error" + error);
      }
    );
  }

//The render method displays a map and the tiles over it
return (
    <View>
      <MapView
        style={{ width: "100%", height: "100%" }}
        initialRegion={mapRegion}
        maxZoomLevel={MAX_ZOOM_LEVEL}     
      >
         ...
   
      <MapLocalTile
         
         //We pass the local URI to our map provider, which will fetch & render the appropriate
         //tiles as the user moves the view
         pathTemplate={offlineTilePath + '/' + SITUM_FLOOR_ID + '/{z}/{x}/{y}.png'}
         tileSize={512}>
      </MapLocalTile>
           
        ...

      </MapView>

   // Do additional stuff
   ...

   </View>
)
};

The same approach can also be used in Android and iOS. You may download the tiles as shown in the following code snippets and then pass that URI to your favourite map provider:

SitumSdk.communicationManager().fetchTilesFromBuilding("BUILDING_IDENTIFIER", new HandlerImpl<String>() {
    @Override
    public void onSuccess(String result) {
       
      //result is an URI string with the local directory 
      //where tiles are stored for this building   
      ... 

    }

    @Override
    public void onFailure(Error error) {
       // Some error happened
       ...
    }
});
SITCommunicationManager.shared().fetchTiles(forBuilding: "BUILDING_IDENTIFIER",
            success: { (mapping: [AnyHashable: Any]?) in
            if let res = mapping {
                // Process results
                print(res["results"])
            }
        }, failure: { (error: Error?) in
            // ... process error
       })

Suscríbete a nuestro boletín

INFORMACIÓN BÁSICA SOBRE PROTECCIÓN DE DATOS

Responsable del tratamiento: SITUM TECHNOLOGIES, S.L.
Contacto: Responsable del tratamiento: situm@situm.es
Responsable de protección: dpo@situm.es
Finalidad y base legal: Gestionar el envío de newsletter de SITUM sólo con consentimiento.
Legitimación: Consentimiento expreso del interesado.
Destinatarios: Los datos no serán cedidos a terceros salvo obligación legal.
Plazo de conservación: Mientras la parte interesada permanezca suscrita al newsletter (en cada newsletter enviado por Situm estará disponible un link para darse de baja).
Derechos: El interesado podrá revocar en cualquier momento su consentimiento, así como ejercitar los derechos de oposición, acceso, conservación, rectificación, limitación, supresión de datos y no ser objeto de una decisión basada únicamente en el tratamiento automatizado de datos, dirigiéndose por escrito a SITUM en las direcciones indicadas.
Información Adicional: Puede consultar la información adicional y detallada sobre Protección de Datos en nuestra política de privacidad.

Por favor, descarga tu copia aquí.

Muchas gracias por descargar nuestro whitepaper. No dudes en contactar con nosotros si quieres saber más sobre cómo nuestras soluciones pueden ayudar a tu negocio.


Cerrar ventana