base.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. """!@package grass.temporal
  2. @brief GRASS Python scripting module (temporal GIS functions)
  3. Temporal GIS base classes to be used in other
  4. Python temporal gis packages.
  5. This packages includes all base classes to store basic information
  6. like id, name, mapset creation and modification time as well as sql
  7. serialization and de-serialization and the sql database interface.
  8. Usage:
  9. @code
  10. >>> import grass.temporal as tgis
  11. >>> rbase = tgis.RasterBase(ident="soil@PERMANENT")
  12. >>> vbase = tgis.VectorBase(ident="soil:1@PERMANENT")
  13. >>> r3base = tgis.Raster3DBase(ident="soil@PERMANENT")
  14. >>> strdsbase = tgis.STRDSBase(ident="soil@PERMANENT")
  15. >>> stvdsbase = tgis.STVDSBase(ident="soil@PERMANENT")
  16. >>> str3dsbase = tgis.STR3DSBase(ident="soil@PERMANENT")
  17. @endcode
  18. (C) 2011-2012 by the GRASS Development Team
  19. This program is free software under the GNU General Public
  20. License (>=v2). Read the file COPYING that comes with GRASS
  21. for details.
  22. @author Soeren Gebbert
  23. """
  24. from datetime import datetime, date, time, timedelta
  25. from core import *
  26. ###############################################################################
  27. class DictSQLSerializer(object):
  28. def __init__(self):
  29. self.D = {}
  30. def serialize(self, type, table, where=None):
  31. """!Convert the internal dictionary into a string of semicolon
  32. separated SQL statements The keys are the column names and
  33. the values are the row entries
  34. Usage:
  35. \code
  36. >>> t = DictSQLSerializer()
  37. >>> t.D["id"] = "soil@PERMANENT"
  38. >>> t.D["name"] = "soil"
  39. >>> t.D["mapset"] = "PERMANENT"
  40. >>> t.D["creator"] = "soeren"
  41. >>> t.D["creation_time"] = datetime(2001,1,1)
  42. >>> t.D["modification_time"] = datetime(2001,1,1)
  43. >>> t.serialize(type="SELECT", table="raster_base")
  44. ('SELECT name , creator , creation_time , modification_time , mapset , id FROM raster_base ;\\n', ())
  45. >>> t.serialize(type="INSERT", table="raster_base")
  46. ('INSERT INTO raster_base ( name ,creator ,creation_time ,modification_time ,mapset ,id ) VALUES (? ,? ,? ,? ,? ,?) ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil@PERMANENT'))
  47. >>> t.serialize(type="UPDATE", table="raster_base")
  48. ('UPDATE raster_base SET name = ? ,creator = ? ,creation_time = ? ,modification_time = ? ,mapset = ? ,id = ? ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil@PERMANENT'))
  49. >>> t.serialize(type="UPDATE ALL", table="raster_base")
  50. ('UPDATE raster_base SET name = ? ,creator = ? ,creation_time = ? ,modification_time = ? ,mapset = ? ,id = ? ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil@PERMANENT'))
  51. @type must be SELECT. INSERT, UPDATE
  52. @table The name of the table to select, insert or update
  53. @where The optional where statement
  54. @return a tuple containing the SQL string and the arguments
  55. \endcode
  56. """
  57. sql = ""
  58. args = []
  59. # Create ordered select statement
  60. if type == "SELECT":
  61. sql += 'SELECT '
  62. count = 0
  63. for key in self.D.keys():
  64. if count == 0:
  65. sql += ' %s ' % key
  66. else:
  67. sql += ' , %s ' % key
  68. count += 1
  69. sql += ' FROM ' + table + ' '
  70. if where:
  71. sql += where
  72. sql += ";\n"
  73. # Create insert statement
  74. if type == "INSERT":
  75. count = 0
  76. sql += 'INSERT INTO ' + table + ' ('
  77. for key in self.D.keys():
  78. if count == 0:
  79. sql += ' %s ' % key
  80. else:
  81. sql += ' ,%s ' % key
  82. count += 1
  83. count = 0
  84. sql += ') VALUES ('
  85. for key in self.D.keys():
  86. if count == 0:
  87. if dbmi.paramstyle == "qmark":
  88. sql += '?'
  89. else:
  90. sql += '%s'
  91. else:
  92. if dbmi.paramstyle == "qmark":
  93. sql += ' ,?'
  94. else:
  95. sql += ' ,%s'
  96. count += 1
  97. args.append(self.D[key])
  98. sql += ') '
  99. if where:
  100. sql += where
  101. sql += ";\n"
  102. # Create update statement for existing entries
  103. if type == "UPDATE":
  104. count = 0
  105. sql += 'UPDATE ' + table + ' SET '
  106. for key in self.D.keys():
  107. # Update only entries which are not None
  108. if self.D[key] is not None:
  109. if count == 0:
  110. if dbmi.paramstyle == "qmark":
  111. sql += ' %s = ? ' % key
  112. else:
  113. sql += ' %s ' % key
  114. sql += '= %s '
  115. else:
  116. if dbmi.paramstyle == "qmark":
  117. sql += ' ,%s = ? ' % key
  118. else:
  119. sql += ' ,%s ' % key
  120. sql += '= %s '
  121. count += 1
  122. args.append(self.D[key])
  123. if where:
  124. sql += where
  125. sql += ";\n"
  126. # Create update statement for all entries
  127. if type == "UPDATE ALL":
  128. count = 0
  129. sql += 'UPDATE ' + table + ' SET '
  130. for key in self.D.keys():
  131. if count == 0:
  132. if dbmi.paramstyle == "qmark":
  133. sql += ' %s = ? ' % key
  134. else:
  135. sql += ' %s ' % key
  136. sql += '= %s '
  137. else:
  138. if dbmi.paramstyle == "qmark":
  139. sql += ' ,%s = ? ' % key
  140. else:
  141. sql += ' ,%s ' % key
  142. sql += '= %s '
  143. count += 1
  144. args.append(self.D[key])
  145. if where:
  146. sql += where
  147. sql += ";\n"
  148. return sql, tuple(args)
  149. def deserialize(self, row):
  150. """!Convert the content of the dbmi dictionary like row into the
  151. internal dictionary
  152. @param row: The dictionary like row to store in the internal dict
  153. """
  154. self.D = {}
  155. for key in row.keys():
  156. self.D[key] = row[key]
  157. def clear(self):
  158. """!Initialize the internal storage"""
  159. self.D = {}
  160. def print_self(self):
  161. """!Print the content of the internal dictionary to stdout
  162. """
  163. print self.D
  164. ###############################################################################
  165. class SQLDatabaseInterface(DictSQLSerializer):
  166. """!This class represents the SQL database interface
  167. Functions to insert, select and update the internal
  168. structure of this class in the temporal database are implemented.
  169. This is the base class for raster, raster3d, vector and
  170. space time datasets data management classes:
  171. * Identification information (base)
  172. * Spatial extent
  173. * Temporal extent
  174. * Metadata
  175. Usage:
  176. \code
  177. >>> t = SQLDatabaseInterface("raster", "soil@PERMANENT")
  178. >>> t.D["name"] = "soil"
  179. >>> t.D["mapset"] = "PERMANENT"
  180. >>> t.D["creator"] = "soeren"
  181. >>> t.D["creation_time"] = datetime(2001,1,1)
  182. >>> t.get_delete_statement()
  183. "DELETE FROM raster WHERE id = 'soil@PERMANENT';\\n"
  184. >>> t.get_is_in_db_statement()
  185. "SELECT id FROM raster WHERE id = 'soil@PERMANENT';\\n"
  186. >>> t.get_select_statement()
  187. ("SELECT creation_time , mapset , name , creator FROM raster WHERE id = 'soil@PERMANENT';\\n", ())
  188. >>> t.get_select_statement_mogrified()
  189. "SELECT creation_time , mapset , name , creator FROM raster WHERE id = 'soil@PERMANENT';\\n"
  190. >>> t.get_insert_statement()
  191. ('INSERT INTO raster ( creation_time ,mapset ,name ,creator ) VALUES (? ,? ,? ,?) ;\\n', (datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil', 'soeren'))
  192. >>> t.get_insert_statement_mogrified()
  193. "INSERT INTO raster ( creation_time ,mapset ,name ,creator ) VALUES ('2001-01-01 00:00:00' ,'PERMANENT' ,'soil' ,'soeren') ;\\n"
  194. >>> t.get_update_statement()
  195. ("UPDATE raster SET creation_time = ? ,mapset = ? ,name = ? ,creator = ? WHERE id = 'soil@PERMANENT';\\n", (datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil', 'soeren'))
  196. >>> t.get_update_statement_mogrified()
  197. "UPDATE raster SET creation_time = '2001-01-01 00:00:00' ,mapset = 'PERMANENT' ,name = 'soil' ,creator = 'soeren' WHERE id = 'soil@PERMANENT';\\n"
  198. >>> t.get_update_all_statement()
  199. ("UPDATE raster SET creation_time = ? ,mapset = ? ,name = ? ,creator = ? WHERE id = 'soil@PERMANENT';\\n", (datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil', 'soeren'))
  200. >>> t.get_update_all_statement_mogrified()
  201. "UPDATE raster SET creation_time = '2001-01-01 00:00:00' ,mapset = 'PERMANENT' ,name = 'soil' ,creator = 'soeren' WHERE id = 'soil@PERMANENT';\\n"
  202. \endcode
  203. """
  204. def __init__(self, table=None, ident=None):
  205. """!Constructor of this class
  206. @param table: The name of the table
  207. @param ident: The identifier (primary key) of this
  208. object in the database table
  209. """
  210. DictSQLSerializer.__init__(self)
  211. self.table = table # Name of the table, set in the subclass
  212. self.ident = ident
  213. def get_table_name(self):
  214. """!Return the name of the table in which the internal
  215. data are inserted, updated or selected"""
  216. return self.table
  217. def get_delete_statement(self):
  218. """!Return the delete string"""
  219. return "DELETE FROM " + self.get_table_name() + \
  220. " WHERE id = \'" + str(self.ident) + "\';\n"
  221. def delete(self, dbif=None):
  222. """!Delete the entry of this object from the temporal database
  223. @param dbif: The database interface to be used,
  224. if None a temporary connection will be established
  225. """
  226. sql = self.get_delete_statement()
  227. #print sql
  228. if dbif:
  229. dbif.cursor.execute(sql)
  230. else:
  231. dbif = SQLDatabaseInterfaceConnection()
  232. dbif.connect()
  233. dbif.cursor.execute(sql)
  234. dbif.close()
  235. def get_is_in_db_statement(self):
  236. """!Return the selection string"""
  237. return "SELECT id FROM " + self.get_table_name() + \
  238. " WHERE id = \'" + str(self.ident) + "\';\n"
  239. def is_in_db(self, dbif=None):
  240. """!Check if this object is present in the temporal database
  241. @param dbif: The database interface to be used,
  242. if None a temporary connection will be established
  243. """
  244. sql = self.get_is_in_db_statement()
  245. #print sql
  246. if dbif:
  247. dbif.cursor.execute(sql)
  248. row = dbif.cursor.fetchone()
  249. else:
  250. dbif = SQLDatabaseInterfaceConnection()
  251. dbif.connect()
  252. dbif.cursor.execute(sql)
  253. row = dbif.cursor.fetchone()
  254. dbif.close()
  255. # Nothing found
  256. if row is None:
  257. return False
  258. return True
  259. def get_select_statement(self):
  260. """!Return the sql statement and the argument list in
  261. database specific style"""
  262. return self.serialize("SELECT", self.get_table_name(),
  263. "WHERE id = \'" + str(self.ident) + "\'")
  264. def get_select_statement_mogrified(self, dbif=None):
  265. """!Return the select statement as mogrified string
  266. @param dbif: The database interface to be used,
  267. if None a temporary connection will be established
  268. """
  269. if not dbif:
  270. dbif = SQLDatabaseInterfaceConnection()
  271. return dbif.mogrify_sql_statement(self.get_select_statement())
  272. def select(self, dbif=None):
  273. """!Select the content from the temporal database and store it
  274. in the internal dictionary structure
  275. @param dbif: The database interface to be used,
  276. if None a temporary connection will be established
  277. """
  278. sql, args = self.get_select_statement()
  279. #print sql
  280. #print args
  281. if dbif:
  282. if len(args) == 0:
  283. dbif.cursor.execute(sql)
  284. else:
  285. dbif.cursor.execute(sql, args)
  286. row = dbif.cursor.fetchone()
  287. else:
  288. dbif = SQLDatabaseInterfaceConnection()
  289. dbif.connect()
  290. if len(args) == 0:
  291. dbif.cursor.execute(sql)
  292. else:
  293. dbif.cursor.execute(sql, args)
  294. row = dbif.cursor.fetchone()
  295. dbif.close()
  296. # Nothing found
  297. if row is None:
  298. return False
  299. if len(row) > 0:
  300. self.deserialize(row)
  301. else:
  302. core.fatal(_("Object <%s> not found in the temporal database")
  303. % self.get_id())
  304. return True
  305. def get_insert_statement(self):
  306. """!Return the sql statement and the argument
  307. list in database specific style"""
  308. return self.serialize("INSERT", self.get_table_name())
  309. def get_insert_statement_mogrified(self, dbif=None):
  310. """!Return the insert statement as mogrified string
  311. @param dbif: The database interface to be used,
  312. if None a temporary connection will be established
  313. """
  314. if not dbif:
  315. dbif = SQLDatabaseInterfaceConnection()
  316. return dbif.mogrify_sql_statement(self.get_insert_statement())
  317. def insert(self, dbif=None):
  318. """!Serialize the content of this object and store it in the temporal
  319. database using the internal identifier
  320. @param dbif: The database interface to be used,
  321. if None a temporary connection will be established
  322. """
  323. sql, args = self.get_insert_statement()
  324. #print sql
  325. #print args
  326. if dbif:
  327. dbif.cursor.execute(sql, args)
  328. else:
  329. dbif = SQLDatabaseInterfaceConnection()
  330. dbif.connect()
  331. dbif.cursor.execute(sql, args)
  332. dbif.close()
  333. def get_update_statement(self):
  334. """!Return the sql statement and the argument list
  335. in database specific style"""
  336. return self.serialize("UPDATE", self.get_table_name(),
  337. "WHERE id = \'" + str(self.ident) + "\'")
  338. def get_update_statement_mogrified(self, dbif=None):
  339. """!Return the update statement as mogrified string
  340. @param dbif: The database interface to be used,
  341. if None a temporary connection will be established
  342. """
  343. if not dbif:
  344. dbif = SQLDatabaseInterfaceConnection()
  345. return dbif.mogrify_sql_statement(self.get_update_statement())
  346. def update(self, dbif=None):
  347. """!Serialize the content of this object and update it in the temporal
  348. database using the internal identifier
  349. Only object entries which are exists (not None) are updated
  350. @param dbif: The database interface to be used,
  351. if None a temporary connection will be established
  352. """
  353. if self.ident is None:
  354. raise IOError("Missing identifer")
  355. sql, args = self.get_update_statement()
  356. #print sql
  357. #print args
  358. if dbif:
  359. dbif.cursor.execute(sql, args)
  360. else:
  361. dbif = SQLDatabaseInterfaceConnection()
  362. dbif.connect()
  363. dbif.cursor.execute(sql, args)
  364. dbif.close()
  365. def get_update_all_statement(self):
  366. """!Return the sql statement and the argument
  367. list in database specific style"""
  368. return self.serialize("UPDATE ALL", self.get_table_name(),
  369. "WHERE id = \'" + str(self.ident) + "\'")
  370. def get_update_all_statement_mogrified(self, dbif=None):
  371. """!Return the update all statement as mogrified string
  372. @param dbif: The database interface to be used,
  373. if None a temporary connection will be established
  374. """
  375. if not dbif:
  376. dbif = SQLDatabaseInterfaceConnection()
  377. return dbif.mogrify_sql_statement(self.get_update_all_statement())
  378. def update_all(self, dbif=None):
  379. """!Serialize the content of this object, including None objects,
  380. and update it in the temporal database using the internal identifier
  381. @param dbif: The database interface to be used,
  382. if None a temporary connection will be established
  383. """
  384. if self.ident is None:
  385. raise IOError("Missing identifer")
  386. sql, args = self.get_update_all_statement()
  387. #print sql
  388. #print args
  389. if dbif:
  390. dbif.cursor.execute(sql, args)
  391. else:
  392. dbif = SQLDatabaseInterfaceConnection()
  393. dbif.connect()
  394. dbif.cursor.execute(sql, args)
  395. dbif.close()
  396. ###############################################################################
  397. class DatasetBase(SQLDatabaseInterface):
  398. """!This is the base class for all maps and spacetime datasets storing
  399. basic identification information
  400. Usage:
  401. \code
  402. >>> t = DatasetBase("raster", "soil@PERMANENT", creator="soeren", ctime=datetime(2001,1,1), ttype="absolute")
  403. >>> t.id
  404. 'soil@PERMANENT'
  405. >>> t.name
  406. 'soil'
  407. >>> t.mapset
  408. 'PERMANENT'
  409. >>> t.creator
  410. 'soeren'
  411. >>> t.ctime
  412. datetime.datetime(2001, 1, 1, 0, 0)
  413. >>> t.ttype
  414. 'absolute'
  415. >>> t.print_info()
  416. +-------------------- Basic information -------------------------------------+
  417. | Id: ........................ soil@PERMANENT
  418. | Name: ...................... soil
  419. | Mapset: .................... PERMANENT
  420. | Creator: ................... soeren
  421. | Creation time: ............. 2001-01-01 00:00:00
  422. | Temporal type: ............. absolute
  423. >>> t.print_shell_info()
  424. id=soil@PERMANENT
  425. name=soil
  426. mapset=PERMANENT
  427. creator=soeren
  428. creation_time=2001-01-01 00:00:00
  429. temporal_type=absolute
  430. \endcode
  431. """
  432. def __init__(self, table=None, ident=None, name=None, mapset=None,
  433. creator=None, ctime=None,ttype=None):
  434. """!Constructor
  435. @param table: The name of the temporal database table
  436. that should be used to store the values
  437. @param ident: The unique identifier must be a combination of
  438. the dataset name, layer name and the mapset
  439. name@mapset or name:1@mapset
  440. used as as primary key in the temporal database
  441. @param name: The name of the map or dataset
  442. @param mapset: The name of the mapset
  443. @param creator: The name of the creator
  444. @param ctime: The creation datetime object
  445. @param ttype: The temporal type
  446. * "absolute" Identifier for absolute time
  447. * "relative" Identifier for relative time
  448. """
  449. SQLDatabaseInterface.__init__(self, table, ident)
  450. self.set_id(ident)
  451. if ident is not None and name is None and mapset is None:
  452. if ident.find("@") >= 0:
  453. name, mapset = ident.split("@")
  454. if name.find(":") >= 0:
  455. name, layer = ident.split(":")
  456. self.set_name(name)
  457. self.set_mapset(mapset)
  458. self.set_creator(creator)
  459. self.set_ctime(ctime)
  460. self.set_ttype(ttype)
  461. # Commented out for performance reasons
  462. #self.set_mtime(mtime)
  463. #self.set_revision(revision)
  464. def set_id(self, ident):
  465. """!Convenient method to set the unique identifier (primary key)
  466. @param ident: The unique identifier must be a combination
  467. of the dataset name, layer name and the mapset
  468. name@mapset or name:1@mapset
  469. """
  470. self.ident = ident
  471. self.D["id"] = ident
  472. if ident is not None:
  473. if ident.find("@") >= 0:
  474. name, mapset = ident.split("@")
  475. self.set_mapset(mapset)
  476. self.set_name(name)
  477. else:
  478. core.fatal(_("Wrong identifier, the mapset is missing"))
  479. if name.find(":") >= 0:
  480. name, layer = ident.split(":")
  481. self.set_layer(layer)
  482. self.set_name(name)
  483. def set_name(self, name):
  484. """!Set the name of the dataset
  485. @param name: The name of the dataset
  486. """
  487. self.D["name"] = name
  488. def set_mapset(self, mapset):
  489. """!Set the mapset of the dataset
  490. @param mapsets: The name of the mapset in which this dataset is stored
  491. """
  492. self.D["mapset"] = mapset
  493. def set_layer(self, layer):
  494. """!Convenient method to set the layer of the map (part of primary key)
  495. Layer are supported for vector maps
  496. @param layer: The layer of the map
  497. """
  498. self.D["layer"] = layer
  499. def set_creator(self, creator):
  500. """!Set the creator of the dataset
  501. @param creator: The name of the creator
  502. """
  503. self.D["creator"] = creator
  504. def set_ctime(self, ctime=None):
  505. """!Set the creation time of the dataset,
  506. if nothing set the current time is used
  507. @param ctime: The current time of type datetime
  508. """
  509. if ctime is None:
  510. self.D["creation_time"] = datetime.now()
  511. else:
  512. self.D["creation_time"] = ctime
  513. def set_ttype(self, ttype):
  514. """!Set the temporal type of the dataset: absolute or relative,
  515. if nothing set absolute time will assumed
  516. @param ttype: The temporal type of the dataset "absolute or relative"
  517. """
  518. if ttype is None or (ttype != "absolute" and ttype != "relative"):
  519. self.D["temporal_type"] = "absolute"
  520. else:
  521. self.D["temporal_type"] = ttype
  522. # def set_mtime(self, mtime=None):
  523. # """!Set the modification time of the map, if nothing set the current time is used"""
  524. # if mtime == None:
  525. # self.D["modification_time"] = datetime.now()
  526. # else:
  527. # self.D["modification_time"] = mtime
  528. # def set_revision(self, revision=1):
  529. # """!Set the revision of the map: if nothing set revision 1 will assumed"""
  530. # self.D["revision"] = revision
  531. def get_id(self):
  532. """!Convenient method to get the unique identifier (primary key)
  533. @return None if not found
  534. """
  535. if "id" in self.D:
  536. return self.D["id"]
  537. else:
  538. return None
  539. def get_map_id(self):
  540. """!Convenient method to get the unique map identifier
  541. without layer information
  542. @param return the name of the vector map as name@mapset
  543. """
  544. if self.id.find(":") >= 0:
  545. # Remove the layer identifier from the id
  546. return self.id.split("@")[0].split(":")[0] + "@" + \
  547. self.id.split("@")[1]
  548. else:
  549. return self.id
  550. def get_layer(self):
  551. """!Convenient method to get the layer of the map (part of primary key)
  552. Layer are currently supported for vector maps
  553. @return None if not found
  554. """
  555. if "layer" in self.D:
  556. return self.D["layer"]
  557. else:
  558. return None
  559. def get_name(self):
  560. """!Get the name of the dataset
  561. @return None if not found"""
  562. if "name" in self.D:
  563. return self.D["name"]
  564. else:
  565. return None
  566. def get_mapset(self):
  567. """!Get the name of mapset of this dataset
  568. @return None if not found"""
  569. if "mapset" in self.D:
  570. return self.D["mapset"]
  571. else:
  572. return None
  573. def get_creator(self):
  574. """!Get the creator of the dataset
  575. @return None if not found"""
  576. if "creator" in self.D:
  577. return self.D["creator"]
  578. else:
  579. return None
  580. def get_ctime(self):
  581. """!Get the creation time of the dataset, datatype is datetime
  582. @return None if not found"""
  583. if "creation_time" in self.D:
  584. return self.D["creation_time"]
  585. else:
  586. return None
  587. def get_ttype(self):
  588. """!Get the temporal type of the map
  589. @return None if not found"""
  590. if "temporal_type" in self.D:
  591. return self.D["temporal_type"]
  592. else:
  593. return None
  594. # def get_mtime(self):
  595. # """!Get the modification time of the map, datatype is datetime
  596. # @return None if not found"""
  597. # if self.D.has_key("modification_time"):
  598. # return self.D["modification_time"]
  599. # else:
  600. # return None
  601. # def get_revision(self):
  602. # """!Get the revision of the map
  603. # @return None if not found"""
  604. # if self.D.has_key("revision"):
  605. # return self.D["revision"]
  606. # else:
  607. # return None
  608. # Properties of this class
  609. id = property(fget=get_id, fset=set_id)
  610. map_id = property(fget=get_map_id, fset=None)
  611. name = property(fget=get_name, fset=set_name)
  612. mapset = property(fget=get_mapset, fset=set_mapset)
  613. ctime = property(fget=get_ctime, fset=set_ctime)
  614. ttype = property(fget=get_ttype, fset=set_ttype)
  615. creator = property(fget=get_creator, fset=set_creator)
  616. def print_info(self):
  617. """!Print information about this class in human readable style"""
  618. # 0123456789012345678901234567890
  619. print " +-------------------- Basic information -------------------------------------+"
  620. print " | Id: ........................ " + str(self.get_id())
  621. print " | Name: ...................... " + str(self.get_name())
  622. print " | Mapset: .................... " + str(self.get_mapset())
  623. if self.get_layer():
  624. print " | Layer:...................... " + str(self.get_layer())
  625. print " | Creator: ................... " + str(self.get_creator())
  626. print " | Creation time: ............. " + str(self.get_ctime())
  627. print " | Temporal type: ............. " + str(self.get_ttype())
  628. # print " | Modification time: ......... " + str(self.get_mtime())
  629. # print " | Revision in database: ...... " + str(self.get_revision())
  630. def print_shell_info(self):
  631. """!Print information about this class in shell style"""
  632. print "id=" + str(self.get_id())
  633. print "name=" + str(self.get_name())
  634. print "mapset=" + str(self.get_mapset())
  635. if self.get_layer():
  636. print "layer=" + str(self.get_layer())
  637. print "creator=" + str(self.get_creator())
  638. print "creation_time=" + str(self.get_ctime())
  639. print "temporal_type=" + str(self.get_ttype())
  640. # print "modification_time=" + str(self.get_mtime())
  641. # print "revision=" + str(self.get_revision())
  642. ###############################################################################
  643. class RasterBase(DatasetBase):
  644. """!Time stamped raster map base information class"""
  645. def __init__(self, ident=None, name=None, mapset=None, creator=None,
  646. creation_time=None, temporal_type=None):
  647. DatasetBase.__init__(self, "raster_base", ident, name, mapset,
  648. creator, creation_time, temporal_type)
  649. class Raster3DBase(DatasetBase):
  650. """!Time stamped 3D raster map base information class"""
  651. def __init__(self, ident=None, name=None, mapset=None, creator=None,
  652. creation_time=None, temporal_type=None,):
  653. DatasetBase.__init__(self, "raster3d_base", ident, name,
  654. mapset, creator, creation_time,
  655. temporal_type)
  656. class VectorBase(DatasetBase):
  657. """!Time stamped vector map base information class"""
  658. def __init__(self, ident=None, name=None, mapset=None, layer=None,
  659. creator=None, creation_time=None, temporal_type=None):
  660. DatasetBase.__init__(self, "vector_base", ident, name, mapset,
  661. creator, creation_time, temporal_type)
  662. self.set_id(ident)
  663. if ident is not None and name is None and mapset is None:
  664. if ident.find("@") >= 0:
  665. name, mapset = ident.split("@")
  666. if layer is None:
  667. if name.find(":") >= 0:
  668. name, layer = name.split(":")
  669. self.set_name(name)
  670. self.set_mapset(mapset)
  671. # Layer currently only in use by vector maps
  672. self.set_layer(layer)
  673. ###############################################################################
  674. class STDSBase(DatasetBase):
  675. """!Base class for space time datasets
  676. This class adds the semantic type member variable to the dataset
  677. base class.
  678. Usage:
  679. \code
  680. >>> t = STDSBase("stds", "soil@PERMANENT", semantic_type="average", creator="soeren", ctime=datetime(2001,1,1), ttype="absolute")
  681. >>> t.semantic_type
  682. 'average'
  683. >>> t.print_info()
  684. +-------------------- Basic information -------------------------------------+
  685. | Id: ........................ soil@PERMANENT
  686. | Name: ...................... soil
  687. | Mapset: .................... PERMANENT
  688. | Creator: ................... soeren
  689. | Creation time: ............. 2001-01-01 00:00:00
  690. | Temporal type: ............. absolute
  691. | Semantic type:.............. average
  692. >>> t.print_shell_info()
  693. id=soil@PERMANENT
  694. name=soil
  695. mapset=PERMANENT
  696. creator=soeren
  697. creation_time=2001-01-01 00:00:00
  698. temporal_type=absolute
  699. semantic_type=average
  700. \endcode
  701. """
  702. def __init__(self, table=None, ident=None, name=None, mapset=None,
  703. semantic_type=None, creator=None, ctime=None,
  704. ttype=None):
  705. DatasetBase.__init__(self, table, ident, name, mapset, creator,
  706. ctime, ttype)
  707. self.set_semantic_type(semantic_type)
  708. def set_semantic_type(self, semantic_type):
  709. """!Set the semantic type of the space time dataset"""
  710. self.D["semantic_type"] = semantic_type
  711. def get_semantic_type(self):
  712. """!Get the semantic type of the space time dataset
  713. @return None if not found"""
  714. if "semantic_type" in self.D:
  715. return self.D["semantic_type"]
  716. else:
  717. return None
  718. semantic_type = property(fget=get_semantic_type, fset=set_semantic_type)
  719. def print_info(self):
  720. """!Print information about this class in human readable style"""
  721. DatasetBase.print_info(self)
  722. # 0123456789012345678901234567890
  723. print " | Semantic type:.............. " + str(
  724. self.get_semantic_type())
  725. def print_shell_info(self):
  726. """!Print information about this class in shell style"""
  727. DatasetBase.print_shell_info(self)
  728. print "semantic_type=" + str(self.get_semantic_type())
  729. ###############################################################################
  730. class STRDSBase(STDSBase):
  731. """!Space time raster dataset base information class"""
  732. def __init__(self, ident=None, name=None, mapset=None,
  733. semantic_type=None, creator=None, ctime=None,
  734. ttype=None):
  735. STDSBase.__init__(self, "strds_base", ident, name, mapset,
  736. semantic_type, creator, ctime,
  737. ttype)
  738. class STR3DSBase(STDSBase):
  739. """!Space time 3D raster dataset base information class"""
  740. def __init__(self, ident=None, name=None, mapset=None,
  741. semantic_type=None, creator=None, ctime=None,
  742. ttype=None):
  743. STDSBase.__init__(self, "str3ds_base", ident, name, mapset,
  744. semantic_type, creator, ctime,
  745. ttype)
  746. class STVDSBase(STDSBase):
  747. """!Space time vector dataset base information class"""
  748. def __init__(self, ident=None, name=None, mapset=None,
  749. semantic_type=None, creator=None, ctime=None,
  750. ttype=None):
  751. STDSBase.__init__(self, "stvds_base", ident, name, mapset,
  752. semantic_type, creator, ctime,
  753. ttype)
  754. ###############################################################################
  755. if __name__ == "__main__":
  756. import doctest
  757. doctest.testmod()