Sélection groupée des voisins les plus proches dans QGIS

14

J'ai une liste contenant plus de 100 000 points au format lat / long que j'ai importé dans qgis.

Maintenant, ce que j'essaie de faire ici est de regrouper tous ces points en groupes de boîtes et j'entends par là essentiellement que je veux diviser la carte en boîtes englobantes.

Mes exigences sont les suivantes:

  • aucun groupe en boîte ne devrait avoir MOINS DE 100 et PAS PLUS DE 200 points
  • aucun point ne doit être situé dans plus d'un groupe
  • tous les points doivent être basés sur leur plus proche voisin

Comment pourrais-je y parvenir grâce à qgis?

Je suppose que l'on peut passer du code de requête personnalisé et enregistrer les résultats ou les boîtes créées en tant que fichier de formes correct? Quelqu'un pourrait-il expliquer comment cela pourrait être fait et à quoi ressemblerait le code?

Comme mentionné, mon objectif est d'avoir un tas de boîtes carrées affichées comme une couche de fichier de formes où, dans chaque boîte, il n'y a pas moins de 100 propriétés et pas plus de 200.

NetConstructor.com
la source
6
À tous ceux qui ont marqué cette question comme "favorite": pourquoi ne pas voter aussi? On pourrait penser que votre question préférée devrait être une bonne question.
underdark
1
Pourquoi avez-vous besoin de boxe? Si vous créez des boîtes en fonction du nombre, elles seront de toute façon de tailles différentes, donc le carrelage est hors de question. Il est probablement plus facile de regrouper en polygones (c.-à-d. Coque convexe).
diciu
@diciu merci pour la réponse. Oui, je suppose qu'une coque convexe conviendrait, car je pourrais les transformer en boîtes par la suite. Quel code devrais-je utiliser pour le faire en utilisant l'approche coque convexe?
NetConstructor.com
2
Si vous utilisez des coques convexes, vos boîtes englobantes (entourant les coques) se chevaucheront et votre exigence pour qu'un point soit dans un seul BBOX n'est plus satisfaite. Les coques convexes ne fonctionnent pas comme une étape intermédiaire vers BBOX mais plutôt comme remplacement. Et même alors, la création d'une solution générique sera plutôt impliquée.
diciu

Réponses:

13

Je peux vous y aider en supposant que vous avez trouvé comment demander (a) la moitié la plus à l'est d'un ensemble de points et (b) la moitié la plus au nord d'un ensemble de points. De ceux-ci, vous pouvez bien sûr facilement obtenir (c) la moitié la plus à l'ouest ou (d) la moitié la plus au sud. (Je ne connais pas QGIS, mais une façon de faire (a) en général est de demander la coordonnée médiane x puis de chercher tous les points dont les coordonnées x dépassent cela. Les solutions pour (b) - (d) sont similaires .)

En utilisant cette capacité, la solution est obtenue avec une récursivité facile. Pour le décrire, supposons qu'il existe une procédure Half, implémentant les opérations précédentes, qui prend deux arguments: le premier est un ensemble de points et le second est un code égal au truemoment où le partitionnement est-ouest est souhaité et égal au falsecontraire. Il renvoie deux sous-ensembles de son entrée qui le partitionnent comme demandé.

Procedure Box(P: set of points, i: boolean, n: integer)
Begin
    If (Count(P) > 2*n) then
        {R,S} = Half(P,i)
        Q = Box(R,!i,n) + Box(S,!i,n)
    Else
        Q = {P}
    Endif
    Return Q
End

Dans ce pseudocode, partition R et S P; La boîte (R,! I, n) est une partition de R dans la direction orthogonale , la boîte (S,! I, n) est une partition de S dans la direction orthogonale, "+" signifie la réunion de l'ensemble théorique, et {} désigne un ensemble. (Alterner le sens de division crée des boîtes plutôt que des bandes.) Le paramètre n spécifie la taille minimale d'un groupe dans la partition; la taille maximale est de 2 n .

Exemple

Ici, à titre d'illustration, est un ensemble P de 12 891 points aléatoires partitionnés par Box(P,true,100)en groupes de 100 à 200. L'algorithme crée 128 boîtes dont 37 ont 100 points et 91 ont 101 points.

whuber
la source
2
L'algorithme est efficace. Fonctionnant sur un seul cœur, il a traité dix fois plus de points (128 910) en 18 secondes. Il évolue comme O (n log (n) log (n)) pour n points. (Il pourrait être amélioré pour supprimer l'un de ces facteurs de log (n), mais l'effort ne
vaudra
1
@W avez-vous utilisé un tri lexicographique pour faciliter la partition des coordonnées des points?
2
@whuber c'est génial
dassouki
1
@Dan Un tri lexical aiderait mais n'est pas nécessaire. Notez qu'une médiane de n valeurs peut être trouvée en temps O (n) (pas O (n log (n)) temps), donc la partition des points en moitiés est-ouest ou moitiés nord-sud est asymptotiquement un O (n ) calcul.
whuber