space_time_datasets.py 51 KB

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