{"id":21834275,"url":"https://github.com/simonneutert/bb-map-tile-metrics","last_synced_at":"2026-05-15T13:34:08.306Z","repository":{"id":264920816,"uuid":"872374214","full_name":"simonneutert/bb-map-tile-metrics","owner":"simonneutert","description":"A babashka library and CLI tool for analyzing \"slippy\" map tile sets.","archived":false,"fork":false,"pushed_at":"2024-11-26T19:27:33.000Z","size":125,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-19T21:46:43.943Z","etag":null,"topics":["babashka","cli","clojure","lisp"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simonneutert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"publiccode":null,"codemeta":null}},"created_at":"2024-10-14T10:26:02.000Z","updated_at":"2024-11-26T19:27:37.000Z","dependencies_parsed_at":"2024-11-26T20:38:12.907Z","dependency_job_id":null,"html_url":"https://github.com/simonneutert/bb-map-tile-metrics","commit_stats":null,"previous_names":["simonneutert/bb-map-tile-metrics"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fbb-map-tile-metrics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fbb-map-tile-metrics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fbb-map-tile-metrics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fbb-map-tile-metrics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simonneutert","download_url":"https://codeload.github.com/simonneutert/bb-map-tile-metrics/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244811374,"owners_count":20514276,"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":["babashka","cli","clojure","lisp"],"created_at":"2024-11-27T20:09:44.107Z","updated_at":"2026-05-15T13:34:03.286Z","avatar_url":"https://github.com/simonneutert.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Babashka Map Tile Metrics\u003c!-- omit from toc --\u003e\n\nA library and CLI tool for analyzing map tile sets using X and Y coordinates. \\\nEach tile can also be defined by a zoom level (z, an integer), which represents the map's scale. \\\nWhen using this tool, the zoom level (z) must be the same for the given input and is therefore not required.\n\n[Slippy map tilenames on OSM](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames)\n\n[![Tests](https://github.com/simonneutert/bb-map-tile-metrics/actions/workflows/tests.yaml/badge.svg)](https://github.com/simonneutert/bb-map-tile-metrics/actions/workflows/tests.yaml)\n\n---\n\n\u003e Il faut toujours se réserver le droit de rire le lendemain de ses idées de la veille.\n\u003e\n\u003e \\- Napoleon Bonaparte\n\n---\n\n- [Definitions](#definitions)\n- [Metrics Calculated by the Tool (Scores)](#metrics-calculated-by-the-tool-scores)\n- [A Visualisation is Worth a Thousand Words](#a-visualisation-is-worth-a-thousand-words)\n- [Requirements](#requirements)\n- [Run the tool in the terminal](#run-the-tool-in-the-terminal)\n  - [Options](#options)\n  - [Input file structure / Data Schema](#input-file-structure--data-schema)\n  - [Example command](#example-command)\n  - [Docker](#docker)\n  - [Call from Ruby](#call-from-ruby)\n- [Other ...](#other-)\n- [Plans, Wishes, Hopes and Dreams](#plans-wishes-hopes-and-dreams)\n\n---\n\n## Definitions\n\n- **Tile**: A tile has coordinates x and y (integer values) representing its position in a grid. Optionally, a tile can have a zoom level `z` (integer value) to represent the scale of the map (tile).\n- **Point**: A point has coordinates x and y as integer values. May be used as a substitue for `tile` in this lib.\n- **Cluster Tile**: A tile that has neighboring tiles to all its four sides.\n  - e.g. for a tile (x, y) the neighbors' coordinates are (x-1, y), (x+1, y), (x, y-1), (x, y+1). A tile is a cluster-tile if all the neighboring tiles (top, right, bottom, left) are present.\n\n## Metrics Calculated by the Tool (Scores)\n\nThis tool calculates the following metrics:\n\n- **Clusters**: Lists tiles that are in close proximity to cluster coordinates. Each cluster represents a group of neighboring tiles.\n\n```text\n// including the maximum cluster\n{\n  ..., // other metrics\n  \"clusters\": [\n    [\n      {\n        \"x\": 2,\n        \"y\": 2,\n      },\n      {\n        \"x\": 3,\n        \"y\": 2,\n      }\n    ],\n    [\n      {\n        \"x\": 12,\n        \"y\": 22,\n      } ,\n      {\n        \"x\": 13,\n        \"y\": 22,\n      },\n    ],\n    ...\n  ]\n}\n```\n\n- **Maximum Clusters**: Identifies the largest clusters based on either the number of tiles it contains or the area it covers (or a combination of both).\n\n```text\n// all clusters with of the largest size\n{\n  ..., // other metrics\n  \"max_clusters\": [\n    [\n      {\n        \"x\": 2,\n        \"y\": 2,\n      },\n      {\n        \"x\": 3,\n        \"y\": 2,\n      },\n      ...\n    ],\n    [\n      {\n        \"x\": 22,\n        \"y\": 22,\n      },\n      {\n        \"x\": 23,\n        \"y\": 22,\n      },\n      ...\n    ]\n  ]\n}\n```\n\n- **Maximum Squares**: The biggest detected square formation of visited tiles. To be considered, a square must have a minimum edge length of 4 tiles.\n\n```text\n// upper left corner of the square\n{\n  ..., // other metrics\n  \"squares\": [\n    {\n      \"x\": 2,\n      \"y\": 2,\n      \"edge_length\": 3\n    }\n  ]\n}\n```\n\nThese metrics provide insights into the spatial distribution and patterns within the tile data.\n\n## A Visualisation is Worth a Thousand Words\n\nThe following table shows a grid of tiles. \n\nCoordinates are represented as (x, y) where x is the column and y is the row. The origin (0, 0) is at the top left corner.\n\n- `V` is a visited tile.\n- `c` is a cluster tile.\n- `C` is a cluster tile that is part of the max cluster.\n- `Cs` is a cluster tile that is part of the max square.\n- `Vs` is a visited tile that is part of the max square.\n\n| 0x0\u003cbr\u003e👇 | -   | -   | -   | -   | -   | -   | -   | -   | -   | -   | -   | -   | -   |\n| -------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| V        | V   | V   |     |     |     |     |     |     |     |     |     |     |     |\n| V        | Cs  | Cs  | Vs  | Vs  | V   | V   |     |     |     |     |     |     |     |\n| V        | Cs  | C   | C   | Vs  |     | V   | V   | V   | V   | V   | V   | V   | V   |\n| V        | Cs  | C   | C   | Vs  |     |     |     |     | V   | c   | c   | c   | V   |\n|          | Vs  | Vs  | Vs  | Vs  |     |     |     |     |     | V   | V   | V   |     |\n|          |     |     |     |     |     |     | V   |     |     |     |     |     |     |\n|          |     |     |     |     |     |     | V   |     |     |     |     |     |     |\n|          |     |     |     |     |     |     | V   |     |     |     |     |     |     |\n|          |     |     |     |     |     |     | Vs  | Vs  | Vs  | Vs  |     |     |     |\n|          |     |     |     |     |     |     | Vs  | c   | c   | Vs  |     |     |     |\n|          |     |     |     |     |     |     | Vs  | c   | c   | Vs  |     |     |     |\n|          |     |     |     |     |     |     | Vs  | Vs  | Vs  | Vs  |     |     |     |\n\n- Max Squares have a score of 4. \n  - One of two max squares in the example located with its top left corner at x=1, y=1.\n  - The other's top left tile is located at x=7, y=8.\n- Max Clusters have a score of 7. There is just one cluster with size 7.\n- Clusters have a score of 7, 4 and 3. There are three clusters.\n\n## Requirements\n\n- [babashka](https://babashka.org)\n\n## Run the tool in the terminal\n\nIn order to use this you need to have your data formatted as JSON or EDN.\n\n### Options\n\n- `--json` to pass JSON as string\n- `--edn` to pass EDN as string (strings and keywords supported)\n- `--file` to read a .edn/.json file\n\n### Input file structure / Data Schema\n\nThe expected JSON object should look like this:\n\n```text\n[\n  {\"x\": Integer, \"y\": Integer},\n  {\"x\": Integer, \"y\": Integer},\n  ...\n]\n```\n\n### Example command\n\nThis will work after you clone the repository and run the following command in the terminal.\n\n```bash\n# --file (with .json)\n$ bb -o --main map-tile-metrics.main --file \"test/map_tile_metrics/resources/test-data.json\"\n# --file (with .edn, keys are keywords)\n$ bb -o --main map-tile-metrics.main --file \"test/map_tile_metrics/resources/test-data.edn\"\n# --file (with .edn, keys are strings)\n$ bb -o --main map-tile-metrics.main --file \"test/map_tile_metrics/resources/test-data-str.edn\"\n```\n\nRead in a JSON string inline, the example shown utilizes `cat` for this:\n\n```bash\n# --json\n$ bb -o --main map-tile-metrics.main --json \"$(cat test/map_tile_metrics/resources/test-data.json)\"\n```\n\nReading in `EDN` is also supported 🚀 you can pass it inline - as shown - or use `cat` as in the example above:\n\n```bash\n# --edn\n$ bb -o --main map-tile-metrics.main --edn '#{{:x 1 :y 1} {:x 2 :y 1} {:x 3 :y 1} {:x 1 :y 2} {:x 2 :y 2} {:x 3 :y 2} {:x 1 :y 3} {:x 2 :y 3} {:x 3 :y 3}}'\n```\n\n### Docker\n\nBuild the image and run the tool in a container. But please note that the entrypoint is set already, so you just need to pass the option and data.\n\nSee example below:\n\n```bash\n# build the image first\n$ docker build -t bb-map-tile-metrics .\n```\n\n```bash\n$ docker run --rm -it bb-map-tile-metrics --edn '#{{:x 1 :y 1} {:x 2 :y 1} {:x 3 :y 1} {:x 1 :y 2} {:x 2 :y 2} {:x 3 :y 2} {:x 1 :y 3} {:x 2 :y 3} {:x 3 :y 3}}' \u003e output.json\n```\n\n### Call from Ruby\n\nUse this tool in a Ruby project\n\n```ruby\n# {x: 2, y: 2} is the only cluster-coordinate\ndata = [\n  {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1},\n  {x: 1, y: 2}, {x: 2, y: 2}, {x: 3, y: 2},\n  {x: 1, y: 3}, {x: 2, y: 3}, {x: 3, y: 3}\n]\ntile_metrics = JSON.parse(\n  `bb -o --main map-tile-metrics.main --json '#{data.to_json}'`\n)\n```\n\n## Other ...\n\nCompact JSON data using jq: `$ cat test-data.json | jq -c \u003e output.json`\n\n## Plans, Wishes, Hopes and Dreams\n\n- [ ] transfer this to a clojar library\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonneutert%2Fbb-map-tile-metrics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonneutert%2Fbb-map-tile-metrics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonneutert%2Fbb-map-tile-metrics/lists"}