Arka fon
Bilinen bir noktadan, diyagramda gösterildiği gibi bir MultiLineStrings tablosuna en yakın çevreleyen "görünür çevre" yi kurmam gerekiyor.
Bu siteyi bir dizi terimle aradım (örneğin minimum kenar, minimum çevre, en yakın komşu, klip, çokgen, görünürlük, çıtçıt, kesim düğümleri, ışın izi, taşkın dolgu, iç sınır, yönlendirme, içbükey gövde) bu senaryo ile eşleşmiş gibi görünen herhangi bir soru bulamıyor
Diyagram
- Yeşil daire bilinen noktadır.
- Siyah çizgiler bilinen MultiLineStrings'tir.
- Gri çizgiler bilinen Noktadan radyal bir süpürmenin bir göstergesidir.
- Kırmızı noktalar, radyal süpürmenin ve MultiLineStrings'in en yakın kesişimidir.
Parametreler
- Nokta asla MultiLineStrings ile kesişmez.
- Nokta her zaman nominal olarak MultiLineStrings içinde ortalanır.
- MultiLineStrings hiçbir zaman Noktayı tam olarak kapsamaz, bu nedenle çevre bir MultiLineString olacaktır.
- Yaklaşık 1.000 MultiLineStrings içeren bir tablo olacaktır (normalde yaklaşık 100 puntoluk tek bir çizgi içerir).
Dikkate Alınan Metodoloji
- Bilinen Noktadan (örneğin 1 derecelik artışlarla) bir dizi çizgi oluşturarak radyal bir tarama yapın.
- MultiLineStrings ile her radyal süpürme hattının en yakın kesişim noktasını belirleyin.
- Radyal süpürme hatlarından biri MultiLineStrings'in herhangi biriyle kesişmediğinde, bu çevre çevresinde MultiLineString yapısında kalacak bir boşluğu gösterir.
özet
Bu teknik en yakın kavşakları bulsa da, radyal süpürmenin çözünürlüğüne bağlı olarak en yakın çevre düğüm noktalarının hepsini bulamaz. Herkes tüm çevre noktalarını belirlemek veya radyal tarama tekniğini bir çeşit tamponlama, sektör oluşturma veya ofsetleme ile desteklemek için alternatif bir yöntem önerebilir mi?
Yazılım
Benim tercihim çözüm için SpatiaLite ve / veya Shapely kullanmak ama açık kaynak yazılım kullanılarak uygulanabilecek önerileri memnuniyetle karşılıyoruz.
Düzenleme: Çalışma Çözümü (@gene tarafından verilen cevaba göre)
from shapely.geometry import Point, LineString, mapping, shape
from shapely.ops import cascaded_union
from shapely import affinity
import fiona
sweep_res = 10 # sweep resolution (degrees)
focal_pt = Point(0, 0) # radial sweep centre point
sweep_radius = 100.0 # sweep radius
# create the radial sweep lines
line = LineString([(focal_pt.x,focal_pt.y), \
(focal_pt.x, focal_pt.y + sweep_radius)])
sweep_lines = [affinity.rotate(line, i, (focal_pt.x, focal_pt.y)) \
for i in range(0, 360, sweep_res)]
radial_sweep = cascaded_union(sweep_lines)
# load the input lines and combine them into one geometry
input_lines = fiona.open("input_lines.shp")
input_shapes = [shape(f['geometry']) for f in input_lines]
all_input_lines = cascaded_union(input_shapes)
perimeter = []
# traverse each radial sweep line and check for intersection with input lines
for radial_line in radial_sweep:
inter = radial_line.intersection(all_input_lines)
if inter.type == "MultiPoint":
# radial line intersects at multiple points
inter_dict = {}
for inter_pt in inter:
inter_dict[focal_pt.distance(inter_pt)] = inter_pt
# save the nearest intersected point to the sweep centre point
perimeter.append(inter_dict[min(inter_dict.keys())])
if inter.type == "Point":
# radial line intersects at one point only
perimeter.append(inter)
if inter.type == "GeometryCollection":
# radial line doesn't intersect, so skip
pass
# combine the nearest perimeter points into one geometry
solution = cascaded_union(perimeter)
# save the perimeter geometry
schema = {'geometry': 'MultiPoint', 'properties': {'test': 'int'}}
with fiona.open('perimeter.shp', 'w', 'ESRI Shapefile', schema) as e:
e.write({'geometry':mapping(solution), 'properties':{'test':1}})