نظرًا لأن Shapely لا يدعم أكثر من GEOS 3.4.0 في الوقت الحالي ، فسيكون من الرائع إضافة وظائف أخرى مثل GEOSSTRtree_nearest في GEOS 3.6.0. لذلك كنت أحاول إضافة هذه الوظيفة بنفسي ومواجهة بعض المشاكل.
كود مصدر GEOS هو مثل:
const GEOSGeometry *
GEOSSTRtree_nearest (geos::index::strtree::STRtree *tree,
const geos::geom::Geometry *g)
{
return GEOSSTRtree_nearest_r( handle, tree, g);
}
const void* GEOSSTRtree_nearest_generic(GEOSSTRtree *tree,
const void* item,
const GEOSGeometry* itemEnvelope,
GEOSDistanceCallback distancefn,
void* userdata)
{
return GEOSSTRtree_nearest_generic_r( handle, tree, item, itemEnvelope, distancefn, userdata);
}
ثم أضفت الكود في strtree.py و ctypes_declarations.py و test.py وحاولت تشغيل الاختبار لكنني حصلت على خطأ التجزئة: 11
strtree.py
from shapely.geometry.base import geom_factory
class STRtree:
def nearest(self, geom):
if self._n_geoms == 0:
return None
return geom_factory(lgeos.GEOSSTRtree_nearest(self._tree_handle, geom._geom))
ctypes_declarations.py
def prototype(lgeos, geos_version):
if geos_version >= (3, 6, 0):
lgeos.GEOSSTRtree_nearest.argtypes = [c_void_p, c_void_p]
lgeos.GEOSSTRtree_nearest.restype = c_void_p
test.py
from shapely.geometry import Point, Polygon
from shapely.strtree import STRtree
a = []
a.append(Polygon([(1,0),(2,0),(2,1),(1,1)]))
a.append(Polygon([(0,2),(1,2),(1,3),(0,3)]))
a.append(Polygon([(-1.5,0),(-2.5,0),(-2.5,-1),(-1.5,-1)]))
tree = STRtree(a)
tree.nearest(Point(0,0))
اعتقدت أن مشكلتي تتعلق بمعالجة البيانات بين الأنواع والهندسة ، لذلك حاولت إعادة تطبيق وظيفة المسار المشترك ولكن لا يزال هناك خطأ ما.
from shapely.geometry import LineString
from shapely.geometry.base import geom_factory
from ctypes import CDLL, c_void_p
dll = CDLL('/Users/*****/anaconda3/lib/python3.7/site-packages/shapely/.dylibs/libgeos_c.1.dylib')
shared_path = dll.GEOSSharedPaths
shared_path.restype = c_void_p
shared_path.argtypes = [c_void_p, c_void_p]
g1 = LineString([((0, 0), (1, 1)), ((-1, 0), (1, 0))])
g2 = LineString([((0, 0), (1, 1)), ((-2, 0), (1, 5))])
geom_factory(shared_path(g1._geom, g2._geom))
هل يمكنك مساعدتي في اكتشاف هذا ، تشك!
مرحبًا FuriousRococo ، لست على دراية باستخدام وظائف البحث عن أقرب الجيران ، ولكن يبدو أنك على المسار الصحيح تقريبًا. ومع ذلك ، في https://github.com/libgeos/geos/blob/master/capi/geos_c.h.in#L1824 ، أرى علامة على أننا بحاجة إلى استخدام الطريقة العامة لأن العناصر الموجودة في شجرتنا هي كائنات Python . أعتقد أنك ستحتاج إلى تجربة https://github.com/libgeos/geos/blob/master/capi/geos_c.h.in#L1850 .
شكرا على النصيحة sgillies ، أعتقد أنها تعمل الآن.
strtree.py
class STRtree:
def nearest(self, geom):
if self._n_geoms == 0:
return None
envelope = geom.envelope
def callback(item1, item2, distance, userdata):
try:
geom1 = ctypes.cast(item1, ctypes.py_object).value
geom2 = ctypes.cast(item2, ctypes.py_object).value
dist = ctypes.cast(distance, ctypes.POINTER(ctypes.c_double))
lgeos.GEOSDistance(geom1._geom, geom2._geom, dist)
return 1
except:
return 0
item = lgeos.GEOSSTRtree_nearest_generic(self._tree_handle, ctypes.py_object(geom), envelope._geom, \
lgeos.GEOSDistanceCallback(callback), None)
geom = ctypes.cast(item, ctypes.py_object).value
return geom
ctypes_declarations.py
def prototype(lgeos, geos_version):
if geos_version >= (3, 6, 0):
lgeos.GEOSDistanceCallback = CFUNCTYPE(c_int, c_void_p, c_void_p, c_void_p, c_void_p)
lgeos.GEOSSTRtree_nearest_generic.argtypes = [
c_void_p, py_object, c_void_p, lgeos.GEOSDistanceCallback, py_object]
lgeos.GEOSSTRtree_nearest_generic.restype = c_void_p
test.py
from shapely.geometry import Point, Polygon
from shapely.strtree import STRtree
a = []
a.append(Polygon([(1,0),(2,0),(2,1),(1,1)]))
a.append(Polygon([(0,2),(1,2),(1,3),(0,3)]))
a.append(Polygon([(-1.5,0),(-2.5,0),(-2.5,-1),(-1.5,-1)]))
a.append(Point(0,0.5))
tree = STRtree(a)
pt = tree.nearest(Point(0,0))
print(pt.wkt)
انتاج |
POINT (0 0.5)
FuriousRococo هل تريد إرسال طلبات سحب بهذه الميزة الجديدة؟
شكرًا لإضافة الميزةFuriousRococo. سؤال أثناء محاولة فهم أقرب وظيفة. لنفترض أنني أحاول العثور على أقرب طريق لنقطة ما. لذا فإن شجرة STR هي شجرة من طرق MultiLineString. إذن ، في هذه الحالة ، هل تم تحديد أقرب طريق باستخدام المسافة المسقطة من النقطة إلى السلاسل المتعددة الخطوط؟ أم أنها تستند إلى أصغر مسافة إلى النقط الوسطى من MultiLineStrings التي تمثل الطرق؟ شكرا لك!
لقد كتبت اختبارًا وأعتقد أن أقرب وظيفة تتحقق من كل سطر في MultiLineString لمعرفة ما إذا كان أقرب سطر داخل MultiLineString. هنا نصي @ asif-rehan
test.py
from shapely.strtree import STRtree
from shapely.geometry import Point, LineString, MultiLineString
tree_list = [LineString([[0,1],[1,1]])]
tree_list.append(MultiLineString([LineString([[0,0],[1,0]]),LineString([[0,3],[1,3]])]))
tree = STRtree(tree_list)
tree.nearest(Point(0.5,0.25)).wkt
انتاج |
MULTILINESTRING ((0 0, 1 0), (0 3, 1 3))
التعليق الأكثر فائدة
شكرا على النصيحة sgillies ، أعتقد أنها تعمل الآن.
strtree.py
ctypes_declarations.py
test.py
انتاج |
POINT (0 0.5)