find.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Mar 19 11:09:30 2013
  4. @author: pietro
  5. """
  6. import grass.lib.vector as libvect
  7. from grass.pygrass.errors import must_be_open
  8. from grass.pygrass.vector.basic import Ilist, BoxList
  9. from grass.pygrass.vector.geometry import read_line, Isle, Area, Point
  10. class AbstractFinder(object):
  11. def __init__(self, c_mapinfo, table=None, writable=False):
  12. """AbstractFinder
  13. -----------------
  14. Find geometry feature around a point.
  15. """
  16. self.c_mapinfo = c_mapinfo
  17. self.table = table
  18. self.writable = writable
  19. self.vtype = {'point': libvect.GV_POINT, # 1
  20. 'line': libvect.GV_LINE, # 2
  21. 'boundary': libvect.GV_BOUNDARY, # 3
  22. 'centroid': libvect.GV_CENTROID, # 4
  23. 'all': -1}
  24. def is_open(self):
  25. """Check if the vector map is open or not"""
  26. from . import abstract
  27. return abstract.is_open(self.c_mapinfo)
  28. class PointFinder(AbstractFinder):
  29. """PointFinder
  30. Find the geomtry features of a vector map that are close to a point.
  31. >>> from grass.pygrass.vector import VectorTopo
  32. >>> zipcodes = VectorTopo('zipcodes', 'PERMANENT')
  33. >>> schools = VectorTopo('schools', 'PERMANENT')
  34. >>> zipcodes.open('r')
  35. >>> schools.open('r')
  36. >>> result = []
  37. >>> for school in schools:
  38. ... zipcode = zipcodes.find['by_point'].area(school)
  39. ... result.append((school.attrs['NAMESHORT'],
  40. ... zipcode.attrs['ZIPCODE']))
  41. ...
  42. >>> result[0]
  43. (u'SWIFT CREEK', u'RALEIGH 27606')
  44. >>> result[1]
  45. (u'BRIARCLIFF', u'CARY 27511')
  46. >>> result[2]
  47. (u'FARMINGTON WOODS', u'CARY 27511')
  48. >>> from grass.pygrass.vector.geometry import Point
  49. >>> pnt = Point(631213.349291, 224684.900084)
  50. >>> school = schools.find['by_point'].geo(pnt, maxdist=300.)
  51. >>> school.attrs['NAMELONG']
  52. u'ADAMS ELEMENTARY'
  53. >>> for school in schools.find['by_point'].geos(pnt, maxdist=1000.):
  54. ... print school.attrs['NAMELONG']
  55. ...
  56. CARY HIGH
  57. EAST CARY MIDDLE SITE
  58. ADAMS ELEMENTARY
  59. >>> schools.close()
  60. >>> zipcodes.close()
  61. """
  62. def __init__(self, c_mapinfo, table=None, writable=False):
  63. """Find geometry feature around a point.
  64. """
  65. super(PointFinder, self).__init__(c_mapinfo, table, writable)
  66. # TODO: add the Node class and enable this method
  67. # def node(self, point, maxdist):
  68. # """Find the nearest node. Vect_find_node"""
  69. # i = libvect.Vect_find_node(self.c_mapinfo, point.x, point.y, point.z,
  70. # float(maxdist), int(not point.is2D))
  71. # return geometry.Node(self.c_mapinfo.contents.plus.contents.Node[i])
  72. @must_be_open
  73. def geo(self, point, maxdist, type='all', exclude=0):
  74. """Find the nearest line. Vect_find_line
  75. Valid type are all the keys in find.vtype dictionary
  76. """
  77. feature_id = libvect.Vect_find_line(self.c_mapinfo,
  78. point.x, point.y,
  79. point.z if point.z else 0,
  80. self.vtype[type], float(maxdist),
  81. int(not point.is2D), exclude)
  82. if feature_id:
  83. return read_line(feature_id, self.c_mapinfo,
  84. self.table, self.writable)
  85. @must_be_open
  86. def geos(self, point, maxdist, type='all', exclude=None):
  87. """Find the nearest line. Vect_find_line_list
  88. Valid type are all the keys in find.vtype dictionary
  89. """
  90. excl = Ilist(exclude) if exclude else Ilist([])
  91. found = Ilist()
  92. if libvect.Vect_find_line_list(self.c_mapinfo,
  93. point.x, point.y,
  94. point.z if point.z else 0,
  95. self.vtype[type], float(maxdist),
  96. int(not point.is2D),
  97. excl.c_ilist, found.c_ilist):
  98. return [read_line(f_id, self.c_mapinfo, self.table, self.writable)
  99. for f_id in found]
  100. else:
  101. return []
  102. @must_be_open
  103. def area(self, point):
  104. """Find the nearest area. Vect_find_area"""
  105. area_id = libvect.Vect_find_area(self.c_mapinfo, point.x, point.y)
  106. if area_id:
  107. return Area(v_id=area_id, c_mapinfo=self.c_mapinfo,
  108. table=self.table, writable=self.writable)
  109. @must_be_open
  110. def island(self, point):
  111. """Find the nearest island. Vect_find_island"""
  112. isle_id = libvect.Vect_find_island(self.c_mapinfo, point.x, point.y)
  113. if isle_id:
  114. return Isle(v_id=isle_id, c_mapinfo=self.c_mapinfo,
  115. table=self.table, writable=self.writable)
  116. class BboxFinder(AbstractFinder):
  117. def __init__(self, c_mapinfo, table=None, writable=False):
  118. super(BboxFinder, self).__init__(c_mapinfo, table, writable)
  119. @must_be_open
  120. def geos(self, bbox, type='all', bbox_list=False):
  121. """Find the geometry features contained in the bbox.
  122. Vect_select_lines_by_box
  123. Valid type are all the keys in find.vtype dictionary
  124. """
  125. found = BoxList()
  126. if libvect.Vect_select_lines_by_box(self.c_mapinfo, bbox.c_bbox,
  127. self.vtype[type], found.c_boxlist):
  128. if bbox_list:
  129. return found
  130. else:
  131. return (read_line(f_id, self.c_mapinfo, self.table,
  132. self.writable) for f_id in found.ids)
  133. @must_be_open
  134. def nodes(self, bbox):
  135. """Find the nearest area. Vect_find_area"""
  136. found = Ilist()
  137. if libvect.Vect_select_nodes_by_box(self.c_mapinfo, bbox.c_bbox,
  138. found.c_ilist):
  139. for n_id in found:
  140. yield Point(v_id=n_id, c_mapinfo=self.c_mapinfo,
  141. table=self.table, writable=self.writable)
  142. @must_be_open
  143. def areas(self, bbox, boxlist=None, bboxlist_only=False):
  144. """Find the nearest area. Vect_find_area"""
  145. boxlist = boxlist if boxlist else BoxList()
  146. if libvect.Vect_select_areas_by_box(self.c_mapinfo, bbox.c_bbox,
  147. boxlist.c_boxlist):
  148. if bboxlist_only:
  149. return boxlist
  150. else:
  151. return (Area(v_id=a_id, c_mapinfo=self.c_mapinfo,
  152. table=self.table, writable=self.writable)
  153. for a_id in boxlist.ids)
  154. return []
  155. @must_be_open
  156. def islands(self, bbox, bbox_list=False):
  157. """Find the nearest island. Vect_find_island"""
  158. found = BoxList()
  159. if libvect.Vect_select_isles_by_box(self.c_mapinfo, bbox.c_bbox,
  160. found.c_boxlist):
  161. if bbox_list:
  162. return found
  163. else:
  164. return (Isle(v_id=i_id, c_mapinfo=self.c_mapinfo,
  165. table=self.table, writable=self.writable)
  166. for i_id in found.ids)
  167. return []
  168. class PolygonFinder(AbstractFinder):
  169. def __init__(self, c_mapinfo, table=None, writable=False):
  170. super(PolygonFinder, self).__init__(c_mapinfo, table, writable)
  171. def lines(self, polygon, isles=None):
  172. pass
  173. def areas(self, polygon, isles=None):
  174. pass