Life and Shell

Writing · drones

Spridningstillstånd: how Ollebo keeps drone maps legal to share in Sweden

By Mattias Hemmingsson · · 5 min read

Flying a drone in Sweden is one set of rules. Sharing what you filmed is another. Under the law on protection of geographic information (Lag 2016:319), spreading aerial imagery needs a permit, a spridningstillstånd, from Lantmäteriet. Lantmäteriet's regulations (LMFS 2016:1) list exceptions, and the important one for us is simple: an orthophoto with a resolution of 0.5 m per pixel or coarser can be shared without a permit.

A modern drone makes maps at 2 to 5 cm per pixel. That is ten to twenty-five times finer than the limit. So every public drone map on Ollebo was a problem waiting to happen. Today we fixed that, across the whole pipeline.

This is how we read the rules for our own service. It is not legal advice.

What counts as spreading

The definition is wide. Spreading is making material available to anyone outside the organisation that owns it. That includes:

  • a public web page or a share link
  • an invited external user
  • API responses, WMS/WMTS, exports and downloads
  • embeds (iframes)
  • thumbnails and social previews (og:image)
  • delivering the map to the customer who ordered the flight

The last point surprised us. When Ollebo or one of our pilots flies for a customer, handing over the high-resolution map counts as spreading.

What may be shared without a permit

Material Without a permit?
Orthophoto (straight down), 0.5 m or coarser ✅ Yes (LMFS 2 kap. 4 §)
Orthophoto finer than 0.5 m ❌ No
Single raw photos, oblique photos, video ❌ No
Elevation models (DSM/DTM), point clouds, 3D meshes ❌ No, at any resolution
Thermal, radar, multispectral ❌ Manual review
A theme layer showing only vegetation, land use, geology, ancient remains or slope ✅ Yes (2 kap. 2 §), with no image underneath
Object detections (buildings, vehicles), change analysis ❌ Not public
Material collected before 1950 ✅ Yes (2 kap. 5 §)

Two more things: over water the permit authority is Sjöfartsverket, not Lantmäteriet. And outside Sweden other countries have their own rules. We treat both as "a human looks at it first".

Our rule for the code is: when unsure, choose private or coarse, and flag it for review. Never assume an exception applies.

Two versions of every map

Every map now exists in two separate versions:

Private Public
Who sees it members of the owning Space everyone
Resolution full drone resolution resampled to 0.6 m, verified ≥ 0.5 m
Storage private bucket public/ prefix in the public bucket
Tile catalog terracotta a separate terracotta-public
Tile URL /private-tiles/... (login + Space membership) /public/... (zoom-gated)

The full-resolution files never touch the public bucket, a CDN or a cache. The public version is not "the same map with zoom levels hidden". It is a new file, made from a resampled copy of the source.

Resample, don't just hide zoom levels

Hiding zoom levels in the browser is not enough. Anyone can request a tile URL by hand. So map-maker makes a real coarse copy, in SWEREF 99 TM (a metric projection), and checks the result:

gdalwarp -t_srs EPSG:3006 -tr 0.6 0.6 -r average \
  -co COMPRESS=DEFLATE -co TILED=YES \
  source.tif public_0_6m.tif

gdalinfo -json public_0_6m.tif | jq '.geoTransform[1], .geoTransform[5]'

We use 0.6 m instead of 0.5 m as a margin. If the pixel size check fails, the map stays private.

Max zoom depends on latitude

Web maps use Web Mercator, where a pixel covers less ground the further north you go. A zoom level that is fine in Malmö can be too sharp in Kiruna. So the public max zoom is calculated from the map's northernmost point:

EARTH_RES_Z0 = 156543.03392804097   # m/px at the equator, zoom 0, 256 px tiles

def max_public_zoom(max_abs_lat_deg, tile_size=256, pixel_ratio=1):
    base = (EARTH_RES_Z0 * math.cos(math.radians(max_abs_lat_deg))
            * 256 / tile_size / pixel_ratio)
    return math.floor(math.log2(base / (0.5 * 1.2)))

# Stockholm (59.3°N) -> 17, Kiruna (68°N) -> 16

The tile proxy refuses any public tile above that zoom. The map in the browser can still zoom further, but it just enlarges the coarse tile (overzoom).

Going public is a request

Before today, ticking "public" on a map made it public. Now it starts a process:

private ──publish──▶ rendering ──passed──▶ public
                        ├──uncertain──▶ pending_review ──approved──▶ rendering
                        └──forbidden──▶ rejected
public ──unpublish / protected-site report──▶ private (tiles deleted, cache purged)
  • The upload form now asks what kind of material it is: orthophoto, elevation model, 3D, raw images and so on.
  • map-maker's coarse render decides. An orthophoto that is fully over Swedish land and at most 10 % water passes automatically.
  • Elevation models, point clouds, meshes, oblique and raw photos, and video are rejected. 3D models can never be public.
  • Everything else goes to a review queue at /admin/compliance. A reviewer can approve one specific check, but the 0.6 m resample and the zoom gate always apply.
  • A late result can never re-publish a map that was unpublished in the meantime.

Unpublishing deletes the public files and purges the tile cache. Changing a permission is never enough on its own.

Everything is logged

Every publish, refusal, unpublish, delete, review decision and publish request is written to an append-only audit log. Each row has the dataset, owner, user, time, bounding box, resolution, max zoom, material type and the legal basis (which exception, or which permit).

Closing every way out

The tiles were the easy part. The policy says every way out must give the coarse version, so we also changed:

  • The public map list and search only show public maps, and only with the coarse tile URL.
  • The tile proxy no longer serves raw COG files, catalog listings or metadata to the public.
  • Object detections (buildings, vehicles) always go to the private bucket.
  • Raw mission photos need Space membership.
  • Old public maps were hidden when we deployed and are being re-rendered through the coarse pipeline. That also deletes their too-sharp files from the public bucket.

There is also a public page in Swedish, Privata och publika kartor (/map-sharing), linked from the site footer and the upload form. It explains to users why their public map is blurrier than the private one.

What is still missing

  • No permit register yet. If a customer has a real spridningstillstånd, there is no way to record it yet, so nothing high-resolution leaves a Space.
  • The water check is coarse. It uses Natural Earth data, which misses small lakes and rivers.
  • No public "report a protected site" form yet. Members can report through the API. A report unpublishes the map at once.
  • Area exceptions (farmland, golf courses, building sites and others in 2 kap. 3 §) are never applied automatically. They will need a declaration from the user and a human check.

Why bother

It is tempting to treat this as small print. But a public drone map at 3 cm per pixel shows everything: fences, alarms, windows, cars, what is in people's gardens. The 0.5 m rule exists for a reason, and protected sites (skyddsobjekt) are off limits at any resolution.

For us it was also about trust. Customers fly their own land and share maps with neighbours, buyers and authorities. Now they can share without having to know the law, because the platform knows it for them.

Filed underdrones · gis · sweden · compliance · lantmateriet · ollebo