ScienceForChange / SoundCollect_dashboard

0 stars 0 forks source link

Polygon filter #31

Closed OtariOboladzeSfC closed 1 day ago

OtariOboladzeSfC commented 3 weeks ago

Implement polygon filter into backend

OtariOboladzeSfC commented 2 weeks ago

php function url to filter points in polygon: https://assemblysys.com/php-point-in-polygon-algorithm/

OtariOboladzeSfC commented 2 weeks ago

There is a need for an API endpoint that will receive polygon coordinates and return all the observations that are within this polygon.

OtariOboladzeSfC commented 2 weeks ago

solucion si en algun momento funcion pointInPolygon no reconozca los numeros como integers:

       if (
            floatval($point['y']) > min(floatval($vertex1['y']), floatval($vertex2['y'])) and
            floatval($point['y']) <= max(floatval($vertex1['y']), floatval($vertex2['y'])) and
            floatval($point['x']) <= max(floatval($vertex1['x']), floatval($vertex2['x'])) and
            floatval($vertex1['y']) != floatval($vertex2['y'])
        ) {

            // $xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];

            $xinters = (floatval($point['y']) - floatval($vertex1['y']))
                * (floatval($vertex2['x']) - floatval($vertex1['x']))
                / (floatval($vertex2['y']) - floatval($vertex1['y']))
                + floatval($vertex1['x']);

            // Check if point is on the polygon boundary (other than horizontal)
            if (floatval($xinters) == floatval($point['x'])) {
                return "boundary";
            }

            if (floatval($vertex1['x']) == floatval($vertex2['x']) || floatval($point['x']) <= floatval($xinters)) {
                $intersections++;
            }
        }
CarlosMillanSfC commented 2 weeks ago

@almenarasfc

Para poder filtrar observaciones por polígonos, tal y como está ahora la bbdd estructurada, lo he dejado para que si me envías una petición POSTcon las cabeceras:

Accept:application/json
Content-Type:application/json

Y un JSON en el body tal que así:

{
    "concern": "inside",
    "polygon": ["2.1493506 41.3755365", "2.1458209 41.3778471", "2.1496511 41.3804554", "2.1528375 41.3779518", "2.1493614 41.3755446"] 
}

En la clave "concern" solo se permite enviar 'inside', 'outside', 'boundary' o 'vertex' (en minúscula siempre)

Y te devolverá las observaciones que se ajusten a ese concern

Y en polígono es un array de strings donde me envías por cada elemento la "longitud latitud" separados por un espacio en blanco.

CarlosMillanSfC commented 2 weeks ago

Después de hablar con @almenarasfc me dijo que también va a hacer falta que el filtro del polígono tenga en cuenta un tramo horario que se enviará en la petición por lo que modifico el filtrado para que pueda filtrarse por cualquier intervalo horario de cualquier día (por ejemplo de 13:00 a 20:00 de cualquier día. Al menos así entendí, me confirmas cuando puedas @OtariOboladzeSfC )

lo que cambia es el JSON que se envía que pasa a ser:

{
    "concern": "inside",
    "polygon": ["2.1493506 41.3755365", "2.1458209 41.3778471", "2.1496511 41.3804554", "2.1528375 41.3779518", "2.1493614 41.3755446"],
    "interval": {
        "start" : "13:15:33",
        "end" : "13:15:33" 
    }
}

La clave interval tiene una validación muy simple que es:

El código está comentado por si hiciera falta para cualquier cosa, PR linkada