Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

417: Allow default map settings to be configurable #421

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 42 additions & 29 deletions ifcbdb/assets/js/site.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
// TODO: Move default location to settings
var defaultLat = 41.5507768;
var defaultLng = -70.6593102;
var minLatitude = -180;
var minLongitude = -180;
var zoomLevel = 6;
var GPS_PRECISION = 4;
var DEPTH_PRECISION = 1;
var PLOT_X_DEFAULT = "roi_x";
var PLOT_Y_DEFAULT = "roi_y";
var MAX_SELECTABLE_IMAGES = 25;
var _binFilterMode = "timeline";

$(function(){
$("#dataset-switcher").change(function(){
// These values are populated from app settings
let defaultLat = undefined;
let defaultLng = undefined;
let zoomLevel = undefined;

// Constants
const minLatitude = -180;
const minLongitude = -180;
const GPS_PRECISION = 4;
const DEPTH_PRECISION = 1;
const PLOT_X_DEFAULT = "roi_x";
const PLOT_Y_DEFAULT = "roi_y";
const MAX_SELECTABLE_IMAGES = 25;

let _binFilterMode = "timeline";

function initDashboard(appSettings) {
defaultLat = appSettings.default_latitude;
defaultLng = appSettings.default_longitude;
zoomLevel = appSettings.default_zoom_level;

$('[data-toggle="tooltip"]').tooltip();

$('.navbar-toggler').on('click', function () {
$('.animated-burger').toggleClass('open');
});

// hide navbar after a bit of scrolling
$(window).scroll(function (e) {
var scroll = $(window).scrollTop();
if (scroll >= 150) {
$('.navbar').addClass("navbar-hide");
} else {
$('.navbar').removeClass("navbar-hide");
}
});

$("#dataset-switcher").change(function () {
location.href = "/timeline?dataset=" + $(this).val();
});

$("#go-to-bin").click(function(){
$("#go-to-bin").click(function () {
goToBin($("#go-to-bid-pid").val());
});

$("#go-to-bid-pid").keypress(function(e){
$("#go-to-bid-pid").keypress(function (e) {
if (e.which == 13 /* Enter */) {
goToBin($(this).val());
}
Expand All @@ -33,7 +56,7 @@ $(function(){
$('[data-toggle="popover"]').popover('hide');
}
});
})
}

function isKnownLocation(lat, lng) {
return parseFloat(lat) >= minLatitude && parseFloat(lng) >= minLongitude;
Expand Down Expand Up @@ -339,17 +362,6 @@ function changeImage(img, src, blobImg, outlineImg){
});
}

/* Deprecated */
/*
function buildColorArray(dataPoints, index) {
var colors = $.map(dataPoints, function(){ return "#1f77b4"; });
if (index >= 0 && index < dataPoints.length)
colors[index] = "#bb0000";

return colors;
}
*/

function highlightSelectedBinByDate() {
if (_binTimestamp == null)
return;
Expand Down Expand Up @@ -566,6 +578,7 @@ function isFilteringUsed() {
if (_sampleType != "" && _sampleType != "null")
return true;
}

$(function () {
$('#dataset-popover').popover({
container: 'body',
Expand Down
22 changes: 22 additions & 0 deletions ifcbdb/dashboard/migrations/0037_appsettings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 4.2.14 on 2024-11-01 19:46

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dashboard', '0036_datadirectory_unique_path'),
]

operations = [
migrations.CreateModel(
name='AppSettings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('default_latitude', models.FloatField(default=41.5507768)),
('default_longitude', models.FloatField(default=-70.6593102)),
('default_zoom_level', models.IntegerField(default=6)),
],
),
]
12 changes: 12 additions & 0 deletions ifcbdb/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
FILL_VALUE = -9999999
SRID = 4326

# The default latitude and longitude reference original values that were set prior to the ability to customize the
# default values. The location is, roughly, Woods Hole Oceanographic Institution
DEFAULT_LATITUDE = 41.5507768
DEFAULT_LONGITUDE = -70.6593102
DEFAULT_ZOOM_LEVEL = 6

def do_nothing(*args, **kw):
pass

Expand Down Expand Up @@ -905,3 +911,9 @@ def __str__(self):
else:
return self.content

# settings

class AppSettings(models.Model):
default_latitude = models.FloatField(blank=False, null=False, default=DEFAULT_LATITUDE)
default_longitude = models.FloatField(blank=False, null=False, default=DEFAULT_LONGITUDE)
default_zoom_level = models.IntegerField(blank=False, null=False, default=DEFAULT_ZOOM_LEVEL)
16 changes: 15 additions & 1 deletion ifcbdb/dashboard/templatetags/nav.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import json
from django import template
from django.shortcuts import reverse
from django.utils.html import mark_safe

from dashboard.models import Dataset, Instrument, Tag, bin_query
from dashboard.models import Dataset, Instrument, Tag, bin_query, AppSettings, \
DEFAULT_LATITUDE, DEFAULT_LONGITUDE, DEFAULT_ZOOM_LEVEL

register = template.Library()

@register.simple_tag(takes_context=False)
def app_settings():
app_settings = AppSettings.objects.first()

settings = json.dumps({
"default_latitude": app_settings.default_latitude if app_settings else DEFAULT_LATITUDE,
"default_longitude": app_settings.default_longitude if app_settings else DEFAULT_LONGITUDE,
"default_zoom_level": app_settings.default_zoom_level if app_settings else DEFAULT_ZOOM_LEVEL,
})

return mark_safe(settings)

@register.inclusion_tag('dashboard/_dataset_switcher.html')
def dataset_switcher():
Expand Down
58 changes: 57 additions & 1 deletion ifcbdb/secure/forms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import re, os
from django import forms

from dashboard.models import Dataset, Instrument, DataDirectory
from dashboard.models import Dataset, Instrument, DataDirectory, AppSettings, \
DEFAULT_LATITUDE, DEFAULT_LONGITUDE, DEFAULT_ZOOM_LEVEL


MIN_LATITUDE = -90
MAX_LATITUDE = 90
MIN_LONGITUDE = -180
MAX_LONGITUDE = 180

# Leaflet does not limit the zoom level, but appears to start having issues with very large numbers. Here, it's limited
# to 13 because that appears to be the limit of the basemap that's being used. Any higher than that, and it produces
# "map not available" errors
MIN_ZOOM_LEVEL = 0
MAX_ZOOM_LEVEL = 13


class DatasetForm(forms.ModelForm):
Expand Down Expand Up @@ -168,3 +181,46 @@ class Meta:

class MetadataUploadForm(forms.Form):
file = forms.FileField(label="Choose file", widget=forms.ClearableFileInput(attrs={"class": "custom-file-input"}))


class AppSettingsForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.fields["default_latitude"].required = True
self.fields["default_longitude"].required = True
self.fields["default_zoom_level"].required = True

def clean_default_latitude(self):
data = self.cleaned_data.get("default_latitude")

if data < MIN_LATITUDE or data > MAX_LATITUDE:
raise forms.ValidationError(f"Default Latitude must be between {MIN_LATITUDE} and {MAX_LATITUDE}")

return data

def clean_default_longitude(self):
data = self.cleaned_data.get("default_longitude")

if data < MIN_LONGITUDE or data > MAX_LONGITUDE:
raise forms.ValidationError(f"Default Longitude must be between {MIN_LONGITUDE} and {MAX_LONGITUDE}")

return data

def clean_default_zoom_level(self):
data = self.cleaned_data.get("default_zoom_level")

if data < MIN_ZOOM_LEVEL or data > MAX_ZOOM_LEVEL:
raise forms.ValidationError(f"Default Zoom Level must be between {MIN_ZOOM_LEVEL} and {MAX_ZOOM_LEVEL}")

return data

class Meta:
model = AppSettings
fields = ["default_latitude", "default_longitude", "default_zoom_level", ]
widgets = {
"default_latitude": forms.TextInput(attrs={"class": "form-control form-control-sm"}),
"default_longitude": forms.TextInput(attrs={"class": "form-control form-control-sm"}),
"default_zoom_level": forms.TextInput(attrs={"class": "form-control form-control-sm"}),
}
1 change: 1 addition & 0 deletions ifcbdb/secure/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
path('upload-metadata', views.upload_metadata, name='upload-metadata'),
path('directory-management/<int:dataset_id>', views.directory_management, name='directory-management'),
path('edit-directory/<int:dataset_id>/<int:id>', views.edit_directory, name='edit-directory'),
path('app-settings', views.app_settings, name='app-settings'),

# Paths used for AJAX requests specifically for returning data formatted for DataTables
path('api/dt/datasets', views.dt_datasets, name='datasets_dt'),
Expand Down
Loading