Busabase
Busabase is an open-source (MIT) database and workspace for AI agents — data, docs, skills, and apps in one place. Run it locally, self-host it inside your network, or use Busabase Cloud, and turn age
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A map for Civic Joy Fund data. Joiner joins rows from a spreadsheet, a file, an Airtable view, a Google Sheet or a DataSF dataset to areas on a map. The areas include San Francisco districts, ZIPs, neighborhoods and census tracts, H3 hexagons, Bay Area counties and ZIPs, election precincts and the districts made from them, or polygons you upload. Each area is colored by how many rows it has, or by the total, average or share of any number column. Rows with a location are drawn too. The join logic is JoinKit, shared with Selecter.
Live at https://civic-joy-fund.github.io/joiner/. Hover the Joiner logo to see the version; CHANGELOG.md says what changed in each. Nothing is uploaded: files are read in your browser.
Drop a file anywhere on the page, or click Load data. The dialog has Open a file… and a box for a link.
data.records:read and schema.bases:read.
records JSON as a file.Sharing. After loading a link or an Airtable view, the page address carries it (?url=… or ?airtable=…), so the page can be shared. The Airtable token is never put in the address: it stays in your browser tab until the tab closes, and whoever opens a shared page uses their own token. Snapshots contain every column you loaded, so remove names, emails and phone numbers before sharing one.
Big files. Files with tens or hundreds of thousands of rows show their progress as they read, place, count and color. A 26 MB CSV of 367,000 rows loads in about 3 seconds. Above 2,000 located rows, a file starts drawn as pinpoints; above 50,000, its points start hidden (the areas still count them).
Match rows by picks the column, or Location (the area that contains each row's point; lines count by their midpoint). Joiner tries every column and picks the one that places the most rows; the menu shows each column's count.
match in config/layers.json. For example, districts accept 5, D5 or District 5.The tabs along the top are District, ZIP, Neighborhood (SF Find, Analysis, Planning, Realtor or Who's on First), H3 hexbins and Other. Other holds:
Bay Area sets zoom out to show all of themselves.
H3 hexbins work anywhere, not just in SF.
Basemap. Streets draw above the areas from zoom 13 (or put the areas under the basemap). Highway shields and one-way arrows are hidden. The creek fix from Block Party and Selecter hides streams and "Creek" and "Arroyo" waterways, which Protomaps tags as rivers even where they're culverted.
When the file has locations, Format features controls how its rows are drawn:
Table (next to Areas) shows every row, below or beside the map; the two icons switch between them.
The polygon sets are in data/boundaries/: one GeoJSON file per layer, plus index.json, which the map reads to build its tabs. They're built by a script and committed, so the map never calls DataSF while it runs.
| Layer | Tab | Join key | Features | Source |
|---|---|---|---|---|
supervisor_districts | District | sup_dist (1–11) | 11 | DataSF cqbw-m5m3 |
zip_codes | ZIP | zip_code | 27 | DataSF srq6-hmpi |
sf_find_neighborhoods | Neighborhood (default) | name | 117 | DataSF pty2-tcw4 |
analysis_neighborhoods | Neighborhood | nhood | 41 | DataSF p5b7-5n3h |
planning_neighborhoods | Neighborhood | neighborho | 37 | DataSF Planning Neighborhood Groups |
realtor_neighborhoods | Neighborhood | nbrhood | 92 | DataSF 5gzd-g9ns |
wof_neighbourhoods | Neighborhood | name | 116 | data/wof/ (84 current + 32 unverified) |
census_tracts | Other | geoid | 242 | DataSF sevw-6tgi |
Each layer's settings are in config/layers.json:
tab decides where the layer appears. Layers that share a tab become one menu, and "Other" puts a layer in the Other menu."default": true picks the set a tab opens with.regional marks a layer beyond SF.dissolve: { from, by } builds a layer by merging another layer's polygons that share a value. That's how precincts become districts, with clean outlines.A few precincts sit alone in their own district: one on the Bay Bridge and one near Angel Island.
node scripts/get_layers.mjs # download all layers (Node 18+, no npm install)
node scripts/get_layers.mjs zip_codes # just one
node scripts/get_layers.mjs --check # validate what's in data/boundaries
If a download fails, export the GeoJSON from the DataSF page and pass the file instead:
node scripts/get_layers.mjs --file zip_codes=~/Downloads/SF_ZIP_Codes.geojson
The script cleans each layer the same way:
keep, and sets each feature's id to its join key;mergeByKey is set (ZIPs 94121, 94133 and 94158 come in several pieces);bbox to the mainland only, so fitting the map to a layer doesn't zoom out to the Farallones (part of District 4 and tract 06075980401). The full extent is kept as extent.To add a layer, add an entry to config/layers.json with its DataSF dataset id (the id of the dataset, not of a map view built on it), join key, display name and the properties to keep, then run the script for it. Dissolved layers are built from their source's file, so run the source first.
data/wof/ holds the San Francisco macrohoods, neighbourhoods and microhoods from Who's on First, gathered from the Spelunker's descendant list for San Francisco. Unlike the DataSF sets, WOF records a hierarchy (a microhood inside a neighbourhood inside a macrohood), which is what we need for broad names like "Sunset" or "Richmond".
| File | What |
|---|---|
places.csv | every record: id, name, placetype, status, macrohood, parent, geometry source, Spelunker and download URLs |
macrohoods.geojson | 4 macrohoods: Downtown, Mission District, Richmond District, Sunset District |
neighbourhoods.geojson | 84 current neighbourhoods (mz:is_current 1) |
neighbourhoods-unverified.geojson | 32 neighbourhoods with mz:is_current -1 |
microhoods.geojson | 46 current microhoods |
microhoods-unverified.geojson | 49 microhoods with mz:is_current -1 |
raw/ | the original WOF records, one file per id |
ids.txt, missing.txt | ids from the Spelunker; ids not found in whosonfirst-data-admin-us |
Current vs. unverified. WOF marks 84 SF neighbourhoods current (mz:is_current 1). Another 32 have mz:is_current -1: never reviewed, but not deprecated, superseded or ceased. These files are named -unverified rather than "not current" because in WOF "not current" is mz:is_current 0, the retired records. They include Excelsior, Inner and Outer Sunset, Inner and Outer Richmond, Chinatown, Bayview and Ingleside. The two sets don't overlap, and together they cover all of SF; the 84 alone cover 62% of its land. So for a full neighbourhood map, load both files. Records with mz:is_current 0 (deprecated, superseded or ceased) aren't in any layer but are listed in places.csv. None of these records set mz:is_deprecated; deprecation is in edtf:deprecated and wof:superseded_by.
node scripts/get_wof.mjs # walk the Spelunker, download new records, rebuild outputs
node scripts/get_wof.mjs --from-ids # skip the Spelunker; use data/wof/ids.txt
node scripts/get_wof.mjs --offline # rebuild outputs from data/wof/raw only
Records come from GitHub (whosonfirst-data/whosonfirst-data-admin-us); places.csv also lists each record's data.whosonfirst.org URL.
Each merged change is a new version:
_BUILD_VERSION at the top of js/app.js (v37 → v38).## v38 section at the top of CHANGELOG.md saying what changed, in terms someone using the map would notice..github/workflows/tag-version.yml) reads _BUILD_VERSION and tags the merge commit v38.To tag an older commit, run the action by hand: Actions → Tag version → Run workflow, with the tag (v1) and the commit SHA.
JoinKit is pinned to one commit in index.html, and the same commit is kept in js/vendor/joinkit.js for when the CDN fails. Update both together. CLAUDE.md has the steps, and notes on how changes are built and tested.
AGPL-3.0 — see LICENSE.
bay_area_counties | Other | county | 9 | California county boundaries, the nine Bay Area counties (to be replaced by DataSF wamw-vt4s) |
bay_area_zip_codes | Other | zip | 323 | DataSF 4kz9-76pb |
election_precincts | Other | prec_2022 | 514 | DataSF d6x4-hefw |
us_house_districts | Other | cong22 | 4 | precincts dissolved by district |
state_senate_districts | Other | sen22 | 3 | precincts dissolved by district |
assembly_districts | Other | assemb22 | 4 | precincts dissolved by district |
bart_districts | Other | bart22 | 3 | precincts dissolved by district |