From 502d404934a8dcbfafebc22141e6dc92f92846c7 Mon Sep 17 00:00:00 2001 From: Brian Kelly Date: Tue, 29 Oct 2024 12:31:16 -0500 Subject: [PATCH] Basic GPX support via Leaflet --- MANIFEST.in | 4 +++ .../css/invenio_previewer_geospatial/gpx.css | 6 ++++ .../js/invenio_previewer_geospatial/gpx.js | 30 +++++++++++++++++++ .../extensions/__init__.py | 3 ++ .../extensions/gpx.py | 21 +++++++++++++ .../invenio_previewer_geospatial/gpx.html | 5 ++++ invenio_previewer_geospatial/webpack.py | 18 +++++++++++ setup.cfg | 5 ++++ 8 files changed, 92 insertions(+) create mode 100644 invenio_previewer_geospatial/assets/semantic-ui/css/invenio_previewer_geospatial/gpx.css create mode 100644 invenio_previewer_geospatial/assets/semantic-ui/js/invenio_previewer_geospatial/gpx.js create mode 100644 invenio_previewer_geospatial/extensions/__init__.py create mode 100644 invenio_previewer_geospatial/extensions/gpx.py create mode 100644 invenio_previewer_geospatial/templates/semantic-ui/invenio_previewer_geospatial/gpx.html create mode 100644 invenio_previewer_geospatial/webpack.py diff --git a/MANIFEST.in b/MANIFEST.in index 24c063f..e2d8538 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -31,3 +31,7 @@ recursive-include docs Makefile recursive-include invenio_previewer_geospatial *.html recursive-include invenio_previewer_geospatial/translations *.po *.pot *.mo recursive-include tests *.py + +# added by check-manifest +recursive-include invenio_previewer_geospatial *.css +recursive-include invenio_previewer_geospatial *.js diff --git a/invenio_previewer_geospatial/assets/semantic-ui/css/invenio_previewer_geospatial/gpx.css b/invenio_previewer_geospatial/assets/semantic-ui/css/invenio_previewer_geospatial/gpx.css new file mode 100644 index 0000000..edb9af7 --- /dev/null +++ b/invenio_previewer_geospatial/assets/semantic-ui/css/invenio_previewer_geospatial/gpx.css @@ -0,0 +1,6 @@ +@import "leaflet/dist/leaflet.css"; + +#map { + width: 100%; + height: 480px; +} diff --git a/invenio_previewer_geospatial/assets/semantic-ui/js/invenio_previewer_geospatial/gpx.js b/invenio_previewer_geospatial/assets/semantic-ui/js/invenio_previewer_geospatial/gpx.js new file mode 100644 index 0000000..04de4e7 --- /dev/null +++ b/invenio_previewer_geospatial/assets/semantic-ui/js/invenio_previewer_geospatial/gpx.js @@ -0,0 +1,30 @@ +import L from "leaflet" +import 'leaflet-gpx'; +import "leaflet/dist/leaflet.css"; + +document.addEventListener("DOMContentLoaded", () => { + const mapElement = document.getElementById("map"); + const gpxFileUri = mapElement.getAttribute("data-file-uri") + const gpxUrl = new URL(gpxFileUri, window.location.href); + + const map = L.map('map').setView([0, 0], 13); + + L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '© OpenStreetMap' + }).addTo(map); + + new L.GPX(gpxUrl.href, { + async: true, + gpx_options: { + parseElements: ['track', 'route'] + }, + markers: { + // TODO: Figure out how to display stock images from leaflet-gpx + startIcon: null, + endIcon: null + } + }).on('loaded', (e) => { + map.fitBounds(e.target.getBounds()); + }).addTo(map); +}); diff --git a/invenio_previewer_geospatial/extensions/__init__.py b/invenio_previewer_geospatial/extensions/__init__.py new file mode 100644 index 0000000..b6db6c7 --- /dev/null +++ b/invenio_previewer_geospatial/extensions/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +"""Geospatial Previewers.""" diff --git a/invenio_previewer_geospatial/extensions/gpx.py b/invenio_previewer_geospatial/extensions/gpx.py new file mode 100644 index 0000000..3caae7e --- /dev/null +++ b/invenio_previewer_geospatial/extensions/gpx.py @@ -0,0 +1,21 @@ +"""GPX Previewer.""" + +from flask import render_template +from invenio_previewer.proxies import current_previewer + +previewable_extensions = ["gpx"] + + +def can_preview(file): + """Check if file can be previewed.""" + return file.is_local() and file.has_extensions(".gpx") + + +def preview(file): + """Render the GPX template.""" + return render_template( + "invenio_previewer_geospatial/gpx.html", + file=file, + js_bundles=current_previewer.js_bundles + ["gpx_js.js"], + css_bundles=current_previewer.css_bundles + ["gpx_css.css"], + ) diff --git a/invenio_previewer_geospatial/templates/semantic-ui/invenio_previewer_geospatial/gpx.html b/invenio_previewer_geospatial/templates/semantic-ui/invenio_previewer_geospatial/gpx.html new file mode 100644 index 0000000..4a6a532 --- /dev/null +++ b/invenio_previewer_geospatial/templates/semantic-ui/invenio_previewer_geospatial/gpx.html @@ -0,0 +1,5 @@ +{%- extends config.PREVIEWER_ABSTRACT_TEMPLATE %} + +{% block panel %} +
+{% endblock %} diff --git a/invenio_previewer_geospatial/webpack.py b/invenio_previewer_geospatial/webpack.py new file mode 100644 index 0000000..e2d51ad --- /dev/null +++ b/invenio_previewer_geospatial/webpack.py @@ -0,0 +1,18 @@ +"""JS/CSS Webpack bundles for Invenio Previewer Geospatial.""" + +from invenio_assets.webpack import WebpackThemeBundle + +theme = WebpackThemeBundle( + __name__, + "assets", + default="semantic-ui", + themes={ + "semantic-ui": dict( + entry={ + "gpx_js": "./js/invenio_previewer_geospatial/gpx.js", + "gpx_css": "./css/invenio_previewer_geospatial/gpx.css", + }, + dependencies={"leaflet": "^1.9.4", "leaflet-gpx": "^2.1.2"}, + ), + }, +) diff --git a/setup.cfg b/setup.cfg index efcc073..10b3443 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,6 +29,7 @@ zip_safe = False install_requires = invenio-base>=1.2.5,<2.0.0 invenio-i18n>=2.0.0,<3.0.0 + invenio-previewer>=2.0.0,<3.0.0 [options.extras_require] tests = @@ -44,6 +45,10 @@ invenio_base.blueprints = invenio_previewer_geospatial = invenio_previewer_geospatial.views:blueprint invenio_i18n.translations = messages = invenio_previewer_geospatial +invenio_assets.webpack = + invenio_previewer_geospatial = invenio_previewer_geospatial.webpack:theme +invenio_previewer.previewers = + gpx = invenio_previewer_geospatial.extensions.gpx [build_sphinx] source-dir = docs/