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