spatial_topology_dataset_connector.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. # -*- coding: utf-8 -*-
  2. """
  3. Spatial topology connector class
  4. Usage:
  5. >>> import grass.temporal as tgis
  6. >>> tmr = tgis.SpatialTopologyDatasetConnector()
  7. (C) 2012-2013 by the GRASS Development Team
  8. This program is free software under the GNU General Public
  9. License (>=v2). Read the file COPYING that comes with GRASS
  10. for details.
  11. :authors: Soeren Gebbert
  12. """
  13. import copy
  14. class SpatialTopologyDatasetConnector(object):
  15. """This class implements a spatial topology access structure to connect spatial related datasets
  16. This object will be set up by spatial topology creation method provided by the
  17. SpatioTemporalTopologyBuilder.
  18. The following spatial relations with access methods are supported:
  19. - equivalent
  20. - overlap
  21. - in
  22. - contain
  23. - meet
  24. - cover
  25. - covered
  26. Usage:
  27. .. code-block:: python
  28. >>> import grass.temporal as tgis
  29. >>> tgis.init()
  30. >>> map = tgis.RasterDataset("a@P")
  31. >>> tmr = tgis.SpatialTopologyDatasetConnector()
  32. >>> tmr.append_equivalent(map)
  33. >>> tmr.append_overlap(map)
  34. >>> tmr.append_in(map)
  35. >>> tmr.append_contain(map)
  36. >>> tmr.append_meet(map)
  37. >>> tmr.append_cover(map)
  38. >>> tmr.append_covered(map)
  39. >>> tmr.print_spatial_topology_info()
  40. +-------------------- Spatial Topology --------------------------------------+
  41. | Equivalent: ................ a@P
  42. | Cover: ..................... a@P
  43. | Covered: ................... a@P
  44. | Overlap: ................... a@P
  45. | In: ........................ a@P
  46. | Contain: ................... a@P
  47. | Meet: ...................... a@P
  48. >>> tmr.print_spatial_topology_shell_info()
  49. equivalent=a@P
  50. cover=a@P
  51. covered=a@P
  52. overlap=a@P
  53. in=a@P
  54. contain=a@P
  55. meet=a@P
  56. >>> rlist = tmr.get_spatial_relations()
  57. >>> if "COVER" in rlist.keys():
  58. ... print rlist["COVER"][0].get_id()
  59. a@P
  60. """
  61. def __init__(self):
  62. self.reset_spatial_topology()
  63. def reset_spatial_topology(self):
  64. """Reset any information about temporal topology"""
  65. self._spatial_topology = {}
  66. self._has_spatial_topology = False
  67. def get_spatial_relations(self):
  68. """Return the dictionary of spatial relationships
  69. Keys are the spatial relationships in upper case,
  70. values are abstract map objects.
  71. :return: The spatial relations dictionary
  72. """
  73. return copy.copy(self._spatial_topology)
  74. def get_number_of_spatial_relations(self):
  75. """ Return a dictionary in which the keys are the relation names and the value
  76. are the number of relations.
  77. The following relations are available:
  78. - equivalent
  79. - overlap
  80. - in
  81. - contain
  82. - meet
  83. - cover
  84. - covered
  85. To access topological information the spatial topology must be build first
  86. using the SpatialTopologyBuilder.
  87. :return: the dictionary with relations as keys and number as values or None in case the topology wasn't build
  88. """
  89. if self._has_spatial_topology == False:
  90. return None
  91. relations = {}
  92. try:
  93. relations["equivalent"] = len(self._spatial_topology["EQUIVALENT"])
  94. except:
  95. relations["equivalent"] = 0
  96. try:
  97. relations["overlap"] = len(self._spatial_topology["OVERLAP"])
  98. except:
  99. relations["overlap"] = 0
  100. try:
  101. relations["in"] = len(self._spatial_topology["IN"])
  102. except:
  103. relations["in"] = 0
  104. try:
  105. relations["contain"] = len(self._spatial_topology["CONTAIN"])
  106. except:
  107. relations["contain"] = 0
  108. try:
  109. relations["meet"] = len(self._spatial_topology["MEET"])
  110. except:
  111. relations["meet"] = 0
  112. try:
  113. relations["cover"] = len(self._spatial_topology["COVER"])
  114. except:
  115. relations["cover"] = 0
  116. try:
  117. relations["covered"] = len(self._spatial_topology["COVERED"])
  118. except:
  119. relations["covered"] = 0
  120. return relations
  121. def set_spatial_topology_build_true(self):
  122. """Same as name"""
  123. self._has_spatial_topology = True
  124. def set_spatial_topology_build_false(self):
  125. """Same as name"""
  126. self._has_spatial_topology = False
  127. def is_spatial_topology_build(self):
  128. """Check if the temporal topology was build"""
  129. return self._has_spatial_topology
  130. def append_equivalent(self, map):
  131. """Append a map with equivalent spatial extent as this map
  132. :param map: This object should be of type AbstractMapDataset
  133. or derived classes
  134. """
  135. if "EQUIVALENT" not in self._spatial_topology:
  136. self._spatial_topology["EQUIVALENT"] = []
  137. self._spatial_topology["EQUIVALENT"].append(map)
  138. def get_equivalent(self):
  139. """Return a list of map objects with equivalent spatial extent as this map
  140. :return: A list of map objects or None
  141. """
  142. if "EQUIVALENT" not in self._spatial_topology:
  143. return None
  144. return self._spatial_topology["EQUIVALENT"]
  145. def append_overlap(self, map):
  146. """Append a map that this spatial overlap with this map
  147. :param map: This object should be of type AbstractMapDataset
  148. or derived classes
  149. """
  150. if "OVERLAP" not in self._spatial_topology:
  151. self._spatial_topology["OVERLAP"] = []
  152. self._spatial_topology["OVERLAP"].append(map)
  153. def get_overlap(self):
  154. """Return a list of map objects that this map spatial overlap with
  155. :return: A list of map objects or None
  156. """
  157. if "OVERLAP" not in self._spatial_topology:
  158. return None
  159. return self._spatial_topology["OVERLAP"]
  160. def append_in(self, map):
  161. """Append a map that this is spatial in this map
  162. :param map: This object should be of type AbstractMapDataset
  163. or derived classes
  164. """
  165. if "IN" not in self._spatial_topology:
  166. self._spatial_topology["IN"] = []
  167. self._spatial_topology["IN"].append(map)
  168. def get_in(self):
  169. """Return a list of map objects that are spatial in this map
  170. :return: A list of map objects or None
  171. """
  172. if "IN" not in self._spatial_topology:
  173. return None
  174. return self._spatial_topology["IN"]
  175. def append_contain(self, map):
  176. """Append a map that this map spatially contains
  177. :param map: This object should be of type AbstractMapDataset
  178. or derived classes
  179. """
  180. if "CONTAIN" not in self._spatial_topology:
  181. self._spatial_topology["CONTAIN"] = []
  182. self._spatial_topology["CONTAIN"].append(map)
  183. def get_contain(self):
  184. """Return a list of map objects that this map contains
  185. :return: A list of map objects or None
  186. """
  187. if "CONTAIN" not in self._spatial_topology:
  188. return None
  189. return self._spatial_topology["CONTAIN"]
  190. def append_meet(self, map):
  191. """Append a map that spatially meet with this map
  192. :param map: This object should be of type AbstractMapDataset
  193. or derived classes
  194. """
  195. if "MEET" not in self._spatial_topology:
  196. self._spatial_topology["MEET"] = []
  197. self._spatial_topology["MEET"].append(map)
  198. def get_meet(self):
  199. """Return a list of map objects that spatially meet with this map
  200. :return: A list of map objects or None
  201. """
  202. if "MEET" not in self._spatial_topology:
  203. return None
  204. return self._spatial_topology["MEET"]
  205. def append_cover(self, map):
  206. """Append a map that spatially cover this map
  207. :param map: This object should be of type AbstractMapDataset
  208. or derived classes
  209. """
  210. if "COVER" not in self._spatial_topology:
  211. self._spatial_topology["COVER"] = []
  212. self._spatial_topology["COVER"].append(map)
  213. def get_cover(self):
  214. """Return a list of map objects that spatially cover this map
  215. :return: A list of map objects or None
  216. """
  217. if "COVER" not in self._spatial_topology:
  218. return None
  219. return self._spatial_topology["COVER"]
  220. def append_covered(self, map):
  221. """Append a map that is spatially covered by this map
  222. :param map: This object should be of type AbstractMapDataset
  223. or derived classes
  224. """
  225. if "COVERED" not in self._spatial_topology:
  226. self._spatial_topology["COVERED"] = []
  227. self._spatial_topology["COVERED"].append(map)
  228. def get_covered(self):
  229. """Return a list of map objects that are spatially covered by this map
  230. :return: A list of map objects or None
  231. """
  232. if "COVERED" not in self._spatial_topology:
  233. return None
  234. return self._spatial_topology["COVERED"]
  235. def _generate_map_list_string(self, map_list, line_wrap=True):
  236. count = 0
  237. string = ""
  238. for map_ in map_list:
  239. if line_wrap and count > 0 and count % 3 == 0:
  240. string += "\n | ............................ "
  241. count = 0
  242. if count == 0:
  243. string += map_.get_id()
  244. else:
  245. string += ",%s" % map_.get_id()
  246. count += 1
  247. return string
  248. # Set the properties
  249. equivalent = property(fget=get_equivalent,
  250. fset=append_equivalent)
  251. cover = property(fget=get_cover,
  252. fset=append_cover)
  253. covered = property(fget=get_covered,
  254. fset=append_covered)
  255. overlap = property(fget=get_overlap,
  256. fset=append_overlap)
  257. in_ = property(fget=get_in,
  258. fset=append_in)
  259. contain = property(fget=get_contain,
  260. fset=append_contain)
  261. meet = property(fget=get_meet,
  262. fset=append_meet)
  263. def print_spatial_topology_info(self):
  264. """Print information about this class in human readable style"""
  265. print " +-------------------- Spatial Topology --------------------------------------+"
  266. # 0123456789012345678901234567890
  267. if self.equivalent is not None:
  268. print " | Equivalent: ................ " + \
  269. self._generate_map_list_string(self.equivalent)
  270. if self.cover is not None:
  271. print " | Cover: ..................... " + \
  272. self._generate_map_list_string(self.cover)
  273. if self.covered is not None:
  274. print " | Covered: ................... " + \
  275. self._generate_map_list_string(self.covered)
  276. if self.overlap is not None:
  277. print " | Overlap: ................... " + \
  278. self._generate_map_list_string(self.overlap)
  279. if self.in_ is not None:
  280. print " | In: ........................ " + \
  281. self._generate_map_list_string(self.in_)
  282. if self.contain is not None:
  283. print " | Contain: ................... " + \
  284. self._generate_map_list_string(self.contain)
  285. if self.meet is not None:
  286. print " | Meet: ...................... " + \
  287. self._generate_map_list_string(self.meet)
  288. def print_spatial_topology_shell_info(self):
  289. """Print information about this class in shell style"""
  290. if self.equivalent is not None:
  291. print "equivalent=" + self._generate_map_list_string(self.equivalent, False)
  292. if self.cover is not None:
  293. print "cover=" + self._generate_map_list_string(
  294. self.cover, False)
  295. if self.covered is not None:
  296. print "covered=" + \
  297. self._generate_map_list_string(self.covered, False)
  298. if self.overlap is not None:
  299. print "overlap=" + \
  300. self._generate_map_list_string(self.overlap)
  301. if self.in_ is not None:
  302. print "in=" + \
  303. self._generate_map_list_string(self.in_)
  304. if self.contain is not None:
  305. print "contain=" + \
  306. self._generate_map_list_string(self.contain)
  307. if self.meet is not None:
  308. print "meet=" + \
  309. self._generate_map_list_string(self.meet)
  310. ###############################################################################
  311. if __name__ == "__main__":
  312. import doctest
  313. doctest.testmod()