Pivot
Pivot은 오픈 데이터 형식 기반 고성능 실시간 분석 데이터베이스입니다
인터랙티브 3D 37개국 인구밀도 지도, 미국·중국·인도·방글라데시·일본·독일 등. 육각형에 마우스 올리면 인구 확인
Population density map of 37 countries in interactive 3D: the US, China, India, Bangladesh, Japan, Germany and more. Hover any hexagon for its population.
데이터HTML · RGitHub @niloy-biswas온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기3D population density maps from Kontur H3 hexagon data: ray-traced renders in R (rayshader) and an interactive web explorer (deck.gl + MapLibre).
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗3D population density maps from Kontur population data, in two forms:
Both read the same country list in scripts/countries.R, but they run independently: making a rendered map never touches web/, and the explorer never needs Rayshader.
Population/
├── run_country.R # Entry point for rendered maps
├── scripts/
│ ├── countries.R # All country configs (both outputs read this)
│ ├── helpers.R # Palette creation utilities
│ ├── create_pop_matrix.R
│ ├── plot_population_3d.R
│ ├── annotate_population_map.R
│ ├── export_web_data.R # Country data + pages for the explorer (web/)
│ ├── templates/ # explorer.html: template for every explorer page
│ ├── download_kontur.R # Fetch Kontur files by ISO code into data/kontur/
│ ├── setup_packages.R # Run once to install dependencies
│ └── legacy/ # Old per-country scripts (reference only)
├── data/ # Kontur .gpkg population + boundary files
│ └── kontur/ # Downloaded by download_kontur.R (gitignored)
├── output/
│ ├── plots/ # Raw 3D renders
│ └── annotated/ # Final annotated maps
├── web/ # Interactive explorer (static, deployed to GitHub Pages)
│ ├── app.js, style.css
│ ├── index.html # Landing page (generated)
│ ├── <country>/ # One page per country, e.g. sri-lanka/ (generated)
│ ├── sitemap.xml # Every page, for search engines (generated)
│ └── data/
│ ├── countries.json # Search index: countries + their views (generated)
│ └── <country>/ # hexes.json + boundaries.geojson (generated)
└── .github/workflows/pages.yml # Deploys web/ on push to main
1. Install R Download from cran.r-project.org (v4.4+)
2. Install XQuartz (macOS only — required for rgl) Download from xquartz.org, install, then restart Mac.
3. Install R packages
Open scripts/setup_packages.R and run it once.
Open run_country.R, uncomment the country you want, and source the file:
run_country("bangladesh")
# run_country("finland")
# run_country("india")
# ... etc
Output saves automatically to output/annotated/<Country>_population_density.png.
Download the Kontur population and boundary files by ISO 3166 code:
Rscript scripts/download_kontur.R GB DE # → data/kontur/
This fetches kontur_population_XX_20231101.gpkg and kontur_boundaries_XX_20230628.gpkg from Kontur's public bucket (the same files HDX links to) and skips files you already have. data/kontur/ is gitignored: some files are over GitHub's 100 MB limit, and a fresh clone can re-download them.
Add a config block to scripts/countries.R:
my_country = list(
name = "My Country",
hex_file = "data/kontur/kontur_population_XX_20231101.gpkg",
admin_file = "data/kontur/kontur_boundaries_XX_20230628.gpkg",
crs = 3857, # find at epsg.io
size = 3000,
palette = list(source = "metbrewer", name = "Benedictus", direction = -1),
zscale = 40,
camera = list(theta = 0, phi = 55, zoom = 0.75, fov = 100),
light_dir = 315,
width = 1400, height = 1800,
solid = FALSE, shadow_depth = 0
)
run_country.R:run_country("my_country")
See the comment block at the top of scripts/countries.R for what each parameter does.
web/ is a static page with no build step. deck.gl draws each Kontur H3 hexagon (about 0.74 km²) as a 3D column over a MapLibre basemap from OpenFreeMap. The page reads web/data/countries.json for the search box (every country plus its cities and regions, so typing "Dhaka" offers Dhaka city in Bangladesh), then loads one country's folder at a time. Every country has its own page, so links are shareable and search engines can find each one: bangladesh/, bangladesh/#dhaka-city. Old #bangladesh links still work.
scripts/export_web_data.R writes that data. For each country it:
Rscript scripts/export_web_data.R bangladesh # one country
Rscript scripts/export_web_data.R bangladesh nepal # several
Each run rebuilds countries.json and the pages (web/index.html, web/<country>/index.html, from scripts/templates/explorer.html) from the folders in web/data/, so search always matches what's exported. To rebuild only those, run Rscript scripts/export_web_data.R --manifest. Edit the template, not the generated pages.
Preview locally: python3 -m http.server -d web, then open localhost:8000.
Publish: push changes under web/ to main. The workflow deploys them to niloy.tech/Population-Density-Map.
Make sure the country has a block in scripts/countries.R with hex_file and admin_file (see Adding a New Country). The export only reads name, those two files and the optional web settings. A block with just those is enough for the explorer (most of the newer countries are like this); run_country() refuses it until you add the Rayshader fields.
Check which Kontur admin levels it uses. They differ between countries:
a <- sf::st_read("data/kontur/kontur_boundaries_XX_20230628.gpkg")
table(a$admin_level)
| Country | region | district | subdistrict |
|---|---|---|---|
| Austria | 4 | 8 | 9 |
| Bangladesh | 4 | 6 | 8, 10 |
| Belgium | 4 | 7 | 9 |
| Bhutan | 4 | 6 | none |
| Canada | 4 | 8 | 10 |
| China | 3 | 4 | 6 |
| Czechia | 7 | 8 | 9 |
| Denmark | 4 | 8 | none |
| Finland | 6 | 7 | 8 |
| France | 5 | 6 | 8 |
| Germany | 4 | 7 | 10 |
| Greece | 5 | 6 | 9 |
| Hungary | 6 | 7 | 9 |
| India | 4 | 5 | 7 |
| Ireland | 6 | 10 | 11 |
| Italy | 4 | 7 | 9 |
| Japan | 5 | 9 | 10 |
| Maldives | 4 | none | 9 |
| Myanmar | 3 |
To remove a country, delete its web/data/<country>/ folder and run the export for any remaining country to rebuild the index.
Countries range from under 50 KB of JSON (Maldives, Singapore) to about 18 MB (France, Nigeria, Canada, each around 600k hexagons); GitHub Pages compresses the largest to about 3.3 MB as served.
Tiled countries. The US (4.2M hexagons), China (3.1M) and India (2.1M) are too big for one file, so they set tiles = TRUE. The export then sums the hexagons into coarser H3 cells and cuts every level into map tiles under web/data/<country>/tiles/:
| Map zoom | Hexagons | Area each | US cells |
|---|---|---|---|
| up to 5 | resolution 6 | ~36 km² | 190k |
| 6–7 | resolution 7 | ~5 km² | 990k |
| 8 and up | resolution 8 | ~0.74 km² | 4.2M |
The browser fetches only the tiles on screen: the whole US as about 190k coarse cells, a city as a few full-resolution tiles (each under 400 KB, ~70 KB as served). The legend follows the level in view. This needs the h3jsr package. A tiled export takes 10 to 30 minutes and several GB of memory.
Fork the repo, add your country config to scripts/countries.R, and submit a pull request.
| 7 |
| 9 |
| Nepal | 3 | 7 | 8 |
| Netherlands | 5 | 10 | 12 |
| Nigeria | 4 | 7 | 9 |
| Norway | 4 | 8 | none |
| Pakistan | 3 | 6 | 7 |
| Poland | 4 | 8 | 9 |
| Portugal | 4, 7 | 8 | 10 |
| Romania | 4 | none | 9 |
| Singapore | 7 | none | none |
| Spain | 4 | 7 | 9 |
| Sri Lanka | 4 | 6 | 7 |
| Sweden | 4 | 8 | none |
| Switzerland | 4 | 8 | 11 |
| Ukraine | 4 | 6 | 7 |
| United Kingdom | 4 | 7 | 10 |
| United States | 4 | 6 | 8 |
Use character(0) for a tier the file lacks. The Israel and Palestine boundary files carry no area names, so those maps show the columns and the country view without region buttons, outlines or place names.
The defaults are Bangladesh's. For anything else, add a web list to the country's block:
nepal = list(
...
web = list(levels = list(region = "3", district = "7", subdistrict = "8"))
)
web also takes views (extra camera presets, like Bangladesh's "Dhaka city"), palette (the country's default column colours; visitors can also switch to the Bangladesh, India or Nepal render palettes from the map's layers button) and crop (a lon/lat box; hexagons and areas outside it are dropped). France, the Netherlands, Norway and the UK use crop to leave out overseas territories, Svalbard and Rockall, which would otherwise stretch the country view across oceans. bounds sets only the first (country) view and keeps everything else: Spain, Portugal and Japan use it so the Canaries, Azores, Madeira and Okinawa stay on the map (with their own region buttons) without shrinking the mainland; the US uses it for the lower 48 (Alaska and Hawaii are region buttons), Canada to keep the Arctic islands from pushing the south off screen. For very large countries, mask_km coarsens the land mask (Canada, the US, China, India), simplify_m simplifies thousands of district outlines, and tiles = TRUE exports a tile pyramid (below). See the comment at the top of countries.R.
Export it, preview, and push:
Rscript scripts/export_web_data.R nepal