Skip to content

Commit

Permalink
Make "Map view" URL configurable in backend settings (#106)
Browse files Browse the repository at this point in the history
When a query results contains WKT literals in its last column, a "Map view" button appears. A click on that button leads to an instance of https://github.com/ad-freiburg/qlever-petrimaps, which visualizes the result.

So far, this only worked for selected backends, and it was hard-coded in `backend/static/js/qleverUI.js` which ones. Now this can be configured invididually for each backend, via a field `Map view base URL`. The URL should be the base URL of the `qlever-petrimaps` instance. When the field is empty (which is the default), no "Map View" button is shown for that backend. Fixes #102 . Since a new field was added to the backend configuration, this requires a migration.
  • Loading branch information
Qup42 authored Sep 23, 2024
1 parent 9b6a90b commit 177ef3a
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 6 deletions.
2 changes: 1 addition & 1 deletion backend/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class BackendAdmin(ImportExportModelAdmin):
}
fieldsets = (
("General", {
'fields': ('name', 'slug', 'sortKey', 'baseUrl', 'isDefault', 'isNoSlugMode', 'apiToken')
'fields': ('name', 'slug', 'sortKey', 'baseUrl', 'mapViewBaseURL', 'isDefault', 'isNoSlugMode', 'apiToken')
}),
('UI Suggestions', {
'fields': ('maxDefault', 'fillPrefixes', 'filterEntities', 'filteredLanguage', 'supportedKeywords', 'supportedFunctions', 'suggestPrefixnamesForPredicates', 'supportedPredicateSuggestions', 'suggestedPrefixes'),
Expand Down
24 changes: 24 additions & 0 deletions backend/migrations/0073_backend_mapviewbaseurl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 5.0.3 on 2024-09-22 19:29

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("backend", "0072_backend_isnoslugmode"),
]

operations = [
migrations.AddField(
model_name="backend",
name="mapViewBaseURL",
field=models.CharField(
blank=True,
default="",
help_text="The base URL of the https://github.com/ad-freiburg/qlever-petrimaps instance; if empty, no Map View button will appear",
max_length=2048,
verbose_name="Map view base URL",
),
),
]
8 changes: 8 additions & 0 deletions backend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@ class Backend(models.Model):
help_text="The query for <em>context-insensitive</em> object autocompletion",
verbose_name="Context-insensitive object autocompletion query")

mapViewBaseURL = models.CharField(
default="",
blank=True,
max_length=2048, # URLs don't have a length limit, but this should be plenty long
verbose_name="Map view base URL",
help_text="The base URL of the https://github.com/ad-freiburg/qlever-petrimaps instance; if empty, no Map View button will appear",
)

def save(self, *args, **kwargs):
# We need to replace \r because QLever can't handle them very well
for field in (
Expand Down
4 changes: 2 additions & 2 deletions backend/static/js/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,8 @@ function getFormattedResultEntry(str, maxLength, column = undefined) {
icon_class = "glyphicon glyphicon-search";
str = "Query view";
} else {
mapview_url = `https://qlever.cs.uni-freiburg.de/mapui-petri/` +
`?query=${encodeURIComponent(str)}` +
mapview_url = MAP_VIEW_BASE_URL +
`/?query=${encodeURIComponent(str)}` +
`&mode=objects&backend=${BASEURL}`;
icon_class = "glyphicon glyphicon-globe";
str = "Map view";
Expand Down
5 changes: 2 additions & 3 deletions backend/static/js/qleverUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,10 +582,9 @@ async function processQuery(sendLimit=0, element=$("#exebtn")) {
let mapViewButtonPetri = '';
if (result.res.length > 0 && /wktLiteral/.test(result.res[0][columns.length - 1])) {
let mapViewUrlVanilla = 'http://qlever.cs.uni-freiburg.de/mapui/index.html?';
let mapViewUrlPetri = 'http://qlever.cs.uni-freiburg.de/mapui-petri/?';
let params = new URLSearchParams({ query: normalizeQuery(query), backend: BASEURL });
mapViewButtonVanilla = `<a class="btn btn-default" href="${mapViewUrlVanilla}${params}" target="_blank"><i class="glyphicon glyphicon-map-marker"></i> Map view</a>`;
mapViewButtonPetri = `<a class="btn btn-default" href="${mapViewUrlPetri}${params}" target="_blank"><i class="glyphicon glyphicon-map-marker"></i> Map view</a>`;
mapViewButtonPetri = `<a class="btn btn-default" href="${MAP_VIEW_BASE_URL}/?${params}" target="_blank"><i class="glyphicon glyphicon-map-marker"></i> Map view</a>`;
}

// Show the buttons (if there are any).
Expand All @@ -595,7 +594,7 @@ async function processQuery(sendLimit=0, element=$("#exebtn")) {
// the Django configuration of the respective backend).
var res = "<div id=\"res\">";
if (showAllButton || (mapViewButtonVanilla && mapViewButtonPetri)) {
if (BASEURL.match("wikidata|osm|ohm|dblp")) {
if (MAP_VIEW_BASE_URL.length > 0) {
res += `<div class="pull-right" style="margin-left: 1em;">${showAllButton} ${mapViewButtonPetri}</div>`;
} else {
res += `<div class="pull-right" style="margin-left: 1em;">${showAllButton}</div>`;
Expand Down
1 change: 1 addition & 0 deletions backend/templates/partials/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
{% for example in examples %}
examples.push(`{{ example.query|safe }}`);
{% endfor %}
var MAP_VIEW_BASE_URL = "{{ backend.mapViewBaseURL }}";
</script>

<!-- Bootstraps JavaScript -->
Expand Down
Binary file modified db/qleverui.sqlite3
Binary file not shown.
12 changes: 12 additions & 0 deletions docs/configure_qleverui.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ If everything worked correctly you should see backend details displayed on the t

You can also import the respective `*-sample.csv` file for the example backend or manually create examples in the "Examples" section in the admin panel that will be shown in the user interface later on.

# Configure the Map view

Geometry objects ([WKT literals](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) to be exact) can be displayed on a map using [qlever-petrimaps](https://github.com/ad-freiburg/qlever-petrimaps). The objects can be visualized as a heatmap or discrete objects.
qlever-petrimaps is the tool that does the heavy-lifting for visualizing the data on the map. You have to host your own instance of qlever-petrimaps.

- Enable the Map view by setting the field `Map view base URL` to the location of your own qlever-petrimaps instance.

The "Map view" button appears for a query if and only the following two requirements are met:

- the geometry objects must be in the **last column**
- the column must contain literals with the datatype `http://www.opengis.net/ont/geosparql#wktLiteral`

# Configure the autocompletion queries
QLever UI offers several settings that can be used to configure the autocompletion. They are separated into five categories:
- [Variable Names](#variable-names)
Expand Down

0 comments on commit 177ef3a

Please sign in to comment.