find.py 7.4 KB

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