{"id":29248649,"url":"https://github.com/rstudio-tech/geometry-polygon","last_synced_at":"2025-07-04T00:08:23.078Z","repository":{"id":302494978,"uuid":"898981484","full_name":"rstudio-tech/Geometry-Polygon","owner":"rstudio-tech","description":"Geometry library for C - Fast point-in-polygon","archived":false,"fork":false,"pushed_at":"2024-12-05T12:04:36.000Z","size":5131,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-02T17:55:28.189Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","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/rstudio-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","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,"zenodo":null}},"created_at":"2024-12-05T11:59:48.000Z","updated_at":"2024-12-05T12:04:42.000Z","dependencies_parsed_at":"2025-07-02T18:05:37.761Z","dependency_job_id":null,"html_url":"https://github.com/rstudio-tech/Geometry-Polygon","commit_stats":null,"previous_names":["rstudio-tech/geometry-polygon"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rstudio-tech/Geometry-Polygon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rstudio-tech%2FGeometry-Polygon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rstudio-tech%2FGeometry-Polygon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rstudio-tech%2FGeometry-Polygon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rstudio-tech%2FGeometry-Polygon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rstudio-tech","download_url":"https://codeload.github.com/rstudio-tech/Geometry-Polygon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rstudio-tech%2FGeometry-Polygon/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263421931,"owners_count":23464051,"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":[],"created_at":"2025-07-04T00:08:22.357Z","updated_at":"2025-07-04T00:08:23.007Z","avatar_url":"https://github.com/rstudio-tech.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"docs/assets/logo.png\" width=\"240\" alt=\"TG\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"docs/API.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/api-reference-blue.svg?style=flat-square\" alt=\"API Reference\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nTG is a geometry library for C that is small, fast, and easy to use.\nI designed it for programs that need real-time geospatial, such as geofencing, monitoring, and streaming analysis.\n\n## Features\n\n- Implements OGC [Simple Features](https://en.wikipedia.org/wiki/Simple_Features) including Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection. \n- Optimized [polygon indexing](docs/POLYGON_INDEXING.md) that introduces two new structures.\n- Reads and writes [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry), [WKB](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry), and [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON).\n- Provides a purely functional [API](docs/API.md) that is reentrant and thread-safe.\n- Spatial predicates including \"intersects\", \"covers\", \"touches\", \"equals\", etc.\n- Compiles to Webassembly using Emscripten\n- [Test suite](tests/README.md) with 100% coverage using sanitizers and [Valgrind](https://valgrind.org).\n- Self-contained library that is encapsulated in the single [tg.c](tg.c) source file.\n- Pretty darn good performance. 🚀 \u003csup\u003e[[benchmarks]](docs/BENCHMARKS.md)\u003c/sup\u003e\n\n## Goals\n\nThe main goal of TG is to provide the fastest, most memory efficent geometry library for the purpose of monitoring spatial relationships, specifically operations like point-in-polygon and geometry intersect.\n\nIt's a non-goal for TG to be a full GIS library. Consider [GEOS](https://libgeos.org) if you need GIS algorithms like generating a convex hull or voronoi diagram.\n\n## Performance\n\nTG uses [entirely new](docs/POLYGON_INDEXING.md) indexing structures that speed up [geometry predicates](docs/API.md#geometry-predicates). It can index more than 10GB per second of point data on modern hardware, while using less than 7% of additional memory, and can perform over 10 million point-in-polygon operations per second, even when using large polygons with over 10K points.\n\nThe following benchmark provides an example of the point-in-polygon performance\nof TG when using a large polygon. In this case of Brazil, which has 39K points.\n\n\u003cpre\u003e\n\u003cb\u003eBrazil              ops/sec    ns/op  points  hits       built      bytes\u003c/b\u003e\ntg/none              96,944    10315   39914  3257    46.73 µs    638,720\ntg/natural       10,143,419       99   39914  3257    53.17 µs    681,360\ntg/ystripes      15,174,761       66   39914  3257   884.06 µs  1,059,548\ngeos/none            29,708    33661   39914  3257   135.18 µs    958,104\ngeos/prepared     7,885,512      127   39914  3257  2059.94 µs  3,055,496\n\u003c/pre\u003e\n\n- \"built\": Column showing how much time the polygon and index took to construct.\n- \"bytes\": Column showing the final in-memory size of the polygon and index.\n- \"none\": No indexing was used.\n- \"natural\": Using TG [Natural](docs/POLYGON_INDEXING.md#natural) indexing\n- \"ystripes\": Using TG [YStripes](docs/POLYGON_INDEXING.md#ystripes) indexing\n- \"prepared\": Using a [GEOS](https://libgeos.org) PreparedGeometry\n\nSee all [benchmarks](docs/BENCHMARKS.md) for more information.\n\n## Using\n\nJust drop the \"tg.c\" and \"tg.h\" files into your project. \nUses standard C11 so most modern C compilers should work.\n\n```sh\n$ cc -c tg.c\n```\n\n## Programmer notes\n\n*Check out the complete [API](docs/API.md) for detailed information.*\n\n#### Pure functions\n\nTG library functions are thread-safe, reentrant, and (mostly) without side\neffects.\nThe exception being with the use of malloc by some functions like\n[geometry constructors](docs/API.md#geometry-constructors).\nIn those cases, it's the programmer's responsibiilty to check the return value\nbefore continuing.\n\n```c\nstruct tg_geom *geom = tg_geom_new_point(-112, 33);\nif (!geom) {\n    // System is out of memory.\n}\n```\n\n#### Fast cloning\n\nThe cloning of geometries, as with [tg_geom_clone()](docs/API.md#tg_geom_clone), are\nO(1) operations that use implicit sharing through an atomic reference counter.\nGeometry constructors like [tg_geom_new_polygon()](docs/API.md#tg_geom_new_polygon) will\nuse this method under the hood to maintain references of its inputs.\n\nWhile this may only be an implementation detail, it's important for the\nprogrammer to understand how TG uses memory and object references.\n\nFor example:\n\n```c\nstruct tg_geom *geom = tg_geom_new_polygon(exterior, holes, nholes);\n```\n\nAbove, a new geometry \"geom\" was created and includes a cloned reference to the \n[tg_ring](docs/API.md#tg_ring) \"exterior\" and all of the holes.\n\nProviding `TG_NOATOMICS` to the compiler will disable the use of atomics and \ninstead use non-atomic reference counters.\n\n```\ncc -DTG_NOATOMICS tg.c ...\n```\n\nAlternatively, the [tg_geom_copy()](docs/API.md#tg_geom_copy) method is available to perform a deep copy of the\ngeometry.\n\n#### Avoid memory leaks\n\nTo avoid memory leaks, call [tg_geom_free()](docs/API.md#tg_geom_free) on geometries\ncreated from [geometry constructors](docs/API.md#geometry-constructors), \n[geometry parsers](docs/API.md#geometry-parsing), [tg_geom_clone()](docs/API.md#tg_geom_clone), and [tg_geom_copy()](docs/API.md#tg_geom_copy)\n\nIn other words, for every `tg_geom_new_*()`, `tg_geom_parse_*()`, \n`tg_geom_clone()`, and `tg_geom_copy()` there should be (eventually and exactly)\none `tg_geom_free()`.\n\n#### Upcasting\n\nThe TG object types [tg_line](docs/API.md#tg_line), [tg_ring](docs/API.md#tg_ring), and \n[tg_poly](docs/API.md#tg_poly) can be safely upcasted to a [tg_geom](docs/API.md#tg_geom) with no\ncost at runtime.\n\n```c\nstruct tg_geom *geom1 = (struct tg_geom*)line; // Cast tg_line to tg_geom\nstruct tg_geom *geom2 = (struct tg_geom*)ring; // Cast tg_ring to tg_geom\nstruct tg_geom *geom3 = (struct tg_geom*)poly; // Cast tg_poly to tg_geom\n```\n\nThis allows for exposing all [tg_geom](docs/API.md#tg_geom) functions to the other\nobject types.\n\nIn addition, the [tg_ring](docs/API.md#tg_ring) type can also cast to a\n[tg_poly](docs/API.md#tg_poly).\n\n```c\nstruct tg_poly *poly = (struct tg_poly*)ring; // Cast tg_ring to tg_poly\n```\n\n*Do not downcast. It's not generally safe to cast from a [tg_geom](docs/API.md#tg_geom) to other\ntypes.*\n\n\n## Example\n\nCreate a program that tests if two geometries intersect using [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) as inputs.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003ctg.h\u003e\n\nint main(int argc, char **argv) {\n    if (argc != 3) {\n        fprintf(stderr, \"Usage: %s \u003cgeom-a\u003e \u003cgeom-b\u003e\\n\", argv[0]);\n        return 1;\n    }\n\n    // Parse the input geometries and check for errors.\n    struct tg_geom *a = tg_parse_wkt(argv[1]);\n    if (tg_geom_error(a)) {\n        fprintf(stderr, \"%s\\n\", tg_geom_error(a));\n        return 1;\n    }\n    struct tg_geom *b = tg_parse_wkt(argv[2]);\n    if (tg_geom_error(b)) {\n        fprintf(stderr, \"%s\\n\", tg_geom_error(b));\n        return 1;\n    }\n\n    // Execute the \"intersects\" predicate to test if both geometries intersect.\n    if (tg_geom_intersects(a, b)) {\n        printf(\"yes\\n\");\n    } else {\n        printf(\"no\\n\");\n    }\n\n    // Free geometries when done.\n    tg_geom_free(a);\n    tg_geom_free(b);\n    return 0;\n}\n```\n\nBuild and run the example:\n\n```sh\n$ cc -I. examples/intersects.c tg.c\n$ ./a.out 'POINT(15 15)' 'POLYGON((10 10,20 10,20 20,10 20,10 10))'\nyes\n```\n\n## License\n\nTG source code is available under the MIT [License](/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frstudio-tech%2Fgeometry-polygon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frstudio-tech%2Fgeometry-polygon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frstudio-tech%2Fgeometry-polygon/lists"}