48 |
51 |
52 |
run: gp_build()
53 |
54 |
55 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: geoplumber
2 | Title: Geospatial applications with R and frontend libraries
3 | Version: 0.1
4 | Authors@R: c(
5 | person("Layik", "Hama", email = "layik.hama@gmail.com", role = c("aut", "cre"),
6 | comment = c(ORCID = "0000-0003-1912-4890")),
7 | person("Robin", "Lovelace", email = "rob00x@gmail.com", role = c("ctb"),
8 | comment = c(ORCID = "0000-0001-5679-6536")),
9 | person("Mark", "Padgham", role=c("ctb"),
10 | comment = c(ORCID = "0000-0003-2172-5265")),
11 | person("Thomas", "Kluth", email = "t.kluth@posteo.de", role = c("ctb"))
12 | )
13 | Description: Utilize the power of R and ReactJS to build web applications.
14 | Depends: R (>= 3.4.0)
15 | License: GPL-3
16 | Encoding: UTF-8
17 | URL: https://atfutures.github.com/geoplumber
18 | BugReports: https://github.com/ATFutures/geoplumber/issues
19 | LazyData: true
20 | Imports:
21 | plumber,
22 | geojsonsf,
23 | callr
24 | Suggests:
25 | clipr,
26 | testthat,
27 | knitr,
28 | rmarkdown,
29 | stats19,
30 | dplyr,
31 | remotes,
32 | htmltools,
33 | devtools,
34 | RCurl
35 | RoxygenNote: 7.1.1
36 | Roxygen: list(markdown = TRUE)
37 | VignetteBuilder: knitr
38 | Language: en-GB
39 |
--------------------------------------------------------------------------------
/man/gp_add_slider.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/add_slider.R
3 | \name{gp_add_slider}
4 | \alias{gp_add_slider}
5 | \title{Adds a basic slider with a callback function to parent.}
6 | \usage{
7 | gp_add_slider(
8 | min = 1L,
9 | max = 10L,
10 | step = 1L,
11 | js_on_change_function = "onChange={(sliderInput) => this.setState({sliderInput})}",
12 | to_vector = "NA"
13 | )
14 | }
15 | \arguments{
16 | \item{min}{min to pass to the slider}
17 |
18 | \item{max}{max to pass to the slider}
19 |
20 | \item{step}{step changes for min & max}
21 |
22 | \item{js_on_change_function}{the function to run on React parent (Welcome). By default,
23 | \verb{onChange=\{(sliderInput) => this.setState(\{sliderInput\})\}} sets the state of parent
24 | with value returned from the html input's onChange function.}
25 |
26 | \item{to_vector}{instead of reading default Welcome.js}
27 | }
28 | \description{
29 | At this moment, there is no strategy to manage parent <> child
30 | interaction between what is main component (Welcome) and
31 | children. React does have strong tools for this but geoplumber
32 | is still young.
33 | }
34 | \examples{
35 | \dontrun{
36 | gp_add_slider()
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/man/traffic_casualties_2014.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/data.R
3 | \docType{data}
4 | \name{traffic_casualties_2014}
5 | \alias{traffic_casualties_2014}
6 | \title{Road traffic casualties}
7 | \format{
8 | An object of class \code{sf} (inherits from \code{tbl_df}, \code{tbl}, \code{data.frame}) with 1652 rows and 3 columns.
9 | }
10 | \usage{
11 | traffic_casualties_2014
12 | }
13 | \description{
14 | From OpenStreetMap
15 | }
16 | \examples{
17 | \dontrun{
18 | stplanr::dl_stats19()
19 | ac = stplanr::read_stats19_ac() # 214 mb compressed data
20 | ac = ac[!is.na(ac$Latitude), ]
21 | ac_few_cols = ac[ c("Accident_Severity", "Longitude", "Latitude", "Date")]
22 | ac_sf = sf::st_as_sf(ac_few_cols, coords = c("Longitude", "Latitude"))
23 | sf::st_crs(ac_sf) = 4326
24 | bb = stplanr::bb2poly(bb = sf::as_Spatial(traffic))
25 | bb_sf = sf::st_as_sf(bb)
26 | traffic_casualties = ac_sf[bb_sf, ]
27 | pryr::object_size(traffic_casualties) # 2 MB
28 | traffic_casualties_2014 = traffic_casualties[
29 | traffic_casualties$Date > "2014-01-01",
30 | ]
31 | pryr::object_size(traffic_casualties_2014) # 200 kB
32 | usethis::use_data(traffic_casualties_2014)
33 | }
34 | plot(traffic_casualties_2014$Date, traffic_casualties_2014$Accident_Severity)
35 | }
36 | \keyword{datasets}
37 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r
2 | language: r
3 | warnings_are_errors: true
4 | sudo: required
5 | cache: packages
6 |
7 | r_github_packages:
8 | - jimhester/covr
9 | r_check_args: --no-build-vignettes
10 |
11 | addons:
12 | apt:
13 | packages:
14 | - libudunits2-dev # paper.Rmd see travis builds/508333361#L1622
15 | - libgdal-dev
16 | - libgeos-dev
17 | - libssl-dev
18 | - xclip
19 | - libsodium-dev
20 | - libharfbuzz-dev
21 | - libfribidi-dev
22 |
23 | # copy from
24 | # https://github.com/mdlincoln/clipr/blob/master/.travis.yml
25 | env: TRAVIS_CLIP=xclip DISPLAY=:99.0 CLIPR_ALLOW=TRUE
26 | # see https://github.com/mdlincoln/clipr/issues/21
27 | # Ensure xclip can still run headlessly
28 | services:
29 | - xvfb
30 | before_script:
31 | - if [ "$TRAVIS_CLIP" == "xclip" ]; then uptime | xclip -i -sel p -f | xclip -i -sel c; xclip -o -sel clipboard; fi
32 |
33 | before_install:
34 | - nvm install 12.18.3
35 | - npm i -g create-react-app
36 | - Rscript -e 'install.packages("ragg")'
37 | - Rscript -e 'install.packages("pkgdown")'
38 |
39 | after_success:
40 | - Rscript -e "covr::codecov()"
41 |
42 | deploy:
43 | provider: script
44 | script: Rscript -e 'pkgdown::deploy_site_github()'
45 | skip_cleanup: true
46 |
--------------------------------------------------------------------------------
/tests/testthat/test-geojson.R:
--------------------------------------------------------------------------------
1 | context("test-geojson")
2 |
3 | test_that("geojson fails on missing path", {
4 | expect_error(gp_geojson())
5 | })
6 |
7 | test_that("geojson fails on no geoplumber app path", {
8 | expect_error(gp_geojson("/dev/null"))
9 | })
10 |
11 | test_that("geojson works on a geoplumber app path", {
12 | # wd = /tests/testthat
13 | temp.dir <- file.path(tempdir(), "foo")
14 | dir.create(temp.dir, recursive = TRUE)
15 | oldwd <- setwd(temp.dir)
16 | on.exit(oldwd)
17 | cat("\n.......\n", "Mocking a geoplumber app\n", list.files(), "\n......\n")
18 | gp_create()
19 | expect_true(gp_is_wd_geoplumber())
20 | Sys.setenv(DO_NOT_PLUMB = 'false')
21 | # run tests
22 | geojson_url = paste0("http://opendata.canterburymaps.govt.nz/datasets/",
23 | "fb00b553120b4f2fac49aa76bc8d82aa_26.geojson")
24 | expect_equal(gp_geojson(geojson_url = geojson_url, colour_pal = "mock"),
25 | TRUE)
26 | # we should now have a 'style={(feature) => ({fillColor:feature.properties.'
27 | # section in the Welcome.js
28 | expect_true(any(grepl("fillColor:feature.properties.",
29 | readLines(file.path(
30 | temp.dir, "src/Welcome.js"
31 | )))))
32 | Sys.unsetenv("DO_NOT_PLUMB")
33 | setwd(oldwd)
34 | unlink (temp.dir, recursive = TRUE)
35 | })
36 |
--------------------------------------------------------------------------------
/man/gp_add_geojson.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/add_geojson.R
3 | \name{gp_add_geojson}
4 | \alias{gp_add_geojson}
5 | \title{For now, views a geojson served from an endpoint on leafletjs.}
6 | \usage{
7 | gp_add_geojson(
8 | endpoint = "/api/data",
9 | color = "#3388ff",
10 | line_weight = NA,
11 | properties = FALSE
12 | )
13 | }
14 | \arguments{
15 | \item{endpoint}{where to fetch the geojson from}
16 |
17 | \item{color}{for now color value for all geojson}
18 |
19 | \item{line_weight}{worded carefully for leaflet geojson lineweight.}
20 |
21 | \item{properties}{logical, by default \code{FALSE}. If TRUE \code{color} and \code{line_weight} will
22 | be obtained from properties/columns from corresponding data served via \code{endpoint}}
23 | }
24 | \description{
25 | Assumes there is a valid geoplumber app at wd
26 | TODO: work with valid paths too
27 | TODO: either here, or separate function, add my own component.
28 | \enumerate{
29 | \item Add a component with ability to fetch geojson from an endpoint to /components
30 | \item Import it into the App.js (TODO: into any other component)
31 | Errors: stop execution if either React 'src' folder or for now "Welcome.js" component
32 | does not exist. This is because for now we are adding the ready to use GeoJSONComponent component
33 | into src/Welcome.js
34 | }
35 | }
36 | \examples{
37 | \dontrun{
38 | if(gp_is_wd_geoplumber()) {
39 | gp_add_geojson()
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/man/traffic_volumes.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/data.R
3 | \docType{data}
4 | \name{traffic_volumes}
5 | \alias{traffic_volumes}
6 | \title{Traffic data from CDRC data sets}
7 | \format{
8 | An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 1522 rows and 20 columns.
9 | }
10 | \usage{
11 | traffic_volumes
12 | }
13 | \description{
14 | See \href{https://data.cdrc.ac.uk/dataset/southwark-traffic-counts}{data.cdrc.ac.uk/dataset/southwark-traffic-counts}
15 | This dataset represents travel levels at the point locations stored in
16 | \code{traffic}
17 | }
18 | \examples{
19 | \dontrun{
20 | f = "/tmp/2010-2016-allaveragedailytrafficflowcdrcmapreducedfile.xlsx"
21 | traffic_volumes = readxl::read_excel(f)
22 | summary(traffic_volumes$ID \%in\% traffic$cp)
23 | pryr::object_size(traffic_volumes)
24 | usethis::use_data(traffic_volumes)
25 | library(dplyr)
26 | traffic_agg = traffic_volumes \%>\%
27 | group_by(cp = ID) \%>\%
28 | summarise(
29 | total = sum(`TOTAL FLOW`),
30 | cycle_or_motorcycle = sum(`ARX PEDAL-MOTORCYCLE`),
31 | av_speed = mean(AVERAGE_SPEED),
32 | year = mean(YEAR)
33 | )
34 | if(ncol(traffic) < 8) {
35 | traffic = left_join(traffic, traffic_agg)
36 | usethis::use_data(traffic, overwrite = TRUE)
37 | }
38 | mapview::mapview(traffic, zcol = "total")
39 | sf:::plot.sf(traffic)
40 | }
41 | summary(traffic_volumes)
42 | plot(traffic$total, traffic$cycle_or_motorcycle)
43 | }
44 | \keyword{datasets}
45 |
--------------------------------------------------------------------------------
/inst/js/src/components/RBSlider.jsx:
--------------------------------------------------------------------------------
1 | 'use-strict'
2 |
3 | import React, { Component } from 'react';
4 | import Control from 'react-leaflet-control';
5 |
6 | export default class RBSlider extends Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 | value: null
11 | }
12 | }
13 |
14 | _handleChange(event) {
15 | if (typeof (this.props.onChange) === 'function') {
16 | this.props.onChange(event.target.value)
17 | }
18 | this.setState({ value: event.target.value })
19 | }
20 |
21 | render() {
22 | let { min, max, step } = this.props;
23 | min = min || 1
24 | max = max || 10
25 | step = step || 1
26 | const { value } = this.state;
27 | return (
28 |