Skip to content

View or edit on GitHub

This page is synchronized from trase/data/indonesia/palm_oil/logistics/plantations/Q1_2026/id_palm_ffb_prod_unit.md. Last modified on 2026-05-06 16:54 CEST by Trase Admin. Please view or edit the original file there; changes should be reflected here after a midnight build (CET time), or manually triggering it with a GitHub action (link).

FFB production unit

Adelina Chandra 2026-03-06

Notes

Preparation

library(dplyr)
library(ggplot2)
library(tidyverse)
library(sf)
library(fs)
library(aws.signature)
library(aws.s3)
library(arrow)
library(tidylog)
library(lwgeom)

aws.signature::use_credentials()
Sys.setenv("AWS_DEFAULT_REGION" = "eu-west-1")
bucket <- "trase-storage"

Read data

# palm oil concessions
op_conc <- st_read("/vsis3/trase-storage/indonesia/logistics/out/plantations/q1_2026/id_op2025_noOverlaps_v2026.geojson")
Reading layer `id_op2025_noOverlaps_v2026' from data source 
  `/vsis3/trase-storage/indonesia/logistics/out/plantations/q1_2026/id_op2025_noOverlaps_v2026.geojson' 
  using driver `GeoJSON'
Simple feature collection with 6663 features and 22 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 95.2443 ymin: -8.49672 xmax: 140.9885 ymax: 5.809408
Geodetic CRS:  WGS 84
# concession links
conc_mill <- st_read("/vsis3/trase-storage/indonesia/logistics/out/plantations/q1_2026/Matching/idn_op2025_conc_matched_2026.geojson")
Reading layer `idn_op2025_conc_matched_2026' from data source 
  `/vsis3/trase-storage/indonesia/logistics/out/plantations/q1_2026/Matching/idn_op2025_conc_matched_2026.geojson' 
  using driver `GeoJSON'

Simple feature collection with 10192 features and 33 fields (with 4 geometries empty)
Geometry type: GEOMETRY
Dimension:     XY
Bounding box:  xmin: 95.2443 ymin: -8.49672 xmax: 140.9885 ymax: 5.809408
Geodetic CRS:  WGS 84
conc_mill <- conc_mill %>% dplyr::filter(!st_is_empty(geometry))

# old ffb production unit
ffb_o <- st_read("/vsis3/trase-storage/indonesia/production/out/CONC_KAB_SPLIT_BY_KEC.geojson")
Reading layer `file6b202d963237' from data source 
  `/vsis3/trase-storage/indonesia/production/out/CONC_KAB_SPLIT_BY_KEC.geojson' 
  using driver `GeoJSON'
Simple feature collection with 11891 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 94.97195 ymin: -11.00762 xmax: 141.02 ymax: 6.076768
Geodetic CRS:  WGS 84
# took too long to process in R, did union in QGIS
ffb_n <- st_read("/vsis3/trase-storage/indonesia/production/out/q1_2026/idn_conc_kec_v2026.geojson")
Reading layer `idn_conc_kec_v2026' from data source 
  `/vsis3/trase-storage/indonesia/production/out/q1_2026/idn_conc_kec_v2026.geojson' 
  using driver `GeoJSON'
Simple feature collection with 18510 features and 32 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 94.97191 ymin: -11.00762 xmax: 141.02 ymax: 6.076832
Geodetic CRS:  WGS 84

We decided to keep retain old concession codes but have new FFB production unit.

Admin read and preparation

# kab boundaries
# kab <- st_read("/vsis3/trase-storage/indonesia/spatial/BOUNDARIES/big/out/q1_2026/kabupaten_boundaries_2023_v2026.geojson")

#kec boundaries 
kec <- st_read("/vsis3/trase-storage/indonesia/spatial/BOUNDARIES/big/out/q1_2026/kecamatan_boundaries_2023_v2026.geojson")
Reading layer `kecamatan_boundaries_2023_v2026' from data source 
  `/vsis3/trase-storage/indonesia/spatial/BOUNDARIES/big/out/q1_2026/kecamatan_boundaries_2023_v2026.geojson' 
  using driver `GeoJSON'
Simple feature collection with 7325 features and 10 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 94.97191 ymin: -11.00762 xmax: 141.02 ymax: 6.076832
Geodetic CRS:  WGS 84
# proj: Cylindrical Equal Area
indonesian_crs <- "+proj=cea +lon_0=115.0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs"

Took too long than expected to merge - skipped and did this in QGIS to speed up

# kec_prep <- kec  %>%  
#   mutate(kec_id = paste0("KEC", gsub("\\.", "", as.character(kec_code))))

# kec_in_op <- st_intersection(kec_prep  %>% select(kec_id), op_conc %>% select(code))

# op_union <- st_union(op_conc)

# kec_out_op <- st_difference(kec_prep, op_union)

# kec_partitioned <- bind_rows(
#   kec_in_op %>% mutate(part = "intersect"),
#   kec_out_op %>% mutate(part = "outside"))

Clean up merged data

glimpse(ffb_o)
Rows: 11,891
Columns: 5
$ kab_code  <dbl> 3208, 3208, 3208, 3208, 3208, 3304, 3304, 3304, 3304, 3304, …
$ prov_code <dbl> 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 35, 35, 35, …
$ ffb_code  <chr> "FFB-00001", "FFB-00002", "FFB-00003", "FFB-00004", "FFB-000…
$ conc_code <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ geometry  <MULTIPOLYGON [°]> MULTIPOLYGON (((108.4436 -6..., MULTIPOLYGON ((…
glimpse(ffb_n)
Rows: 18,510
Columns: 33
$ code       <chr> "BPN0823", "BPN0823", "BPN0823", "GPC1079", "BPN0228", "BPN…
$ dataSource <chr> "BPN", "BPN", "BPN", "Greenpeace", "BPN", "BPN", "BPN", "BP…
$ company    <chr> "PT Sinar Gunung Sawit Raya", "PT Sinar Gunung Sawit Raya",…
$ group_     <chr> "Andalas Lestari International / Mujur Timber", "Andalas Le…
$ rspoCert_c <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ extra_data <chr> "company name from GC", "company name from GC", "company na…
$ geoPresenc <chr> "no", "no", "no", "no", "no", "no", "no", "no", "no", "no",…
$ geoOwner   <chr> "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA",…
$ aerialPres <chr> "yes", "yes", "yes", "unclear", "yes", "yes", "yes", "yes",…
$ notes      <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "gc cal…
$ NIB        <chr> "02.14.00.00.00016", "02.14.00.00.00016", "02.14.00.00.0001…
$ NO_HAK     <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ legalStatu <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ admin0     <chr> "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indone…
$ joinDate   <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ status     <chr> "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA",…
$ memberNumb <chr> "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA",…
$ rspoMember <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ georspoCer <chr> "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA",…
$ memberYear <chr> "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA",…
$ newedit    <chr> "old", "old", "old", "old", "old", "old", "old", "old", "ol…
$ area_ha    <dbl> 7157.739, 7157.739, 7157.739, 1465.951, 27.601, 27.601, 30.…
$ fid        <int> 196, 318, 324, 6423, 6186, 6198, 6186, 6198, 6186, 6198, 61…
$ metadata   <chr> "TASWIL1000020230928_DATA_BATAS_KECAMATAN", "TASWIL10000202…
$ prov_name  <chr> "Aceh", "Sumatera Utara", "Sumatera Utara", "Maluku Utara",…
$ kab_name   <chr> "Aceh Singkil", "Tapanuli Tengah", "Tapanuli Tengah", "Halm…
$ kec_code   <chr> "11.10.11", "12.01.05", "12.01.11", "82.02.07", "75.04.01",…
$ kab_code   <chr> "11.10", "12.01", "12.01", "82.02", "75.04", "75.04", "75.0…
$ prov_code  <chr> "11", "12", "12", "82", "75", "75", "75", "75", "75", "75",…
$ kec_name   <chr> "Danau Paris", "Manduamas", "Sirandorung", "Weda Tengah", "…
$ shape_area <dbl> 336483685, 305702048, 107826715, 541315295, 61508005, 40580…
$ trase_id   <chr> "ID-111011", "ID-120105", "ID-120111", "ID-820207", "ID-750…
$ geometry   <MULTIPOLYGON [°]> MULTIPOLYGON (((98.12695 2...., MULTIPOLYGON (…
#check area 
kec_proj <- st_transform(kec, indonesian_crs)
ffb_proj <- st_transform(ffb_n, indonesian_crs)

sum(as.numeric(st_area(ffb_proj)))
[1] 1.89108e+12
sum(as.numeric(st_area(kec_proj))) #great!
[1] 1.890904e+12
#prepare details
ffb_prep <- ffb_n  %>% 
  mutate(kec_code = gsub("\\.", "", as.character(kec_code)),
        kab_code = gsub("\\.", "", as.character(kab_code)),
        ffb_code = paste0("FFB", sprintf("%06d", row_number())),,
        conc_code = code)  %>% 
  select(kec_code, kab_code, prov_code, conc_code, ffb_code, kec_code, geometry)

print(glimpse(ffb_prep))
Rows: 18,510
Columns: 6
$ kec_code  <chr> "111011", "120105", "120111", "820207", "750401", "750412", …
$ kab_code  <chr> "1110", "1201", "1201", "8202", "7504", "7504", "7504", "750…
$ prov_code <chr> "11", "12", "12", "82", "75", "75", "75", "75", "75", "75", …
$ conc_code <chr> "BPN0823", "BPN0823", "BPN0823", "GPC1079", "BPN0228", "BPN0…
$ ffb_code  <chr> "FFB000001", "FFB000002", "FFB000003", "FFB000004", "FFB0000…
$ geometry  <MULTIPOLYGON [°]> MULTIPOLYGON (((98.12695 2...., MULTIPOLYGON ((…
Simple feature collection with 18510 features and 5 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 94.97191 ymin: -11.00762 xmax: 141.02 ymax: 6.076832
Geodetic CRS:  WGS 84
First 10 features:
   kec_code kab_code prov_code conc_code  ffb_code
1    111011     1110        11   BPN0823 FFB000001
2    120105     1201        12   BPN0823 FFB000002
3    120111     1201        12   BPN0823 FFB000003
4    820207     8202        82   GPC1079 FFB000004
5    750401     7504        75   BPN0228 FFB000005
6    750412     7504        75   BPN0228 FFB000006
7    750401     7504        75   BPN0472 FFB000007
8    750412     7504        75   BPN0472 FFB000008
9    750401     7504        75   BPN0497 FFB000009
10   750412     7504        75   BPN0497 FFB000010
                         geometry
1  MULTIPOLYGON (((98.12695 2....
2  MULTIPOLYGON (((98.24567 2....
3  MULTIPOLYGON (((98.28083 2....
4  MULTIPOLYGON (((128.0005 0....
5  MULTIPOLYGON (((121.4944 0....
6  MULTIPOLYGON (((121.4964 0....
7  MULTIPOLYGON (((121.4859 0....
8  MULTIPOLYGON (((121.4846 0....
9  MULTIPOLYGON (((121.4758 0....
10 MULTIPOLYGON (((121.471 0.5...
ffb_prep <- ffb_prep %>%
  st_make_valid() %>%
  filter(!st_is_empty(geometry))

Save data

st_write(
  ffb_prep,
  "/vsis3/trase-storage/indonesia/production/out/q1_2026/idn_ffb_unit_v2026.geojson",
  delete_dsn = TRUE
)
Deleting source `/vsis3/trase-storage/indonesia/production/out/q1_2026/idn_ffb_unit_v2026.geojson' using driver `GeoJSON'
Writing layer `idn_ffb_unit_v2026' to data source 
  `/vsis3/trase-storage/indonesia/production/out/q1_2026/idn_ffb_unit_v2026.geojson' using driver `GeoJSON'
Writing 18417 features with 5 fields and geometry type Unknown (any).