{"id":13508258,"url":"https://github.com/pkinney/topo","last_synced_at":"2025-10-21T18:43:27.218Z","repository":{"id":8364697,"uuid":"57012814","full_name":"pkinney/topo","owner":"pkinney","description":"A Geometry library for Elixir that calculates spatial relationships between two geometries","archived":false,"fork":false,"pushed_at":"2025-01-25T23:09:08.000Z","size":4338,"stargazers_count":165,"open_issues_count":2,"forks_count":25,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-12T09:45:24.401Z","etag":null,"topics":["computational-geometry","geometry","geospatial","gis","spatial-analysis"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/pkinney.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2016-04-25T04:58:55.000Z","updated_at":"2025-09-25T04:26:31.000Z","dependencies_parsed_at":"2023-02-10T05:15:43.264Z","dependency_job_id":"38b07d28-72b8-45f4-b125-ffe057d5a419","html_url":"https://github.com/pkinney/topo","commit_stats":{"total_commits":37,"total_committers":9,"mean_commits":4.111111111111111,"dds":"0.43243243243243246","last_synced_commit":"87b1e2ace56c9e9daf9a298755831525b3d9ee62"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pkinney/topo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkinney%2Ftopo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkinney%2Ftopo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkinney%2Ftopo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkinney%2Ftopo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pkinney","download_url":"https://codeload.github.com/pkinney/topo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkinney%2Ftopo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279579088,"owners_count":26194580,"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","status":"online","status_checked_at":"2025-10-18T02:00:06.492Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["computational-geometry","geometry","geospatial","gis","spatial-analysis"],"created_at":"2024-08-01T02:00:50.449Z","updated_at":"2025-10-21T18:43:27.202Z","avatar_url":"https://github.com/pkinney.png","language":"Elixir","funding_links":[],"categories":["Geolocation","Geospatial Library","Elixir"],"sub_categories":["Elixir"],"readme":"# Geometry Library for Elixir\n\n![Build Status](https://github.com/pkinney/topo/actions/workflows/ci.yaml/badge.svg)\n[![Hex.pm](https://img.shields.io/hexpm/v/topo.svg)](https://hex.pm/packages/topo)\n\nA Geometry library for Elixir that calculates spatial relationships between two\ngeometries. Geometries can be of any of the following types:\n\n- Point\n- LineString\n- Polygon\n- MultiPoint\n- MultiLineString\n- MultiPolygon\n\n## Installation\n\n```elixir\ndefp deps do\n  [{:topo, \"~\u003e 1.0\"}]\nend\n```\n\n## Usage\n\n**[Full Documentation](https://hexdocs.pm/topo/Topo.html)**\n\nThe `Topo` module provides functions for determining the relationship between\ntwo geometries. Each function returns a boolean and accepts any combination of\nPoint, LineString, Polygon, MultiPoint, MultiLineString, or MultiPolygon.\n\n- **`intersects?`** - Geometries **A** and **B** share at least one point in\n  common.\n- **`disjoint?`** - Disjoint geometries share no points in common. This is the\n  direct opposite of the `intersects?` result.\n- **`contains?`** - All points of geometry **B** lie within **A**. See section\n  below on [Contains].\n- **`within?`** - This is the direct inverse of `contains?`. All points of\n  geometry **A** lie within geometry **B**.\n- **`equals?`** - Geometries **A** and **B** are equivalent and cover the exact\n  same set of points. By definition, **A** and **B** are equal if **A** contains\n  **B** and **B** contains **A**. Equality does not necessarily mean that the\n  geometries are of the same type. A Point **A** is equal to a MultiPoint that\n  contains only the same Point **A**.\n\nEach of these functions can be passed any two Geometries in either a Map with a\n`:type` and `:coordinates` keys or as a struct generated via the [Geo library](https://github.com/bryanjos/geo). Coordinates are represented as atoms `{x, y}`\nand multiple coordinates as Lists.\n\n```elixir\na = %{type: \"Polygon\", coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}\nb = %Geo.Polygon{coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}\n\nTopo.equals? a, b # =\u003e true\n```\n\nInstead of a Point geometry, just a single coordinate can be used.\n\n```elixir\na = %{type: \"Polygon\", coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}\n\nTopo.intersects? a, {4, 6} # =\u003e true\n```\n\nThe `Topo` library's functions will automatically attempt to \"clean\" geometries\npassed to them:\n\n- Linear Rings (including Polygons) will be reordered to a counter-clockwise\n  direction.\n- Polygon's Linear Rings will automatically be closed if the first point is not\n  repeated as the last point.\n- Points that are equal or collinear with surrounding points are removed from\n  LineStrings or Polygons.\n\n## A note on `contains?`\n\nThere are a few non-obvious special cases that are worth mentioning:\n\n- A Polygon does not contain its own boundary. Specifically a LineString that\n  is the exact same as a Polygon's exterior Linear ring is not contained within a\n  that Polygon.\n\n```elixir\na = %Geo.Polygon{coordinates: [[{2, 2}, {20, 2}, {11, 11}, {2, 2}]]}\nb = %Geo.LineString{coordinates: [{2, 2}, {20, 2}, {11, 11}, {2, 2}]}\n\nTopo.contains? a, b # =\u003e false\nTopo.intersects? a, b  # =\u003e true\n```\n\n- A LineString does not contain it's own first and last point (unless those\n  points are the same, as in a LinearRing)\n\n```elixir\na = %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}]}\nb = %Geo.LineString{coordinates: [{1, 3}, {2, -1}, {0, -1}, {1, 3}]}\n\nTopo.contains? a, {1, 3} # =\u003e false\nTopo.intersects? a, {1, 3} # =\u003e true\nTopo.contains? b, {1, 3} # =\u003e true\n```\n\n## Float Precision Issues\n\nIt is possible that floating point math imprecision can cause incorrect results for certain inputs. This is often encountered during the line segment comparison (see [LineStringPolygonTest](https://github.com/pkinney/topo/blob/master/test/linestring_polygon_test.exs) for an example).  By default, `Topo` is strict on intersection math; however, if you with to allow a less strict requirement for line segment intersection, you can set an `:epsilon` value at compile time, which will be passed to the [SegSeg](https://github.com/pkinney/segseg_ex) library (see [here](https://github.com/pkinney/segseg_ex#float-precision-issues) for a more detailed explanation).\n\nIn your application's config file add\n\n```elixir\nconfig :topo, epsilon: true\n```\n\nTopo uses the `Application.config_env/3` function to avoid querying the value on each computation, so you may have to clean and recompile the dependencies of your application after changing.  The default value is `false` will will apply strict comparison to the resulting floating point numbers used in calculating line segment relationships.\n\n\n## Tests\n\n```bash\n\u003e mix test\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpkinney%2Ftopo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpkinney%2Ftopo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpkinney%2Ftopo/lists"}