{"id":27553002,"url":"https://github.com/2gis/general","last_synced_at":"2025-04-19T11:42:29.902Z","repository":{"id":57093574,"uuid":"86564796","full_name":"2gis/general","owner":"2gis","description":"Fast marker generalization algorithm","archived":false,"fork":false,"pushed_at":"2020-02-12T05:44:27.000Z","size":1447,"stargazers_count":8,"open_issues_count":0,"forks_count":3,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-13T02:07:50.412Z","etag":null,"topics":["javascript","webmaps"],"latest_commit_sha":null,"homepage":"https://2gis.github.io/general/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/2gis.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}},"created_at":"2017-03-29T09:42:16.000Z","updated_at":"2023-01-02T16:20:10.000Z","dependencies_parsed_at":"2022-08-22T20:40:34.975Z","dependency_job_id":null,"html_url":"https://github.com/2gis/general","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2gis%2Fgeneral","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2gis%2Fgeneral/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2gis%2Fgeneral/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2gis%2Fgeneral/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/2gis","download_url":"https://codeload.github.com/2gis/general/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249685334,"owners_count":21310585,"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":["javascript","webmaps"],"created_at":"2025-04-19T11:42:26.593Z","updated_at":"2025-04-19T11:42:29.891Z","avatar_url":"https://github.com/2gis.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# General [![Build Status](https://travis-ci.org/2gis/general.svg?branch=master)](https://travis-ci.org/2gis/general)\n\nFast marker generalization algorithm\n\n[Demo](https://2gis.github.io/general/)\n\n## Содержание\n- [Общий принцип работы](#Общий-принцип-работы)\n- [Установка](#Установка)\n- [Использование](#Использование)\n- [Релиз](#Релиз)\n\n## Общий принцип работы ##\nНа вход алгоритму генерализации маркеров передается большой список маркеров. Алгоритм во время работы откидывает какое-то количество маркеров из этого списка так, чтобы оставшиеся отобразились на карте не пересекаясь друг с другом.\n\n![generalbeforeandafter](https://2gis.github.io/general/img/generalbeforeandafter.png)\\\n_Пример отображения маркеров на карте до и после генерализации_\n\nСчитается, что список маркеров отсортирован в порядке убывания приоритета. Маркера идущие впереди списка имеет больше шансов отобразиться на карте.\n\nМожно отображать разные группы маркеров на карте одновременно, например:\n- С коронкой\n- Обычный\n- Точка\n\nКаждая группа имеет собственные настройки того, как она будет обрабатываться алгоритмом.\n\nПример настроек:\n```js\n{\n  safeZone: 5,\n  margin: 10,\n  degradation: 180\n}\n```\n\nИзначально каждый из маркеров привязан к какой-то конкретной группе. Группы идут по порядку. Если маркер из первой группы не смог разместиться на карте, он попробует это сделать уже в рамках менее приоритетной _(второй)_ группы. Если и там он не смог появиться на карте, то он перейдет в следующую _(третью)_ группу и т.д.\n\nКаждый маркер для алгоритма генерализации представляется прямоугольной областью размерами равными размерам иконки маркера плюс один из вышеперечисленных параметров.\n\n### safeZone ###\nПеред вставкой на карту маркер проверяется на пересечение с другими, уже попавшими маркерами на карту. Для этой проверки берется область вокруг маркера равная его размеру плюс параметру `safeZone`.\n\n![safezone](https://2gis.github.io/general/img/safezone.png)\n\nМаркер A уже встал на карту и занял область равную своему размеру, но:\n- В первом случае маркер B успешно попадает на карту, т.к. параметр safeZone равен 40, и проверяемая область (красный квадрат) не пересекает область маркера A.\n- Во втором случае safeZone равен 80, проверяемая область пересекает маркер A, и B вынужден сменить группу на менее приоритетную (точка), в которой safeZone равен 0.\n\nТаким образом можно регулировать плотность одинаковых групп маркеров на карте, так чтобы они не кучковались, а распределялись равномерно.\n\n### margin ###\nКогда маркер попадает на карту, он занимает уже другую область не связанную с той, которая использовалась при проверке. Размеры этой области равны размерам иконки маркера плюс параметр `margin`.\n\nЭто параметр можно использовать, чтобы освободить зону на карте вокруг одного маркера от любых других:\n\n![margin](https://2gis.github.io/general/img/margin.png)\\\n_Слева параметр margin равен 0, справа – 40_\n\n### degradation ###\nМаркер, попавший в область заданную параметром `degradation` маркера из более приоритетной группы, автоматически переходят на одну группу ниже, вне зависимости от свободного места. Если группа была последней, то маркер пропадает.\n\nТаким образом можно выделить одни маркера, не уничтожая других полностью:\n\n![degradation](https://2gis.github.io/general/img/degradation.png)\\\n_Слева параметр degradation равен 0, справа - 40_\n\n## Установка ##\nС помощью `npm`:\n```bash\nnpm install @2gis/general\n```\nМожно подключить через `script` использовать через глобальную переменную `General`:\n```html\n\u003cscript src=\"node_modules/general/dist/general.js\"\u003e\u003c/script\u003e\n```\nЛибо подключить как es6 модуль:\n```js\nimport { General } from 'general';\n```\n## Использование ##\nДля работы нужно создать экземпляр класса:\n```js\nconst general = new General();\n```\nОсновной метод для генерализации:\n```js\ngeneral.generalize(bounds, groups, atlas, markers);\n```\nгде\n- `bounds: BBox` – границы, в которых происходит генерализация, маркера не попавшие в эти границы просто откидываются\n- `groups: PriorityGroup[]` – массив групп маркеров с настройками для генерализации\n- `atlas: Sprite[]` – массив объектов описывающих размеры иконок, которые могут использоваться маркерами\n- `markers: Marker[]` – массив маркеров\n\nМетод возвращает `Promise`, который резолвится после выполнения генерализации. Алгоритм выполняется асинхронно в воркере.\n\nКаждая из групп `PriorityGroup` содержит следующие параметры:\n- `iconIndex` – индекс иконки в атласе, которая будет установлена маркеру, попавшему в эту группу\n- `safeZone`, `margin`, `degradation` – описывались выше\n\nАтлас описывается массивом из `Sprite`, каждый из которых состоит из:\n- `size: Vec2` – размер иконки\n- `anchor: Vec2` – центр иконки относительно ее размеров, принимает значения от 0 до 1\n\nКаждый `Marker` состоит из:\n- `pixelPosition` – позиция маркера в пикселях, должна вычисляться вне алгоритма генерализации и находиться в той же системе координат, что и `bounds` переданные в метод `generalize`\n- `groupIndex` – индекс в массиве групп, к которой маркер будет изначально принадлежать\n\nМетод `generalize` **не возвращает** новый массив маркеров, он мутирует старый.\n\nВ процессе генерализации, алгоритм выставляет маркерам параметр `iconIndex` соответсвующий какой-то иконке в атласе. Если этот параметр стал равным `-1`, значит, что маркер не должен попасть на карту и его надо скрыть.\n\n## Релиз ##\n1. `npm version patch` – обновить версию в `package.json`\n2. `git push --follow-tags` – запушить изменения на github\n3. `rm -rf dist \u0026\u0026 npm run build` – собрать проект\n4. `npm publish` – отправить в npm\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2gis%2Fgeneral","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F2gis%2Fgeneral","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2gis%2Fgeneral/lists"}