diff --git a/DESCRIPTION b/DESCRIPTION index 5b9a2a3..5447ef4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -12,5 +12,8 @@ RoxygenNote: 7.3.3 Imports: AVSDevR.DBClient, dplyr, + htmltools, magrittr, - R6 + plotly, + R6, + shiny diff --git a/NAMESPACE b/NAMESPACE index 8eee395..e733b4b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,7 +7,11 @@ export(MNR.DB.Applications) export(MNR.DB.Geometries) export(MNR.DB.Organisations) export(MNR.DB.Users) +export(MNR.GeoPlot) +export(resourcePrefix) +export(use_mnr_ui) import(dplyr) +import(plotly) importFrom(AVSDevR.DBClient,DBClient) importFrom(AVSDevR.DBClient,DBConnection) importFrom(R6,R6Class) diff --git a/R/aaa.R b/R/aaa.R index 6c859b6..5b223af 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -3,4 +3,5 @@ #' @importFrom AVSDevR.DBClient DBClient #' @importFrom R6 R6Class #' @import dplyr +#' @import plotly NULL diff --git a/R/db_organisations.R b/R/db_organisations.R index eef039b..99558b9 100644 --- a/R/db_organisations.R +++ b/R/db_organisations.R @@ -6,6 +6,7 @@ MNR.DB.Organisations <- R6::R6Class( public = list( getOrganisation = function(org_id, collect = TRUE) { private$db_client$table("organisations") %>% + dplyr::filter(flag_approved == TRUE) %>% dplyr::filter(id == !!org_id) %>% private$db_client$collectOrReturn() }, @@ -55,9 +56,37 @@ MNR.DB.Organisations <- R6::R6Class( } }, - getUsersFromOrg = function(org_name = "", org_id = -1, collect = TRUE) { + getOrganisationMembers = function( + org_name = "", org_id = -1, collect = TRUE + ) { private$db_client$table("users") %>% - dplyr::filter(flag_enabled == TRUE, flag_verified == TRUE) %>% + dplyr::filter(flag_enabled == TRUE) %>% + dplyr::filter(flag_verified == TRUE) %>% + dplyr::mutate(known_as = paste(first_name, last_name)) %>% + dplyr::left_join( + private$db_client$table("organisation_members") %>% + dplyr::filter(flag_approved == TRUE) %>% + dplyr::select(user_id, organisation_id), + by = c(id = "user_id") + ) %>% + dplyr::inner_join( + private$db_client$table("organisations") %>% + dplyr::filter(flag_approved == TRUE) %>% + dplyr::filter((id == !!org_id) | (name == !!org_name)) %>% + dplyr::select(id), + by = c(organisation_id = "id") + ) %>% + dplyr::select(-organisation_id) %>% + private$db_client$collectOrReturn() + }, + + #' @depricated + getUsersFromOrg = function(org_name = "", org_id = -1, collect = TRUE) { + .Deprecated(new = "getOrganisationMembers") + + private$db_client$table("users") %>% + dplyr::filter(flag_enabled == TRUE) %>% + dplyr::filter(flag_verified == TRUE) %>% dplyr::mutate(known_as = paste(first_name, last_name)) %>% dplyr::left_join( private$db_client$table("organisation_members") %>% @@ -76,6 +105,7 @@ MNR.DB.Organisations <- R6::R6Class( isAgent = function(user_id) { private$db_client$table("organisation_members") %>% + dplyr::filter(flag_approved == TRUE) %>% dplyr::filter(user_id == !!user_id) %>% dplyr::inner_join( private$db_client$table("organisation_agents") %>% @@ -87,9 +117,54 @@ MNR.DB.Organisations <- R6::R6Class( magrittr::is_greater_than(0) }, + getOrganisationAgents = function(org_id, as_int = FALSE, collect = TRUE) { + qry <- private$db_client$table("organisation_agents") %>% + dplyr::filter(flag_approved == TRUE) %>% + dplyr::filter(organisation_id == !!org_id) %>% + dplyr::select(id = agent_id) %>% + dplyr::distinct() %>% + dplyr::left_join( + private$db_client$table("organisations") %>% + dplyr::filter(flag_approved == TRUE), + by = "id" + ) + + if (as_int) { + qry %>% + dplyr::pull(id) + } else { + qry %>% + private$db_client$collectOrReturn() + } + }, + + getAgentRecipients = function(agent_id, as_int = FALSE, collect = TRUE) { + qry <- private$db_client$table("organisation_agents") %>% + dplyr::filter(flag_approved == TRUE) %>% + dplyr::filter(agent_id == !!agent_id) %>% + dplyr::select(id = organisation_id) %>% + dplyr::distinct() %>% + dplyr::left_join( + private$db_client$table("organisations") %>% + dplyr::filter(flag_approved == TRUE), + by = "id" + ) + + if (as_int) { + qry %>% + dplyr::pull(id) + } else { + qry %>% + private$db_client$collectOrReturn() + } + }, + + #' @depricated getAgentForOrganisations = function( org_ids, as_int = FALSE, name_only = TRUE, collect = TRUE ) { + .Deprecated(new = "getOrganisationAgents") + qry <- private$db_client$table("organisations") %>% dplyr::filter(flag_approved == TRUE) %>% dplyr::inner_join( @@ -113,9 +188,12 @@ MNR.DB.Organisations <- R6::R6Class( } }, + #' @depricated getRecipientOrganisations = function( org_id, as_int = FALSE, name_only = TRUE, collect = TRUE ) { + .Deprecated(new = "getAgentRecipients") + qry <- private$db_client$table("organisations") %>% dplyr::filter(flag_approved == TRUE) %>% dplyr::inner_join( @@ -139,16 +217,19 @@ MNR.DB.Organisations <- R6::R6Class( } }, + #' @depricated getUserOrgs = function( user_id, as_int = TRUE, name_only = TRUE, collect = TRUE ) { + .Deprecated(new = "getUserOrganisation") + qry <- private$db_client$table("organisations") %>% + dplyr::filter(flag_approved == TRUE) %>% dplyr::left_join( private$db_client$table("organisation_members") %>% dplyr::select(user_id, organisation_id), by = c(id = "organisation_id") ) %>% - dplyr::filter(flag_approved == TRUE) %>% dplyr::filter(user_id == !!user_id) if (as_int) { @@ -167,12 +248,13 @@ MNR.DB.Organisations <- R6::R6Class( user_id, as_int = TRUE, name_only = TRUE, collect = TRUE ) { qry <- private$db_client$table("organisations") %>% + dplyr::filter(flag_approved == TRUE) %>% dplyr::left_join( private$db_client$table("organisation_members") %>% + dplyr::filter(flag_approved == TRUE) %>% dplyr::select(user_id, organisation_id), by = c(id = "organisation_id") ) %>% - dplyr::filter(flag_approved == TRUE) %>% dplyr::filter(user_id == !!user_id) %>% dplyr::slice_min(user_id, n = 1) diff --git a/R/db_users.R b/R/db_users.R index fbba3c9..c2581f1 100644 --- a/R/db_users.R +++ b/R/db_users.R @@ -14,13 +14,13 @@ MNR.DB.Users <- R6::R6Class( }, getUser = function(user_id, collect = TRUE) { - db_uf$getUser(user_id, collect) + private$db_uf$getUser(user_id, collect) }, getUserName = function(user_id) { - db_uf$getUserName(user_id) + private$db_uf$getUserName(user_id) }, getUserRoles = function(user_id, collect = TRUE) { - db_uf$getUserRoles(user_id, collect) + private$db_uf$getUserRoles(user_id, collect) }, isApplicationsAdmin = function(user_id) { diff --git a/R/geoPlot.R b/R/geoPlot.R new file mode 100644 index 0000000..a2d5d36 --- /dev/null +++ b/R/geoPlot.R @@ -0,0 +1,382 @@ +#' @export +# nolint next: object_name_linter. R6Class +MNR.GeoPlot <- R6::R6Class( + "MNR.GeoPlot", + public = list( + initialize = function() { + private$bootGridLines() + }, + + bootLayers = function() { + private$boundaryIoM <- sf::st_read( + file.path( + system.file(package = "AVSDevR.MarineNoiseRegistry"), + "layers", + "20230411_IoM" + ), + quiet = TRUE + ) + private$boundaryMSFD <- sf::st_read( + file.path( + system.file(package = "AVSDevR.MarineNoiseRegistry"), + "layers", + "20250123_MSFD_BoundaryLine" + ), + quiet = TRUE + ) + private$boundaryUKCS <- sf::st_read( + file.path( + system.file(package = "AVSDevR.MarineNoiseRegistry"), + "layers", + "20230411_UKCSBoundary" + ), + quiet = TRUE + ) + private$boundaryUKTerritorial <- sf::st_read( + file.path( + system.file(package = "AVSDevR.MarineNoiseRegistry"), + "layers", + "20250123_UK_Territorial_Sea_Limit" + ), + quiet = TRUE + ) + }, + + bootQuadrants = function() { + old_opts <- options(sf_use_s2 = FALSE) + on.exit({ + options(old_opts) + }) + + private$quadrants <- sf::st_read( + file.path( + system.file(package = "AVSDevR.MarineNoiseRegistry"), + "layers", + "20230411_OGBQuadrants" + ), + quiet = TRUE + ) + private$quadrant_annotations <- suppressWarnings({ + private$quadrants %>% + dplyr::select(quadrnt) %>% + sf::st_centroid() + }) + }, + + bootConservationAreas = function(db_client) { + old_opts <- options(sf_use_s2 = FALSE) + on.exit({ + options(old_opts) + }) + + private$conservation_areas <- db_client$table("conservation_areas") %>% + dplyr::select(name, season, geom) %>% + db_client$collectGeometries() %>% + sf::st_sf() %>% + sf::st_cast("MULTIPOLYGON") + + colour_palette <- private$conservation_areas %>% + dplyr::mutate( + colour = sapply(season, function(s) { + switch( + s, + Winter = "rgba(30,203,225,0.3)", + Summer = "rgba(225,52,30,0.3)", + "rgba(235,175,20,0.3)" + ) + }) + ) %>% + dplyr::pull(colour) + + private$conservation_area_colours <- private$conservation_areas %>% + sf::st_coordinates() %>% + tibble::as_tibble() %>% + dplyr::mutate(colour = colour_palette[L3]) %>% + dplyr::pull(colour) + }, + + makeBasePlot = function( + ..., with_jncc_layers = TRUE, with_quadrants = FALSE, + with_conservation_areas = FALSE + ) { + do.call(plotly::plot_ly, list(...)) %>% + private$addGridLines() %>% + private$addQuadrants(with_quadrants) %>% + private$addJNCCLayers(with_jncc_layers) %>% + private$addConservationAreas(with_conservation_areas) %>% + plotly::layout( + mapbox = list(style = "carto-positron"), + legend = list( + groupclick = "toggleitem", + itemdoubleclick = FALSE + ), + xaxis = list( + title = list(text = "Longitude", font = list(size = 18)), + visible = FALSE, + # Grid: + showgrid = TRUE, + gridcolor = "#BEBEBE", + # Line: + showline = TRUE, + linewidth = 2, + linecolor = "#7F7F7F", + mirror = TRUE, + zeroline = FALSE, + # Ticks: + showticklabels = TRUE, + tickmode = "linear", + tick0 = 0, + dtick = 5, + ticksuffix = " ° W" + ), + yaxis = list( + title = list(text = "Latitude", font = list(size = 18)), + visible = FALSE, + # Grid: + showgrid = TRUE, + gridcolor = "#BEBEBE", + # Line: + showline = TRUE, + linewidth = 2, + linecolor = "#7F7F7F", + mirror = TRUE, + zeroline = FALSE, + # Ticks: + showticklabels = TRUE, + tickmode = "linear", + tick0 = 0, + dtick = 5, + ticksuffix = " ° N" + ) + ) + }, + + boundMap = function( + p, c_lat = 56, c_lon = -5.5, zoom = 3.5, xmin = -25, ymin = 45, xmax = 5, + ymax = 65 + ) { + p %>% + plotly::layout( + mapbox = list( + zoom = zoom, + center = list(lat = c_lat, lon = c_lon), + `_fitBounds` = list( + bounds = list(list(xmin, ymin), list(xmax, ymax)), + options = list() + ) + ) + ) + } + ), + private = list( + major_lines = NULL, + minor_lines = NULL, + zero_lines = NULL, + + boundaryIoM = NULL, + boundaryMSFD = NULL, + boundaryUKCS = NULL, + boundaryUKTerritorial = NULL, + + quadrants = NULL, + quadrant_annotations = NULL, + + conservation_areas = NULL, + conservation_area_colours = NULL, + + + bootGridLines = function() { + old_opts <- options(sf_use_s2 = FALSE) + on.exit({ + options(old_opts) + }) + + points <- tibble::tibble() + for (lat in seq(-90, +90, 5)) { + points <- points %>% + dplyr::bind_rows( + tibble::tibble( + grp = nrow(points) + 1, + lat = lat, + lon = c(-180, 180), + is_major = (lat %% 10) == 0 + ) + ) + } + for (lon in seq(-180, +175, 5)) { + points <- points %>% + dplyr::bind_rows( + tibble::tibble( + grp = nrow(points) + 1, + lat = c(-90, 90), + lon = lon, + is_major = (lat %% 10) == 0 + ) + ) + } + suppressMessages({ + private$major_lines <- points %>% + dplyr::filter(is_major) %>% + sf::st_as_sf(coords = c("lon", "lat"), crs = 4326) %>% + dplyr::group_by(grp) %>% + dplyr::summarise() %>% + sf::st_cast("LINESTRING") + private$minor_lines <- points %>% + dplyr::filter(!is_major) %>% + sf::st_as_sf(coords = c("lon", "lat"), crs = 4326) %>% + dplyr::group_by(grp) %>% + dplyr::summarise() %>% + sf::st_cast("LINESTRING") + private$zero_lines <- points %>% + dplyr::filter((lat == 0) | (lon == 0)) %>% + sf::st_as_sf(coords = c("lon", "lat"), crs = 4326) %>% + dplyr::group_by(grp) %>% + dplyr::summarise() %>% + sf::st_cast("LINESTRING") + }) + }, + + addGridLines = function(p) { + p %>% + plotly::add_sf( + type = "scattermapbox", + data = private$minor_lines, + name = "minor_grid_lines", + line = list(width = 1), + color = I("#6161ff20"), + showlegend = FALSE, + hoverinfo = I("skip") + ) %>% + plotly::add_sf( + type = "scattermapbox", + data = private$major_lines, + name = "major_grid_lines", + line = list(width = 2), + color = I("#6161ff30"), + showlegend = FALSE, + hoverinfo = I("skip") + ) %>% + plotly::add_sf( + type = "scattermapbox", + data = private$zero_lines, + name = "zero_grid_lines", + line = list(width = 2), + color = I("#3131ff40"), + showlegend = FALSE, + hoverinfo = I("skip") + ) + }, + + addJNCCLayers = function(p, with_jncc_layers) { + if (length(with_jncc_layers) == 0 || !with_jncc_layers) { + return(p) + } + if (is.null(private$boundaryIoM)) { + rlang::abort( + "JNCC layers have not been loaded. Call bootLayers first!" + ) + } + p %>% + plotly::add_sf( + type = "scattermapbox", + data = dplyr::bind_rows( + sf::st_cast(private$boundaryUKCS, "LINESTRING", warn = FALSE), + sf::st_cast(private$boundaryIoM, "LINESTRING", warn = FALSE), + sf::st_cast(private$boundaryMSFD, "LINESTRING", warn = FALSE) + ), + fillcolor = "#96005b00", + line = list(width = 1.5), + color = I("#96005b"), + name = "UKMS Sub-region Borders", + legendgrouptitle = list(text = "Regional Boundaries"), + legendgroup = "regional_boundaries", + legendrank = 850, + hoverinfo = I("skip") + ) %>% + plotly::add_sf( + type = "scattermapbox", + data = private$boundaryUKCS, + fillcolor = "#00000000", + line = list(width = 1.5), + color = I("#000000"), + name = "UK Continental Shelf", + legendgrouptitle = list(text = "Regional Boundaries"), + legendgroup = "regional_boundaries", + legendrank = 800, + hoverinfo = I("skip") + ) %>% + plotly::add_sf( + type = "scattermapbox", + data = private$boundaryUKTerritorial, + fillcolor = "#008ac100", + line = list(width = 1), + color = I("#008ac1"), + name = "UK Territorial Sea Limit", + legendgrouptitle = list(text = "Regional Boundaries"), + legendgroup = "regional_boundaries", + legendrank = 800, + hoverinfo = I("skip") + ) + }, + + addQuadrants = function(p, with_quadrants) { + if (length(with_quadrants) == 0 || !with_quadrants) { + return(p) + } + if (is.null(private$quadrants)) { + rlang::abort( + "Quadrants have not been loaded. Call bootQuadrants first!" + ) + } + p %>% + plotly::add_sf( + type = "scattermapbox", + data = private$quadrants, + fillcolor = "rgba(0,0,0,0)", + line = list(width = 1), + color = I("#bebebe"), + name = "Oil & Gas Quadrants", + legendgrouptitle = list(text = "Oil & Gas"), + legendgroup = "oil_and_gas", + legendrank = 900, + hoverinfo = I("none") + ) %>% + plotly::add_sf( + type = "scattermapbox", + data = private$quadrant_annotations, + color = I("#bebebe00"), + name = "Oil & Gas Quadrant Labels", + showlegend = FALSE, + text = ~quadrnt, + hoverinfo = I("text"), + hovertemplate = I("O&G Quadrant: %{text}") + ) + }, + + addConservationAreas = function(p, with_conservation_areas) { + if (length(with_conservation_areas) == 0 || !with_conservation_areas) { + return(p) + } + if (is.null(private$conservation_areas)) { + rlang::abort( + "Conservation Areas have not been loaded. \ + Call bootConservationAreas first!" + ) + } + p %>% + plotly::add_sf( + type = "scattermapbox", + data = private$conservation_areas, + fillcolor = private$conservation_area_colours, + line = list(width = 0), + color = I(private$conservation_area_colours), + name = ~paste0(name, " (", season, ")"), + legendgrouptitle = list( + text = "Special Areas of Conservation" + ), + legendgroup = "conservation_areas", + legendrank = 950 + ) + } + ) +) diff --git a/R/use_mnr_ui.R b/R/use_mnr_ui.R new file mode 100644 index 0000000..d7c0cd2 --- /dev/null +++ b/R/use_mnr_ui.R @@ -0,0 +1,36 @@ +#' @export +use_mnr_ui <- function() { + attachResourcePaths() + htmltools::tags$head( + htmltools::singleton( + htmltools::HTML(paste0( + "" + )) + ), + htmltools::singleton( + htmltools::HTML(paste0( + "" + )) + ), + htmltools::singleton( + htmltools::HTML(paste0( + "" + )) + ) + ) +} + +#' @export +resourcePrefix <- function() { + paste0("avsdev_mnr_", utils::packageVersion("AVSDevR.MarineNoiseRegistry")) +} + +attachResourcePaths <- function() { + if (!(resourcePrefix() %in% names(shiny::resourcePaths()))) { + shiny::addResourcePath( + resourcePrefix(), + system.file("www", package = "AVSDevR.MarineNoiseRegistry") + ) + } +} diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 0000000..c7df506 --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,3 @@ +.onAttach <- function(libname, pkgname) { + attachResourcePaths() +} diff --git a/inst/layers/20230411_IoM/20230411_IoM_WGS84.dbf b/inst/layers/20230411_IoM/20230411_IoM_WGS84.dbf new file mode 100644 index 0000000..689391f Binary files /dev/null and b/inst/layers/20230411_IoM/20230411_IoM_WGS84.dbf differ diff --git a/inst/layers/20230411_IoM/20230411_IoM_WGS84.prj b/inst/layers/20230411_IoM/20230411_IoM_WGS84.prj new file mode 100644 index 0000000..f45cbad --- /dev/null +++ b/inst/layers/20230411_IoM/20230411_IoM_WGS84.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/inst/layers/20230411_IoM/20230411_IoM_WGS84.shp b/inst/layers/20230411_IoM/20230411_IoM_WGS84.shp new file mode 100644 index 0000000..1c94f6d Binary files /dev/null and b/inst/layers/20230411_IoM/20230411_IoM_WGS84.shp differ diff --git a/inst/layers/20230411_IoM/20230411_IoM_WGS84.shx b/inst/layers/20230411_IoM/20230411_IoM_WGS84.shx new file mode 100644 index 0000000..8917335 Binary files /dev/null and b/inst/layers/20230411_IoM/20230411_IoM_WGS84.shx differ diff --git a/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.dbf b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.dbf new file mode 100644 index 0000000..c751c1f Binary files /dev/null and b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.dbf differ diff --git a/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.prj b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.prj new file mode 100644 index 0000000..79a08dc --- /dev/null +++ b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],METADATA["World",-180.0,-90.0,180.0,90.0,0.0,0.0174532925199433,0.0,1262]] \ No newline at end of file diff --git a/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.shp b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.shp new file mode 100644 index 0000000..7930261 Binary files /dev/null and b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.shp differ diff --git a/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.shx b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.shx new file mode 100644 index 0000000..2eabbc7 Binary files /dev/null and b/inst/layers/20230411_OGBQuadrants/20230411_OGBQ_WGS84.shx differ diff --git a/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.dbf b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.dbf new file mode 100644 index 0000000..689391f Binary files /dev/null and b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.dbf differ diff --git a/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.prj b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.prj new file mode 100644 index 0000000..f45cbad --- /dev/null +++ b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.shp b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.shp new file mode 100644 index 0000000..0803e90 Binary files /dev/null and b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.shp differ diff --git a/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.shx b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.shx new file mode 100644 index 0000000..253286c Binary files /dev/null and b/inst/layers/20230411_UKCSBoundary/20230411_UKCSBoundary_WGS84.shx differ diff --git a/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.dbf b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.dbf new file mode 100644 index 0000000..6b256a1 Binary files /dev/null and b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.dbf differ diff --git a/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.prj b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.prj new file mode 100644 index 0000000..f45cbad --- /dev/null +++ b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.shp b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.shp new file mode 100644 index 0000000..2e29c88 Binary files /dev/null and b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.shp differ diff --git a/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.shx b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.shx new file mode 100644 index 0000000..f1fee68 Binary files /dev/null and b/inst/layers/20250123_MSFD_BoundaryLine/20170202_MSFD_BL_WGS84.shx differ diff --git a/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.dbf b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.dbf new file mode 100644 index 0000000..2a96c37 Binary files /dev/null and b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.dbf differ diff --git a/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.prj b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.prj new file mode 100644 index 0000000..f45cbad --- /dev/null +++ b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.shp b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.shp new file mode 100644 index 0000000..1f08be7 Binary files /dev/null and b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.shp differ diff --git a/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.shx b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.shx new file mode 100644 index 0000000..64187f7 Binary files /dev/null and b/inst/layers/20250123_UK_Territorial_Sea_Limit/20250123_UK_TSL_WGS84.shx differ diff --git a/inst/www/css/mnr-shiny.css b/inst/www/css/mnr-shiny.css new file mode 100644 index 0000000..8199d90 --- /dev/null +++ b/inst/www/css/mnr-shiny.css @@ -0,0 +1,8 @@ +div.selectize-input > div.item { + line-height: 41px; +} + +input[type="text"], input[type="password"], input[type="number"] { + font-size: 12pt !important; + height: 41px !important; +} \ No newline at end of file diff --git a/inst/www/css/mnr.css b/inst/www/css/mnr.css new file mode 100644 index 0000000..d528843 --- /dev/null +++ b/inst/www/css/mnr.css @@ -0,0 +1,567 @@ +/* JNCC preferred font */ +*, body, h1, h2, h3, h4, h5, h6, th { + font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +body, th { + /* font-size: 14.25pt; */ + font-size: 12pt; +} + +h1 { + font-size: 31.5pt; +} +h2 { + font-size: 22.5pt; +} +h3 { + font-size: 21pt; +} +h4 { + font-size: 19pt; +} +h5 { + font-size: 15pt; +} +h6 { + font-size: 12pt; +} + +.tablesorter-bootstrap tfoot td, .tablesorter-bootstrap tfoot th, .tablesorter-bootstrap thead td, .tablesorter-bootstrap thead th { + font-size: 12pt !important; +} + +/* + * Skin: Green - JNCC + * ----------- + */ +.skin-green .main-header .navbar { + background-color: #3f9c35 !important; +} +.skin-green .main-header .navbar .sidebar-toggle:hover { + background-color: #36822c !important; +} +@media (max-width: 767px) { + .skin-green .main-header .navbar .dropdown-menu li a:hover { + background: #36822c !important; + } +} +.skin-green .main-header .logo { + background-color: #36822c !important; +} +.skin-green .main-header .logo:hover { + background-color: #337a2a !important; +} +.skin-green .main-header li.user-header { + background-color: #3f9c35 !important; +} +.skin-green .sidebar-menu > li.active > a { + border-left-color: #3f9c35 !important; +} + +.widget-user-header.bg-green { + background-color: #3f9c35 !important; +} + +.bg-success, .alert-success, .bg-green { + background-color: #3f9c35 !important; +} + +.box-success { + border: 1px solid #3f9c35 !important; +} + +.box-success > .box-header { + background-color: #3f9c35 !important; +} + +.btn-success { + background-color: #3f9c35 !important; +} +.btn-success:hover { + background-color: #008d4c !important; +} +.box.box-solid > .box-header .btn:hover, .box.box-solid > .box-header a:hover { + background: rgba(0, 0, 0, 0.1) !important; +} + + +.table.dataTable tbody td.active, +.table.dataTable tbody tr.active td { + background-color: #3f9c35 !important; +} + +table.dataTable tbody tr.selected > * { + box-shadow: inset 0 0 0 9999px #3f9c35 !important; +} + +table.dataTable.hover tbody tr.selected:hover > *, +table.dataTable.display tbody tr.selected:hover > * { + box-shadow: inset 0 0 0 9999px #44a939 !important; +} + +/* Cookie control banner */ +.ccc-notify-text { + margin-top: 7em; + margin-bottom: 7em; + padding-right: 2em; +} + + +/* AdminLTE overrides - Including for accessibility*/ +.callout.callout-warning, .callout.callout-info, .alert-warning, .alert-info { + font-size: 18pt; +} +.callout.callout-success, .alert-success { + font-size: 18pt; + /* background-color: #36822c !important; */ +} +.callout.callout-danger, .alert-danger, .alert-error { + background-color: #DA3A25 !important; +} + +.alert .close { + font-size: 30pt; + top: -15px; +} + +.main-header { + position: fixed; + top: 0; + width: 100%; +} +.main-header .logo { + font-size: 15pt; + width: 270px; +} +@media (max-width: 767px) { + .main-header .logo, .main-header .navbar { + width: 100%; + } +} +.main-header .navbar { + margin-left: 270px; +} +@media (max-width: 767px) { + .main-header .navbar { + margin-left: 0px; + } +} +.main-sidebar { + position: fixed; + top: 0; + width: 270px; +} +@media (max-width: 767px) { + .main-sidebar { + -webkit-transform: translate(-270px, 0); + -ms-transform: translate(-270px, 0); + -o-transform: translate(-270px, 0); + transform: translate(-270px, 0); + } +} +.main-header .sidebar-toggle { + line-height: 20px; +} +.main-sidebar .user-panel .info p { + white-space: break-spaces; +} +.sidebar-menu { + /* height: calc(100vh - 125px); */ + position: fixed; + width: 270px; + overflow-y: scroll; + top: 125px; + bottom: 0; + height: auto; + -webkit-transition: -webkit-transform 0.3s ease-in-out, width 0.3s ease-in-out; + -moz-transition: -moz-transform 0.3s ease-in-out, width 0.3s ease-in-out; + -o-transition: -o-transform 0.3s ease-in-out, width 0.3s ease-in-out; + transition: transform 0.3s ease-in-out, width 0.3s ease-in-out; +} +.sidebar-menu:hover { + overflow-y: scroll; +} +.sidebar-mini.sidebar-collapse .sidebar-menu { + width: 50px; + -webkit-transition: -webkit-transform 0.3s ease-in-out, width 0.3s ease-in-out; + -moz-transition: -moz-transform 0.3s ease-in-out, width 0.3s ease-in-out; + -o-transition: -o-transform 0.3s ease-in-out, width 0.3s ease-in-out; + transition: transform 0.3s ease-in-out, width 0.3s ease-in-out; +} +@media (max-width: 767px) { + .sidebar-menu { + top: 175px; + } +} + +@media (max-width: 767px) { + .sidebar-open .content-wrapper, .sidebar-open .main-footer { + -webkit-transform: translate(270px, 0); + -ms-transform: translate(270px, 0); + -o-transform: translate(270px, 0); + transform: translate(270px, 0); + } +} +.content-header h1 { + font-size: 30pt; +} +.content-wrapper { + margin-top: 50px; +} +@media (max-width: 767px) { + .content-wrapper { + margin-top: 100px; + } +} +.content-wrapper, .main-footer { + margin-left: 270px; +} +@media (max-width: 767px) { + .content-wrapper, .main-footer { + margin-left: 0; + } +} + +.widget-user-desc a { + font-size: 14pt; + color: #FFFFFF; + font-weight: bold; +} +.widget-user-desc a:hover { + color: #BBBBFF; +} + +.widget-user-2 .widget-user-username { + font-weight: bolder; +} + +/* AdminLTE extensions */ +.widget-user-3 .widget-user-header { + padding: 20px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.widget-user-3 h1 { + padding: 0px; + margin: 0px; + font-size: 18pt; +} + +.login-box-footer { + margin-top: 20px; +} + +/* UF extensions */ +.page-description { + font-size: 14pt; + padding-top: 4px; + color: #6D6D6D; +} + + + +/* Navbar tweaks */ +.landing-nav > .container{ + display: flex; +} +.navbar-spacer { + display: inline-block; + flex-grow: 1; + padding-top: 15px; + padding-bottom: 15px; + line-height: 20px; + color: #ffffff; + font-weight: bolder; + z-index: 900; +} +.landing-nav .collapse { + float: right; +} +.landing-nav .navbar-spacer { + display: none; +} +.landing-nav > .container > .navbar-spacer { + display: inline-block; +} +@media (max-width: 767px) { + .landing-nav > .container{ + display: inherit; + } + .landing-nav .collapse { + float: none; + } + .landing-nav .navbar-spacer { + display: inline-block; + } + .landing-nav > .container > .navbar-spacer { + display: none; + } +} + +.landing-nav > .container{ + display: flex; +} +.navbar-beta { + display: inline-block; + flex-grow: 1; + padding-top: 15px; + padding-bottom: 15px; + line-height: 20px; + color: #ffffff; + font-weight: bolder; + z-index: 900; +} +.navbar-brand .navbar-beta { + font-size: 18pt; + font-weight: normal; +} +.navbar-beta a { + color: #ffffff; +} +.landing-nav .collapse { + float: right; +} +.landing-nav.navbar-beta { + font-size: 18pt; + display: none; +} +.landing-nav > .container > .navbar-beta { + display: inline-block; +} +@media (max-width: 767px) { + .landing-nav > .container { + display: inherit; + } + .landing-nav .collapse { + float: none; + } + .landing-nav.navbar-beta { + display: inline-block; + } + .navbar-brand .navbar-beta { + display: none; + } + .landing-nav > .container > .navbar-beta { + display: none; + } +} + +@media (min-width: 900px) { + .public-app-frame { + width: 90vw; + } +} +@media (max-width: 900px) { + .public-app-frame { + width: 100vw; + } +} + +/* Cookies table */ +.table-cookies { + border: 1px solid #888888 !important; + max-width: 80%; + margin-left: auto; + margin-right: auto; +} +.table-cookies th, .table-cookies td { + border: 1px solid #888888 !important; +} +.table-cookies thead th, .table-cookies thead td { + border-bottom-width: 2px !important; +} + +/* Good/Bad list styling */ +ul.good-list { + list-style-type: '\2713'; +} +ul.good-list li::marker { + color: #3c763d; + font-size: 24px; + line-height: 1.1; +} + +ul.bad-list { + list-style-type: '\2717'; +} +ul.bad-list li::marker { + color: #a94442; + font-size: 24px; + line-height: 1.1; +} + +/* */ +.anchor-location { + padding-top: 60px; + margin-top: -60px; +} +@media (max-width: 767px) { + .anchor-location { + padding-top: 120px; + margin-top: -120px; + } +} + +.switch { + top: 5px; +} + +.switch-label { + font-weight: normal; +} + +.modal-title { + font-size: 21pt; +} + +/* Accessibility overrides */ +a { + color: #286080; +} +p a, h1 a, h2 a, h3 a, h4 a, td a, .content li a, .message-banner a, .link { + color: #286080; + text-decoration: underline; +} +.dropdown-menu a { + color: #286080; + text-decoration: none !important; +} +a:hover, +a:active, +a:focus { + text-decoration: underline; + color: #72afd2; +} +.login-box-footer a { + text-decoration: underline; +} + +.btn { + font-size: 14pt; + /* + font-size: 12pt; + */ + font-weight: bold; +} + +.btn-info { + background-color: #009FC7; +} +.btn-warning { + background-color: #CB820B; +} + +.text-muted { + color: #6D6D6D; +} + +.login-box-body h2 { + font-size: 16pt; + font-weight: bold; +} + +input[type="text"], input[type="password"], input[type="number"] { + /* + font-size: 14pt !important; + height: 41px !important; + */ + font-size: 12pt !important; + height: 37px !important; +} + +.content-jump-link { + position: absolute; + left: -10000px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; +} +.content-jump-link:focus { + position: static; + width: auto; + height: auto; +} + +.box-header > i { + font-weight: bolder; + font-size: 18pt !important; +} + +.box-title { + font-weight: bolder; + font-size: 18pt !important; +} + +.breadcrumb li { + font-size: 14pt; + color: #6B6B6B; +} +.breadcrumb li:active { + font-size: 14pt; + color: #6B6B6B; +} +.breadcrumb > .active { + color: #6B6B6B; +} +.breadcrumb > li + li::before { + content: "/\00a0" !important; + color: #6B6B6B; +} + +.dropdown-menu { + font-size: 12pt; +} + +.navbar-brand { + font-size: 24pt; + line-height: 27.15px; + padding: 0px; +} +@media (max-width: 767px) { + .navbar-brand { + font-size: 20pt; + padding: 15px; + } +} +.navbar-brand a { + color: #FFFFFF; +} + +.navbar .nav > li > a { + font-size: 14pt; + font-weight: bold; +} + +.navbar .nav .dropdown-menu a { + font-size: 14pt; +} + +.sidebar-toggle { + font-size: 14pt; +} + +.login-logo a { + text-decoration: none; +} + +.skin-green .sidebar-menu > li.header { + color: #70979E; + font-weight: bolder; +} + +.uf-table-info { + color: #757575; +} + +.label { + padding-top: 0.5em; +} + +.btn-xs, .btn-group-xs > .btn { + padding: 1px 5px; +} + +.badge { + padding: 6px 9px 3px 9px; +} \ No newline at end of file diff --git a/inst/www/images/dolphin.svg b/inst/www/images/dolphin.svg new file mode 100644 index 0000000..cabee23 --- /dev/null +++ b/inst/www/images/dolphin.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/inst/www/js/frameHeight.js b/inst/www/js/frameHeight.js new file mode 100644 index 0000000..4e9f246 --- /dev/null +++ b/inst/www/js/frameHeight.js @@ -0,0 +1,7 @@ +window.addEventListener('message', function (event) { + if (event.data == "FrameHeight") { + var body = document.body, html = document.documentElement; + var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); + event.source.postMessage({ "FrameHeight": height }, "*"); + } +}); \ No newline at end of file