círculo máximo dentro de un polígono irregular desde un punto aleatorio

8

Estoy tratando de elaborar un algoritmo para crear el círculo de radio máximo dentro de un polígono irregular (un tramo censal) basado en un centro dado del círculo.

La motivación para esto es oscurecer la ubicación de una persona que ha respondido una encuesta. Su ubicación real es conocida, sin embargo, debe oscurecerse en el análisis, para divulgar los datos al público, para un análisis más detallado.

Queremos tener un polígono con forma de rosquilla para cada encuestado que tenga un radio interno (fácil), limitado por un radio externo que esté limitado por el tramo censal en el que se encuentra el individuo. Su ubicación final se colocará al azar dentro del polígono de la rosquilla .

He visto muchas respuestas a preguntas similares aquí, pero no esta específica, que en este caso comienza con una ubicación ESPECÍFICA.

Una vez que tenemos establecida la dona, podemos aleatorizar la ubicación de la respuesta individual dentro del polígono. Eso es relativamente fácil ...

Gracias por sus ideas, las mías hasta ahora me han parecido bastante brutas, y computacionalmente "caras" o ineficientes ...

Percy
fuente
1
¿No es solo la distancia más corta desde la ubicación específica hasta el límite del polígono que desea?
Nicklas Avén
¿Qué software o lenguaje de programación estás usando?
Pablo
¿Por qué no solo intersecta el anillo deseado con el tracto? Mejor aún, no hay razón para usar formas circulares: también podría usar un anillo cuadrado, lo que conduciría a una ejecución más rápida.
whuber
3
Parece haber poco o ningún consenso . Aquí aparece una descripción general de algunos métodos , comenzando p. 34 . Se propuso un método sofisticado en nuestro sitio . Un grupo de trabajo internacional reciente exploró muchos temas relacionados. Una revisión reciente de Mathews & Harel puede ser útil.
whuber
3
@whuber, muchas gracias! Supongo que eres el mismo Bill Huber que ha estado publicando ayuda y código fuente desde que comencé a usar GIS en 1998. Me encantaron todos tus scripts de Avenue, aprendí mucho de ellos (y supongo que el programa al que se hace referencia a continuación es ArcView, es ¡Increíble lo rápido que corre estos días!). ¡Solo quería hacerle saber cuánto lo aprecian en la comunidad de profesionales de SIG! ¡Gracias por todos sus años de buenos consejos!
Percy

Respuestas:

3

Un método simple para mover ubicaciones dentro de tales anillos explota una representación cuadriculada de la distancia al límite del tracto. Comenzando con una representación poligonal de las secciones del Censo (que es lo habitual),

  1. Convierta eso en los límites del polígono (una capa de polilínea).

  2. Calcule la cuadrícula de distancia euclidiana a los límites.

  3. Extraiga las distancias euclidianas en los lugares dados.

  4. Mueva cada ubicación dentro del rango dado por la distancia, que, por definición, es el máximo al límite.

Normalmente, cada uno requiere un solo comando con un SIG, lo que hace que toda la secuencia se automatice fácilmente y se ejecute fácilmente de forma manual. Estos son comandos eficientes , ya que no requieren la construcción de un búfer para cada punto (que generalmente crea varias docenas a casi mil puntos para describir un anillo o anillo ). Tampoco se necesitan búsquedas o ensayos aleatorios: los puntos se desplazan directamente por cantidades garantizadas para dejarlos dentro de sus secciones censales originales.


Por ejemplo, moví 172,902 ubicaciones dentro de 47 tractos en direcciones aleatorias mediante desplazamientos distribuidos uniformemente entre la mitad de la distancia y la distancia total hasta el límite. Aquí hay una parte de un tratado antes del traslado:

Figura 1

(cuadrados amarillos marcan las ubicaciones) y después del movimiento:

Figura 2

(ahora los cuadrados grises marcan las nuevas ubicaciones). La operación total tomó solo uno o dos minutos (usando un viejo SIG obsoleto :-).

Al comparar estas cifras de cerca, puede ver que

  • Los puntos que ahora están cerca del límite (como cerca de los dos lagos que se muestran como "agujeros" blancos en estas figuras) permanecen necesariamente cerca del límite.

  • Los puntos alejados del límite tienden a moverse lejos.

En consecuencia, un punto cercano al límite probablemente (pero no ciertamente) se originó muy cerca, mientras que cualquier punto alejado del límite probablemente se originó en otro lugar lejos del límite. Estas dos tendencias están lejos de ser completamente aleatorias: podrían (con bastante facilidad) ser explotadas por alguien que desea penetrar en la privacidad que estos movimientos estaban destinados a permitir.

Mejores métodos harían que las conexiones entre la ubicación final y la inicial fueran más tenues y más aleatorias. Como mínimo, los puntos deben moverse dentro de vecindarios razonablemente grandes en lugar de dentro de vecindarios de tamaño variable (y posiblemente arbitrariamente pequeño). Dichos movimientos no se llevan a cabo fácilmente con cuadrículas, porque generalmente requieren un poco de prueba y error: genera un grupo de puntos aleatorios dentro de un vecindario de cada punto original y selecciona el primero que se encuentra dentro del mismo tramo del Censo. Es un ciclo que involucra (1) un movimiento aleatorio y (2) una investigación de punto en el polígono. Ambas operaciones son rápidas, pero esto requiere un poco de programación para implementar el bucle.

(En un comentario a la pregunta, proporciono enlaces a algunos estudios de métodos utilizados para disfrazar datos de ubicación con fines de privacidad).

whuber
fuente
2

Solo quería probar tus donas en PostGIS

Lo probé en PostGISonline.

Para hacer la misma prueba, vaya a: http://postgisonline.org/map.php

Hay algunos polígonos llamados impresión de "propiedad":

SELECT * FROM property;

y presiona "Mapa1"

Luego, puede probar el código de rosquilla copiando el siguiente en el área de texto y presionando "map2" (entonces el mapa de propiedades permanecerá):

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

Eso debería darte un resultado similar a: ingrese la descripción de la imagen aquí

Nicklas Avén
fuente
¡PostGIS simplemente es genial! Gracias, eso es genial, buen trabajo!
Percy
1

Esperemos que esta solución de Python te ayude. El flujo de trabajo general es el siguiente:

  1. Convierta polígonos en polilíneas para poder calcular una distancia cercana
  2. Almacenar los puntos en función de la distancia cercana

ingrese la descripción de la imagen aquí

# 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")
Aaron
fuente
¡Gracias! ¡Parece que podría funcionar! :-) lo intentaremos!
Percy