cercle maximum à l'intérieur d'un polygone irrégulier à partir d'un point aléatoire


8

J'essaie d'élaborer un algorithme pour créer le cercle de rayon maximum dans un polygone irrégulier (un secteur de recensement) basé sur un centre donné du cercle.

La motivation pour cela est de masquer l'emplacement d'une personne qui a répondu à un sondage. Leur emplacement réel est connu, mais il doit être obscurci dans l'analyse, afin de divulguer les données au public, pour une analyse plus approfondie.

Nous voulons avoir un polygone en forme d'anneau pour chaque répondant au sondage qui a un rayon intérieur (facile), délimité par un rayon extérieur qui est contraint par le secteur de recensement dans lequel l'individu se trouve. Leur emplacement final sera placé au hasard dans le polygone de l'anneau .

J'ai vu de nombreuses réponses à des questions similaires ici, mais pas celle-ci, qui dans ce cas commence par un emplacement SPÉCIFIQUE.

Une fois le beignet établi, nous pouvons randomiser l'emplacement de la réponse individuelle dans le polygone. C'est relativement facile ...

Merci pour vos idées, les miennes jusqu'à présent ont semblé assez brutales, et computationnellement "chères" ou inefficaces ...


1
N'est-ce pas simplement la distance la plus courte entre l'emplacement spécifique et la limite du polygone que vous souhaitez?
Nicklas Avén

Quel logiciel ou langage de programmation utilisez-vous?
Pablo

Pourquoi ne pas simplement couper l'espace annulaire souhaité avec le tractus? Mieux encore, il n'y a aucune raison d'utiliser des formes circulaires - vous pourriez tout aussi bien utiliser un anneau carré, ce qui conduirait à une exécution plus rapide.
whuber

3
Il semble y avoir peu ou pas de consensus . Un aperçu de certaines méthodes apparaît ici, en commençant p. 34 . Une méthode sophistiquée a été proposée sur notre site . Un récent groupe de travail international a exploré de nombreuses questions connexes. Un examen récent par Mathews & Harel peut être utile.
whuber

3
@whuber, merci beaucoup! Je suppose que vous êtes le même Bill Huber qui publie de l'aide et du code source depuis que j'ai commencé à utiliser SIG en 1998. J'ai adoré tous vos scripts Avenue, j'ai beaucoup appris d'eux (et je suppose que le programme référencé ci-dessous est ArcView, c'est incroyable à quelle vitesse il fonctionne ces jours-ci !!!). Je voulais juste vous faire savoir à quel point vous êtes apprécié dans la communauté des praticiens SIG! Merci pour toutes vos années de bons conseils!
Percy

Réponses:


3

Une méthode simple pour déplacer des emplacements dans de tels anneaux exploite une représentation quadrillée de la distance à la limite du tractus. Commençant par une représentation polygonale des secteurs de recensement (ce qui est habituel),

  1. Convertissez-le en limites de polygone (une couche de polyligne).

  2. Calculez la grille de distance euclidienne jusqu'aux limites.

  3. Extraire les distances euclidiennes aux emplacements donnés.

  4. Déplacez chaque emplacement dans la plage donnée par la distance - qui, par définition, est le maximum de la limite.

Chacun nécessite généralement une seule commande avec un SIG, ce qui rend la séquence entière facilement automatisée et facilement exécutée manuellement. Ce sont des commandes efficaces , car elles ne nécessitent pas la construction d'un tampon pour chaque point (ce qui crée généralement plusieurs dizaines à près de mille points pour décrire un anneau ou un anneau ). Aucune recherche ni aucun essai aléatoire ne sont nécessaires non plus: les points sont directement déplacés par des montants garantis pour les laisser dans leurs secteurs de recensement d'origine.


Par exemple, j'ai déplacé 172 902 emplacements dans 47 secteurs dans des directions aléatoires par des déplacements uniformément répartis entre la moitié de la distance et la pleine distance de la frontière. Voici une partie d'un tract avant le déménagement:

Figure 1

(des carrés jaunes marquent les emplacements) et après le déplacement:

Figure 2

(maintenant des carrés gris marquent les nouveaux emplacements). L'opération totale n'a pris qu'une minute ou deux (en utilisant un ancien SIG obsolète :-).

En comparant ces chiffres de près, vous pouvez voir que

  • Les points qui sont maintenant proches de la frontière (comme près des deux lacs représentés par des "trous" blancs sur ces figures) restent nécessairement proches de la frontière.

  • Les points éloignés de la frontière ont tendance à s'éloigner.

Par conséquent, un point proche de la frontière est probablement (mais pas certainement) originaire de très près, tandis que tout point éloigné de la frontière provient probablement d'un autre endroit loin de la frontière. Ces deux tendances sont loin d'être totalement aléatoires: elles pourraient (assez facilement) être exploitées par quelqu'un qui souhaite pénétrer l'intimité que ces mouvements étaient censés offrir.

De meilleures méthodes rendraient les connexions entre l'emplacement final et initial plus ténues et plus aléatoires. Au minimum, les points devraient être déplacés dans des quartiers raisonnablement grands plutôt que dans des quartiers de taille variable (et éventuellement arbitrairement petite). De tels mouvements ne sont pas facilement effectués avec des grilles, car ils nécessitent généralement des essais et des erreurs: vous générez un tas de points aléatoires dans un voisinage de chaque point d'origine et sélectionnez le premier qui se trouve dans le même secteur de recensement. C'est une boucle impliquant (1) un mouvement aléatoire et (2) une interrogation ponctuelle. Les deux opérations sont rapides, mais cela nécessite un peu de programmation pour implémenter la boucle.

(Dans un commentaire à la question, je fournis des liens vers certaines études sur les méthodes utilisées pour masquer les données de localisation à des fins de confidentialité.)


2

Je voulais juste tester vos beignets dans PostGIS

Je l'ai essayé sur PostGISonline.

Pour faire le même test, vous allez sur: http://postgisonline.org/map.php

Il existe des polygones appelés "propriété":

SELECT * FROM property;

et appuyez sur "Map1"

Ensuite, vous pouvez tester le code beignet en copiant ce qui suit dans la zone de texte et appuyez sur "map2" (alors la propriété-carte restera):

SELECT ST_Difference(ST_Buffer(the_geom,dist),ST_Buffer(the_geom,dist/3)) the_geom,dist FROM
(
    SELECT ST_Distance(poly.boundary,points.the_geom) dist, points.the_geom FROM
    (
        SELECT ST_Boundary(the_geom) boundary,the_geom FROM property
    ) poly
    INNER JOIN
    (
        SELECT ST_SetSrid('POINT(137816 267009)'::geometry,3021) the_geom
        UNION ALL
        SELECT ST_SetSrid('POINT(139816 268542)'::geometry,3021) the_geom
        UNION ALL
        SELECT ST_SetSrid('POINT(135016 268102)'::geometry,3021) the_geom
    ) points
    ON ST_Contains(poly.the_geom,points.the_geom)
) a

Cela devrait vous donner quelque chose comme: entrez la description de l'image ici


PostGIS est tout simplement incroyable! Merci, c'est génial, beau travail!
Percy

1

J'espère que cette solution Python vous aidera. Le workflow général est le suivant:

  1. Convertir des polygones en polylignes pour calculer une distance proche
  2. Mettre les points en mémoire tampon en fonction de la distance proche

entrez la description de l'image ici

# Import arcpy module
import arcpy, os
from arcpy import env

env.overwriteOutput = 1

env.workspace = r'C:\sample.gdb\temp'
Dir = env.workspace

# Local variables:
points = "points"
polygon = "polygon"
points_2 = "points"
buffers = "buffers"
polyline = "polyline"

# Polygon To Line
arcpy.PolygonToLine_management(polygon, polyline, "IDENTIFY_NEIGHBORS")

# Near
arcpy.Near_analysis(points, polyline)

# Buffer
arcpy.Buffer_analysis(points_2, buffers, "NEAR_DIST")

Merci! on dirait que ça pourrait bien marcher! :-) nous allons essayer!
Percy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.