r-lidar-lab / ALSroads

Road corrections and measurements from ALS data
19 stars 4 forks source link

sf::st_geometry() en remplacement $geometry #10

Closed jfbourdon closed 2 years ago

jfbourdon commented 2 years ago

Si la colonne contenant les géométries dans l'object sf ne s'appelle pas geometry, la fonction st_snap_lines() échouait avec l'erreur suivante:

Error in roads[j, ]$geometry[[1]][1, 1] <- u[i][[1]][[1]] : 
  incorrect number of subscripts on matrix

Dans mon jeu de données, la colonne de géométrie utilisait geom causant une erreur si on cherchait geometry. En utilisant sf::st_geometry() on évite la confusion possible.

J'ai aussi précisé que la variable de tolérance est en unité de distance.

Finalement, j'ai rendu dynamique la tolérance de sf::st_is_within_distance() lors de la jointure pour qu'elle soit fonction de la tolérance principale. À mon avis, si en souhaite une tolérance de 15 m en entrée au lieu du 8 m par défaut, on accepte alors probablement que le point milieu soit potentiellement à plus de 5 m des extrémités, soit dans ce cas-ci à un maximum de 9.375 m.

Jean-Romain commented 2 years ago

Dans mon jeu de données, la colonne de géométrie utilisait geom causant une erreur si on cherchait geometry. En utilisant sf::st_geometry()

Ok mais es tu sûr que ca marche toujours ? Parce que ca à l'air d'une erreur (et s'en est une) mais une erreur pour une bonne raison. Si tu updates une copie de la variable ca marche pas. Enfin j'imagine que tu as testé

Finalement, j'ai rendu dynamique la tolérance de sf::st_is_within_distance() lors de la jointure pour qu'elle soit fonction de la tolérance principale. À mon avis, si en souhaite une tolérance de 15 m en entrée au lieu du 8 m par défaut, on accepte alors probablement que le point milieu soit potentiellement à plus de 5 m des extrémités, soit dans ce cas-ci à un maximum de 9.375 m.

J'ai pas compris désolé

jfbourdon commented 2 years ago

Enfin j'imagine que tu as testé

Oui j'ai testé et ça fonctionne bien, mais je dois t'avouer que je pensais que j'allais devoir utiliser st_set_geometry() à la place de st_geometry, mais il semble que non.

J'ai pas compris désolé

https://github.com/Jean-Romain/MFFProads/blob/e7527e2c16c776d0066d21e0245959e4f50c37aa/R/line_tools.R#L17-L26

Puisque la position des points stockés dans u correspondent au point milieu entre deux segments, si tolerance vaut 8 m, la distance entre u et l'une des extrémités sera forcément d'au plus 4 m. Ainsi, quand on fait v <- sf::st_is_within_distance(u, start, 5), on aura forcément une valeur valide. Toutefois, si tolerance vaut 16 m, la distance entre u et l'une des extrémités sera pourra valoir jusqu' 8 m ce qui fera entre que des jointures seront refusée à cause de la valeur de 5 inscrite en dur. En l'ajustant par rapport à la tolérance principale, on s'assure de respecter la volonté de l'utilisateur. En fait, cette valeur devrait peut-être être carrément tolerance/2

Jean-Romain commented 2 years ago

Ok je comprend que j'ai laissé un 5 codé en dur (erreur de ma part). Par contre je ne comprend pas le 5/8 * tolerance. tolerance/2 pourquoi pas. tolerance me semble intuitivement mieux. On peut le dessiner pour s'en convaincre

st_snap

jfbourdon commented 2 years ago

J'avais mis 5/8 * tolerance pour que le résultat soit inchangé avec la valeur par défaut de tolerance, soit 5 / 8 * 8 = 5, pensant qu'il y avait quand même une raison particulière pour laquelle tu avais laissé le 5 là.

Ça peut effectivement être remplacé par tolerance tout court au lieu de tolerance / 2 puisque la coordonnée du point milieu sera inévitablement à moins de 1 * tolerance. Je te laisse éditer avec ce que tu préfères.