find.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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
  9. from geometry import read_line, Isle, Area
  10. class Finder(object):
  11. """Find the geomtry features of a vector map that are close to a point. ::
  12. >>> from grass.pygrass.vector import VectorTopo
  13. >>> zipcodes = VectorTopo('zipcodes', 'PERMANENT')
  14. >>> schools = VectorTopo('schools', 'PERMANENT')
  15. >>> zipcodes.open('r')
  16. >>> schools.open('r')
  17. >>> result = []
  18. >>> for school in schools:
  19. ... zipcode = zipcodes.find.area(school)
  20. ... result.append((school.attrs['NAMESHORT'],
  21. ... zipcode.attrs['ZIPCODE']))
  22. ...
  23. >>> result[0]
  24. (u'SWIFT CREEK', u'RALEIGH 27606')
  25. >>> result[1]
  26. (u'BRIARCLIFF', u'CARY 27511')
  27. >>> result[2]
  28. (u'FARMINGTON WOODS', u'CARY 27511')
  29. >>> from grass.pygrass.vector.geometry import Point
  30. >>> pnt = Point(631213.349291, 224684.900084)
  31. >>> school = schools.find.geo(pnt, maxdist=300.)
  32. >>> school.attrs['NAMELONG']
  33. u'ADAMS ELEMENTARY'
  34. >>> for school in schools.find.geos(pnt, maxdist=1000.):
  35. ... print school.attrs['NAMELONG']
  36. ...
  37. CARY HIGH
  38. EAST CARY MIDDLE SITE
  39. ADAMS ELEMENTARY
  40. >>> schools.close()
  41. >>> zipcodes.close()
  42. """
  43. def __init__(self, c_mapinfo, table=None, writable=False):
  44. """Find geometry feature around a point.
  45. """
  46. self.c_mapinfo = c_mapinfo
  47. self.table = table
  48. self.writable = writable
  49. self.vtype = {'point': libvect.GV_POINT, # 1
  50. 'line': libvect.GV_LINE, # 2
  51. 'boundary': libvect.GV_BOUNDARY, # 3
  52. 'centroid': libvect.GV_CENTROID, # 4
  53. 'all': -1} # -1
  54. # TODO: add the Node class and enable this method
  55. # def node(self, point, maxdist):
  56. # """Find the nearest node. Vect_find_node"""
  57. # i = libvect.Vect_find_node(self.c_mapinfo, point.x, point.y, point.z,
  58. # float(maxdist), int(not point.is2D))
  59. # return geometry.Node(self.c_mapinfo.contents.plus.contents.Node[i])
  60. @must_be_open
  61. def geo(self, point, maxdist, type='all', exclude=0):
  62. """Find the nearest line. Vect_find_line
  63. Valid type are all the keys in find.vtype dictionary
  64. """
  65. feature_id = libvect.Vect_find_line(self.c_mapinfo,
  66. point.x, point.y,
  67. point.z if point.z else 0,
  68. self.vtype[type], float(maxdist),
  69. int(not point.is2D), exclude)
  70. if feature_id:
  71. return read_line(feature_id, self.c_mapinfo,
  72. self.table, self.writable)
  73. @must_be_open
  74. def geos(self, point, maxdist, type='all', exclude=[]):
  75. """Find the nearest line. Vect_find_line_list
  76. Valid type are all the keys in find.vtype dictionary
  77. """
  78. excl = Ilist(exclude)
  79. found = Ilist()
  80. if libvect.Vect_find_line_list(self.c_mapinfo,
  81. point.x, point.y,
  82. point.z if point.z else 0,
  83. self.vtype[type], float(maxdist),
  84. int(not point.is2D),
  85. excl.c_ilist, found.c_ilist):
  86. return [read_line(f_id, self.c_mapinfo, self.table, self.writable)
  87. for f_id in found]
  88. else:
  89. return []
  90. @must_be_open
  91. def area(self, point):
  92. """Find the nearest area. Vect_find_area"""
  93. area_id = libvect.Vect_find_area(self.c_mapinfo, point.x, point.y)
  94. if area_id:
  95. return Area(v_id=area_id, c_mapinfo=self.c_mapinfo,
  96. table=self.table, writable=self.writable)
  97. @must_be_open
  98. def island(self, point):
  99. """Find the nearest island. Vect_find_island"""
  100. isle_id = libvect.Vect_find_island(self.c_mapinfo, point.x, point.y)
  101. if isle_id:
  102. return Isle(v_id=isle_id, c_mapinfo=self.c_mapinfo,
  103. table=self.table, writable=self.writable)
  104. def is_open(self):
  105. """Check if the vector map is open or not"""
  106. import abstract
  107. return abstract.is_open(self.c_mapinfo)