diff --git a/JM_notes b/JM_notes index 9b2d967..dd79266 100644 --- a/JM_notes +++ b/JM_notes @@ -4,25 +4,32 @@ WORK DONE #udpated POWO search to trap when you have no results, ugly but works #tweak map size to be same as left panel - -WORK NEEDED -HIGH -# User editable, moveable, delete point etc +#180 date line delt with for EOO, AOO not that useful +#Suggest Rating for EOO and AOO added +#Projection details stored for use later +#updated so that data progresses through to map +#updated so default fields are build etc as below # a. geocat_id = an internal ID which is populated on import (ie 1:nrow), new points will be added to this with a nrow + _leaflet_id (_leaflet_id is a unique number from leaflet) this should allow me to use this id to query all on map edits/delete. The reason for odd allocation is that leaflet assigns its own unique values and I can’t find a way to update (read only), there is a possibility of a clash if, I just increment ID and I may have get back out the leaflet ID as some point (not sure I do). I may simplify this later. #b. geo_status = a record of what has happen to a point ie “new point”, “moved point”, “deleted point” #c. geocat_use = Flag to false it point is deleted (could query on above, but I feel this is quicker)? #d. geocat_analysis = Flag for any queries (ie GBIF only etc), which we can switch on or off depending on reactive # elements (ie your switches for GBIF/user) -#GBIF query + +WORK NEEDED +HIGH +# User editable, moveable, delete point etc +# GBIF query MEDIUM -#Split polygon when over date line -# add suggestted IUCN ratings linked to EOO and AOO values -# return the projection used to the user? -#colour points by data_source +#report Projection +#report metadata (ie projection, GBIF query and citations etc) +# colour points by data_source +# TDWG maps from species name LOW # POWO search which returns nothing, need to inform user in the information box to the left (where steve reports missing values) # POWO search clear off old searches (maybe a button) # Map to reproduce over date line (ie not say map data not available) +# split aoo over dateline (not going to happen very often) +# allow data with long 180++ diff --git a/R/app.R b/R/app.R index 066bd9f..54849e5 100644 --- a/R/app.R +++ b/R/app.R @@ -4,7 +4,7 @@ geocatApp <- function(...) { ui <- fluidPage( shinyjs::useShinyjs(), - + tags$html(lang = "en"), # title @@ -80,7 +80,7 @@ geocatApp <- function(...) { column( 12, align = "centre", - shiny::helpText("Upload a CSV with a unique 'id' and 'longitude', 'latitude' fields "), + shiny::helpText("Upload a CSV with at least 'longitude', 'latitude' fields "), shiny::fileInput( "csv_in", NULL, @@ -152,9 +152,12 @@ geocatApp <- function(...) { ##### server ##### server <- function(input, output, session) { + #JM builds an empty df to populate later + ################################ values <- reactiveValues( analysis_data=empty_tbl_() ) + values$analysis_data <- buildspdf() observeEvent(input$reset, { session$reload() @@ -168,21 +171,27 @@ server <- function(input, output, session) { } else { shiny::validate("Invalid file; please upload a .csv file") } - - shiny::validate(check_fields_(data, c("longitude", "latitude", "id"))) + ########################################################### + #ID not needed any more + #shiny::validate(check_fields_(data, c("longitude", "latitude","id"))) shiny::validate(check_numeric_(data, c("longitude", "latitude"))) - - values$analysis_data <- - dplyr::bind_rows( - values$analysis_data, - data %>% + + csv_imported <- data %>% dplyr::select(longitude,latitude, id) %>% dplyr::filter(if_all(everything(), ~!is.na(.))) %>% dplyr::filter(longitude < 180, longitude > -180, latitude < 90, latitude > -90) %>% - dplyr::mutate(group="csv") + dplyr::mutate( + geocat_id=seq.int(nrow(values$analysis_data)), + geocat_source="csv import", + ) + + values$analysis_data <- + dplyr::bind_rows( + values$analysis_data, + csv_imported ) - + data }) @@ -210,7 +219,7 @@ server <- function(input, output, session) { leaflet::setView(lng = 0, lat = 0, - zoom = 2) %>% + zoom = 3) %>% leaflet.extras::addSearchOSM(options = leaflet.extras::searchOptions( autoCollapse = F, @@ -220,7 +229,28 @@ server <- function(input, output, session) { )) %>% leaflet::addScaleBar(position = "bottomright") %>% - + ###################################################### + #JM + #df <- values$analysis_data + leaflet.extras::addDrawToolbar(editOptions = editToolbarOptions(edit=TRUE), + targetGroup = 'mappoints', + circleMarkerOptions=FALSE, + rectangleOptions=FALSE, + circleOptions=FALSE, + polygonOptions=FALSE, + polylineOptions=FALSE) %>% + + leaflet::addCircleMarkers(data = values$analysis_data[values$analysis_data$geocat_use==TRUE,], + popup = "popup",#~thetext, + layerId = ~geocat_id, + group="mappoints", + radius = 7, + color="#FFFFFF", + stroke = T, + fillColor = "#FF0000", + fillOpacity = 1, + options = markerOptions(draggable = FALSE)) %>% + ##################################################### leaflet::addMeasure( position = "bottomleft", primaryLengthUnit = "meters", @@ -236,12 +266,6 @@ server <- function(input, output, session) { options = leaflet::providerTileOptions(noWrap = TRUE) ) %>% - leaflet::addProviderTiles( - provider = "Esri.WorldStreetMap", - group = "ESRI Open Street map", - options = leaflet::providerTileOptions(noWrap = TRUE) - ) %>% - leaflet::addProviderTiles( provider = "OpenStreetMap.Mapnik", group = "Open Street Map", @@ -258,33 +282,32 @@ server <- function(input, output, session) { baseGroups = c( "ESRI World Imagery", "Open Street Map", - "Open Topo Map", - "ESRI Open Street map" + "Open Topo Map" ), options = leaflet::layersControlOptions(collapsed = FALSE) ) }) - - output$csvValidation <- shiny::renderPrint({ + + shiny::observeEvent(input$leafmap_draw_new_feature, { + print("New Feature added") + }) + + output$validation <- shiny::renderPrint({ data <- csvpointsInput() if (! is.data.frame(data)) { data } msg <- c( - check_complete_(data, c("longitude", "latitude", "id")), - check_range_(data, "longitude", -180, 180), - check_range_(data, "latitude", -90, 90), + #check_complete_(data, c("longitude", "latitude", "id")), + #check_range_(data, "longitude", -180, 180), + #check_range_(data, "latitude", -90, 90), check_rounded_(data, "longitude"), - check_rounded_(data, "latitude"), - check_zeros_(data, "longitude"), - check_zeros_(data, "latitude") ) - if (! is.null(msg)) { msg } }) - + output$gbifValidation <- shiny::renderPrint({ data <- gbifPointsInput() if (nrow(data) == 0) { @@ -325,7 +348,9 @@ server <- function(input, output, session) { shiny::observeEvent(input$csv_in, { - df <- csvpointsInput() + df <- values$analysis_data + #needs cleaning up with formating and maybe more information + popuptext <- paste(df$geocat_id,df$sci_name,df$latitude,df$longitude) leaflet::leafletProxy("mymap", data=df) %>% @@ -341,7 +366,7 @@ server <- function(input, output, session) { fillOpacity = 1, fill = T, fillColor = "#0070ff", - popup = as.character(df$id)) + popup = as.character(popuptext)) }) shiny::observeEvent(input$queryGBIF, { @@ -444,8 +469,33 @@ server <- function(input, output, session) { shiny::observeEvent(list(input$Analysis, values$eoo_polygon, values$aoo_polygon), { if (input$Analysis){ - leaflet::leafletProxy("mymap", data=values$aoo_polygon) %>% - leaflet::clearGroup("AOOpolys") %>% + #analysis here + #print(values$analysis_data) + d <- data.frame(long=values$analysis_data$longitude,lat=values$analysis_data$latitude) + # if (!input$gbif_onoff) { + # d <- dplyr::filter(d, source != "gbif") + # } + #if (!input$csv_onoff) { + # d <- dplyr::filter(d, source != "csv") + #} + if (nrow(d) == 0) { + return() + } + #d <- dplyr::select(d, -source)#is this needed or is it the above needed, I think they are doing the same thing + #JMJJMJMJMJM + #project the data so we can work on it in a sensible space for areas and distance + projp <- simProjWiz(d) + #reports projection need to sent this to validate + # + print (projp$crs) + EOO <- eoosh(projp$p) + AOO <- aoosh(projp$p) + values$eooarea <- EOO$area + values$aooarea <- AOO$area + values$eoo_rat <- ratingEoo(EOO$area,abb=TRUE) + values$aoo_rat <- ratingAoo(AOO$area,abb=TRUE) + #JMJMJMMJ + leaflet::leafletProxy("mymap",data = AOO$polysf) %>% leaflet::addPolygons( color = "#000000", stroke = T, diff --git a/R/validate-data.R b/R/validate-data.R index 1d3c006..e8a4f39 100644 --- a/R/validate-data.R +++ b/R/validate-data.R @@ -1,3 +1,51 @@ +#Function to setup empty dataframe for geoCAT to work with +#JM +#notes +#geocat_source = where the data has come from (ie gbif, csv import, user defined) +#geocat_id = an internal ID which is populated on import (ie 1:nrow), new points will be added to this with a nrow + _leaflet_id (_leaflet_id is a unique number from leaflet) this should allow me to use this id to query all on map edits/delete. The reason for odd allocation is that leaflet assigns its own unique values and I can’t find a way to update (read only), there is a possibility of a clash if, I just increment ID and I may have get back out the leaflet ID as some point (not sure I do). I may simplify this later. +#geocat_status = a record of what has happen to a point ie “new point”, “moved point”, “deleted point” +#geocat_use = Flag to false it point is deleted (could query on above, but I feel this is quicker)? +#geocat_analysis = Flag for any queries (ie GBIF only etc), which we can switch on or off depending on reactive # elements (ie your switches for GBIF/user) +#geocat_notes = records what has happened the points when moved (ie moved from x,y to p,q) +#note at this point #geocat_analysis is not used +buildspdf <- function(){ + df <- data.frame(BasisOfRec = as.character(), + EVENT_YEAR = as.integer(), + latitude = as.numeric(), + longitude = as.numeric(), + sci_name = as.character(), + PRESENCE = as.integer(), + ORIGIN = as.integer(), + SEASONAL = as.integer(), + CATALOG_NO = as.character(), + SPATIALREF = as.character(), + CITATION = as.character(), + COMPILER = as.character(), + recordno = as.character(), + recordedBy = as.character(), + yrcompiled = as.integer(), + DATA_SENS = as.logical(), + SOURCE = as.logical(), + dist_comm = as.logical(), + tax_comm = as.logical(), + #user specific + id = as.integer(), + #geocat specific fields + geocat_source = as.character(), + geocat_id = as.integer(), + geocat_status = as.character(), + geocat_use = as.logical(), + geocat_analysis = as.logical(), + geocat_notes = as.character() + ) + #add some dummy data + mypoints <- data.frame(longitude = rnorm(4) + 46, latitude = rnorm(4) + -21, geocat_id = c(1:4),geocat_use=TRUE) + merge(df,mypoints, all=TRUE) + + +} + + # Functions to validate occurrences and occurrence files check_fields_ <- function(df, required_fields) { diff --git a/app.R b/app.R index c38ea1d..9273328 100644 --- a/app.R +++ b/app.R @@ -1,3 +1,4 @@ library(shiny) +library(leaflet.extras) pkgload::load_all(".") geocatApp()