---
id: point_in_ring_py_geo
name: point_in_ring
kind: function
lang: py
domain: geo
version: "1.0.0"
purity: pure
signature: "point_in_ring(lon: float, lat: float, ring: list[tuple[float, float]]) -> bool"
description: "Determina si el punto (lon, lat) esta dentro de un anillo poligonal usando ray casting. Retorna False si len(ring) < 3."
tags: [geo, polygon, ray-casting, point-in-polygon]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
example: |
  from geo.point_in_ring import point_in_ring
  ring = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)]
  inside = point_in_ring(0.5, 0.5, ring)  # True
tested: true
tests: ["punto_dentro_cuadrado", "punto_fuera_cuadrado", "ring_menor_3_vertices"]
test_file_path: "python/functions/geo/tests/test_point_in_ring.py"
file_path: "python/functions/geo/point_in_ring.py"
params:
  - {name: lon, desc: "longitud del punto a comprobar en grados decimales"}
  - {name: lat, desc: "latitud del punto a comprobar en grados decimales"}
  - {name: ring, desc: "lista de vertices (lon, lat) que forman el anillo cerrado"}
output: "True si el punto esta dentro del anillo, False en caso contrario"
source_repo: "internal:footprint_aurgi"
source_license: "internal-aurgi"
source_file: "zonas_mapas_aurgi/backend/app.py:715"
---

## Ejemplo

```python
from geo.point_in_ring import point_in_ring

ring = [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)]
point_in_ring(0.5, 0.5, ring)  # True
point_in_ring(2.0, 2.0, ring)  # False
```

## Notas

Algoritmo de ray casting clasico. El epsilon 1e-15 en el denominador evita division por cero en aristas horizontales.
