--- 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.