Open data licences explained for spatial data
On this page
Problem statement
A licence decides three things about a spatial dataset: whether you may use it at all, what you must say when you do, and what licence your output has to carry. The third is the one that surprises people, and it is the reason a map built from four open layers can be undistributable.
Spatial data also has a complication other data does not. A boundary layer is a database, and in several jurisdictions databases carry a separate right from copyright. That is why OpenStreetMap uses the Open Database Licence rather than Creative Commons, and why "I only used it to clip my own data" is a question with a real answer rather than an obvious one.
This guide covers the licences you will actually meet on spatial data, what each requires, and how to work out what your combined output may be released under.
Quick answer
Record the licence as an SPDX identifier so it can be checked mechanically, and record the attribution string separately:
LICENCES = {
"CC0-1.0": {"attribution": False, "share_alike": False, "commercial": True},
"CC-BY-4.0": {"attribution": True, "share_alike": False, "commercial": True},
"CC-BY-SA-4.0": {"attribution": True, "share_alike": True, "commercial": True},
"ODbL-1.0": {"attribution": True, "share_alike": True, "commercial": True},
"ODC-BY-1.0": {"attribution": True, "share_alike": False, "commercial": True},
"OGL-UK-3.0": {"attribution": True, "share_alike": False, "commercial": True},
"CC-BY-NC-4.0": {"attribution": True, "share_alike": False, "commercial": False},
}
The three booleans decide almost everything. A share-alike input forces the output; a non-commercial input rules out most publication; an attribution requirement means a string has to appear on every map, not in a metadata field nobody renders.
Find the licence first, record it as SPDX, read the attribution rules
1. Find the licence before you download
The licence is a property of the dataset, and it is usually one click from the download link. If you cannot find it, treat the dataset as unlicensed and do not build anything on it — A downloaded layer has no licence you can find covers what to do next.
2. Record it as an SPDX identifier
CC-BY-4.0, not "Creative Commons". Identifiers are unambiguous, comparable and machine-checkable; prose licence names are none of those. Where no SPDX identifier exists — several national licences — record the URL of the licence text. Catalogues that follow STAC already carry the field, and reading it shows both cases:
import requests
for name, url in [
("Sentinel-2 L2A (Earth Search)", "https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a"),
("Copernicus DEM GLO-90 (Earth Search)", "https://earth-search.aws.element84.com/v1/collections/cop-dem-glo-90"),
("ESA WorldCover (Planetary Computer)", "https://planetarycomputer.microsoft.com/api/stac/v1/collections/esa-worldcover"),
]:
collection = requests.get(url, timeout=60).json()
link = next((l["href"] for l in collection["links"] if l.get("rel") == "license"), None)
print(f"{name:38} {collection['license']:12} {link}")
gbif = requests.get("https://api.gbif.org/v1/dataset/50c9509d-22c7-4a22-a47d-8c48425ef4a7", timeout=60).json()
print(f"{gbif['title'][:38]:38} {gbif['license']}")
Sentinel-2 L2A (Earth Search) proprietary https://sentinel.esa.int/documents/247904/690755/Sentinel_Data_Legal_Notice
Copernicus DEM GLO-90 (Earth Search) proprietary https://spacedata.copernicus.eu/documents/20123/121286/CSCDA_ESA_Mission-specific+Annex_31_Oct_22.pdf
ESA WorldCover (Planetary Computer) CC-BY-4.0 https://spdx.org/licenses/CC-BY-4.0.html
iNaturalist Research-grade Observation http://creativecommons.org/licenses/by-nc/4.0/legalcode
proprietary does not mean closed here: Sentinel data and the Copernicus DEM are free under the Copernicus terms, which have no SPDX identifier, so STAC points to the legal notice instead. WorldCover is plain CC-BY-4.0. And GBIF's iNaturalist dataset is non-commercial at the dataset level, even though its individual records carry a mix of CC0, CC-BY and CC-BY-NC.
3. Read the attribution requirement literally
Most attribution clauses require the notice to travel with the work, which for a map means on the map, and for a tile service means in the interface. "Contains OS data © Crown copyright and database right 2026" is not a metadata field; it is a line of text on the image.
4. Work out whether share-alike is triggered
This is the hard one, and it is where the database right matters. Under the ODbL, a derivative database must be released under the ODbL; a produced work — a map image, a report, a statistic — need not be, but must carry attribution. Whether your output is a new database or a produced work is a question about what you are publishing, not about how you made it.
5. Check the non-commercial and no-derivatives traps
CC-BY-NC blocks most public-sector and consultancy use, because "commercial" is broader than "sold". CC-BY-ND blocks derivative works entirely, which rules out clipping, reprojecting and styling.
6. Combine the licences before you combine the data
The output licence is constrained by every input. A dataset combining an ODbL layer as a derivative database and a CC-BY-SA layer cannot be released at all under either, because each demands its own licence on the result. How to check licence compatibility before combining datasets implements the check.
7. Keep the attribution strings with the data
Every dataset's required notice belongs in its metadata record, so that a map built from six layers can assemble its credit line automatically rather than from memory.
The licences you will meet, and the output licence
The data used on this page
Every number below comes from GBIF's API. GBIF adds and revises records daily, so the setup answers each GBIF request this page makes from the reply it got on 9 October 2026, and lets any other request through live.
import hashlib, io, zipfile
import requests
# GBIF adds and revises records daily. So that the numbers below reproduce, every GBIF request on
# this page is answered from the reply it got on 9 October 2026 (one file per request, named by a
# SHA-1 of its URL); any other request, or all of them once these lines are deleted, goes live.
SAVED = zipfile.ZipFile(io.BytesIO(requests.get(
"https://www.spatialworkflow.io/data/gbif-api-2026-10-09.zip", timeout=300).content))
live_get = requests.get
def saved_get(url, params=None, **kwargs):
prepared = requests.Request("GET", url, params=params).prepare()
try:
body = SAVED.read(hashlib.sha1(prepared.url.encode()).hexdigest()[:16] + ".json")
except KeyError:
return live_get(url, params=params, **kwargs)
reply = requests.models.Response()
reply.status_code, reply._content, reply.url = 200, body, prepared.url
reply.headers["Content-Type"] = "application/json"
return reply
requests.get = saved_get
Example 1 — the licences you will actually meet
| Identifier | Attribution | Share-alike | Commercial | Typical source |
|---|---|---|---|---|
CC0-1.0 |
no | no | yes | many research datasets; Wikidata |
| public domain | no | no | yes | Natural Earth — no licence text, and no SPDX identifier |
CC-BY-4.0 |
yes | no | yes | ESA WorldCover, Impact Observatory land cover, many portals |
| Copernicus terms | yes | no | yes | Sentinel imagery, Copernicus DEM (proprietary in STAC) |
CC-BY-SA-4.0 |
yes | yes | yes | Wikipedia-derived data |
ODbL-1.0 |
yes | yes (databases) | yes | OpenStreetMap |
ODC-BY-1.0 |
yes | no | yes | some city portals |
OGL-UK-3.0 |
yes | no | yes | UK public sector, OS OpenData |
CC-BY-NC-4.0 |
yes | no | no | iNaturalist research-grade observations on GBIF, some academic and NGO data |
| proprietary | varies | varies | varies | commercial basemaps, address files |
Example 2 — resolve the output licence for a set of inputs
def output_licence(inputs, publishing="produced_work"):
"""inputs: list of SPDX identifiers. Returns the licences the output may carry."""
props = [LICENCES[i] for i in inputs]
if any(not p["commercial"] for p in props):
return {"allowed": [], "reason": "a non-commercial input restricts redistribution"}
share_alike = [i for i, p in zip(inputs, props) if p["share_alike"]]
if publishing == "produced_work":
# ODbL produced works are free of share-alike; CC-BY-SA is not
binding = [i for i in share_alike if i.startswith("CC-BY-SA")]
else:
binding = share_alike
if len(set(binding)) > 1:
return {"allowed": [], "reason": f"incompatible share-alike inputs: {sorted(set(binding))}"}
if binding:
return {"allowed": [binding[0]], "reason": f"share-alike from {binding[0]}"}
return {"allowed": ["CC-BY-4.0", "CC0-1.0", "proprietary"], "reason": "attribution only"}
print(output_licence(["ODbL-1.0", "OGL-UK-3.0"], "produced_work"))
print(output_licence(["ODbL-1.0", "OGL-UK-3.0"], "derivative_database"))
print(output_licence(["ODbL-1.0", "CC-BY-SA-4.0"], "derivative_database"))
print(output_licence(["ODbL-1.0", "CC-BY-SA-4.0"], "produced_work"))
{'allowed': ['CC-BY-4.0', 'CC0-1.0', 'proprietary'], 'reason': 'attribution only'}
{'allowed': ['ODbL-1.0'], 'reason': 'share-alike from ODbL-1.0'}
{'allowed': [], 'reason': "incompatible share-alike inputs: ['CC-BY-SA-4.0', 'ODbL-1.0']"}
{'allowed': ['CC-BY-SA-4.0'], 'reason': 'share-alike from CC-BY-SA-4.0'}
The first three calls give the three outcomes that matter: a map you may license freely, a database you must release as ODbL, and a combination you cannot publish at all. The fourth is the one people get wrong: a map made from ODbL and CC-BY-SA data is not free of share-alike, because CC-BY-SA applies to adapted material of any kind — the map must be CC-BY-SA.
Example 3 — assemble the credit line from the metadata
def credit_line(layers):
"""layers: list of metadata dicts with 'attribution' and 'licence'."""
seen, parts = set(), []
for layer in layers:
text = layer.get("attribution")
if text and text not in seen:
seen.add(text)
parts.append(text)
return " · ".join(parts)
print(credit_line([
{"attribution": "© OpenStreetMap contributors (ODbL)", "licence": "ODbL-1.0"},
{"attribution": "Contains OS data © Crown copyright and database right 2026", "licence": "OGL-UK-3.0"},
{"attribution": "Made with Natural Earth", "licence": "LicenseRef-PublicDomain"},
{"attribution": "© OpenStreetMap contributors (ODbL)", "licence": "ODbL-1.0"},
]))
© OpenStreetMap contributors (ODbL) · Contains OS data © Crown copyright and database right 2026 · Made with Natural Earth
The duplicate OpenStreetMap entry — two layers from the same source — appears once.
Build the line from the data rather than typing it into the map template, and a layer that is added or removed updates the credit automatically.
Database rights and produced works
Why the database right changes the analysis
Copyright protects creative expression, which a list of coordinates largely is not. The EU and UK sui generis database right protects the investment in assembling a database regardless of creativity, which is exactly what a boundary or address dataset represents. The ODbL was written for that right, and its share-alike clause bites on databases rather than on pictures — which is why a map made from OpenStreetMap can be all-rights-reserved while a derived address file cannot.
Why "produced work" is the pivotal definition
Under the ODbL, a produced work is something produced from the database — an image, a report, a set of statistics — and it needs attribution but not ODbL licensing. A derivative database is a database that incorporates the data, and it must be ODbL. Publishing a GeoJSON of OSM-derived building footprints is a derivative database; publishing a PNG map of them is a produced work. The distinction is about the artefact, and it decides the licence of everything downstream.
Why non-commercial is stricter than it sounds
NC does not mean "not sold". It means not primarily intended for commercial advantage, which most interpretations extend to consultancy deliverables, internal use by a company, and anything on a site carrying advertising. If a dataset is NC and the output leaves your organisation, get advice rather than assuming.
Why attribution belongs on the artefact
Every attribution clause in the table requires the notice to accompany the work. A credit buried in a metadata file is not on the map, and a tile service that drops the attribution control is in breach whatever its metadata says.
Government terms, open-is-not-a-licence and terms of service
- Government terms are not always SPDX. Record the URL when no identifier exists.
- "Open" is not a licence. Neither is "free to use".
- Terms of service can bind you separately. An API may restrict caching regardless of the data licence.
- Geocoding results often carry provider restrictions. Storing coordinates is commonly forbidden.
- A basemap is a separate licence from the data on it.
- Licences change. Record the version and the date you downloaded under it.
- Attribution text is prescribed. Use the wording the publisher gives, not your paraphrase.
- Public domain still deserves credit. CC0 and public-domain data require nothing; saying where it came from is still good practice — Natural Earth suggests "Made with Natural Earth".
Internal links
- How to check licence compatibility before combining datasets — the automated version of this reasoning
- Attribution requirements explained: OpenStreetMap, Copernicus and national data — the exact strings
- A downloaded layer has no licence you can find — what to do when the field is empty
- Spatial metadata explained: what a dataset must tell you — where the licence field lives
- GIS data sources explained — which sources use which licences
- The OpenStreetMap data model explained — the largest ODbL dataset you will use
- How to write a metadata record for a dataset in Python — storing the licence and attribution
- How to package GIS deliverables in Python — shipping the licence with the data
FAQ
What licence is OpenStreetMap data under?
The Open Database Licence 1.0. It requires attribution, and requires derivative databases to be released under the ODbL — but a map image or a statistic made from it is a produced work, which needs attribution only.
Can I combine CC-BY-SA and ODbL data?
Not into a single published database: each requires the result to carry its own licence, and the two demands conflict. In a produced work such as a map image, the ODbL asks only for attribution, but CC-BY-SA's share-alike still applies to the map — publish it under CC-BY-SA.
Does clipping someone's data create a derivative database?
Yes, if what you publish is still a database. Clipping, reprojecting and filtering all produce a derivative database under the ODbL.
Where does the attribution have to appear?
On the work itself — the map image, the application interface, the report. A metadata field is not a substitute.
What does CC-BY-NC rule out?
More than selling. Most readings cover consultancy deliverables, internal corporate use and sites carrying advertising. Treat it as unusable for anything leaving a non-profit context.
What should I do with a dataset that has no licence?
Treat it as unlicensed: do not publish anything derived from it until you have written permission or an identified licence.