Skip to main content

SmoothGlue Django Map

A Django app that provides admin-configurable REST APIs for map imagery, terrain providers, and logical entity grouping. Site admins can manage base layers, terrain sources, and group templates (e.g., "Parade Formation") available to frontend map clients without any code changes.

Designed for deployments across diverse networks, including air-gapped environments where public imagery and terrain services are unavailable. When no providers are configured, frontends fall back to Cesium's bundled NaturalEarth imagery and WGS84 Ellipsoid terrain.

Features

  • Imagery Layers — Configure map base-layer providers (ArcGIS, Bing, OpenStreetMap, Cesium Ion, and more) via the Django admin.
  • Terrain Layers — Configure terrain providers (Ellipsoid, Cesium Ion, Cesium Terrain, ArcGIS, Google, VR-TheWorld) via the Django admin.
  • Entity Groups — Group multiple map entities into logical clusters (e.g., Parade Formations) for synchronized frontend operations like multi-drag-and-drop.
  • Group Types — Admin-configurable templates defining standardized nomenclature and iconography for entity groups.
  • Cesium Ion Support — Both imagery and terrain layers support Ion asset IDs for loading layers through the Cesium Ion API.
  • Default Layer — Mark one imagery layer and one terrain layer as the default. The app enforces a single default per layer type automatically.
  • Filterable REST API — Read-only list endpoints with filtering by is_active, is_default, and provider_type.
  • Air-Gap Safe — Ellipsoid terrain (WGS84) requires no network access and is the default terrain provider type.

API Endpoints

Endpoint Description
GET /image-layers/ List active imagery layers
GET /terrain-layers/ List active terrain layers
GET /entity-group-types/ List active group templates
GET /entity-groups/ List active entity groups
POST /entity-groups/ Create a new entity group
DELETE /entity-groups/<id>/ Dissolve an entity group (keeps underlying entities)

List endpoints support query parameters for filtering:

GET /image-layers/?is_default=true
GET /terrain-layers/?provider_type=Cesium+Ion
GET /entity-group-types/?is_active=true

Response Example

{
  "id": "e6227ca5-9e8a-4793-9e63-d8ffa6e858b7",
  "name": "World Imagery",
  "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
  "provider_type": "ArcGis Map Server",
  "ion_asset_id": null,
  "sort_order": 1,
  "is_active": true,
  "is_default": true
}

Orphaned Entity Cleanup (Required Integration)

Because EntityGroup models map generic entities from consuming applications by storing their IDs in a JSONField, the database cannot rely on standard foreign key CASCADE deletions. If an entity is deleted in your consuming application, its ID will become orphaned inside the map group, potentially causing frontend mapping errors.

To prevent this, the package exports a cleanup utility: remove_entities_from_groups. You should trigger this utility inside your app's DRF ViewSet or via a Django post_delete signal whenever a mappable entity is destroyed.

Example using a DRF ViewSet:

from rest_framework import viewsets
from smoothglue.map.utils.entity_group import remove_entities_from_groups

class MyAppEntityViewSet(viewsets.ModelViewSet):
    # ... queryset and serializer ...

    def perform_destroy(self, instance):
        # 1. Clean up the map package groups first
        remove_entities_from_groups(instance.id, auto_dissolve=True)

        # 2. Execute standard deletion
        super().perform_destroy(instance)

(Note: auto_dissolve=True automatically deletes any map group that falls below 2 members after the cleanup).

Installation

Install the Package

pip install smoothglue_django_map

Configure Django

Add the app to INSTALLED_APPS in your settings.py:

INSTALLED_APPS = [
    "smoothglue.map",
    ...,
]

Include the URL routes in your urls.py:

urlpatterns = [
    path("", include("smoothglue.map.urls")),
    ...,
]

Run migrations:

python manage.py migrate

Optionally load the bundled fixtures to seed default imagery and terrain layers:

python manage.py loaddata imagerylayer
python manage.py loaddata terrainlayer

Offline Map Tiles

This package bundles a script to pull completely offline, highly-available map tiles using the Tile Map Service (TMS) standard.

1. Fetching the Tiles: Tiles are pre-bundled in the package. If you need to re-crawl or update the offline tiles, install the optional tools dependency group (poetry install --with tools) and run:

poetry run python tools/default_map_server/fetch_default_map_server_files.py

This script automatically converts the tiles to strict TMS {reverseY} format and generates a tilemapresource.xml file. The XML file is critical because it tells the frontend map engine (Cesium) the maximum available zoom level (level 4), allowing it to intelligently stretch those tiles when users zoom in closer, avoiding 404 errors or "blue globes".

2. Serving the Tiles (for consuming apps): Consuming apps must expose this static directory. If using Docker Compose, mount the directory directly into your backend's static folder:

volumes:
  - ../smoothglue_django_map/smoothglue/map/static/map/default_map_tiles:/home/python/staticfiles/map/default_map_tiles

3. Frontend Integration: In the consuming frontend application, set the fallback map URL (e.g., in @smoothglue-map-tools configs) to point to the backend proxy route:

export const FALLBACK_MAP_URL = '/bestatic/map/default_map_tiles/'

Alternatively, configure the layer via the Django admin UI using provider_type = "Tile Map Service".

Development

Set Up Virtual Environment

This project uses Poetry for dependency management.

  1. Install Poetry if you haven't already.
  2. Run poetry install to create a virtual environment and install dependencies.

Running Tests and Linters

Tests and linters can be executed via Nox or the bundled ./run_test.sh wrapper script:

# Run all linters, matrix tests, and coverage
./run_test.sh

# Run linters only (ruff, flake8, isort, black, pylint)
./run_test.sh lint

# Run matrix tests across supported Python (3.12–3.15) and Django (5.2, 6.0) versions
./run_test.sh tests

# Run tests with terminal and HTML coverage reporting
./run_test.sh coverage

You can also run pytest directly:

poetry run pytest

Management Commands

  • makemigrations.py — Generate migrations for the map app.
  • migrate.py — Apply pending migrations.
  • loaddata.py — Load fixture data (python3.12 loaddata.py smoothglue/map/fixtures/imagerylayer.json).
  • djangoshell.py — Open a Django shell aware of the app.
  • boot_django.py — Bootstraps a standalone Django environment configured with django_settings.py. Used by the standalone management scripts.

Building

poetry build

This creates source and wheel distributions in the dist/ directory.

Metadata

Release files for smoothglue_django_map 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for smoothglue_django_map 1.4.0
File Size Uploaded Provenance Actions
smoothglue_django_map-1.4.0.tar.gz 638.1 kB Without provenance Details for smoothglue_django_map-1.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for smoothglue_django_map 1.4.0
File Interpreter ABI Platform Actions
smoothglue_django_map-1.4.0-py3-none-any.whl Python 3 none any Details for smoothglue_django_map-1.4.0-py3-none-any.whl

Total release size: 1.5 MB

Release files / smoothglue_django_map-1.4.0.tar.gz

Download URL smoothglue_django_map-1.4.0.tar.gz
Size 638.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9e0b64ea2ac483b13f1bb7c2fd0d84a45544dc5e7b51b6bd7fb217f18d6b8fe3
BLAKE2b-256 checksum
How to use checksums
bb74a9a6ec7803d171bb8f53d5f0a3110d59edb28289ec529d44a4d7da0a18c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.12.14 Linux/4.18.0-553.115.1.el8_10.x86_64

Release files / smoothglue_django_map-1.4.0-py3-none-any.whl

Download URL smoothglue_django_map-1.4.0-py3-none-any.whl
Size 866.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c055a6296c1402588afcdad21592612ce084cc996027a9dde90f2d07a22c2d7b
BLAKE2b-256 checksum
How to use checksums
6baa9cd5d8989934b712f79efb4ad26d4ff6b4ab7571695d32da2f554149044d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.12.14 Linux/4.18.0-553.115.1.el8_10.x86_64

Security for smoothglue_django_map 1.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page