gfw-mapbuilder

Template for the GFW Map Builder that is available through ArcGIS Online, as a stand-alone web application, & a library to build custom Forest Atlas web applications

https://github.com/wri/gfw-mapbuilder

Science Score: 36.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    1 of 28 committers (3.6%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (14.9%) to scientific vocabulary

Keywords

esri-js gfw website
Last synced: 6 months ago · JSON representation

Repository

Template for the GFW Map Builder that is available through ArcGIS Online, as a stand-alone web application, & a library to build custom Forest Atlas web applications

Basic Info
Statistics
  • Stars: 34
  • Watchers: 20
  • Forks: 10
  • Open Issues: 45
  • Releases: 27
Topics
esri-js gfw website
Created almost 10 years ago · Last pushed 7 months ago
Metadata Files
Readme Contributing License

README.md

Build Status

GFW Map Builder ArcGIS Online Template

Template for the GFW Map Builder that will be available through ArcGIS Online.

Getting Started

Before you can begin, make sure you have node.js.

Env variables

Create .env file at the root of the project and add REACT_APP_PLANET_API_KEY checkout .env.examples file. Reach out to point of contact for Mapbuilder and ask for api key

Make sure you are using Node version 16x or greater

Install all the javascript dependencies.

shell npm install

Start the server and then the app will be served at http://localhost:3000.

shell npm start

Generating a build

You will need node.js installed for these steps

Run the following command to generate a build to the webpackBuild directory.

shell npm run build

Configuring

This application has a general (resources.js). file that contains things controlled by the developers. Also, the Resources file contains configurations that are controlled via ArcGIS Online or whomever may be deploying the application. You can control things like the layers in the accordion, their source urls, their order on the map and in the UI, service urls (print, geometry, map, etc.), which layers to include in the analysis, and even the configurations for slope analysis and other aspects of the analysis. Anything that needs to be controlled from ArcGIS Online or the person deploying it, should be placed in resources.js.

To ensure that your resources.js has a valid configuration run the following command

shell npm run test

These Jest unit tests will ensure that you have correctly configured any properties that are required in the layerPanel and analysisModules sections.

Adding or updating core layers for MapBuilder

Layer configuration is located atconfigs/layers/*

To Update layer config:

  • To update layer configuration navigate to the configs/layers/, open the index.ts file
  • If you were to update ** Glad Alerts ** layer label for example, navigate to configs/layers/glad-alerts/index.ts

To Add a new layer config:

  • For consistency folder name is the same as layer name, glad-alerts
  • Navigate to configs/, create a folder inside layers folder, make sure folder name matches the layer name for consistency.
  • Once folder created, create an index.ts file and add your new layer configuration.
  • If you are not sure about the expected config schema, you can also reference any of the other layers OR there is also a a schema example of what is expected in configs/layers/types/index.ts that you can also reference.

  • Once new config layer is created, you need to import your new layer configuration to configs/layers/layers-content-config.ts.

  • import your new layer configuration from here, for example: import newLayerConfig from './new-layer-config'

  • Lastly, add your imported layer configuration to layersContentConfig list

Configuring Layers and Accordions

The layers and the accordion are now more easily configurable via the resources.js file. Layers that you want to appear on the map but not in the accordion should be placed under extraLayers. The configuration structure is as follows:

javascript GROUP_LCD: { order: 1, label: { en: 'Land Cover Dynamics', fr: 'Evolution de l\'occupation des sols', es: 'Dinámica de la Cobertura del Suelo', pt: 'Land Cover Dynamics', id: 'Land Cover Dynamics', zh: '土地覆盖动态数据' }, layers: [{ order: 1, id: 'TREE_COVER_LOSS', type: 'image', url: 'https://gis-treecover.wri.org/arcgis/rest/services/ForestCover_lossyear_density/ImageServer', technicalName: 'tree_cover_loss', legendLayer: 0, colormap: [[1, 219, 101, 152]], inputRange: [1, 15], outputRange: [1], label: { en: 'Tree cover loss', fr: 'Perte en couvert arboré', es: 'Pérdida de la cobertura arbórea', pt: 'Tree cover loss', id: 'Tree cover loss', zh: '森林覆盖损失' }, sublabel: { en: '(annual, 30m, global, Hansen/UMD/Google/USGS/NASA)', fr: '(annuel, 30m, global, Hansen/UMD/Google/USGS/NASA)', es: '(anual, 30m, global, Hansen/UMD/Google/USGS/NASA)', pt: '(annual, 30m, global, Hansen/UMD/Google/USGS/NASA)', id: '(annual, 30m, global, Hansen/UMD/Google/USGS/NASA)', zh: '(每年更新, 30米, 全球覆盖, 汉森/马里兰大学/谷歌/美国地质测量局(USGS)/美国宇航局(NASA))' } }] }

Properties for the groups and layers are described in detail in the resources file, but here is a brief description of what you see above as well:

  • GROUP_LCD - Unique key to contain all the properties for the group, this is an accordion section in the layer panel
    • order - Order that the group will appear in the UI and the order in which it's layers will appear on the map. An order of 1 will be above an order of 2 in the UI and the map. MINIMUM is 1, value of 0 may result in layers being placed under the basemap.
    • label - Object containing keys for various languages, this is the label in the UI for the accordion section.
    • layers - an array of layers that will appear in this accordion. Some layers have custom configurations and some support different options for different types of layers.
    • order - order of the layer in the accordion and on the the map. This order is relative to this section. Layers more or less will be stacked similar to how they appear in the UI with the exception of feature/graphics layers as they always go on top. In the below example, layer A will be on top even though it has a higher order because the group it belongs to has a lower order, meaning the group and the layer will appear first:
      • Group 1 - order 1
      • Layer A - order 5
      • Group 2 - order 2
      • Layer B - order 1
    • id - Unique ID for the layer, this must be unique across the whole app, not just the group
    • type - Type of layer. Currently tiled, webtiled, image, dynamic, feature, graphic, glad, and terra are supported types.
    • visible - default layer visibility. Default value if not supplied is false.
    • url - required for all layers except graphics layers.
    • technicalName - key for this layer to retrieve metadata about it from the GFW metadata API
    • legendLayer - If this layer has no legend or a bad legend, and has an alternative one available here, http://gis-gfw.wri.org/arcgis/rest/services/legends/MapServer, you can provide the layer id of it's legend here so the app can pull that legend in.
    • layerIds - An array of layer ids for dynamic layers, should look like this: [0, 1, 2, 3] or [1].
    • label - An object of keys representing various languages, this is the label that shows in the UI
    • sublabel - An object of keys representing various languages, this is the sublabel that shows in the UI
    • popup - See below for more explanation and an example of how to use this

Adding Additional Groups

We are now supporting the ability to add additional group accordions to the layer panel. To add a new group, simply add another entry into the layerPanel object (described above in the 'Configuring' section). Below is an example group that you can copy and paste into the layerPanel object and edit to the configuration that you need. Follow any instructions/suggestions in the commented lines (preceded by //), then be sure to delete any commented lines before you save. Any properties that are commented out are optional, you may safely delete those if they are not needed for your group (exceptions will be noted below).

```javascript // Change the group name to something descriptive and unique. It should be all caps with words separated by underscores. GROUP_NAME: { // Properties must not be duplicated. One groupType is required. Choose one and uncomment it, then delete the others. // groupType: 'checkbox', // groupType: 'radio', // groupType: 'nested',

// Edit the order of this group and the other groups. This determines the order they appear in the layer panel. order: 1, label: { // Edit the group label, this can be anything you want it to be en: 'Group Label', // Optionally add labels for additional languages (see the section on Strings and Translations below). // fr: 'Label for French Language' }, layers: [ // Uncomment the layer item under the corresponding groupType that you selected earlier, then duplicate for any additional layers in this group.

// CHECKBOX
// {
//   Required - the layer id generated from your AGOL webmap
//   id: 'layer_id_1234',

//   Required - the order that you would like this layer to appear within the group accordion section (1 will appear ABOVE 2)
//   order: 1,

//   Optional - sublabel for the layer
//   sublabel: {
//     en: 'Layer sublabel',
//     fr: 'Sublabel for French Language'
//   }
// }

// RADIO
// {
//   Required - the layer id generated from your AGOL webmap
//   id: 'layer_id_1234',

//   Required - the order that you would like this layer to appear within the group accordion section
//   order: 1,

//   If this is a MapServiceLayer you must include the following property. This lets the application know which sublayers you would like included in this group.
//   includedSublayers: [0, 1, 2, 3],

//   Optional - the sublabel for the layer.
//   sublabel: {
//     en: 'Layer Sublabel',
//     fr: 'Sublabel for French Language'
//   }
//   Note: If this is a MapServiceLayer, the sublayer that the sublabel belongs to must be specified.
//   sublabel: {
//     0: {
//       en: 'Sublayer 0 Sublabel',
//       fr: 'Sublayer 0 Sublabel for French Language'
//     },
//     1: {
//       en: 'Sublayer 1 Sublabel',
//       fr: 'Sublayer 1 Sublabel for French Language'
//     }
//   }
// }

// NESTED
// {
//   Required - the order that you would like this layer grouping to appear within the group accordion section
//   order: 1,

//   Required - the label of the nested layer grouping
//   label: {
//     en: 'Nested grouping label',
//     fr: 'Nested grouping label for French Language'
//   },

//   Required - the layers that will appear in this grouping
//   nestedLayers: [
//     {
//       Required - the layer id generated from your AGOL webmap
//       id: 'layer_id_1234',

//       Required - the order that you would like this layer to appear within the nested grouping
//       order: 1,

//       Optional - sublabel for the layer
//       sublabel: {
//         en: 'Layer sublabel',
//         fr: 'Sublabel for French Language'
//       }
//     }
//   ]
// }

] }, ```

Configuring Popups for layers not in Webmaps

This is currently only supported for dynamic layers and feature layers. A popup configuration has some elements it must contain to keep the styling looking appropriate and they are outlined below. Here is an example layer configuration that contains a popup configuration (NOTE the addition of popup at the bottom):

javascript order: 6, id: 'ACTIVE_FIRES', type: 'dynamic', url: 'http://gis-potico.wri.org/arcgis/rest/services/Fires/Global_Fires/MapServer', technicalName: 'noaa18_fires', layerIds: [0, 1, 2, 3], label: { ... }, sublabel: { ... }, popup: { title: { en: 'Active Fires' }, content: { en: [ {'label': 'Brightness', 'fieldExpression': 'BRIGHTNESS'}, {'label': 'Confidence', 'fieldExpression': 'CONFIDENCE'}, {'label': 'Latitude', 'fieldExpression': 'LATITUDE'}, {'label': 'Longitude', 'fieldExpression': 'LONGITUDE'}, {'label': 'Acquisition Date', 'fieldExpression': 'ACQ_DATE:DateString(hideTime:true)'}, {'label': 'Acquisition Time', 'fieldExpression': 'ACQ_TIME'} ] } }

This way you can add more languages and also use modifiers on fields. fieldExpression get's used in the same manner the JSAPI uses fields for popup content, in a string like so: '\${BRIGHTNESS}'. This is why we can use modifiers like ACQ_DATE:DateString(hideTime:true). You can see a list of available modifiers here: Format info window content

Strings

This portion refers to how a developer could add some new strings, if you are looking at adding translations, see Translations below. The convention to add new strings to the application is to add them in each language, in src/js/languages.js. The name should be all uppercase separated by an underscore. For example, a link in the navigation bar for the word about would be added four times, once for each supported language in their appropriate section, like so:

javascript strings.en.NAV_ABOUT = 'About'; ... strings.fr.NAV_ABOUT = 'About'; ... strings.es.NAV_ABOUT = 'About'; ... strings.pt.NAV_ABOUT = 'About';

Then in your components, or any other part of the code, simply import the languages module, get the current language from React's context(or pass it out from a component if needs be).

```javascript import text from 'js/languages';

export default class MyComponent extends Component { static contextTypes = { language: PropTypes.string.isRequired, };

render() { const { language } = this.context;

return <div>{text[language].NAV_ABOUT}</div>;

} } ```

Translations

If you are adding or fixing translations. The strings used in the application can be found in two locations. The majority of them will be in the src/js/languages.js file. They are prefixed by the two digit country code. Add the appropriate translation in the correct language section. You may see something like this:

javascript strings.en.DATA = 'Data'; //English ... strings.fr.DATA = 'Data'; // French ... strings.es.DATA = 'Data'; // Spanish ... strings.pt.DATA = 'Data'; // Portuguese

The other location is the src/js/resources.js file. There are layers and basemaps each with subsections for each of the four languages. In each subsection is an array or objects containing the layer configuration. Be careful what you change in here, the only three things related to labels are label, sublabel, and group. The group refers to the name on the accordion, it needs to be the same as the other layers in the same group (they are linked by a groupKey).

Deployment

Backup 1.5.0 folder

aws s3 sync s3://wri-sites/gfw-mapbuilder.org/library.gfw-mapbuilder.org/1.5.0/ /Users/dstarr/Desktop/MapbuilderBackups/04212022/ --profile wri

Copy dist folder into 1.5.0 aws folder

aws s3 sync --content-type "text/html" /{project_path}/gfw-mapbuilder/dist/ s3://wri-sites/gfw-mapbuilder.org/library.gfw-mapbuilder.org/1.5.0/ --profile wri

Copy dist > 1.5.0.js file in dist folder into 1.5.0.js file in aws folder

aws s3 cp --content-type "text/html" /{project_path}/gfw-mapbuilder/dist/loader/1.5.0.js s3://wri-sites/gfw-mapbuilder.org/library.gfw-mapbuilder.org/1.5.0/1.5.0.js --profile wri

Clear cache

aws cloudfront create-invalidation --distribution-id E58RE0T7L0R9N --path "/" --profile wri

aws cloudfront create-invalidation --distribution-id E2B81LN86UDRTJ --path "/" --profile wri

Owner

  • Name: World Resources Institute
  • Login: wri
  • Kind: organization
  • Email: datalab@wri.org
  • Location: Washington, DC

GitHub Events

Total
  • Watch event: 1
  • Delete event: 9
  • Issue comment event: 1
  • Push event: 37
  • Pull request review comment event: 1
  • Pull request review event: 6
  • Pull request event: 28
  • Create event: 16
Last Year
  • Watch event: 1
  • Delete event: 9
  • Issue comment event: 1
  • Push event: 37
  • Pull request review comment event: 1
  • Pull request review event: 6
  • Pull request event: 28
  • Create event: 16

Committers

Last synced: 6 months ago

All Time
  • Total Commits: 4,125
  • Total Committers: 28
  • Avg Commits per committer: 147.321
  • Development Distribution Score (DDS): 0.797
Past Year
  • Commits: 129
  • Committers: 2
  • Avg Commits per committer: 64.5
  • Development Distribution Score (DDS): 0.233
Top Committers
Name Email Commits
Vaidotas Piekus v****p@g****m 837
Kayla Kremer k****a@g****m 715
Lucas Cotner l****7@u****u 666
Eden e****n@g****m 382
Patrick Moran p****n@b****m 300
Robert Winterbottom r****m@b****m 197
Anthony Amaro a****o@A****l 184
dstarr d****r@b****m 176
Anthony Amaro a****5@g****m 132
Jennifer Boyd j****d@b****m 124
davidlstarr d****r@h****m 120
Timur Girgin t****n@b****m 78
Nick Bumbarger n****r@g****m 61
Thomas Maschler t****r@w****g 40
Anthony a****o@A****l 30
dependabot[bot] 4****]@u****m 23
Richard Barad r****d@w****g 15
bzivkovic b****c@b****m 9
Djoan d****s@w****g 8
Timur Girgin g****r@g****m 8
swingley s****y@g****m 5
Caio de Araujo Barbosa c****a@g****m 3
Eden e****n@g****m 3
Lucas Cotner l****r@c****m 3
Asa Strong a****g@w****g 2
mweisse m****e@u****m 2
Christina Phang c****g@b****m 1
Thomas Maschler T****r@w****g 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 495
  • Total pull requests: 965
  • Average time to close issues: 4 months
  • Average time to close pull requests: 10 days
  • Total issue authors: 12
  • Total pull request authors: 18
  • Average comments per issue: 2.37
  • Average comments per pull request: 0.27
  • Merged pull requests: 865
  • Bot issues: 0
  • Bot pull requests: 46
Past Year
  • Issues: 0
  • Pull requests: 29
  • Average time to close issues: N/A
  • Average time to close pull requests: 11 days
  • Issue authors: 0
  • Pull request authors: 1
  • Average comments per issue: 0
  • Average comments per pull request: 0.0
  • Merged pull requests: 19
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • richardbarad (141)
  • csphang (127)
  • vaidotasp (97)
  • eyosef (64)
  • SwampGuzzler (36)
  • k-kresek (19)
  • davidlstarr (4)
  • palmernet (2)
  • KaylaKremer (2)
  • pkmoran (1)
  • jenboyd (1)
  • jequihua (1)
Pull Request Authors
  • vaidotasp (170)
  • SwampGuzzler (165)
  • KaylaKremer (123)
  • anthonyamaro15 (116)
  • pkmoran (111)
  • eyosef (102)
  • davidlstarr (68)
  • dependabot[bot] (46)
  • jenboyd (25)
  • tgirgin23 (18)
  • thomas-maschler (7)
  • Robert-W (4)
  • nbumbarger (3)
  • richardbarad (2)
  • swingley (2)
Top Labels
Issue Labels
4.x Upgrade (151) high priority (49) bug (36) low priority (27) medium priority (19) HOLD (17) in-contract (13) HIGHEST priority (10) Code Cleanup (9) share-functionality (5) WCS (4) quick PR (3) performance (2) typescript (2) hacktoberfest (1) blocked (1)
Pull Request Labels
4.x Upgrade (218) READY FOR REVIEW (90) dependencies (47) DO NOT MERGE (17) bug (16) HOLD (8) quick PR (8) Client Testing (5) WCS (5) Code Cleanup (4) high priority (3) share-functionality (3) Exemplar (3) HIGHEST priority (2) typescript (2) hacktoberfest (1)

Packages

  • Total packages: 1
  • Total downloads: unknown
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 34
proxy.golang.org: github.com/wri/gfw-mapbuilder
  • Versions: 34
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 5.4%
Average: 5.6%
Dependent repos count: 5.8%
Last synced: 6 months ago

Dependencies

package-lock.json npm
  • 1950 dependencies
package.json npm
  • @types/lodash-es ^4.17.3 development
  • @types/node ^13.1.4 development
  • @types/rc-slider ^8.6.6 development
  • @types/react ^16.9.17 development
  • @types/react-datepicker ^4.1.3 development
  • @types/react-dom ^16.9.4 development
  • @types/react-measure ^2.0.6 development
  • @types/react-redux ^7.1.5 development
  • @types/react-select ^3.0.11 development
  • @types/redux-logger ^3.0.7 development
  • @typescript-eslint/eslint-plugin ^2.15.0 development
  • @typescript-eslint/parser ^2.15.0 development
  • clean-webpack-plugin ^3.0.0 development
  • compression-webpack-plugin ^3.0.1 development
  • copy-webpack-plugin ^5.1.1 development
  • css-loader ^3.4.1 development
  • cypress ^6.9.1 development
  • enzyme ^3.11.0 development
  • eslint ^6.8.0 development
  • eslint-config-prettier ^6.9.0 development
  • eslint-plugin-jsx-a11y ^6.2.3 development
  • eslint-plugin-react ^7.17.0 development
  • eslint-plugin-react-hooks ^2.3.0 development
  • file-loader ^6.2.0 development
  • html-loader ^0.5.5 development
  • html-webpack-plugin ^3.2.0 development
  • husky ^4.0.0 development
  • mini-css-extract-plugin ^0.9.0 development
  • node-sass ^4.13.0 development
  • prettier ^2.6.2 development
  • pretty-quick ^2.0.1 development
  • redux-devtools-extension ^2.13.8 development
  • redux-logger ^3.0.6 development
  • resolve-url-loader ^3.1.1 development
  • sass-loader ^8.0.0 development
  • style-loader ^1.1.2 development
  • terser-webpack-plugin ^2.3.1 development
  • ts-loader ^8.0.17 development
  • tslib ^1.10.0 development
  • typescript ^4.4.4 development
  • url-loader ^3.0.0 development
  • webpack ^4.20.1 development
  • webpack-cli ~3.3.5 development
  • webpack-dev-server ^3.1.10 development
  • webpack-hasjs-plugin ^1.0.3 development
  • webpack-merge ^4.2.2 development
  • @material-ui/core ^4.10.2
  • @material-ui/lab ^4.0.0-alpha.56
  • @types/arcgis-js-api ~4.18.0
  • @types/react-beautiful-dnd ^13.1.2
  • @types/styled-components ^5.1.15
  • clsx ^1.1.1
  • date-fns ^2.11.1
  • esri-loader ^3.0.0
  • immer ^9.0.12
  • lodash-es ^4.17.15
  • png-ts 0.0.3
  • rc-slider ^9.7.1
  • react ^17.0.2
  • react-beautiful-dnd ^13.1.0
  • react-datepicker ^4.1.1
  • react-dom ^17.0.2
  • react-hook-form 7.17.5
  • react-measure ^2.3.0
  • react-redux ^7.1.3
  • react-select ^3.1.0
  • react-spinners-css 2.0.1
  • react-tooltip 4.2.21
  • redux ^4.0.5
  • reselect ^4.0.0
  • styled-components ^5.3.3
  • xml-js ^1.6.11
.github/workflows/build-and-deploy.yml actions
  • actions/checkout master composite
  • actions/setup-node v1 composite
  • blueraster/action-slack master composite
  • blueraster/s3-sync-action master composite
.github/workflows/make-pr-branch.yml actions
  • actions/checkout master composite
  • actions/setup-node v1 composite
  • aws-actions/configure-aws-credentials v1 composite