space_time_datasets_tools.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. """!@package grass.temporal
  2. @brief GRASS Python scripting module (temporal GIS functions)
  3. Temporal GIS related functions to be used in Python scripts.
  4. Usage:
  5. @code
  6. import grass.temporal as tgis
  7. tgis.register_maps_in_space_time_dataset(type, name, maps)
  8. ...
  9. @endcode
  10. (C) 2008-2011 by the GRASS Development Team
  11. This program is free software under the GNU General Public
  12. License (>=v2). Read the file COPYING that comes with GRASS
  13. for details.
  14. @author Soeren Gebbert
  15. """
  16. from space_time_datasets import *
  17. ###############################################################################
  18. def register_maps_in_space_time_dataset(type, name, maps=None, file=None, start=None, end=None, unit=None, increment=None, dbif = None, interval=False, fs="|"):
  19. """Use this method to register maps in space time datasets. This function is generic and
  20. Additionally a start time string and an increment string can be specified
  21. to assign a time interval automatically to the maps.
  22. It takes care of the correct update of the space time datasets from all
  23. registered maps.
  24. @param type: The type of the maps raster, raster3d or vector
  25. @param name: The name of the space time dataset
  26. @param maps: A comma separated list of map names
  27. @param file: Input file one map with optional start and end time, one per line
  28. @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
  29. @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
  30. @param unit: The unit of the relative time: years, months, days, hours, minutes, seconds
  31. @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
  32. @param dbif: The database interface to be used
  33. @param interval: If True, time intervals are created in case the start time and an increment is provided
  34. @param fs: Field separator used in input file
  35. """
  36. start_time_in_file = False
  37. end_time_in_file = False
  38. if maps and file:
  39. core.fatal(_("%s= and %s= are mutually exclusive") % ("input","file"))
  40. if end and increment:
  41. core.fatal(_("%s= and %s= are mutually exclusive") % ("end","increment"))
  42. if end and not start:
  43. core.fatal(_("Please specify %s= and %s=") % ("start_time","end_time"))
  44. if not maps and not file:
  45. core.fatal(_("Please specify %s= or %s=") % ("input","file"))
  46. if start and start == "file":
  47. start_time_in_file = True
  48. if end and end == "file":
  49. end_time_in_file = True
  50. # We may need the mapset
  51. mapset = core.gisenv()["MAPSET"]
  52. # Check if the dataset name contains the mapset as well
  53. if name.find("@") < 0:
  54. id = name + "@" + mapset
  55. else:
  56. id = name
  57. sp = dataset_factory(type, id)
  58. connect = False
  59. if dbif == None:
  60. dbif = sql_database_interface()
  61. dbif.connect()
  62. connect = True
  63. # Read content from temporal database
  64. sp.select(dbif)
  65. if sp.is_in_db(dbif) == False:
  66. dbif.close()
  67. core.fatal(_("Space time %s dataset <%s> no found") % (sp.get_new_map_instance(None).get_type(), name))
  68. maplist = []
  69. # Map names as comma separated string
  70. if maps:
  71. if maps.find(",") == -1:
  72. maplist = (maps,)
  73. else:
  74. maplist = tuple(maps.split(","))
  75. # Read the map list from file
  76. if file:
  77. fd = open(file, "r")
  78. line = True
  79. while True:
  80. line = fd.readline()
  81. if not line:
  82. break
  83. line_list = line.split(fs)
  84. mapname = line_list[0].strip()
  85. if mapname.find("@") < 0:
  86. mapid = mapname + "@" + mapset
  87. else:
  88. mapid = mapname
  89. row = {}
  90. row["id"] = mapid
  91. if start_time_in_file and end_time_in_file:
  92. row["start"] = line_list[1].strip()
  93. row["end"] = line_list[2].strip()
  94. if start_time_in_file and not end_time_in_file:
  95. row["start"] = line_list[1].strip()
  96. maplist.append(row)
  97. num_maps = len(maplist)
  98. count = 0
  99. for entry in maplist:
  100. core.percent(count, num_maps, 1)
  101. # Get a new instance of the space time dataset map type
  102. if file:
  103. map = sp.get_new_map_instance(entry["id"])
  104. else:
  105. if entry.find("@") < 0:
  106. mapid = entry + "@" + mapset
  107. else:
  108. mapid = entry
  109. map = sp.get_new_map_instance(mapid)
  110. # Use the time data from file
  111. if start_time_in_file:
  112. start = entry["start"]
  113. if end_time_in_file:
  114. end = entry["end"]
  115. # Put the map into the database
  116. if map.is_in_db(dbif) == False:
  117. # Break in case no valid time is provided
  118. if start == "" or start == None:
  119. dbif.close()
  120. core.fatal(_("Unable to register %s map <%s>. The map has no valid time and the start time is not set.") % \
  121. (map.get_type(), map.get_id() ))
  122. # Load the data from the grass file database
  123. map.load()
  124. if sp.get_temporal_type() == "absolute":
  125. map.set_time_to_absolute()
  126. else:
  127. map.set_time_to_relative()
  128. # Put it into the temporal database
  129. map.insert(dbif)
  130. else:
  131. map.select(dbif)
  132. if map.get_temporal_type() != sp.get_temporal_type():
  133. dbif.close()
  134. core.fatal(_("Unable to register %s map <%s>. The temporal types are different.") % (map.get_type(), map.get_id()))
  135. # In case the time is in the input file we ignore the increment counter
  136. if start_time_in_file:
  137. count = 1
  138. # Set the valid time
  139. if start:
  140. assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=end, unit=unit, increment=increment, mult=count, dbif=dbif, interval=interval)
  141. # Finally Register map in the space time dataset
  142. sp.register_map(map, dbif)
  143. count += 1
  144. # Update the space time tables
  145. sp.update_from_registered_maps(dbif)
  146. if connect == True:
  147. dbif.close()
  148. core.percent(num_maps, num_maps, 1)
  149. ###############################################################################
  150. def unregister_maps_from_space_time_datasets(type, name, maps, file=None, dbif = None):
  151. """Unregister maps from a single space time dataset or, in case no dataset name is provided,
  152. unregister from all datasets within the maps are registered.
  153. @param type: The type of the maps raster, vector or raster3d
  154. @param name: Name of an existing space time raster dataset. If no name is provided the raster map(s) are unregistered from all space time datasets in which they are registered.
  155. @param maps: A comma separated list of map names
  156. @param dbif: The database interface to be used
  157. """
  158. if maps and file:
  159. core.fatal(_("%s= and %s= are mutually exclusive") % ("input","file"))
  160. mapset = core.gisenv()["MAPSET"]
  161. if dbif == None:
  162. dbif = sql_database_interface()
  163. dbif.connect()
  164. connect = True
  165. # In case a space time dataset is specified
  166. if name:
  167. # Check if the dataset name contains the mapset as well
  168. if name.find("@") < 0:
  169. id = name + "@" + mapset
  170. else:
  171. id = name
  172. if type == "rast":
  173. sp = dataset_factory("strds", id)
  174. if type == "rast3d":
  175. sp = dataset_factory("str3ds", id)
  176. if type == "vect":
  177. sp = dataset_factory("stvds", id)
  178. if sp.is_in_db(dbif) == False:
  179. dbif.close()
  180. core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
  181. maplist = []
  182. # Map names as comma separated string
  183. if maps:
  184. if maps.find(",") == -1:
  185. maplist = (maps,)
  186. else:
  187. maplist = tuple(maps.split(","))
  188. # Read the map list from file
  189. if file:
  190. fd = open(file, "r")
  191. line = True
  192. while True:
  193. line = fd.readline()
  194. if not line:
  195. break
  196. line_list = line.split(fs)
  197. mapname = line_list[0].strip()
  198. maplist.append(mapname)
  199. num_maps = len(maplist)
  200. count = 0
  201. for mapname in maplist:
  202. core.percent(count, num_maps, 1)
  203. mapname = mapname.strip()
  204. # Check if the map name contains the mapset as well
  205. if mapname.find("@") < 0:
  206. mapid = mapname + "@" + mapset
  207. else:
  208. mapid = mapname
  209. map = dataset_factory(type, mapid)
  210. # Unregister map if in database
  211. if map.is_in_db(dbif) == True:
  212. if name:
  213. sp.select(dbif)
  214. sp.unregister_map(map, dbif)
  215. else:
  216. map.select(dbif)
  217. map.unregister(dbif)
  218. count += 1
  219. if name:
  220. sp.update_from_registered_maps(dbif)
  221. if connect == True:
  222. dbif.close()
  223. core.percent(num_maps, num_maps, 1)
  224. ###############################################################################
  225. def assign_valid_time_to_maps(type, maps, ttype, start, end=None, unit=None, file=file, increment=None, dbif = None, interval=False, fs="|"):
  226. """Use this method to assign valid time (absolute or relative) to raster,
  227. raster3d and vector datasets.
  228. It takes care of the correct update of the space time datasets from all
  229. registered maps.
  230. Valid end time and increment are mutual exclusive.
  231. @param type: The type of the maps raster, raster3d or vector
  232. @param maps: A comma separated list of map names
  233. @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
  234. @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
  235. @param unit: The unit of the relative time: years, months, days, hours, minutes, seconds
  236. @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
  237. @param file: Input file one map with optional start and end time, one per line
  238. @param dbif: The database interface to be used
  239. @param interval: If True, time intervals are created in case the start time and an increment is provided
  240. @param fs: Field separator used in input file
  241. """
  242. start_time_in_file = False
  243. end_time_in_file = False
  244. if end and increment:
  245. if dbif:
  246. dbif.close()
  247. core.fatal(_("Valid end time and increment are mutual exclusive"))
  248. # List of space time datasets to be updated
  249. splist = {}
  250. if maps and file:
  251. core.fatal(_("%s= and %s= are mutually exclusive") % ("input","file"))
  252. if end and increment:
  253. core.fatal(_("%s= and %s= are mutually exclusive") % ("end","increment"))
  254. if end and not start:
  255. core.fatal(_("Please specify %s= and %s=") % ("start_time","end_time"))
  256. if not maps and not file:
  257. core.fatal(_("Please specify %s= or %s=") % ("input","file"))
  258. if start and start == "file":
  259. start_time_in_file = True
  260. if end and end == "file":
  261. end_time_in_file = True
  262. # We may need the mapset
  263. mapset = core.gisenv()["MAPSET"]
  264. connect = False
  265. if dbif == None:
  266. dbif = sql_database_interface()
  267. dbif.connect()
  268. connect = True
  269. maplist = []
  270. # Map names as comma separated string
  271. if maps:
  272. if maps.find(",") == -1:
  273. maplist = (maps,)
  274. else:
  275. maplist = tuple(maps.split(","))
  276. # Read the map list from file
  277. if file:
  278. fd = open(file, "r")
  279. line = True
  280. while True:
  281. line = fd.readline()
  282. if not line:
  283. break
  284. line_list = line.split(fs)
  285. mapname = line_list[0].strip()
  286. if mapname.find("@") < 0:
  287. mapid = mapname + "@" + mapset
  288. else:
  289. mapid = mapname
  290. row = {}
  291. row["id"] = mapid
  292. if start_time_in_file and end_time_in_file:
  293. row["start"] = line_list[1].strip()
  294. row["end"] = line_list[2].strip()
  295. if start_time_in_file and not end_time_in_file:
  296. row["start"] = line_list[1].strip()
  297. maplist.append(row)
  298. num_maps = len(maplist)
  299. count = 0
  300. for entry in maplist:
  301. core.percent(count, num_maps, 1)
  302. if file:
  303. mapid = entry["id"]
  304. else:
  305. if entry.find("@") < 0:
  306. mapid = entry + "@" + mapset
  307. else:
  308. mapid = entry
  309. map = dataset_factory(type, mapid)
  310. # Use the time data from file
  311. if start_time_in_file:
  312. start = entry["start"]
  313. if end_time_in_file:
  314. end = entry["end"]
  315. if map.is_in_db(dbif) == False:
  316. # Load the data from the grass file database
  317. map.load()
  318. if ttype == "absolute":
  319. map.set_time_to_absolute()
  320. else:
  321. map.set_time_to_relative()
  322. # Put it into the temporal database
  323. map.insert(dbif)
  324. else:
  325. map.select(dbif)
  326. sprows = map.get_registered_datasets(dbif)
  327. # Make an entry in the dataset list, using a dict make sure that
  328. # each dataset is listed only once
  329. if sprows != None:
  330. for dataset in sprows:
  331. splist[dataset["id"]] = True
  332. # In case the time is in the input file we ignore the increment counter
  333. if start_time_in_file:
  334. count = 1
  335. # Set the valid time
  336. assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, unit=unit, increment=increment, mult=count, dbif=dbif, interval=interval)
  337. count += 1
  338. # Update all the space time datasets in which registered maps are changed there valid time
  339. for name in splist.keys():
  340. sp = map.get_new_stds_instance(name)
  341. sp.select(dbif)
  342. sp.update_from_registered_maps(dbif)
  343. if connect == True:
  344. dbif.close()
  345. core.percent(num_maps, num_maps, 1)
  346. ###############################################################################
  347. def assign_valid_time_to_map(ttype, map, start, end, unit, increment=None, mult=1, dbif = None, interval=False):
  348. """Assign the valid time to a map dataset
  349. @param ttype: The temporal type which should be assigned and which the time format is of
  350. @param map: A map dataset object derived from abstract_map_dataset
  351. @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
  352. @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
  353. @param unit: The unit of the relative time: years, months, days, hours, minutes, seconds
  354. @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative is integer 1)
  355. @param multi: A multiplier for the increment
  356. @param dbif: The database interface to use for sql queries
  357. @param interval: If True, time intervals are created in case the start time and an increment is provided
  358. """
  359. connect = False
  360. if dbif == None:
  361. dbif = sql_database_interface()
  362. dbif.connect()
  363. connect = True
  364. if ttype == "absolute":
  365. start_time = string_to_datetime(start)
  366. if start_time == None:
  367. dbif.close()
  368. core.fatal(_("Unable to convert string \"%s\"into a datetime object")%(start))
  369. end_time = None
  370. if end:
  371. end_time = string_to_datetime(end)
  372. if end_time == None:
  373. dbif.close()
  374. core.fatal(_("Unable to convert string \"%s\"into a datetime object")%(end))
  375. # Add the increment
  376. if increment:
  377. start_time = increment_datetime_by_string(start_time, increment, mult)
  378. if interval:
  379. end_time = increment_datetime_by_string(start_time, increment, 1)
  380. core.verbose(_("Set absolute valid time for map <%s> to %s - %s") % (map.get_id(), str(start_time), str(end_time)))
  381. map.update_absolute_time(start_time, end_time, None, dbif)
  382. else:
  383. start_time = int(start)
  384. end_time = None
  385. if end:
  386. end_time = int(end)
  387. if increment:
  388. start_time = start_time + mult * int(increment)
  389. if interval:
  390. end_time = start_time + int(increment)
  391. core.verbose(_("Set relative valid time for map <%s> to %i - %s with unit %s") % (map.get_id(), start_time, str(end_time), unit))
  392. map.update_relative_time(start_time, end_time, unit, dbif)
  393. if connect == True:
  394. dbif.close()
  395. ###############################################################################
  396. def dataset_factory(type, id):
  397. """A factory functions to create space time or map datasets
  398. @param type: the dataset type: rast, rast3d, vect, strds, str3ds, stvds
  399. @param id: The id of the dataset ("name@mapset")
  400. """
  401. if type == "strds":
  402. sp = space_time_raster_dataset(id)
  403. elif type == "str3ds":
  404. sp = space_time_raster3d_dataset(id)
  405. elif type == "stvds":
  406. sp = space_time_vector_dataset(id)
  407. elif type == "rast":
  408. sp = raster_dataset(id)
  409. elif type == "rast3d":
  410. sp = raster3d_dataset(id)
  411. elif type == "vect":
  412. sp = vector_dataset(id)
  413. else:
  414. core.error(_("Unknown dataset type: %s") % type)
  415. return None
  416. return sp
  417. ###############################################################################
  418. def list_maps_of_stds(type, input, columns, order, where, separator, method, header):
  419. """ List the maps of a space time dataset using diffetent methods
  420. @param type: The type of the maps raster, raster3d or vector
  421. @param input: Name of a space time raster dataset
  422. @param columns: A comma separated list of columns to be printed to stdout
  423. @param order: A comma seoarated list of columns to order the space time dataset by category
  424. @param where: A where statement for selected listing without "WHERE" e.g: start_time < "2001-01-01" and end_time > "2001-01-01"
  425. @param separator: The field separator character between the columns
  426. @param method: String identifier to select a method out of cols,comma,delta or deltagaps
  427. * "cols": Print preselected columns specified by columns
  428. * "comma": Print the map ids (name@mapset) as comma separated string
  429. * "delta": Print the map ids (name@mapset) with start time, end time, relative length of intervals and the relative distance to the begin
  430. * "deltagaps": Same as "delta" with addtitionakl listing of gaps. Gaps can be simply identified as the id is "None"
  431. * "gran": List map using the granularity of the space time dataset, columns are identical to deltagaps
  432. @param header: Set True to print column names
  433. """
  434. mapset = core.gisenv()["MAPSET"]
  435. if input.find("@") >= 0:
  436. id = input
  437. else:
  438. id = input + "@" + mapset
  439. sp = dataset_factory(type, id)
  440. if sp.is_in_db() == False:
  441. core.fatal(_("Dataset <%s> not found in temporal database") % (id))
  442. sp.select()
  443. if separator == None or separator == "":
  444. separator = "\t"
  445. # This method expects a list of objects for gap detection
  446. if method == "delta" or method == "deltagaps" or method == "gran":
  447. columns = "id,start_time,end_time"
  448. if method == "deltagaps":
  449. maps = sp.get_registered_maps_as_objects_with_gaps(where, None)
  450. elif method == "delta":
  451. maps = sp.get_registered_maps_as_objects(where, "start_time", None)
  452. elif method == "gran":
  453. maps = sp.get_registered_maps_as_objects_by_granularity(None)
  454. if header:
  455. string = ""
  456. string += "%s%s" % ("id", separator)
  457. string += "%s%s" % ("start_time", separator)
  458. string += "%s%s" % ("end_time", separator)
  459. string += "%s%s" % ("interval_length", separator)
  460. string += "%s" % ("distance_from_begin")
  461. print string
  462. if maps and len(maps) > 0:
  463. if isinstance(maps[0], list):
  464. first_time, dummy = maps[0][0].get_valid_time()
  465. else:
  466. first_time, dummy = maps[0].get_valid_time()
  467. for mymap in maps:
  468. if isinstance(mymap, list):
  469. map = mymap[0]
  470. else:
  471. map = mymap
  472. start, end = map.get_valid_time()
  473. if end:
  474. delta = end -start
  475. else:
  476. delta = None
  477. delta_first = start - first_time
  478. if map.is_time_absolute():
  479. if end:
  480. delta = time_delta_to_relative_time(delta)
  481. delta_first = time_delta_to_relative_time(delta_first)
  482. string = ""
  483. string += "%s%s" % (map.get_id(), separator)
  484. string += "%s%s" % (start, separator)
  485. string += "%s%s" % (end, separator)
  486. string += "%s%s" % (delta, separator)
  487. string += "%s" % (delta_first)
  488. print string
  489. else:
  490. # In comma separated mode only map ids are needed
  491. if method == "comma":
  492. columns = "id"
  493. rows = sp.get_registered_maps(columns, where, order, None)
  494. if rows:
  495. if method == "comma":
  496. string = ""
  497. count = 0
  498. for row in rows:
  499. if count == 0:
  500. string += row["id"]
  501. else:
  502. string += ",%s" % row["id"]
  503. count += 1
  504. print string
  505. elif method == "cols":
  506. # Print the column names if requested
  507. if header:
  508. output = ""
  509. count = 0
  510. collist = columns.split(",")
  511. for key in collist:
  512. if count > 0:
  513. output += separator + str(key)
  514. else:
  515. output += str(key)
  516. count += 1
  517. print output
  518. for row in rows:
  519. output = ""
  520. count = 0
  521. for col in row:
  522. if count > 0:
  523. output += separator + str(col)
  524. else:
  525. output += str(col)
  526. count += 1
  527. print output
  528. ###############################################################################
  529. def sample_stds_by_stds_topology(intype, sampletype, input, sampler, header, separator, method):
  530. """ Sample the input space time dataset with a sample space time dataset and print the result to stdout
  531. In case multiple maps are located in the current granule, the map names are separated by comma.
  532. Attention: Do not use the comma as separator
  533. @param intype: Type of the input space time dataset (strds, stvds or str3ds)
  534. @param samtype: Type of the sample space time dataset (strds, stvds or str3ds)
  535. @param input: Name of a space time dataset
  536. @param sampler: Name of a space time dataset used for temporal sampling
  537. @param header: Set True to print column names
  538. @param separator: The field separator character between the columns
  539. @param method: The method to be used for sampling (start,during,contain,overlap,equal)
  540. """
  541. mapset = core.gisenv()["MAPSET"]
  542. if input.find("@") >= 0:
  543. id = input
  544. else:
  545. id = input + "@" + mapset
  546. sp = dataset_factory(intype, id)
  547. if sampler.find("@") >= 0:
  548. sid = sampler
  549. else:
  550. sid = sampler + "@" + mapset
  551. ssp = dataset_factory(sampletype, sid)
  552. dbif = sql_database_interface()
  553. dbif.connect()
  554. if sp.is_in_db(dbif) == False:
  555. core.fatal(_("Dataset <%s> not found in temporal database") % (id))
  556. if ssp.is_in_db(dbif) == False:
  557. core.fatal(_("Dataset <%s> not found in temporal database") % (sid))
  558. sp.select(dbif)
  559. ssp.select(dbif)
  560. if separator == None or separator == "" or separator.find(",") >= 0:
  561. separator = " | "
  562. mapmatrix = sp.sample_by_dataset_topology(ssp, method, dbif)
  563. if mapmatrix and len(mapmatrix) > 0:
  564. if header:
  565. string = ""
  566. string += "%s%s" % ("sample_id", separator)
  567. string += "%s%s" % ("ids", separator)
  568. string += "%s%s" % ("start_time", separator)
  569. string += "%s%s" % ("end_time", separator)
  570. string += "%s%s" % ("interval_length", separator)
  571. string += "%s" % ("distance_from_begin")
  572. print string
  573. first_time, dummy = mapmatrix[0]["granule"].get_valid_time()
  574. for entry in mapmatrix:
  575. mapnames = ""
  576. count = 0
  577. for sample in entry["samples"]:
  578. if count == 0:
  579. mapnames += str(sample.get_id())
  580. else:
  581. mapnames += ",%s" % str(sample.get_id())
  582. count += 1
  583. map = entry["granule"]
  584. start, end = map.get_valid_time()
  585. if end:
  586. delta = end - start
  587. else:
  588. delta = None
  589. delta_first = start - first_time
  590. if map.is_time_absolute():
  591. if end:
  592. delta = time_delta_to_relative_time(delta)
  593. delta_first = time_delta_to_relative_time(delta_first)
  594. string = ""
  595. string += "%s%s" % (map.get_id(), separator)
  596. string += "%s%s" % (mapnames, separator)
  597. string += "%s%s" % (start, separator)
  598. string += "%s%s" % (end, separator)
  599. string += "%s%s" % (delta, separator)
  600. string += "%s" % (delta_first)
  601. print string
  602. dbif.close()