space_time_datasets.py 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363
  1. """
  2. Map layer and space time dataset classes
  3. (C) 2012-2013 by the GRASS Development Team
  4. This program is free software under the GNU General Public
  5. License (>=v2). Read the file COPYING that comes with GRASS
  6. for details.
  7. :authors: Soeren Gebbert
  8. """
  9. import getpass
  10. from datetime import datetime
  11. from .core import get_current_mapset
  12. from .abstract_map_dataset import AbstractMapDataset
  13. from .abstract_space_time_dataset import AbstractSpaceTimeDataset
  14. from .base import Raster3DBase, RasterBase, VectorBase, STR3DSBase, STVDSBase, STRDSBase,\
  15. VectorSTDSRegister, Raster3DSTDSRegister, RasterSTDSRegister
  16. from .metadata import Raster3DMetadata, RasterMetadata, VectorMetadata, STRDSMetadata,\
  17. STR3DSMetadata, STVDSMetadata
  18. from .spatial_extent import RasterSpatialExtent, Raster3DSpatialExtent, VectorSpatialExtent,\
  19. STRDSSpatialExtent, STR3DSSpatialExtent, STVDSSpatialExtent
  20. from .temporal_extent import RasterAbsoluteTime, RasterRelativeTime, Raster3DAbsoluteTime, \
  21. Raster3DRelativeTime, VectorAbsoluteTime, VectorRelativeTime, STRDSAbsoluteTime,\
  22. STRDSRelativeTime, STR3DSAbsoluteTime, STR3DSRelativeTime, STVDSAbsoluteTime, STVDSRelativeTime
  23. import grass.script.array as garray
  24. from .core import init
  25. from datetime import datetime
  26. ###############################################################################
  27. class RasterDataset(AbstractMapDataset):
  28. """Raster dataset class
  29. This class provides functions to select, update, insert or delete raster
  30. map information and valid time stamps into the SQL temporal database.
  31. Usage:
  32. .. code-block:: python
  33. >>> import grass.script as grass
  34. >>> import grass.temporal as tgis
  35. >>> init()
  36. >>> grass.use_temp_region()
  37. >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
  38. ... t=1.0, b=0.0, res=10.0)
  39. 0
  40. >>> grass.run_command("r.mapcalc", overwrite=True, quiet=True,
  41. ... expression="strds_map_test_case = 1")
  42. 0
  43. >>> grass.run_command("r.timestamp", map="strds_map_test_case",
  44. ... date="15 jan 1999", quiet=True)
  45. 0
  46. >>> mapset = tgis.get_current_mapset()
  47. >>> name = "strds_map_test_case"
  48. >>> identifier = "%s@%s" % (name, mapset)
  49. >>> rmap = RasterDataset(identifier)
  50. >>> rmap.map_exists()
  51. True
  52. >>> rmap.read_timestamp_from_grass()
  53. True
  54. >>> rmap.get_temporal_extent_as_tuple()
  55. (datetime.datetime(1999, 1, 15, 0, 0), None)
  56. >>> rmap.load()
  57. True
  58. >>> rmap.spatial_extent.print_info()
  59. +-------------------- Spatial extent ----------------------------------------+
  60. | North:...................... 80.0
  61. | South:...................... 0.0
  62. | East:.. .................... 120.0
  63. | West:....................... 0.0
  64. | Top:........................ 0.0
  65. | Bottom:..................... 0.0
  66. >>> rmap.absolute_time.print_info()
  67. +-------------------- Absolute time -----------------------------------------+
  68. | Start time:................. 1999-01-15 00:00:00
  69. | End time:................... None
  70. >>> rmap.metadata.print_info()
  71. +-------------------- Metadata information ----------------------------------+
  72. | Datatype:................... CELL
  73. | Number of columns:.......... 8
  74. | Number of rows:............. 12
  75. | Number of cells:............ 96
  76. | North-South resolution:..... 10.0
  77. | East-west resolution:....... 10.0
  78. | Minimum value:.............. 1.0
  79. | Maximum value:.............. 1.0
  80. >>> grass.run_command("r.timestamp", map="strds_map_test_case",
  81. ... date="2 years", quiet=True)
  82. 0
  83. >>> rmap.read_timestamp_from_grass()
  84. True
  85. >>> rmap.get_temporal_extent_as_tuple()
  86. (2, None)
  87. >>> rmap.get_relative_time_unit()
  88. 'years'
  89. >>> rmap.is_in_db()
  90. False
  91. >>> rmap.is_stds()
  92. False
  93. >>> newmap = rmap.get_new_instance("new@PERMANENT")
  94. >>> isinstance(newmap, RasterDataset)
  95. True
  96. >>> newstrds = rmap.get_new_stds_instance("new@PERMANENT")
  97. >>> isinstance(newstrds, SpaceTimeRasterDataset)
  98. True
  99. >>> rmap.get_type()
  100. 'raster'
  101. >>> rmap.set_absolute_time(start_time=datetime(2001,1,1),
  102. ... end_time=datetime(2012,1,1))
  103. True
  104. >>> rmap.get_absolute_time()
  105. (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
  106. >>> rmap.get_temporal_extent_as_tuple()
  107. (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
  108. >>> rmap.get_name()
  109. 'strds_map_test_case'
  110. >>> rmap.get_mapset() == mapset
  111. True
  112. >>> rmap.get_temporal_type()
  113. 'absolute'
  114. >>> rmap.get_spatial_extent_as_tuple()
  115. (80.0, 0.0, 120.0, 0.0, 0.0, 0.0)
  116. >>> rmap.is_time_absolute()
  117. True
  118. >>> rmap.is_time_relative()
  119. False
  120. >>> grass.run_command("g.remove", flags="f", type="raster", name=name, quiet=True)
  121. 0
  122. >>> grass.del_temp_region()
  123. """
  124. def __init__(self, ident):
  125. AbstractMapDataset.__init__(self)
  126. self.reset(ident)
  127. def is_stds(self):
  128. """Return True if this class is a space time dataset
  129. :return: True if this class is a space time dataset, False otherwise
  130. """
  131. return False
  132. def get_type(self):
  133. return 'raster'
  134. def get_new_instance(self, ident):
  135. """Return a new instance with the type of this class"""
  136. return RasterDataset(ident)
  137. def get_new_stds_instance(self, ident):
  138. """Return a new space time dataset instance in which maps
  139. are stored with the type of this class"""
  140. return SpaceTimeRasterDataset(ident)
  141. def spatial_overlapping(self, dataset):
  142. """Return True if the spatial extents 2d overlap"""
  143. return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
  144. def spatial_relation(self, dataset):
  145. """Return the two dimensional spatial relation"""
  146. return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
  147. def spatial_intersection(self, dataset):
  148. """Return the two dimensional intersection as spatial_extent
  149. object or None in case no intersection was found.
  150. :param dataset: The abstract dataset to intersect with
  151. :return: The intersection spatial extent or None
  152. """
  153. return self.spatial_extent.intersect_2d(dataset.spatial_extent)
  154. def spatial_union(self, dataset):
  155. """Return the two dimensional union as spatial_extent
  156. object or None in case the extents does not overlap or meet.
  157. :param dataset :The abstract dataset to create a union with
  158. :return: The union spatial extent or None
  159. """
  160. return self.spatial_extent.union_2d(dataset.spatial_extent)
  161. def spatial_disjoint_union(self, dataset):
  162. """Return the two dimensional union as spatial_extent object.
  163. :param dataset: The abstract dataset to create a union with
  164. :return: The union spatial extent
  165. """
  166. return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
  167. def get_np_array(self):
  168. """Return this raster map as memmap numpy style array to access the raster
  169. values in numpy style without loading the whole map in the RAM.
  170. In case this raster map does exists in the grass spatial database,
  171. the map will be exported using r.out.bin to a temporary location
  172. and assigned to the memmap object that is returned by this function.
  173. In case the raster map does not exist, an empty temporary
  174. binary file will be created and assigned to the memap object.
  175. You need to call the write function to write the memmap
  176. array back into grass.
  177. """
  178. a = garray.array()
  179. if self.map_exists():
  180. a.read(self.get_map_id())
  181. return a
  182. def reset(self, ident):
  183. """Reset the internal structure and set the identifier"""
  184. self.base = RasterBase(ident=ident)
  185. self.absolute_time = RasterAbsoluteTime(ident=ident)
  186. self.relative_time = RasterRelativeTime(ident=ident)
  187. self.spatial_extent = RasterSpatialExtent(ident=ident)
  188. self.metadata = RasterMetadata(ident=ident)
  189. self.stds_register = RasterSTDSRegister(ident=ident)
  190. def has_grass_timestamp(self):
  191. """Check if a grass file based time stamp exists for this map.
  192. :return: True if success, False on error
  193. """
  194. return self.ciface.has_raster_timestamp(self.get_name(),
  195. self.get_mapset())
  196. def read_timestamp_from_grass(self):
  197. """Read the timestamp of this map from the map metadata
  198. in the grass file system based spatial database and
  199. set the internal time stamp that should be insert/updated
  200. in the temporal database.
  201. :return: True if success, False on error
  202. """
  203. if not self.has_grass_timestamp():
  204. return False
  205. check, dates = self.ciface.read_raster_timestamp(self.get_name(),
  206. self.get_mapset(),)
  207. if check < 1:
  208. self.msgr.error(_("Unable to read timestamp file "
  209. "for raster map <%s>" % (self.get_map_id())))
  210. return False
  211. if len(dates) == 2:
  212. self.set_absolute_time(dates[0], dates[1])
  213. else:
  214. self.set_relative_time(dates[0], dates[1], dates[2])
  215. return True
  216. def write_timestamp_to_grass(self):
  217. """Write the timestamp of this map into the map metadata in
  218. the grass file system based spatial database.
  219. Internally the libgis API functions are used for writing
  220. :return: True if success, False on error
  221. """
  222. check = self.ciface.write_raster_timestamp(self.get_name(),
  223. self.get_mapset(),
  224. self._convert_timestamp())
  225. if check == -1:
  226. self.msgr.error(_("Unable to create timestamp file "
  227. "for raster map <%s>" % (self.get_map_id())))
  228. return False
  229. if check == -2:
  230. self.msgr.error(_("Invalid datetime in timestamp for raster map "
  231. "<%s>" % (self.get_map_id())))
  232. return False
  233. if check == -3:
  234. self.msgr.error(_("Internal error"))
  235. return False
  236. return True
  237. def remove_timestamp_from_grass(self):
  238. """Remove the timestamp from the grass file system based
  239. spatial database
  240. Internally the libgis API functions are used for removal
  241. :return: True if success, False on error
  242. """
  243. check = self.ciface.remove_raster_timestamp(self.get_name(),
  244. self.get_mapset())
  245. if check == -1:
  246. self.msgr.error(_("Unable to remove timestamp for raster map <%s>"
  247. % (self.get_name())))
  248. return False
  249. return True
  250. def map_exists(self):
  251. """Return True in case the map exists in the grass spatial database
  252. :return: True if map exists, False otherwise
  253. """
  254. return self.ciface.raster_map_exists(self.get_name(),
  255. self.get_mapset())
  256. def load(self):
  257. """Load all info from an existing raster map into the internal structure
  258. This method checks first if the map exists, in case it exists
  259. the metadata of the map is put into this object and True is returned
  260. :return: True is the map exists and the metadata was filled
  261. successfully and getting the data was successful,
  262. False otherwise
  263. """
  264. if self.map_exists() is not True:
  265. return False
  266. # Fill base information
  267. self.base.set_creator(str(getpass.getuser()))
  268. kvp = self.ciface.read_raster_info(self.get_name(),
  269. self.get_mapset())
  270. if kvp:
  271. # Fill spatial extent
  272. self.set_spatial_extent_from_values(north=kvp["north"],
  273. south=kvp["south"],
  274. east=kvp["east"],
  275. west=kvp["west"])
  276. # Fill metadata
  277. self.metadata.set_nsres(kvp["nsres"])
  278. self.metadata.set_ewres(kvp["ewres"])
  279. self.metadata.set_datatype(kvp["datatype"])
  280. self.metadata.set_min(kvp["min"])
  281. self.metadata.set_max(kvp["max"])
  282. rows = int(kvp["rows"])
  283. cols = int(kvp["cols"])
  284. ncells = cols * rows
  285. self.metadata.set_cols(cols)
  286. self.metadata.set_rows(rows)
  287. self.metadata.set_number_of_cells(ncells)
  288. return True
  289. return False
  290. ###############################################################################
  291. class Raster3DDataset(AbstractMapDataset):
  292. """Raster3d dataset class
  293. This class provides functions to select, update, insert or delete raster3d
  294. map information and valid time stamps into the SQL temporal database.
  295. Usage:
  296. .. code-block:: python
  297. >>> import grass.script as grass
  298. >>> init()
  299. >>> grass.use_temp_region()
  300. >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
  301. ... t=100.0, b=0.0, res=10.0, res3=10.0)
  302. 0
  303. >>> grass.run_command("r3.mapcalc", overwrite=True, quiet=True,
  304. ... expression="str3ds_map_test_case = 1")
  305. 0
  306. >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case",
  307. ... date="15 jan 1999", quiet=True)
  308. 0
  309. >>> mapset = get_current_mapset()
  310. >>> name = "str3ds_map_test_case"
  311. >>> identifier = "%s@%s" % (name, mapset)
  312. >>> r3map = Raster3DDataset(identifier)
  313. >>> r3map.map_exists()
  314. True
  315. >>> r3map.read_timestamp_from_grass()
  316. True
  317. >>> r3map.get_temporal_extent_as_tuple()
  318. (datetime.datetime(1999, 1, 15, 0, 0), None)
  319. >>> r3map.load()
  320. True
  321. >>> r3map.spatial_extent.print_info()
  322. +-------------------- Spatial extent ----------------------------------------+
  323. | North:...................... 80.0
  324. | South:...................... 0.0
  325. | East:.. .................... 120.0
  326. | West:....................... 0.0
  327. | Top:........................ 100.0
  328. | Bottom:..................... 0.0
  329. >>> r3map.absolute_time.print_info()
  330. +-------------------- Absolute time -----------------------------------------+
  331. | Start time:................. 1999-01-15 00:00:00
  332. | End time:................... None
  333. >>> r3map.metadata.print_info()
  334. +-------------------- Metadata information ----------------------------------+
  335. | Datatype:................... DCELL
  336. | Number of columns:.......... 8
  337. | Number of rows:............. 12
  338. | Number of cells:............ 960
  339. | North-South resolution:..... 10.0
  340. | East-west resolution:....... 10.0
  341. | Minimum value:.............. 1.0
  342. | Maximum value:.............. 1.0
  343. | Number of depths:........... 10
  344. | Top-Bottom resolution:...... 10.0
  345. >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case",
  346. ... date="2 years", quiet=True)
  347. 0
  348. >>> r3map.read_timestamp_from_grass()
  349. True
  350. >>> r3map.get_temporal_extent_as_tuple()
  351. (2, None)
  352. >>> r3map.get_relative_time_unit()
  353. 'years'
  354. >>> r3map.is_in_db()
  355. False
  356. >>> r3map.is_stds()
  357. False
  358. >>> newmap = r3map.get_new_instance("new@PERMANENT")
  359. >>> isinstance(newmap, Raster3DDataset)
  360. True
  361. >>> newstr3ds = r3map.get_new_stds_instance("new@PERMANENT")
  362. >>> isinstance(newstr3ds, SpaceTimeRaster3DDataset)
  363. True
  364. >>> r3map.get_type()
  365. 'raster3d'
  366. >>> r3map.set_absolute_time(start_time=datetime(2001,1,1),
  367. ... end_time=datetime(2012,1,1))
  368. True
  369. >>> r3map.get_absolute_time()
  370. (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
  371. >>> r3map.get_temporal_extent_as_tuple()
  372. (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
  373. >>> r3map.get_name()
  374. 'str3ds_map_test_case'
  375. >>> r3map.get_mapset() == mapset
  376. True
  377. >>> r3map.get_temporal_type()
  378. 'absolute'
  379. >>> r3map.get_spatial_extent_as_tuple()
  380. (80.0, 0.0, 120.0, 0.0, 100.0, 0.0)
  381. >>> r3map.is_time_absolute()
  382. True
  383. >>> r3map.is_time_relative()
  384. False
  385. >>> grass.run_command("g.remove", flags="f", type="raster_3d", name=name, quiet=True)
  386. 0
  387. >>> grass.del_temp_region()
  388. """
  389. def __init__(self, ident):
  390. AbstractMapDataset.__init__(self)
  391. self.reset(ident)
  392. def is_stds(self):
  393. """Return True if this class is a space time dataset
  394. :return: True if this class is a space time dataset, False otherwise
  395. """
  396. return False
  397. def get_type(self):
  398. return "raster3d"
  399. def get_new_instance(self, ident):
  400. """Return a new instance with the type of this class"""
  401. return Raster3DDataset(ident)
  402. def get_new_stds_instance(self, ident):
  403. """Return a new space time dataset instance in which maps
  404. are stored with the type of this class"""
  405. return SpaceTimeRaster3DDataset(ident)
  406. def spatial_overlapping(self, dataset):
  407. """Return True if the spatial extents overlap"""
  408. if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
  409. return self.spatial_extent.overlapping(dataset.spatial_extent)
  410. else:
  411. return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
  412. def spatial_relation(self, dataset):
  413. """Return the two or three dimensional spatial relation"""
  414. if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
  415. return self.spatial_extent.spatial_relation(dataset.spatial_extent)
  416. else:
  417. return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
  418. def spatial_intersection(self, dataset):
  419. """Return the three or two dimensional intersection as spatial_extent
  420. object or None in case no intersection was found.
  421. :param dataset: The abstract dataset to intersect with
  422. :return: The intersection spatial extent or None
  423. """
  424. if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
  425. return self.spatial_extent.intersect(dataset.spatial_extent)
  426. else:
  427. return self.spatial_extent.intersect_2d(dataset.spatial_extent)
  428. def spatial_union(self, dataset):
  429. """Return the three or two dimensional union as spatial_extent
  430. object or None in case the extents does not overlap or meet.
  431. :param dataset: The abstract dataset to create a union with
  432. :return: The union spatial extent or None
  433. """
  434. if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
  435. return self.spatial_extent.union(dataset.spatial_extent)
  436. else:
  437. return self.spatial_extent.union_2d(dataset.spatial_extent)
  438. def spatial_disjoint_union(self, dataset):
  439. """Return the three or two dimensional union as spatial_extent object.
  440. :param dataset: The abstract dataset to create a union with
  441. :return: The union spatial extent
  442. """
  443. if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
  444. return self.spatial_extent.disjoint_union(dataset.spatial_extent)
  445. else:
  446. return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
  447. def get_np_array(self):
  448. """Return this 3D raster map as memmap numpy style array to access the
  449. 3D raster values in numpy style without loading the whole map in
  450. the RAM.
  451. In case this 3D raster map does exists in the grass spatial database,
  452. the map will be exported using r3.out.bin to a temporary location
  453. and assigned to the memmap object that is returned by this function.
  454. In case the 3D raster map does not exist, an empty temporary
  455. binary file will be created and assigned to the memap object.
  456. You need to call the write function to write the memmap
  457. array back into grass.
  458. """
  459. a = garray.array3d()
  460. if self.map_exists():
  461. a.read(self.get_map_id())
  462. return a
  463. def reset(self, ident):
  464. """Reset the internal structure and set the identifier"""
  465. self.base = Raster3DBase(ident=ident)
  466. self.absolute_time = Raster3DAbsoluteTime(ident=ident)
  467. self.relative_time = Raster3DRelativeTime(ident=ident)
  468. self.spatial_extent = Raster3DSpatialExtent(ident=ident)
  469. self.metadata = Raster3DMetadata(ident=ident)
  470. self.stds_register = Raster3DSTDSRegister(ident=ident)
  471. def has_grass_timestamp(self):
  472. """Check if a grass file bsased time stamp exists for this map.
  473. :return: True if success, False on error
  474. """
  475. return self.ciface.has_raster3d_timestamp(self.get_name(),
  476. self.get_mapset())
  477. def read_timestamp_from_grass(self):
  478. """Read the timestamp of this map from the map metadata
  479. in the grass file system based spatial database and
  480. set the internal time stamp that should be insert/updated
  481. in the temporal database.
  482. :return: True if success, False on error
  483. """
  484. if not self.has_grass_timestamp():
  485. return False
  486. check, dates = self.ciface.read_raster3d_timestamp(self.get_name(),
  487. self.get_mapset(),)
  488. if check < 1:
  489. self.msgr.error(_("Unable to read timestamp file "
  490. "for 3D raster map <%s>" % (self.get_map_id())))
  491. return False
  492. if len(dates) == 2:
  493. self.set_absolute_time(dates[0], dates[1])
  494. else:
  495. self.set_relative_time(dates[0], dates[1], dates[2])
  496. return True
  497. def write_timestamp_to_grass(self):
  498. """Write the timestamp of this map into the map metadata
  499. in the grass file system based spatial database.
  500. Internally the libgis API functions are used for writing
  501. :return: True if success, False on error
  502. """
  503. check = self.ciface.write_raster3d_timestamp(self.get_name(),
  504. self.get_mapset(),
  505. self._convert_timestamp())
  506. if check == -1:
  507. self.msgr.error(_("Unable to create timestamp file "
  508. "for 3D raster map <%s>" % (self.get_map_id())))
  509. return False
  510. if check == -2:
  511. self.msgr.error(_("Invalid datetime in timestamp for 3D raster "
  512. "map <%s>" % (self.get_map_id())))
  513. return False
  514. if check == -3:
  515. self.msgr.error(_("Internal error"))
  516. return False
  517. return True
  518. def remove_timestamp_from_grass(self):
  519. """Remove the timestamp from the grass file system based spatial database
  520. :return: True if success, False on error
  521. """
  522. check = self.ciface.remove_raster3d_timestamp(self.get_name(),
  523. self.get_mapset())
  524. if check == -1:
  525. self.msgr.error(_("Unable to remove timestamp for raster map "
  526. "<%s>" % (self.get_name())))
  527. return False
  528. return True
  529. def map_exists(self):
  530. """Return True in case the map exists in the grass spatial database
  531. :return: True if map exists, False otherwise
  532. """
  533. return self.ciface.raster3d_map_exists(self.get_name(),
  534. self.get_mapset())
  535. def load(self):
  536. """Load all info from an existing 3d raster map into the internal structure
  537. This method checks first if the map exists, in case it exists
  538. the metadata of the map is put into this object and True is returned
  539. :return: True is the map exists and the metadata was filled
  540. successfully and getting the data was successful,
  541. False otherwise
  542. """
  543. if self.map_exists() is not True:
  544. return False
  545. # Fill base information
  546. self.base.set_creator(str(getpass.getuser()))
  547. # Fill spatial extent
  548. kvp = self.ciface.read_raster3d_info(self.get_name(),
  549. self.get_mapset())
  550. if kvp:
  551. self.set_spatial_extent_from_values(north=kvp["north"],
  552. south=kvp["south"],
  553. east=kvp["east"],
  554. west=kvp["west"],
  555. top=kvp["top"],
  556. bottom=kvp["bottom"])
  557. # Fill metadata
  558. self.metadata.set_nsres(kvp["nsres"])
  559. self.metadata.set_ewres(kvp["ewres"])
  560. self.metadata.set_tbres(kvp["tbres"])
  561. self.metadata.set_datatype(kvp["datatype"])
  562. self.metadata.set_min(kvp["min"])
  563. self.metadata.set_max(kvp["max"])
  564. rows = int(kvp["rows"])
  565. cols = int(kvp["cols"])
  566. depths = int(kvp["depths"])
  567. ncells = cols * rows * depths
  568. self.metadata.set_cols(cols)
  569. self.metadata.set_rows(rows)
  570. self.metadata.set_depths(depths)
  571. self.metadata.set_number_of_cells(ncells)
  572. return True
  573. return False
  574. ###############################################################################
  575. class VectorDataset(AbstractMapDataset):
  576. """Vector dataset class
  577. This class provides functions to select, update, insert or delete vector
  578. map information and valid time stamps into the SQL temporal database.
  579. Usage:
  580. .. code-block:: python
  581. >>> import grass.script as grass
  582. >>> init()
  583. >>> grass.use_temp_region()
  584. >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
  585. ... t=1.0, b=0.0, res=10.0)
  586. 0
  587. >>> grass.run_command("v.random", overwrite=True, output="stvds_map_test_case",
  588. ... n=100, zmin=0, zmax=100, flags="z", column="elevation", quiet=True)
  589. 0
  590. >>> grass.run_command("v.timestamp", map="stvds_map_test_case",
  591. ... date="15 jan 1999", quiet=True)
  592. 0
  593. >>> mapset = get_current_mapset()
  594. >>> name = "stvds_map_test_case"
  595. >>> identifier = "%s@%s" % (name, mapset)
  596. >>> vmap = VectorDataset(identifier)
  597. >>> vmap.map_exists()
  598. True
  599. >>> vmap.read_timestamp_from_grass()
  600. True
  601. >>> vmap.get_temporal_extent_as_tuple()
  602. (datetime.datetime(1999, 1, 15, 0, 0), None)
  603. >>> vmap.load()
  604. True
  605. >>> vmap.absolute_time.print_info()
  606. +-------------------- Absolute time -----------------------------------------+
  607. | Start time:................. 1999-01-15 00:00:00
  608. | End time:................... None
  609. >>> vmap.metadata.print_info()
  610. +-------------------- Metadata information ----------------------------------+
  611. | Is map 3d .................. True
  612. | Number of points ........... 100
  613. | Number of lines ............ 0
  614. | Number of boundaries ....... 0
  615. | Number of centroids ........ 0
  616. | Number of faces ............ 0
  617. | Number of kernels .......... 0
  618. | Number of primitives ....... 100
  619. | Number of nodes ............ 0
  620. | Number of areas ............ 0
  621. | Number of islands .......... 0
  622. | Number of holes ............ 0
  623. | Number of volumes .......... 0
  624. >>> grass.run_command("v.timestamp", map="stvds_map_test_case",
  625. ... date="2 years", quiet=True)
  626. 0
  627. >>> vmap.read_timestamp_from_grass()
  628. True
  629. >>> vmap.get_temporal_extent_as_tuple()
  630. (2, None)
  631. >>> vmap.get_relative_time_unit()
  632. 'years'
  633. >>> vmap.is_in_db()
  634. False
  635. >>> vmap.is_stds()
  636. False
  637. >>> newmap = vmap.get_new_instance("new@PERMANENT")
  638. >>> isinstance(newmap, VectorDataset)
  639. True
  640. >>> newstvds = vmap.get_new_stds_instance("new@PERMANENT")
  641. >>> isinstance(newstvds, SpaceTimeVectorDataset)
  642. True
  643. >>> vmap.get_type()
  644. 'vector'
  645. >>> vmap.set_absolute_time(start_time=datetime(2001,1,1),
  646. ... end_time=datetime(2012,1,1))
  647. True
  648. >>> vmap.get_absolute_time()
  649. (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
  650. >>> vmap.get_temporal_extent_as_tuple()
  651. (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
  652. >>> vmap.get_name()
  653. 'stvds_map_test_case'
  654. >>> vmap.get_mapset() == mapset
  655. True
  656. >>> vmap.get_temporal_type()
  657. 'absolute'
  658. >>> vmap.is_time_absolute()
  659. True
  660. >>> vmap.is_time_relative()
  661. False
  662. >>> grass.run_command("g.remove", flags="f", type="vector", name=name, quiet=True)
  663. 0
  664. >>> grass.del_temp_region()
  665. """
  666. def __init__(self, ident):
  667. AbstractMapDataset.__init__(self)
  668. self.reset(ident)
  669. def is_stds(self):
  670. """Return True if this class is a space time dataset
  671. :return: True if this class is a space time dataset, False otherwise
  672. """
  673. return False
  674. def get_type(self):
  675. return "vector"
  676. def get_new_instance(self, ident):
  677. """Return a new instance with the type of this class"""
  678. return VectorDataset(ident)
  679. def get_new_stds_instance(self, ident):
  680. """Return a new space time dataset instance in which maps
  681. are stored with the type of this class"""
  682. return SpaceTimeVectorDataset(ident)
  683. def get_layer(self):
  684. """Return the layer"""
  685. return self.base.get_layer()
  686. def spatial_overlapping(self, dataset):
  687. """Return True if the spatial extents 2d overlap"""
  688. return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
  689. def spatial_relation(self, dataset):
  690. """Return the two dimensional spatial relation"""
  691. return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
  692. def spatial_intersection(self, dataset):
  693. """Return the two dimensional intersection as spatial_extent
  694. object or None in case no intersection was found.
  695. :param dataset: The abstract dataset to intersect with
  696. :return: The intersection spatial extent or None
  697. """
  698. return self.spatial_extent.intersect_2d(dataset.spatial_extent)
  699. def spatial_union(self, dataset):
  700. """Return the two dimensional union as spatial_extent
  701. object or None in case the extents does not overlap or meet.
  702. :param dataset: The abstract dataset to create a union with
  703. :return: The union spatial extent or None
  704. """
  705. return self.spatial_extent.union_2d(dataset.spatial_extent)
  706. def spatial_disjoint_union(self, dataset):
  707. """Return the two dimensional union as spatial_extent object.
  708. :param dataset: The abstract dataset to create a union with
  709. :return: The union spatial extent
  710. """
  711. return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
  712. def reset(self, ident):
  713. """Reset the internal structure and set the identifier"""
  714. self.base = VectorBase(ident=ident)
  715. self.absolute_time = VectorAbsoluteTime(ident=ident)
  716. self.relative_time = VectorRelativeTime(ident=ident)
  717. self.spatial_extent = VectorSpatialExtent(ident=ident)
  718. self.metadata = VectorMetadata(ident=ident)
  719. self.stds_register = VectorSTDSRegister(ident=ident)
  720. def has_grass_timestamp(self):
  721. """Check if a grass file bsased time stamp exists for this map.
  722. """
  723. return self.ciface.has_vector_timestamp(self.get_name(),
  724. self.get_mapset(),
  725. self.get_layer())
  726. def read_timestamp_from_grass(self):
  727. """Read the timestamp of this map from the map metadata
  728. in the grass file system based spatial database and
  729. set the internal time stamp that should be insert/updated
  730. in the temporal database.
  731. """
  732. if not self.has_grass_timestamp():
  733. return False
  734. check, dates = self.ciface.read_vector_timestamp(self.get_name(),
  735. self.get_mapset(),)
  736. if check < 1:
  737. self.msgr.error(_("Unable to read timestamp file "
  738. "for vector map <%s>" % (self.get_map_id())))
  739. return False
  740. if len(dates) == 2:
  741. self.set_absolute_time(dates[0], dates[1])
  742. else:
  743. self.set_relative_time(dates[0], dates[1], dates[2])
  744. return True
  745. def write_timestamp_to_grass(self):
  746. """Write the timestamp of this map into the map metadata in
  747. the grass file system based spatial database.
  748. Internally the libgis API functions are used for writing
  749. """
  750. check = self.ciface.write_vector_timestamp(self.get_name(),
  751. self.get_mapset(),
  752. self._convert_timestamp(),
  753. self.get_layer())
  754. if check == -1:
  755. self.msgr.error(_("Unable to create timestamp file "
  756. "for vector map <%s>" % (self.get_map_id())))
  757. return False
  758. if check == -2:
  759. self.msgr.error(_("Invalid datetime in timestamp for vector "
  760. "map <%s>" % (self.get_map_id())))
  761. return False
  762. return True
  763. def remove_timestamp_from_grass(self):
  764. """Remove the timestamp from the grass file system based spatial
  765. database
  766. Internally the libgis API functions are used for removal
  767. """
  768. check = self.ciface.remove_vector_timestamp(self.get_name(),
  769. self.get_mapset())
  770. if check == -1:
  771. self.msgr.error(_("Unable to remove timestamp for vector "
  772. "map <%s>" % (self.get_name())))
  773. return False
  774. return True
  775. def map_exists(self):
  776. """Return True in case the map exists in the grass spatial database
  777. :return: True if map exists, False otherwise
  778. """
  779. return self.ciface.vector_map_exists(self.get_name(),
  780. self.get_mapset())
  781. def load(self):
  782. """Load all info from an existing vector map into the internal structure
  783. This method checks first if the map exists, in case it exists
  784. the metadata of the map is put into this object and True is returned
  785. :return: True is the map exists and the metadata was filled
  786. successfully and getting the data was successful,
  787. False otherwise
  788. """
  789. if self.map_exists() is not True:
  790. return False
  791. # Fill base information
  792. self.base.set_creator(str(getpass.getuser()))
  793. # Get the data from an existing vector map
  794. kvp = self.ciface.read_vector_info(self.get_name(),
  795. self.get_mapset())
  796. if kvp:
  797. # Fill spatial extent
  798. self.set_spatial_extent_from_values(north=kvp["north"],
  799. south=kvp["south"],
  800. east=kvp["east"],
  801. west=kvp["west"],
  802. top=kvp["top"],
  803. bottom=kvp["bottom"])
  804. # Fill metadata
  805. self.metadata.set_3d_info(kvp["map3d"])
  806. self.metadata.set_number_of_points(kvp["points"])
  807. self.metadata.set_number_of_lines(kvp["lines"])
  808. self.metadata.set_number_of_boundaries(kvp["boundaries"])
  809. self.metadata.set_number_of_centroids(kvp["centroids"])
  810. self.metadata.set_number_of_faces(kvp["faces"])
  811. self.metadata.set_number_of_kernels(kvp["kernels"])
  812. self.metadata.set_number_of_primitives(kvp["primitives"])
  813. self.metadata.set_number_of_nodes(kvp["nodes"])
  814. self.metadata.set_number_of_areas(kvp["areas"])
  815. self.metadata.set_number_of_islands(kvp["islands"])
  816. self.metadata.set_number_of_holes(kvp["holes"])
  817. self.metadata.set_number_of_volumes(kvp["volumes"])
  818. return True
  819. return False
  820. ###############################################################################
  821. class SpaceTimeRasterDataset(AbstractSpaceTimeDataset):
  822. """Space time raster dataset class
  823. .. code-block:: python
  824. >>> import grass.temporal as tgis
  825. >>> tgis.init()
  826. >>> mapset = tgis.get_current_mapset()
  827. >>> strds = tgis.SpaceTimeRasterDataset("old@%s"%mapset)
  828. >>> strds.is_in_db()
  829. False
  830. >>> strds.is_stds()
  831. True
  832. >>> strds.get_type()
  833. 'strds'
  834. >>> newstrds = strds.get_new_instance("newstrds@%s"%mapset)
  835. >>> isinstance(newstrds, SpaceTimeRasterDataset)
  836. True
  837. >>> newmap = strds.get_new_map_instance("newmap@%s"%mapset)
  838. >>> isinstance(newmap, RasterDataset)
  839. True
  840. >>> strds.reset("new@%s"%mapset)
  841. >>> strds.is_in_db()
  842. False
  843. >>> strds.reset(None)
  844. >>> strds.is_in_db()
  845. False
  846. >>> strds.get_id()
  847. ...
  848. """
  849. def __init__(self, ident):
  850. AbstractSpaceTimeDataset.__init__(self, ident)
  851. def is_stds(self):
  852. """Return True if this class is a space time dataset
  853. :return: True if this class is a space time dataset, False otherwise
  854. """
  855. return True
  856. def get_type(self):
  857. return "strds"
  858. def get_new_instance(self, ident):
  859. """Return a new instance with the type of this class"""
  860. return SpaceTimeRasterDataset(ident)
  861. def get_new_map_instance(self, ident):
  862. """Return a new instance of a map dataset which is associated "
  863. "with the type of this class"""
  864. return RasterDataset(ident)
  865. def get_map_register(self):
  866. """Return the name of the map register table"""
  867. return self.metadata.get_raster_register()
  868. def set_map_register(self, name):
  869. """Set the name of the map register table"""
  870. self.metadata.set_raster_register(name)
  871. def spatial_overlapping(self, dataset):
  872. """Return True if the spatial extents 2d overlap"""
  873. return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
  874. def spatial_relation(self, dataset):
  875. """Return the two dimensional spatial relation"""
  876. return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
  877. def spatial_intersection(self, dataset):
  878. """Return the two dimensional intersection as spatial_extent
  879. object or None in case no intersection was found.
  880. :param dataset: The abstract dataset to intersect with
  881. :return: The intersection spatial extent or None
  882. """
  883. return self.spatial_extent.intersect_2d(dataset.spatial_extent)
  884. def spatial_union(self, dataset):
  885. """Return the two dimensional union as spatial_extent
  886. object or None in case the extents does not overlap or meet.
  887. :param dataset: The abstract dataset to create a union with
  888. :return: The union spatial extent or None
  889. """
  890. return self.spatial_extent.union_2d(dataset.spatial_extent)
  891. def spatial_disjoint_union(self, dataset):
  892. """Return the two dimensional union as spatial_extent object.
  893. :param dataset: The abstract dataset to create a union with
  894. :return: The union spatial extent
  895. """
  896. return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
  897. def reset(self, ident):
  898. """Reset the internal structure and set the identifier"""
  899. self.base = STRDSBase(ident=ident)
  900. self.base.set_creator(str(getpass.getuser()))
  901. self.absolute_time = STRDSAbsoluteTime(ident=ident)
  902. self.relative_time = STRDSRelativeTime(ident=ident)
  903. self.spatial_extent = STRDSSpatialExtent(ident=ident)
  904. self.metadata = STRDSMetadata(ident=ident)
  905. ###############################################################################
  906. class SpaceTimeRaster3DDataset(AbstractSpaceTimeDataset):
  907. """Space time raster3d dataset class
  908. .. code-block:: python
  909. >>> import grass.temporal as tgis
  910. >>> tgis.init()
  911. >>> mapset = tgis.get_current_mapset()
  912. >>> str3ds = tgis.SpaceTimeRaster3DDataset("old@%s"%mapset)
  913. >>> str3ds.is_in_db()
  914. False
  915. >>> str3ds.is_stds()
  916. True
  917. >>> str3ds.get_type()
  918. 'str3ds'
  919. >>> newstrds = str3ds.get_new_instance("newstrds@%s"%mapset)
  920. >>> isinstance(newstrds, SpaceTimeRaster3DDataset)
  921. True
  922. >>> newmap = str3ds.get_new_map_instance("newmap@%s"%mapset)
  923. >>> isinstance(newmap, Raster3DDataset)
  924. True
  925. >>> str3ds.reset("new@%s"%mapset)
  926. >>> str3ds.is_in_db()
  927. False
  928. >>> str3ds.reset(None)
  929. >>> str3ds.is_in_db()
  930. False
  931. >>> str3ds.get_id()
  932. ...
  933. """
  934. def __init__(self, ident):
  935. AbstractSpaceTimeDataset.__init__(self, ident)
  936. def is_stds(self):
  937. """Return True if this class is a space time dataset
  938. :return: True if this class is a space time dataset, False otherwise
  939. """
  940. return True
  941. def get_type(self):
  942. return "str3ds"
  943. def get_new_instance(self, ident):
  944. """Return a new instance with the type of this class"""
  945. return SpaceTimeRaster3DDataset(ident)
  946. def get_new_map_instance(self, ident):
  947. """Return a new instance of a map dataset which is associated
  948. with the type of this class"""
  949. return Raster3DDataset(ident)
  950. def get_map_register(self):
  951. """Return the name of the map register table"""
  952. return self.metadata.get_raster3d_register()
  953. def set_map_register(self, name):
  954. """Set the name of the map register table"""
  955. self.metadata.set_raster3d_register(name)
  956. def spatial_overlapping(self, dataset):
  957. """Return True if the spatial extents overlap"""
  958. if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
  959. return self.spatial_extent.overlapping(dataset.spatial_extent)
  960. else:
  961. return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
  962. def spatial_relation(self, dataset):
  963. """Return the two or three dimensional spatial relation"""
  964. if self.get_type() == dataset.get_type() or \
  965. dataset.get_type() == "str3ds":
  966. return self.spatial_extent.spatial_relation(dataset.spatial_extent)
  967. else:
  968. return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
  969. def spatial_intersection(self, dataset):
  970. """Return the three or two dimensional intersection as spatial_extent
  971. object or None in case no intersection was found.
  972. :param dataset: The abstract dataset to intersect with
  973. :return: The intersection spatial extent or None
  974. """
  975. if self.get_type() == dataset.get_type() or dataset.get_type() == "raster3d":
  976. return self.spatial_extent.intersect(dataset.spatial_extent)
  977. else:
  978. return self.spatial_extent.intersect_2d(dataset.spatial_extent)
  979. def spatial_union(self, dataset):
  980. """Return the three or two dimensional union as spatial_extent
  981. object or None in case the extents does not overlap or meet.
  982. :param dataset: The abstract dataset to create a union with
  983. :return: The union spatial extent or None
  984. """
  985. if self.get_type() == dataset.get_type() or dataset.get_type() == "raster3d":
  986. return self.spatial_extent.union(dataset.spatial_extent)
  987. else:
  988. return self.spatial_extent.union_2d(dataset.spatial_extent)
  989. def spatial_disjoint_union(self, dataset):
  990. """Return the three or two dimensional union as spatial_extent object.
  991. :param dataset: The abstract dataset to create a union with
  992. :return: The union spatial extent
  993. """
  994. if self.get_type() == dataset.get_type() or dataset.get_type() == "raster3d":
  995. return self.spatial_extent.disjoint_union(dataset.spatial_extent)
  996. else:
  997. return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
  998. def reset(self, ident):
  999. """Reset the internal structure and set the identifier"""
  1000. self.base = STR3DSBase(ident=ident)
  1001. self.base.set_creator(str(getpass.getuser()))
  1002. self.absolute_time = STR3DSAbsoluteTime(ident=ident)
  1003. self.relative_time = STR3DSRelativeTime(ident=ident)
  1004. self.spatial_extent = STR3DSSpatialExtent(ident=ident)
  1005. self.metadata = STR3DSMetadata(ident=ident)
  1006. ###############################################################################
  1007. class SpaceTimeVectorDataset(AbstractSpaceTimeDataset):
  1008. """Space time vector dataset class
  1009. .. code-block:: python
  1010. >>> import grass.temporal as tgis
  1011. >>> tgis.init()
  1012. >>> mapset = tgis.get_current_mapset()
  1013. >>> stvds = tgis.SpaceTimeVectorDataset("old@%s"%mapset)
  1014. >>> stvds.is_in_db()
  1015. False
  1016. >>> stvds.is_stds()
  1017. True
  1018. >>> stvds.get_type()
  1019. 'stvds'
  1020. >>> newstvds = stvds.get_new_instance("newstvds@%s"%mapset)
  1021. >>> isinstance(newstvds, SpaceTimeVectorDataset)
  1022. True
  1023. >>> newmap = stvds.get_new_map_instance("newmap@%s"%mapset)
  1024. >>> isinstance(newmap, VectorDataset)
  1025. True
  1026. >>> stvds.reset("new@%s"%mapset)
  1027. >>> stvds.is_in_db()
  1028. False
  1029. >>> stvds.reset(None)
  1030. >>> stvds.is_in_db()
  1031. False
  1032. >>> stvds.get_id()
  1033. ...
  1034. """
  1035. def __init__(self, ident):
  1036. AbstractSpaceTimeDataset.__init__(self, ident)
  1037. def is_stds(self):
  1038. """Return True if this class is a space time dataset
  1039. :return: True if this class is a space time dataset, False otherwise
  1040. """
  1041. return True
  1042. def get_type(self):
  1043. return "stvds"
  1044. def get_new_instance(self, ident):
  1045. """Return a new instance with the type of this class"""
  1046. return SpaceTimeVectorDataset(ident)
  1047. def get_new_map_instance(self, ident):
  1048. """Return a new instance of a map dataset which is associated
  1049. with the type of this class"""
  1050. return VectorDataset(ident)
  1051. def get_map_register(self):
  1052. """Return the name of the map register table"""
  1053. return self.metadata.get_vector_register()
  1054. def set_map_register(self, name):
  1055. """Set the name of the map register table"""
  1056. self.metadata.set_vector_register(name)
  1057. def spatial_overlapping(self, dataset):
  1058. """Return True if the spatial extents 2d overlap"""
  1059. return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
  1060. def spatial_relation(self, dataset):
  1061. """Return the two dimensional spatial relation"""
  1062. return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
  1063. def spatial_intersection(self, dataset):
  1064. """Return the two dimensional intersection as spatial_extent
  1065. object or None in case no intersection was found.
  1066. :param dataset: The abstract dataset to intersect with
  1067. :return: The intersection spatial extent or None
  1068. """
  1069. return self.spatial_extent.intersect_2d(dataset.spatial_extent)
  1070. def spatial_union(self, dataset):
  1071. """Return the two dimensional union as spatial_extent
  1072. object or None in case the extents does not overlap or meet.
  1073. :param dataset: The abstract dataset to create a union with
  1074. :return: The union spatial extent or None
  1075. """
  1076. return self.spatial_extent.union_2d(dataset.spatial_extent)
  1077. def spatial_disjoint_union(self, dataset):
  1078. """Return the two dimensional union as spatial_extent object.
  1079. :param dataset: The abstract dataset to create a union with
  1080. :return: The union spatial extent
  1081. """
  1082. return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
  1083. def reset(self, ident):
  1084. """Reset the internal structure and set the identifier"""
  1085. self.base = STVDSBase(ident=ident)
  1086. self.base.set_creator(str(getpass.getuser()))
  1087. self.absolute_time = STVDSAbsoluteTime(ident=ident)
  1088. self.relative_time = STVDSRelativeTime(ident=ident)
  1089. self.spatial_extent = STVDSSpatialExtent(ident=ident)
  1090. self.metadata = STVDSMetadata(ident=ident)
  1091. ###############################################################################
  1092. if __name__ == "__main__":
  1093. import doctest
  1094. doctest.testmod()