{"id":18174814,"url":"https://github.com/kylebarron/snap-to-tin","last_synced_at":"2025-06-29T09:38:18.094Z","repository":{"id":43978102,"uuid":"245718506","full_name":"kylebarron/snap-to-tin","owner":"kylebarron","description":"Snap vector features to the faces of a triangulated irregular network (TIN)","archived":false,"fork":false,"pushed_at":"2023-01-05T09:47:58.000Z","size":595,"stargazers_count":22,"open_issues_count":9,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-23T07:28:25.160Z","etag":null,"topics":["mesh","terrain","terrain-rendering","triangular-mesh","vector-tiles"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/kylebarron.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":"2020-03-07T23:02:59.000Z","updated_at":"2024-09-13T18:41:06.000Z","dependencies_parsed_at":"2023-02-03T23:31:42.737Z","dependency_job_id":null,"html_url":"https://github.com/kylebarron/snap-to-tin","commit_stats":null,"previous_names":["kylebarron/snap-features-to-tin"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylebarron%2Fsnap-to-tin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylebarron%2Fsnap-to-tin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylebarron%2Fsnap-to-tin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylebarron%2Fsnap-to-tin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kylebarron","download_url":"https://codeload.github.com/kylebarron/snap-to-tin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232133627,"owners_count":18477294,"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":["mesh","terrain","terrain-rendering","triangular-mesh","vector-tiles"],"created_at":"2024-11-02T16:07:50.178Z","updated_at":"2025-01-01T22:41:06.940Z","avatar_url":"https://github.com/kylebarron.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# snap-to-tin\n\n[![Build Status](https://travis-ci.org/kylebarron/snap-to-tin.svg?branch=master)](https://travis-ci.org/kylebarron/snap-to-tin)\n\nSnap vector features to the faces of a triangulated irregular network (TIN).\n\n## Overview\n\nGiven a TIN representing a terrain mesh, this snaps 2D `Point` and `LineString`\nfeatures to the faces of that mesh.\n\nFor `Point` features, this finds the triangle containing that point and linearly\ninterpolates from the heights of the triangle's vertices to find the point's\nelevation.\n\nFor `LineString` features, this finds the elevation of every vertex using the\nsame method as for `Point`s, but also finds every intersection between each\n`LineString` segment and triangle edges. At each segment-edge intersection, a\nnew vertex is added to the resulting `LineString`, so that every part of the\n`LineString` is attached to a face of the mesh.\n\n## Install\n\n```bash\nyarn add @kylebarron/snap-to-tin\n# or\nnpm install @kylebarron/snap-to-tin\n```\n\n## Usage\n\n**Note that the coordinates of the TIN and the vector features need to be in the\nsame coordinate system.**\n\n```js\nimport snapFeatures from '@kylebarron/snap-to-tin'\nimport {load} from '@loaders.gl/core';\nimport {TerrainLoader} from '@loaders.gl/terrain';\n\n// Load and parse terrain mesh\nconst terrain = await load(terrainImage, TerrainLoader);\n\n// Construct class\nconst snap = new SnapFeatures({\n  // triples of position indices that make up the faces of the terrain\n  indices: terrain.indices.value,\n  // x, y, z positions in space of each index\n  positions: terrain.attributes.POSITION.value,\n  // Optional bounding box to clip features to\n  bounds: [0, 0, 1, 1]\n})\n\n// array of GeoJSON features\nconst features = [...]\nconst snappedFeatures = snap.snapFeatures({features})\n```\n\n## API\n\nThe default export is a class: `SnapFeatures`.\n\n### `SnapFeatures` constructor\n\nAdmits an object with the following keys:\n\n- **`indices`**: a flat TypedArray with triples of indices referring to `positions` of the triangles that make up the TIN. Each triple refers to a triangle face. So `[1, 3, 4, ...]` would mean that the second, fourth, and fifth (since zero-indexed) set of coordinates in `positions` constitute a triangle face.\n- **`positions`**: a flat TypedArray with x, y, z coordinates of the triangles. So `[0.25, 0.5, 625, ...]` would mean that the first position, i.e. `0` in `indices`, has position `x=0.25`, `y=0.5`, `z=625` in the given coordinate space.\n- **`bounds`**: (optional) an array of `[minX, minY, maxX, maxY]` to be used for clipping features. This is used to clip vector features, since heights cannot be found for positions outside the extent defined by the `positions` array. If provided, `bounds` will be intersected with the maximal bounds from the `positions` array. Default: maximum extent of `positions`\n\n    This is especially useful with features generated from vector tiles, since vector tiles usually have buffer outside the geographic extent it represents.\n\n### `SnapFeatures.snapFeatures()`\n\nSnap GeoJSON `Point` and `LineString` features to the TIN. Admits an object with\nthe following keys:\n\n- **`features`**: an array of GeoJSON `Feature`s, containing 2D `Point` and `LineString` geometries. Other geometry types will be silently skipped.\n\nReturns new GeoJSON features with 3D coordinates.\n\n### `SnapFeatures.snapPoints()`\n\nSnap a TypedArray of points to the TIN.\n\n- **`positions`**: a flat TypedArray with positions of 2D `Point` geometries.\n\n  Note that this is different from the `positions` given to the constructor,\n  which are the positions of the triangles of the TIN. These are the positions\n  of `Point`s on the TIN.\n\n- **`featureIds`**: Optional, a flat TypedArray with `featureIds`, one per\n  vertex. If provided, a similar TypedArray will be returned. Since some input\n  points can be omitted from the output (e.g. if outside the bounds of the TIN),\n  this helps to keep track of which snapped point has which properties. This\n  must be the same length as the number of vertices within `positions`. So if\n  `positions` holds five 2D coordinates, the length of `positions` should be 10\n  and the length of `featureIds` should be 5.\n\nReturns:\n\n```js\n{\n  // A flat TypedArray containing 3D coordinates for each point\n  positions: TypedArray,\n  // If provided as input, a mutated featureIds array for each snapped vertex\n  featureIds: TypedArray,\n}\n```\n\n### `SnapFeatures.snapLines()`\n\nSnap a TypedArray of lines to the TIN.\n\n- **`positions`**: a flat TypedArray with positions of 2D `LineString` geometries.\n\n  Note that this is different from the `positions` given to the constructor,\n  which are the positions of the triangles of the TIN. These are the positions\n  of `LineString`s on the TIN.\n\n- **`pathIndices`**: a flat TypedArray with indices of where each individual\n  `LineString` starts. For example, if there are 3 paths of 2, 3, and 4 vertices\n  each, `pathIndices` should be `[0, 2, 5, 9]`. Note, this must have length `n + 1`, where `n` is the number of vertices. If not provided, assumed the entire\n  `positions` array constitutes a single `LineString`.\n\n- **`featureIds`**: Optional, a flat TypedArray with `featureIds`, one per\n  vertex. If provided, a similar TypedArray will be returned. Since some input\n  lines can be omitted from the output (e.g. if outside the bounds of the TIN),\n  this helps to keep track of which snapped vertex has which properties. This\n  must be the same length as the number of vertices within `positions`. So if\n  `positions` holds five 2D coordinates, the length of `positions` should be 10\n  and the length of `featureIds` should be 5.\n\nReturns:\n\n```js\n{\n  // A flat TypedArray containing 3D coordinates for each point\n  positions: TypedArray,\n  // A flat TypedArray with indices of where each snapped `LineString` starts\n  pathIndices: TypedArray,\n  // If provided as input, a mutated featureIds array for each snapped vertex\n  featureIds: TypedArray,\n}\n```\n\n### Use with `TypedArray`s\n\nThis library is designed to support `TypedArray`s (through the `snapPoints` and\n`snapLines` methods) in order to achieve maximum performance. When using web\nworkers, passing `TypedArray`s is most efficient because it allows for bypassing\nserialization and deserialization of the data. In the next release, loaders.gl\n[will have support](https://github.com/uber-web/loaders.gl/pull/690) for reading\nMapbox Vector Tiles directly into `TypedArray`s. Deck.gl [also\nsupports](https://deck.gl/#/documentation/developer-guide/performance-optimization?section=use-binary-data)\npassing binary `TypedArray`s as data to its layers. So the process of\n\n1. Loading vector geometries\n2. Snapping features to the TIN\n3. Passing to deck.gl layers\n\nshould be quite fast, and additionally there would be little main-thread\nperformance cost to doing #2 on a worker thread.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylebarron%2Fsnap-to-tin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkylebarron%2Fsnap-to-tin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylebarron%2Fsnap-to-tin/lists"}