{"id":13857927,"url":"https://github.com/ATFutures/geoplumber","last_synced_at":"2025-07-13T22:31:32.639Z","repository":{"id":46425031,"uuid":"133939396","full_name":"ATFutures/geoplumber","owner":"ATFutures","description":"Serve geographic data from R and consume with scalable front end.","archived":false,"fork":false,"pushed_at":"2023-06-09T08:50:20.000Z","size":3348,"stargazers_count":59,"open_issues_count":7,"forks_count":7,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-08-06T03:04:33.120Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://atfutures.github.io/geoplumber/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ATFutures.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-05-18T10:21:47.000Z","updated_at":"2024-04-22T15:29:23.000Z","dependencies_parsed_at":"2024-02-09T01:57:50.979Z","dependency_job_id":"b16dbb1f-13d0-4990-a2a5-9d1b6150efbf","html_url":"https://github.com/ATFutures/geoplumber","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ATFutures%2Fgeoplumber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ATFutures%2Fgeoplumber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ATFutures%2Fgeoplumber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ATFutures%2Fgeoplumber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ATFutures","download_url":"https://codeload.github.com/ATFutures/geoplumber/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225920516,"owners_count":17545505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-05T03:01:50.976Z","updated_at":"2024-11-22T15:31:22.029Z","avatar_url":"https://github.com/ATFutures.png","language":"R","funding_links":[],"categories":["R"],"sub_categories":[],"readme":"---\noutput: github_document\neditor_options:\n  chunk_output_type: console\n---\n\n# geoplumber \u0026middot; [![Build Status](https://travis-ci.org/ATFutures/geoplumber.svg)](https://travis-ci.org/ATFutures/geoplumber) [![codecov](https://codecov.io/gh/ATFutures/geoplumber/branch/master/graph/badge.svg)](https://codecov.io/gh/ATFutures/geoplumber) [![Project Status: WIP](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#)\n\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r setup, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\ngeoplumber is an R package which enables data scientists and developers in general to develop scalable geospatial web applications. It is work in progress, and right now we consider it an R powered web application \"framework\". It utilizes [`plumber`](https://github.com/trestletech/plumber), which was designed for creating web APIs with R which is Swagger compliant. It supports [React](https://reactjs.org/) frontends at present (it may support other frontend frameworks such as VueJS in the future) and geographic data, building on [`sf`](https://github.com/r-spatial/sf).\n\nIt can be installed with the following command as it is not yet on CRAN:\n\n```{r install_github, message=FALSE, eval=FALSE}\ndevtools::install_github(\"ATFutures/geoplumber\")\n#\u003e the latest dev version\n```\n\n\u003c!-- ## Installation --\u003e\n\n\u003c!-- Currently repo is available only on github. To install the package using `devtools`: --\u003e\n\n\n\u003c!-- geoplumber, like `devtools` and similar packages works by working directory. It does not currently create an `.Rproj` file but may do so in future. --\u003e\n\n## Usage\n* For more detailed introduction see the [vignette](https://atfutures.github.io/geoplumber/articles/geoplumber.html)\n\nTo create a new web application:\n```{r hidden1, echo=FALSE, eval=FALSE}\n# knitr::opts_knit$set(root.dir = tempdir())\n```\n```{r create-example, eval=FALSE}\nlibrary(geoplumber)\ngp_create(\"my_app\")\n```\nThis will create a `my_app` folder at your current working directory. Suppose you started an R session from a folder with path `/Users/ruser/`, you will have `/Users/ruser/my_app` on your machine. \n\nYou can then build the new project\n```{r build-example, eval=FALSE}\nsetwd(\"my_app\")\ngp_build() # the front end and create minified js files.\n\n```\n\nYou can then serve endpoints and front end with:\n`gp_plumb()` \\# provide custom port if you wish, default is 8000\n\nThen visit `localhost:8000` to see your app.\n\n## Example (1) reproducible web app\n```{r nofuss}\nlibrary(geoplumber)\nd \u003c- file.path(tempdir(), \"gp\")\ngp_create(d)\now \u003c- setwd(d)\nps \u003c- gp_plumb()\nSys.sleep(1) # needed on automated build machines :)\nps\nrequire(RCurl)\nwebpage \u003c- getURL(\"http://localhost:8000\")\nwebpage \u003c- readLines(tc \u003c- textConnection(webpage)); close(tc)\ntail(webpage)\nps$kill()\nsetwd(ow)\n# should fail\n# getURL(\"http://localhost:8000\")\n```\n\n\n## Example (2)\nServe the `geoplumber::traffic` dataset (data.frame) at a \"/api/data\" endpoint, and view it on the front end. \n\nThe `traffic` [dataset](https://data.cdrc.ac.uk/dataset/southwark-traffic-counts) is from CDRC at University of Leeds which is traffic data locations for the larger traffic dataset.\n\nTo achive this copy the following endpoint/API to the clipboard of your machine. If you like to understand the function, you need to learn `plumber` package.\n\n```{r eval=FALSE}\n#' Serve geoplumber::traffic from /api/data\n#' @get /api/data\nget_traffic \u003c- function(res) {\n  geojson \u003c- geojsonsf::sf_geojson(geoplumber::traffic)\n  res$body \u003c- geojson\n  res\n}\n```\nThen run (re-copied into clipboard just in case):\n```{r hidden2, echo=FALSE}\nSys.setenv(CLIPR_ALLOW=TRUE)\n```\n```{r add-endpoint-manually, eval=FALSE}\nsetwd(\"my_app\")\nold_clip \u003c- clipr::read_clip()\n# adding above to clipboard\nclipr::write_clip(c(\n \"#' Serve geoplumber::traffic from /api/data\",\n \"#' @get /api/data\",\n \"get_traffic \u003c- function(res) {\",\n \"  geojson \u003c- geojsonsf::sf_geojson(geoplumber::traffic)\",\n \"  res$body \u003c- geojson\",\n \"  res\",\n \"}\"\n ))\ngp_endpoint_from_clip()\nclipr::write_clip(old_clip)\n```\n\nThis has now added a new endpoint at: `/api/data`. To consume it, we can simply run:\n\n```{r add-geojson, eval=FALSE}\nsetwd(\"my_app\")\ngp_add_geojson(\"/api/data\")\n```\n\nYou can now see the data by running:\n```{r eval=FALSE}\ngp_build() # build changes\ngp_plumb()\n```\n\nOr in the following \"export\" function a basic `leaflet` map using the \"headless\" `gp_map` funciton:\n\n```{r, echo=FALSE, fig.align='center', out.width=\"70%\", fig.cap=\"\u003ca href='https://www.cdrc.ac.uk/'\u003eCDRC\u003c/a\u003e London traffic data on geoplumber\"}\n knitr::include_graphics(\"man/figures/gp.png\")\n```\n\n```{r, echo=TRUE, eval=FALSE}\n# cd into a geoplumber app\nsetwd(\"my-app/\")\nlibrary(geoplumber)\n# view a dataset such as the `traffic` sf object bundled \nt \u003c- gp_map(geoplumber::traffic, browse_map = FALSE,\n            height = \"320px\", width = \"90%\")\n# use includeHTML for markdown\nhtmltools::includeHTML(t)\n```\n\nYou can also now see the raw JSON dataset at  `http://localhost:8000/api/data`,\nand on a map on a browser view the map at `http://localhost:8000`.\n\n## Example (3)\n\nWe would like to see default University of Leeds `uni_poly` grow/shrink using `sf::st_buffer()` function. Here is a reproducible example (please take a look at the default `plumber.R` file in your `my_app` project):\n\n```{r, eval=FALSE}\ngp_create(tolower(tempdir()))\nsetwd(tolower(tempdir()))\ngp_is_wd_geoplumber()\ngp_add_slider(\n  min = 0.001,\n  max = 0.01,\n  step = 0.001\n)\ngp_change_file(\n  path = \"src/Welcome.js\",\n  what = '\u003cGeoJSONComponent fetchURL={\"http://localhost:8000/api/uol?grow=\" + this.state.sliderInput} /\u003e\n',\n  pattern = '\u003cGeoJSONComponent fetchURL=\"http://localhost:8000/api/uol\" /\u003e',\n  replace = TRUE,\n  verbose = TRUE\n)\n```\n\nRun the project (this time at `tempdir()` location) by:\n```{r eval=FALSE}\ngp_build() # build changes\nr \u003c- gp_plumb() # run in bg\nr¢kill()\n```\n\nNow you can see:\n```{r, echo=FALSE, fig.align='center', out.width=\"70%\", fig.cap=\"geoplumber::uni_poly grow/shrinking using sf::st_buffer function on server side.\"}\nknitr::include_graphics(\"https://user-images.githubusercontent.com/1825120/46699371-7f79d000-cc11-11e8-9716-e1223296c7d6.gif\")\n```\n\n## geoplumber stack\n\nWe have worked with Shiny and  [`plumber`](https://github.com/trestletech/plumber/) and we consider ourselves experienced in ReactJS, too. In order to put together a web application powered at the backend with R and React at the front-end, there is a lot of setup and boilerplate to put together. This would be also correct for other front end stack such as Angular or VueJS.\n\nCurrently geoplumber uses Facebook's `create-react-app` (CRA) npm package to deal with underlying app management (including building and running) to keep you up to date with updates. `geoplumber` will generally provide detailed installation instructions for all required `npm` packages, but if not, the following are minimally required:\n\n```\nsudo npm i -g create-react-app\n```\n\n### Front end ###\nOnce the geoplumber app `my_app` has been created. It will have a `create-react-app` directory structure with an extra `R` folder to hold the backend R code. The React components, as they are in CRA apps, are in the `src` folder and ready to be customised and developed for your own purposes. So, a React developer could run `npm start` on the root directory and run the built in CRA development server which is what `gp_plumb_front()` does too.\n\n### npm packages used\nThe following are included by default, the versions are just from old .Rmd file. geoplumber updates these as the package is developed. Feel free to replace it with your own .json package definer as and when.\n\n```{r, echo=FALSE}\ndata \u003c- read.csv(text=\n    \"package                , Usage\n    create-react-app        , main package to manage front end\n    prop-types              , React propTypes\n    react                   , React main\n    react-dom               , React DOM\n    react-bootstrap         , bootstrapZ\n    leaflet                 , current default web mapping library \n    react-leaflet           , React wrapper around leaflet above\n    react-leaflet-control   , React map control\n    react-router            , React router (RR) \n    react-router-dom        , React dom for RR\n    react-scripts           , main package to manage front end\n    react-test-renderer     , test suite\n    enzyme                  , test suite\n    enzyme-adapter-react-16 , test suite adapter for React\n    sinon                   , test suite\")\n```\n\n```{r kable-npm}\nknitr::kable(data)\n```\n\n## Showcase\n\nAn example application is deployed at [www.geoplumber.com](www.geoplumber.com). It showcases some zone and flow data using both `LeafletJS` and `MapboxGL` both in React. The application is dockerised automating the production and deployment. \n\n## End-points\n\nR package `plumber` comes with a default end-point for documenting the API using Swagger. This is also available from `geoplumber`'s `/__swagger__/` path.\n\nWe follow a pattern of `/api/` before the end-points and without for other URL's.\nA new web app will have `/api/helloworld` and you can `curl` it:\n\n```{sh eval=FALSE}\ncurl localhost:8000/api/helloworld\n#\u003e {\"msg\":[\"The message is: 'nothing given'\"]}\n```\n\n## Tests\n\nTests currently only apply to restricted components of full functionality.\n\n```{r, eval=FALSE}\ndevtools::test()\n```\n\n## Roadmap\n\nWhat I (Layik) think will work for a version 0.1 to hit CRAN is geoplumber would be able to have:\n\n* basic structure of a R + React app running\n* basics of a production environment via Docker\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FATFutures%2Fgeoplumber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FATFutures%2Fgeoplumber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FATFutures%2Fgeoplumber/lists"}