Abbiamo un protocollo di terra in cui riceviamo una rete da pesca di celle da 1x1 km. Alcune cellule sono scelte casualmente. Dobbiamo mettere 4 punti in ogni cella e anche questi punti devono essere su una strada. La distanza minima tra i punti deve essere di 500 m per ogni punto di ogni cella SE POSSIBILE o, in caso contrario, vogliamo la massima distanza possibile.
In un primo tentativo abbiamo diviso ogni cella in quattro celle da 500x500 m con ST_CreateFishnet, quindi abbiamo inserito i punti nel centroide delle sotto-celle, quindi sulla strada più vicina (ST_ClosestPoint). Otteniamo alcuni buoni risultati ma nell'esempio sotto puoi vedere che il punto 5 è troppo vicino al 6 e potrebbe essere spostato sulla strada a sinistra.
WITH
r1 AS ( -- only sub-cells which intersects random cells
SELECT id_maille, ROW_NUMBER() OVER() AS id_grille, fishnet_500.geomgrille
FROM fishnet_500
JOIN t_mailles
ON ST_Intersects(ST_Buffer(t_mailles.geom,-200), fishnet_500.geomgrille) -- buffer < 0 to not select neightbours
)
,
r2 AS ( -- cut roads in every cells
SELECT id_maille, id_grille, ST_Intersection((ST_Dump(roads.geom)).geom, r1.geomgrille) as geomroute
FROM roads
JOIN r1
ON ST_Intersects(roads.geom, r1.geomgrille)
)
-- select point on each road the closest to cell centroid
SELECT r2.id_maille, r2.id_grille, ST_ClosestPoint(ST_Union(r2.geomroute),ST_Centroid(r1.geomgrille)) as geomipa
FROM r2
JOIN r1
ON r2.id_grille = r1.id_grille
GROUP BY r2.id_maille, r2.id_grille, r1.geomgrille
ORDER BY r2.id_maille, r2.id_grille
Se vuoi provarlo, metto i 3 strati (a rete con celle casuali, sottorete e strade) in un archivio che puoi trovare qui .
Immagino che non possiamo evitare un algoritmo ricorsivo che prova molte possibilità ma non ne sono sicuro.