spatial_topology_dataset_connector.py 13 KB

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