> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tic.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Vector Maps

> Daily-updated vector map tiles for Sweden — property, address, road, and environment layers. Works with Mapbox and MapLibre.

We provide advanced but simple to use vector maps with styles for displaying rich data about properties, addresses, roads and environment and many other things. You can use Mapbox or
MapLibre GL JS to render the maps in both web and mobile apps.

Maps are updated daily and hot swapped.

## Before Getting Started

Prior to using the maps engine you need to ensure you have proper access by allowing domains to use the API. Each domain you use to access our maps needs to be added which is very simple. You
add each domain by posting the domain to the [https://api.tic.io/teams/tiles/cors](https://api.tic.io/teams/tiles/cors) endpoint. If you want to access in development mode you can also add your localhost:port.

```bash cURL theme={null}
curl  \
--request POST
--header "Content-Type: application/json"
--header "x-api-key:your_api_key"
--data '{
  "Domain": "http://mydomain.com"
}'
https://api.tic.io/teams/tiles/cors
```

## Getting Started

This example shows how you get started with MapLibre GL JS in a webpage.

Include the JavaScript and CSS files in the head of your HTML file.

```HTML theme={null}
<script src='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css' rel='stylesheet' />
```

Include the following code in the body of your HTML file.

```HTML theme={null}
<div id='map' style='width: 800px; height: 800px;'></div>

<script>
  var map = new maplibregl.Map({
      container: "map",
      style: "https://tiles2.tic.io/style/super-map-style2",
      center: [19.8756, 63.5569], // starting position [lng, lat]
      zoom: 4,  // starting zoom
      attributionControl: false
  });
</script>
```

## Draw additional details

Property borders and buildings are by default included in the style but if you wish to draw areas and greater details about building numbers, usage type etc you
can download the property details from [https://api.tic.io/datasets/properties/se/uuid](/api-core/properties/details). This endpoint gives you additional
data and areas.

In the example below we are adding four(4) layers:

* Areas
* Building parts (already included in the default style)
* Building parts text (number)
* Areas text (number)

Result will look like the example below where the area is filled with light blue opacity and buildings are drawn in yellow adding the text number.

<img className="block" src="https://mintcdn.com/theintelligencecompany/tfkFeQUl-JEgmAXO/images/map-vector-areas-buildings.png?fit=max&auto=format&n=tfkFeQUl-JEgmAXO&q=85&s=b7d3f72eb4894bc386a2724f683513b1" alt="Vector map with areas and building numbers" width="739" height="759" data-path="images/map-vector-areas-buildings.png" />

For simplicity we are using Lodash.

Include the JavaScript and CSS files in the head of your HTML file.

```HTML theme={null}
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script src='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css' rel='stylesheet' />
```

```HTML theme={null}
<div id='map' style='width: 800px; height: 800px;'></div>

<script>
  // See above make a request to
  // https://api.tic.io/datasets/properties/se/{uuid} (replace uuid with the property id)
  // in your server controller / backend
  const dataFromRequest = {};
  // Then copy and paste the code below

  const areas = dataFromRequest.omraden;
  const byggnader = dataFromRequest.byggnader;

  var map = new maplibregl.Map({
      container: "map",
      style: "https://tiles2.tic.io/style/super-map-style2",
      center: [19.8756, 63.5569], // starting position [lng, lat]
      zoom: 4,  // starting zoom
      attributionControl: false
  });

  let bounds = [];
  map.on('load', async () => {
      const coordinates = [];
      const geojsonOmraden = {
          type: 'geojson',
          data: {
              "type": 'FeatureCollection',
              "features": []
          }
      };
      _.forEach(omraden, function(omrade) {
          geojsonOmraden.data.features.push({
              type: 'Feature',
              properties: {
                  omradesnummer: omrade.omradesnummer
              },
              geometry: {
                  type: 'Polygon',
                  coordinates: omrade.omradeYta
              }
          });
          _.forEach(omrade.omradeYta[0], i => coordinates.push(i));
      });
      map.addSource('omraden', geojsonOmraden);
      map.addLayer({
          'id': 'omraden',
          'type': 'fill',
          'source': 'omraden',
          'paint': {
              'fill-color': '#90E0EF',
              'fill-opacity': 0.7
          },
          'filter': ['==', '$type', 'Polygon']
      });

      const geojsonByggnadsdelar = {
          type: 'geojson',
          data: {
              "type": 'FeatureCollection',
              "features": []
          }
      };

      _.forEach(byggnader, function(byggnad) {
          _.forEach(byggnad.delar, function(del) {
              geojsonByggnadsdelar.data.features.push({
                  type: 'Feature',
                  properties: {
                      byggnadHusnummer: byggnad.byggnadHusnummer
                  },
                  geometry: {
                      type: 'Polygon',
                      coordinates: [del.byggnadsdelYta]
                  }
              });
          });
      });

      map.addSource('byggnadsdelar', geojsonByggnadsdelar);
      map.addLayer({
          'id': 'byggnadsdelar',
          'type': 'fill',
          'source': 'byggnadsdelar',
          'paint': {
              'fill-color': '#FDC86C',
              'fill-opacity': 0.8,
              'fill-outline-color': '#F9A107'
          },
          'filter': ['==', '$type', 'Polygon']
      });

      map.addLayer({
          'id': 'byggnadsdelartext',
          'type': 'symbol',
          'source': 'byggnadsdelar',
          "layout": {
              "text-field": [
                  "concat",
                  "Husnr: ",
                  ["get", "byggnadHusnummer"],
              ],
              "text-font": ["Open Sans SemiBold"],
              "text-size": {
                  "stops": [
                      [2, 10],
                      [4, 12],
                      [6, 12],
                      [12, 12],
                      [16, 16]
                  ]
              },
              "visibility": "visible"
          },
          "paint": {
              "text-color": "#000",
              "text-halo-blur": 1,
              "text-halo-color": "rgba(255, 255, 255, 1)",
              "text-halo-width": 1
          },
          'filter': ['==', '$type', 'Polygon']
      });

      map.addLayer({
          'id': 'omradesnummertext',
          'type': 'symbol',
          'source': 'omraden',
          "layout": {
              "text-field": [
                  "concat",
                  "Omrnr: ",
                  ["get", "omradesnummer"],
              ],
              "text-font": ["Open Sans SemiBold"],
              "text-size": {
                  "stops": [
                      [2, 10],
                      [4, 12],
                      [6, 12],
                      [12, 12],
                      [16, 16]
                  ]
              },
              "visibility": "visible"
          },
          "paint": {
              "text-color": "#000",
              "text-halo-blur": 1,
              "text-halo-color": "rgba(255, 255, 255, 1)",
              "text-halo-width": 1
          },
          'filter': ['==', '$type', 'Polygon']
      });

      const bounds = coordinates.reduce((bounds, coord) => {
          return bounds.extend(coord);
      }, new maplibregl.LngLatBounds(coordinates[0], coordinates[0]));

      map.fitBounds(bounds, {
          padding: 120,
          duration: 0
      });

  });
</script>
```

## Custom Styles

You can copy the style that we provide and make your own adjustments. We recommend using [Maputnik](https://maputnik.github.io/) which is a visual editor for
MapLibre and MapBox style specifiation. It allows you to make modifications to your style and save the json style sheet and host it yourself.

Each source object in the style reference our tileserver, tiles2.tic.io, which requires CORS. Therefore ensure you have added your domain to the API. Each URL consists of
the following format which contains four(4) parts in the URL that should be replaced [https://tiles2.tic.io/database.schema.table.column](https://tiles2.tic.io/database.schema.table.column) e.g database, schema, table and column.

You have access to the following databases that are updated daily and runs on PostGIS with PostgreSQL. The tile server serves tiles cached and it's extremley fast

| Database                | Description                                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| lm\_belagenhetsadress   | Contains all information relating to an address                                                |
| lm\_fastighetsindelning | Contains all information relating to an property                                               |
| lm\_top1m               | Contains topography 1:1M                                                                       |
| lm\_top10               | Contains topography 1:10                                                                       |
| lm\_top10               | Contains topography 1:10                                                                       |
| naturalearth            | Contains [Natural Earth](https://www.naturalearthdata.com/)                                    |
| ormeo                   | Contains extended databases such as the EBH which is a national database of contaminated areas |

Check next section for a full data dictionary.

## Data Dictionary

Each databases consists of geometric tables and in total they are 248. Each table then contains a range of columns that can be used to be displayed on the map. For simplicity we are adding
a full data dictionary in PDF (582 pages) that you can download and easier search in and pick the fields you want to display.

[Download the data dictionary here](https://content.tic.io/tic/DataDictionary_20250720201303.pdf)

Adding a source layer is very simple in the style sheet and we have made an example below.

Let's say you want to show railroads in the map (enabled by default in our stylesheet), you check the PDF-dictionary and find that there is a table called ralstrafik (English: rail roads)
and the column geom contains the geometry of the railroads.

Just add a source object with the nickname "ralstrafik" and you are done:

```json theme={null}
"ralstrafik": {
      "type": "vector",
      "url": "https://tiles2.tic.io/lm_top10.table.public.ralstrafik.geom"
    },
```

This should be interpreted as

Database = lm\_top10
Schema = public
Table = ralstrafik
Column = geom

<Tip>
  Please note that the data directory contains a suffix on the databases in the
  format \_YYYYMMDD which should NOT be included in the URL. It just shows when
  the table was most recentley updated
</Tip>
