12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253 |
- """
- Map layer and space time dataset classes
- (C) 2012-2013 by the GRASS Development Team
- This program is free software under the GNU General Public
- License (>=v2). Read the file COPYING that comes with GRASS
- for details.
- :authors: Soeren Gebbert
- """
- import getpass
- from abstract_map_dataset import *
- from abstract_space_time_dataset import *
- import grass.script.array as garray
- ###############################################################################
- class RasterDataset(AbstractMapDataset):
- """Raster dataset class
- This class provides functions to select, update, insert or delete raster
- map information and valid time stamps into the SQL temporal database.
- Usage:
- .. code-block:: python
- >>> import grass.script as grass
- >>> init()
- >>> grass.use_temp_region()
- >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
- ... t=1.0, b=0.0, res=10.0)
- 0
- >>> grass.run_command("r.mapcalc", overwrite=True, quiet=True,
- ... expression="strds_map_test_case = 1")
- 0
- >>> grass.run_command("r.timestamp", map="strds_map_test_case",
- ... date="15 jan 1999", quiet=True)
- 0
- >>> mapset = get_current_mapset()
- >>> name = "strds_map_test_case"
- >>> identifier = "%s@%s" % (name, mapset)
- >>> rmap = RasterDataset(identifier)
- >>> rmap.map_exists()
- True
- >>> rmap.read_timestamp_from_grass()
- True
- >>> rmap.get_temporal_extent_as_tuple()
- (datetime.datetime(1999, 1, 15, 0, 0), None)
- >>> rmap.load()
- True
- >>> rmap.spatial_extent.print_info()
- +-------------------- Spatial extent ----------------------------------------+
- | North:...................... 80.0
- | South:...................... 0.0
- | East:.. .................... 120.0
- | West:....................... 0.0
- | Top:........................ 0.0
- | Bottom:..................... 0.0
- >>> rmap.absolute_time.print_info()
- +-------------------- Absolute time -----------------------------------------+
- | Start time:................. 1999-01-15 00:00:00
- | End time:................... None
- >>> rmap.metadata.print_info()
- +-------------------- Metadata information ----------------------------------+
- | Datatype:................... CELL
- | Number of columns:.......... 8
- | Number of rows:............. 12
- | Number of cells:............ 96
- | North-South resolution:..... 10.0
- | East-west resolution:....... 10.0
- | Minimum value:.............. 1.0
- | Maximum value:.............. 1.0
- >>> grass.run_command("r.timestamp", map="strds_map_test_case",
- ... date="2 years", quiet=True)
- 0
- >>> rmap.read_timestamp_from_grass()
- True
- >>> rmap.get_temporal_extent_as_tuple()
- (2, None)
- >>> rmap.get_relative_time_unit()
- 'years'
- >>> newmap = rmap.get_new_instance("new@PERMANENT")
- >>> isinstance(newmap, RasterDataset)
- True
- >>> newstrds = rmap.get_new_stds_instance("new@PERMANENT")
- >>> isinstance(newstrds, SpaceTimeRasterDataset)
- True
- >>> rmap.get_type()
- 'raster'
- >>> rmap.set_absolute_time(start_time=datetime(2001,1,1),
- ... end_time=datetime(2012,1,1))
- True
- >>> rmap.get_absolute_time()
- (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
- >>> rmap.get_temporal_extent_as_tuple()
- (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
- >>> rmap.get_name()
- u'strds_map_test_case'
- >>> rmap.get_mapset() == mapset
- True
- >>> rmap.get_temporal_type()
- 'absolute'
- >>> rmap.get_spatial_extent_as_tuple()
- (80.0, 0.0, 120.0, 0.0, 0.0, 0.0)
- >>> rmap.is_time_absolute()
- True
- >>> rmap.is_time_relative()
- False
- >>> grass.run_command("g.remove", flags="f", type="raster", name=name, quiet=True)
- 0
- >>> grass.del_temp_region()
- """
- def __init__(self, ident):
- AbstractMapDataset.__init__(self)
- self.reset(ident)
- def is_stds(self):
- """Return True if this class is a space time dataset
- :return: True if this class is a space time dataset, False otherwise
- """
- return False
- def get_type(self):
- return 'raster'
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return RasterDataset(ident)
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps
- are stored with the type of this class"""
- return SpaceTimeRasterDataset(ident)
- def spatial_overlapping(self, dataset):
- """Return True if the spatial extents 2d overlap"""
- return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
- def spatial_relation(self, dataset):
- """Return the two dimensional spatial relation"""
- return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
- def spatial_intersection(self, dataset):
- """Return the two dimensional intersection as spatial_extent
- object or None in case no intersection was found.
- :param dataset: The abstract dataset to intersect with
- :return: The intersection spatial extent or None
- """
- return self.spatial_extent.intersect_2d(dataset.spatial_extent)
- def spatial_union(self, dataset):
- """Return the two dimensional union as spatial_extent
- object or None in case the extents does not overlap or meet.
- :param dataset :The abstract dataset to create a union with
- :return: The union spatial extent or None
- """
- return self.spatial_extent.union_2d(dataset.spatial_extent)
- def spatial_disjoint_union(self, dataset):
- """Return the two dimensional union as spatial_extent object.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent
- """
- return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
- def get_np_array(self):
- """Return this raster map as memmap numpy style array to access the raster
- values in numpy style without loading the whole map in the RAM.
- In case this raster map does exists in the grass spatial database,
- the map will be exported using r.out.bin to a temporary location
- and assigned to the memmap object that is returned by this function.
- In case the raster map does not exist, an empty temporary
- binary file will be created and assigned to the memap object.
- You need to call the write function to write the memmap
- array back into grass.
- """
- a = garray.array()
- if self.map_exists():
- a.read(self.get_map_id())
- return a
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.base = RasterBase(ident=ident)
- self.absolute_time = RasterAbsoluteTime(ident=ident)
- self.relative_time = RasterRelativeTime(ident=ident)
- self.spatial_extent = RasterSpatialExtent(ident=ident)
- self.metadata = RasterMetadata(ident=ident)
- self.stds_register = RasterSTDSRegister(ident=ident)
- def has_grass_timestamp(self):
- """Check if a grass file bsased time stamp exists for this map.
- :return: True if success, False on error
- """
- return self.ciface.has_raster_timestamp(self.get_name(),
- self.get_mapset())
- def read_timestamp_from_grass(self):
- """Read the timestamp of this map from the map metadata
- in the grass file system based spatial database and
- set the internal time stamp that should be insert/updated
- in the temporal database.
- :return: True if success, False on error
- """
- if not self.has_grass_timestamp():
- return False
- check, dates = self.ciface.read_raster_timestamp(self.get_name(),
- self.get_mapset(),)
- if check < 1:
- self.msgr.error(_("Unable to read timestamp file "
- "for raster map <%s>" % (self.get_map_id())))
- return False
- if len(dates) == 2:
- self.set_absolute_time(dates[0], dates[1])
- else:
- self.set_relative_time(dates[0], dates[1], dates[2])
- return True
- def write_timestamp_to_grass(self):
- """Write the timestamp of this map into the map metadata in
- the grass file system based spatial database.
- Internally the libgis API functions are used for writing
- :return: True if success, False on error
- """
- check = self.ciface.write_raster_timestamp(self.get_name(),
- self.get_mapset(),
- self._convert_timestamp())
- if check == -1:
- self.msgr.error(_("Unable to create timestamp file "
- "for raster map <%s>" % (self.get_map_id())))
- return False
- if check == -2:
- self.msgr.error(_("Invalid datetime in timestamp for raster map "
- "<%s>" % (self.get_map_id())))
- return False
- if check == -3:
- self.msgr.error(_("Internal error"))
- return False
- return True
- def remove_timestamp_from_grass(self):
- """Remove the timestamp from the grass file system based
- spatial database
- Internally the libgis API functions are used for removal
- :return: True if success, False on error
- """
- check = self.ciface.remove_raster_timestamp(self.get_name(),
- self.get_mapset())
- if check == -1:
- self.msgr.error(_("Unable to remove timestamp for raster map <%s>"
- % (self.get_name())))
- return False
- return True
- def map_exists(self):
- """Return True in case the map exists in the grass spatial database
- :return: True if map exists, False otherwise
- """
- return self.ciface.raster_map_exists(self.get_name(),
- self.get_mapset())
- def load(self):
- """Load all info from an existing raster map into the internal structure
- This method checks first if the map exists, in case it exists
- the metadata of the map is put into this object and True is returned
- :return: True is the map exists and the metadata was filled
- successfully and getting the data was successfull,
- False otherwise
- """
- if self.map_exists() is not True:
- return False
- # Fill base information
- self.base.set_creator(str(getpass.getuser()))
- kvp = self.ciface.read_raster_info(self.get_name(),
- self.get_mapset())
- if kvp:
- # Fill spatial extent
- self.set_spatial_extent_from_values(north=kvp["north"],
- south=kvp["south"],
- east=kvp["east"],
- west=kvp["west"])
- # Fill metadata
- self.metadata.set_nsres(kvp["nsres"])
- self.metadata.set_ewres(kvp["ewres"])
- self.metadata.set_datatype(kvp["datatype"])
- self.metadata.set_min(kvp["min"])
- self.metadata.set_max(kvp["max"])
- rows = int(kvp["rows"])
- cols = int(kvp["cols"])
- ncells = cols * rows
- self.metadata.set_cols(cols)
- self.metadata.set_rows(rows)
- self.metadata.set_number_of_cells(ncells)
- return True
- return False
- ###############################################################################
- class Raster3DDataset(AbstractMapDataset):
- """Raster3d dataset class
- This class provides functions to select, update, insert or delete raster3d
- map information and valid time stamps into the SQL temporal database.
- Usage:
- .. code-block:: python
- >>> import grass.script as grass
- >>> init()
- >>> grass.use_temp_region()
- >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
- ... t=100.0, b=0.0, res=10.0, res3=10.0)
- 0
- >>> grass.run_command("r3.mapcalc", overwrite=True, quiet=True,
- ... expression="str3ds_map_test_case = 1")
- 0
- >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case",
- ... date="15 jan 1999", quiet=True)
- 0
- >>> mapset = get_current_mapset()
- >>> name = "str3ds_map_test_case"
- >>> identifier = "%s@%s" % (name, mapset)
- >>> r3map = Raster3DDataset(identifier)
- >>> r3map.map_exists()
- True
- >>> r3map.read_timestamp_from_grass()
- True
- >>> r3map.get_temporal_extent_as_tuple()
- (datetime.datetime(1999, 1, 15, 0, 0), None)
- >>> r3map.load()
- True
- >>> r3map.spatial_extent.print_info()
- +-------------------- Spatial extent ----------------------------------------+
- | North:...................... 80.0
- | South:...................... 0.0
- | East:.. .................... 120.0
- | West:....................... 0.0
- | Top:........................ 100.0
- | Bottom:..................... 0.0
- >>> r3map.absolute_time.print_info()
- +-------------------- Absolute time -----------------------------------------+
- | Start time:................. 1999-01-15 00:00:00
- | End time:................... None
- >>> r3map.metadata.print_info()
- +-------------------- Metadata information ----------------------------------+
- | Datatype:................... DCELL
- | Number of columns:.......... 8
- | Number of rows:............. 12
- | Number of cells:............ 960
- | North-South resolution:..... 10.0
- | East-west resolution:....... 10.0
- | Minimum value:.............. 1.0
- | Maximum value:.............. 1.0
- | Number of depths:........... 10
- | Top-Bottom resolution:...... 10.0
- >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case",
- ... date="2 years", quiet=True)
- 0
- >>> r3map.read_timestamp_from_grass()
- True
- >>> r3map.get_temporal_extent_as_tuple()
- (2, None)
- >>> r3map.get_relative_time_unit()
- 'years'
- >>> newmap = r3map.get_new_instance("new@PERMANENT")
- >>> isinstance(newmap, Raster3DDataset)
- True
- >>> newstr3ds = r3map.get_new_stds_instance("new@PERMANENT")
- >>> isinstance(newstr3ds, SpaceTimeRaster3DDataset)
- True
- >>> r3map.get_type()
- 'raster3d'
- >>> r3map.set_absolute_time(start_time=datetime(2001,1,1),
- ... end_time=datetime(2012,1,1))
- True
- >>> r3map.get_absolute_time()
- (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
- >>> r3map.get_temporal_extent_as_tuple()
- (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
- >>> r3map.get_name()
- u'str3ds_map_test_case'
- >>> r3map.get_mapset() == mapset
- True
- >>> r3map.get_temporal_type()
- 'absolute'
- >>> r3map.get_spatial_extent_as_tuple()
- (80.0, 0.0, 120.0, 0.0, 100.0, 0.0)
- >>> r3map.is_time_absolute()
- True
- >>> r3map.is_time_relative()
- False
- >>> grass.run_command("g.remove", flags="f", type="raster_3d", name=name, quiet=True)
- 0
- >>> grass.del_temp_region()
- """
- def __init__(self, ident):
- AbstractMapDataset.__init__(self)
- self.reset(ident)
- def is_stds(self):
- """Return True if this class is a space time dataset
- :return: True if this class is a space time dataset, False otherwise
- """
- return False
- def get_type(self):
- return "raster3d"
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return Raster3DDataset(ident)
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps
- are stored with the type of this class"""
- return SpaceTimeRaster3DDataset(ident)
- def spatial_overlapping(self, dataset):
- """Return True if the spatial extents overlap"""
- if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
- return self.spatial_extent.overlapping(dataset.spatial_extent)
- else:
- return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
- def spatial_relation(self, dataset):
- """Return the two or three dimensional spatial relation"""
- if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
- return self.spatial_extent.spatial_relation(dataset.spatial_extent)
- else:
- return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
- def spatial_intersection(self, dataset):
- """Return the three or two dimensional intersection as spatial_extent
- object or None in case no intersection was found.
- :param dataset: The abstract dataset to intersect with
- :return: The intersection spatial extent or None
- """
- if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
- return self.spatial_extent.intersect(dataset.spatial_extent)
- else:
- return self.spatial_extent.intersect_2d(dataset.spatial_extent)
- def spatial_union(self, dataset):
- """Return the three or two dimensional union as spatial_extent
- object or None in case the extents does not overlap or meet.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent or None
- """
- if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
- return self.spatial_extent.union(dataset.spatial_extent)
- else:
- return self.spatial_extent.union_2d(dataset.spatial_extent)
- def spatial_disjoint_union(self, dataset):
- """Return the three or two dimensional union as spatial_extent object.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent
- """
- if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
- return self.spatial_extent.disjoint_union(dataset.spatial_extent)
- else:
- return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
- def get_np_array(self):
- """Return this 3D raster map as memmap numpy style array to access the
- 3D raster values in numpy style without loading the whole map in
- the RAM.
- In case this 3D raster map does exists in the grass spatial database,
- the map will be exported using r3.out.bin to a temporary location
- and assigned to the memmap object that is returned by this function.
- In case the 3D raster map does not exist, an empty temporary
- binary file will be created and assigned to the memap object.
- You need to call the write function to write the memmap
- array back into grass.
- """
- a = garray.array3d()
- if self.map_exists():
- a.read(self.get_map_id())
- return a
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.base = Raster3DBase(ident=ident)
- self.absolute_time = Raster3DAbsoluteTime(ident=ident)
- self.relative_time = Raster3DRelativeTime(ident=ident)
- self.spatial_extent = Raster3DSpatialExtent(ident=ident)
- self.metadata = Raster3DMetadata(ident=ident)
- self.stds_register = Raster3DSTDSRegister(ident=ident)
- def has_grass_timestamp(self):
- """Check if a grass file bsased time stamp exists for this map.
- :return: True if success, False on error
- """
- return self.ciface.has_raster3d_timestamp(self.get_name(),
- self.get_mapset())
- def read_timestamp_from_grass(self):
- """Read the timestamp of this map from the map metadata
- in the grass file system based spatial database and
- set the internal time stamp that should be insert/updated
- in the temporal database.
- :return: True if success, False on error
- """
- if not self.has_grass_timestamp():
- return False
- check, dates = self.ciface.read_raster3d_timestamp(self.get_name(),
- self.get_mapset(),)
- if check < 1:
- self.msgr.error(_("Unable to read timestamp file "
- "for 3D raster map <%s>" % (self.get_map_id())))
- return False
- if len(dates) == 2:
- self.set_absolute_time(dates[0], dates[1])
- else:
- self.set_relative_time(dates[0], dates[1], dates[2])
- return True
- def write_timestamp_to_grass(self):
- """Write the timestamp of this map into the map metadata
- in the grass file system based spatial database.
- Internally the libgis API functions are used for writing
- :return: True if success, False on error
- """
- check = self.ciface.write_raster3d_timestamp(self.get_name(),
- self.get_mapset(),
- self._convert_timestamp())
- if check == -1:
- self.msgr.error(_("Unable to create timestamp file "
- "for 3D raster map <%s>" % (self.get_map_id())))
- return False
- if check == -2:
- self.msgr.error(_("Invalid datetime in timestamp for 3D raster "
- "map <%s>" % (self.get_map_id())))
- return False
- if check == -3:
- self.msgr.error(_("Internal error"))
- return False
- return True
- def remove_timestamp_from_grass(self):
- """Remove the timestamp from the grass file system based spatial database
- :return: True if success, False on error
- """
- check = self.ciface.remove_raster3d_timestamp(self.get_name(),
- self.get_mapset())
- if check == -1:
- self.msgr.error(_("Unable to remove timestamp for raster map "
- "<%s>" % (self.get_name())))
- return False
- return True
- def map_exists(self):
- """Return True in case the map exists in the grass spatial database
- :return: True if map exists, False otherwise
- """
- return self.ciface.raster3d_map_exists(self.get_name(),
- self.get_mapset())
- def load(self):
- """Load all info from an existing 3d raster map into the internal structure
- This method checks first if the map exists, in case it exists
- the metadata of the map is put into this object and True is returned
- :return: True is the map exists and the metadata was filled
- successfully and getting the data was successfull,
- False otherwise
- """
- if self.map_exists() is not True:
- return False
- # Fill base information
- self.base.set_creator(str(getpass.getuser()))
- # Fill spatial extent
- kvp = self.ciface.read_raster3d_info(self.get_name(),
- self.get_mapset())
- if kvp:
- self.set_spatial_extent_from_values(north=kvp["north"],
- south=kvp["south"],
- east=kvp["east"],
- west=kvp["west"],
- top=kvp["top"],
- bottom=kvp["bottom"])
- # Fill metadata
- self.metadata.set_nsres(kvp["nsres"])
- self.metadata.set_ewres(kvp["ewres"])
- self.metadata.set_tbres(kvp["tbres"])
- self.metadata.set_datatype(kvp["datatype"])
- self.metadata.set_min(kvp["min"])
- self.metadata.set_max(kvp["max"])
- rows = int(kvp["rows"])
- cols = int(kvp["cols"])
- depths = int(kvp["depths"])
- ncells = cols * rows * depths
- self.metadata.set_cols(cols)
- self.metadata.set_rows(rows)
- self.metadata.set_depths(depths)
- self.metadata.set_number_of_cells(ncells)
- return True
- return False
- ###############################################################################
- class VectorDataset(AbstractMapDataset):
- """Vector dataset class
- This class provides functions to select, update, insert or delete vector
- map information and valid time stamps into the SQL temporal database.
- Usage:
- .. code-block:: python
- >>> import grass.script as grass
- >>> init()
- >>> grass.use_temp_region()
- >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
- ... t=1.0, b=0.0, res=10.0)
- 0
- >>> grass.run_command("v.random", overwrite=True, output="stvds_map_test_case",
- ... n=100, zmin=0, zmax=100, flags="z", column="elevation", quiet=True)
- 0
- >>> grass.run_command("v.timestamp", map="stvds_map_test_case",
- ... date="15 jan 1999", quiet=True)
- 0
- >>> mapset = get_current_mapset()
- >>> name = "stvds_map_test_case"
- >>> identifier = "%s@%s" % (name, mapset)
- >>> vmap = VectorDataset(identifier)
- >>> vmap.map_exists()
- True
- >>> vmap.read_timestamp_from_grass()
- True
- >>> vmap.get_temporal_extent_as_tuple()
- (datetime.datetime(1999, 1, 15, 0, 0), None)
- >>> vmap.load()
- True
- >>> vmap.absolute_time.print_info()
- +-------------------- Absolute time -----------------------------------------+
- | Start time:................. 1999-01-15 00:00:00
- | End time:................... None
- >>> vmap.metadata.print_info()
- +-------------------- Metadata information ----------------------------------+
- | Is map 3d .................. True
- | Number of points ........... 100
- | Number of lines ............ 0
- | Number of boundaries ....... 0
- | Number of centroids ........ 0
- | Number of faces ............ 0
- | Number of kernels .......... 0
- | Number of primitives ....... 100
- | Number of nodes ............ 0
- | Number of areas ............ 0
- | Number of islands .......... 0
- | Number of holes ............ 0
- | Number of volumes .......... 0
- >>> grass.run_command("v.timestamp", map="stvds_map_test_case",
- ... date="2 years", quiet=True)
- 0
- >>> vmap.read_timestamp_from_grass()
- True
- >>> vmap.get_temporal_extent_as_tuple()
- (2, None)
- >>> vmap.get_relative_time_unit()
- 'years'
- >>> newmap = vmap.get_new_instance("new@PERMANENT")
- >>> isinstance(newmap, VectorDataset)
- True
- >>> newstvds = vmap.get_new_stds_instance("new@PERMANENT")
- >>> isinstance(newstvds, SpaceTimeVectorDataset)
- True
- >>> vmap.get_type()
- 'vector'
- >>> vmap.set_absolute_time(start_time=datetime(2001,1,1),
- ... end_time=datetime(2012,1,1))
- True
- >>> vmap.get_absolute_time()
- (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
- >>> vmap.get_temporal_extent_as_tuple()
- (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
- >>> vmap.get_name()
- u'stvds_map_test_case'
- >>> vmap.get_mapset() == mapset
- True
- >>> vmap.get_temporal_type()
- 'absolute'
- >>> vmap.is_time_absolute()
- True
- >>> vmap.is_time_relative()
- False
- >>> grass.run_command("g.remove", flags="f", type="vector", name=name, quiet=True)
- 0
- >>> grass.del_temp_region()
- """
- def __init__(self, ident):
- AbstractMapDataset.__init__(self)
- self.reset(ident)
- def is_stds(self):
- """Return True if this class is a space time dataset
- :return: True if this class is a space time dataset, False otherwise
- """
- return False
- def get_type(self):
- return "vector"
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return VectorDataset(ident)
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps
- are stored with the type of this class"""
- return SpaceTimeVectorDataset(ident)
- def get_layer(self):
- """Return the layer"""
- return self.base.get_layer()
- def spatial_overlapping(self, dataset):
- """Return True if the spatial extents 2d overlap"""
- return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
- def spatial_relation(self, dataset):
- """Return the two dimensional spatial relation"""
- return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
- def spatial_intersection(self, dataset):
- """Return the two dimensional intersection as spatial_extent
- object or None in case no intersection was found.
- :param dataset: The abstract dataset to intersect with
- :return: The intersection spatial extent or None
- """
- return self.spatial_extent.intersect_2d(dataset.spatial_extent)
- def spatial_union(self, dataset):
- """Return the two dimensional union as spatial_extent
- object or None in case the extents does not overlap or meet.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent or None
- """
- return self.spatial_extent.union_2d(dataset.spatial_extent)
- def spatial_disjoint_union(self, dataset):
- """Return the two dimensional union as spatial_extent object.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent
- """
- return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.base = VectorBase(ident=ident)
- self.absolute_time = VectorAbsoluteTime(ident=ident)
- self.relative_time = VectorRelativeTime(ident=ident)
- self.spatial_extent = VectorSpatialExtent(ident=ident)
- self.metadata = VectorMetadata(ident=ident)
- self.stds_register = VectorSTDSRegister(ident=ident)
- def has_grass_timestamp(self):
- """Check if a grass file bsased time stamp exists for this map.
- """
- return self.ciface.has_vector_timestamp(self.get_name(),
- self.get_mapset(),
- self.get_layer())
- def read_timestamp_from_grass(self):
- """Read the timestamp of this map from the map metadata
- in the grass file system based spatial database and
- set the internal time stamp that should be insert/updated
- in the temporal database.
- """
- if not self.has_grass_timestamp():
- return False
- check, dates = self.ciface.read_vector_timestamp(self.get_name(),
- self.get_mapset(),)
- if check < 1:
- self.msgr.error(_("Unable to read timestamp file "
- "for vector map <%s>" % (self.get_map_id())))
- return False
- if len(dates) == 2:
- self.set_absolute_time(dates[0], dates[1])
- else:
- self.set_relative_time(dates[0], dates[1], dates[2])
- return True
- def write_timestamp_to_grass(self):
- """Write the timestamp of this map into the map metadata in
- the grass file system based spatial database.
- Internally the libgis API functions are used for writing
- """
- check = self.ciface.write_vector_timestamp(self.get_name(),
- self.get_mapset(),
- self._convert_timestamp(),
- self.get_layer())
- if check == -1:
- self.msgr.error(_("Unable to create timestamp file "
- "for vector map <%s>" % (self.get_map_id())))
- return False
- if check == -2:
- self.msgr.error(_("Invalid datetime in timestamp for vector "
- "map <%s>" % (self.get_map_id())))
- return False
- return True
- def remove_timestamp_from_grass(self):
- """Remove the timestamp from the grass file system based spatial
- database
- Internally the libgis API functions are used for removal
- """
- check = self.ciface.remove_vector_timestamp(self.get_name(),
- self.get_mapset())
- if check == -1:
- self.msgr.error(_("Unable to remove timestamp for vector "
- "map <%s>" % (self.get_name())))
- return False
- return True
- def map_exists(self):
- """Return True in case the map exists in the grass spatial database
- :return: True if map exists, False otherwise
- """
- return self.ciface.vector_map_exists(self.get_name(),
- self.get_mapset())
- def load(self):
- """Load all info from an existing vector map into the internal structure
- This method checks first if the map exists, in case it exists
- the metadata of the map is put into this object and True is returned
- :return: True is the map exists and the metadata was filled
- successfully and getting the data was successfull,
- False otherwise
- """
- if self.map_exists() is not True:
- return False
- # Fill base information
- self.base.set_creator(str(getpass.getuser()))
- # Get the data from an existing vector map
- kvp = self.ciface.read_vector_info(self.get_name(),
- self.get_mapset())
- if kvp:
- # Fill spatial extent
- self.set_spatial_extent_from_values(north=kvp["north"],
- south=kvp["south"],
- east=kvp["east"],
- west=kvp["west"],
- top=kvp["top"],
- bottom=kvp["bottom"])
- # Fill metadata
- self.metadata.set_3d_info(kvp["map3d"])
- self.metadata.set_number_of_points(kvp["points"])
- self.metadata.set_number_of_lines(kvp["lines"])
- self.metadata.set_number_of_boundaries(kvp["boundaries"])
- self.metadata.set_number_of_centroids(kvp["centroids"])
- self.metadata.set_number_of_faces(kvp["faces"])
- self.metadata.set_number_of_kernels(kvp["kernels"])
- self.metadata.set_number_of_primitives(kvp["primitives"])
- self.metadata.set_number_of_nodes(kvp["nodes"])
- self.metadata.set_number_of_areas(kvp["areas"])
- self.metadata.set_number_of_islands(kvp["islands"])
- self.metadata.set_number_of_holes(kvp["holes"])
- self.metadata.set_number_of_volumes(kvp["volumes"])
- return True
- return False
- ###############################################################################
- class SpaceTimeRasterDataset(AbstractSpaceTimeDataset):
- """Space time raster dataset class
- """
- def __init__(self, ident):
- AbstractSpaceTimeDataset.__init__(self, ident)
- def is_stds(self):
- """Return True if this class is a space time dataset
- :return: True if this class is a space time dataset, False otherwise
- """
- return True
- def get_type(self):
- return "strds"
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return SpaceTimeRasterDataset(ident)
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated "
- "with the type of this class"""
- return RasterDataset(ident)
- def get_map_register(self):
- """Return the name of the map register table"""
- return self.metadata.get_raster_register()
- def set_map_register(self, name):
- """Set the name of the map register table"""
- self.metadata.set_raster_register(name)
- def spatial_overlapping(self, dataset):
- """Return True if the spatial extents 2d overlap"""
- return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
- def spatial_relation(self, dataset):
- """Return the two dimensional spatial relation"""
- return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
- def spatial_intersection(self, dataset):
- """Return the two dimensional intersection as spatial_extent
- object or None in case no intersection was found.
- :param dataset: The abstract dataset to intersect with
- :return: The intersection spatial extent or None
- """
- return self.spatial_extent.intersect_2d(dataset.spatial_extent)
- def spatial_union(self, dataset):
- """Return the two dimensional union as spatial_extent
- object or None in case the extents does not overlap or meet.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent or None
- """
- return self.spatial_extent.union_2d(dataset.spatial_extent)
- def spatial_disjoint_union(self, dataset):
- """Return the two dimensional union as spatial_extent object.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent
- """
- return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.base = STRDSBase(ident=ident)
- self.base.set_creator(str(getpass.getuser()))
- self.absolute_time = STRDSAbsoluteTime(ident=ident)
- self.relative_time = STRDSRelativeTime(ident=ident)
- self.spatial_extent = STRDSSpatialExtent(ident=ident)
- self.metadata = STRDSMetadata(ident=ident)
- ###############################################################################
- class SpaceTimeRaster3DDataset(AbstractSpaceTimeDataset):
- """Space time raster3d dataset class
- """
- def __init__(self, ident):
- AbstractSpaceTimeDataset.__init__(self, ident)
- def is_stds(self):
- """Return True if this class is a space time dataset
- :return: True if this class is a space time dataset, False otherwise
- """
- return True
- def get_type(self):
- return "str3ds"
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return SpaceTimeRaster3DDataset(ident)
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated
- with the type of this class"""
- return Raster3DDataset(ident)
- def get_map_register(self):
- """Return the name of the map register table"""
- return self.metadata.get_raster3d_register()
- def set_map_register(self, name):
- """Set the name of the map register table"""
- self.metadata.set_raster3d_register(name)
- def spatial_overlapping(self, dataset):
- """Return True if the spatial extents overlap"""
- if self.get_type() == dataset.get_type() or dataset.get_type() == "str3ds":
- return self.spatial_extent.overlapping(dataset.spatial_extent)
- else:
- return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
- def spatial_relation(self, dataset):
- """Return the two or three dimensional spatial relation"""
- if self.get_type() == dataset.get_type() or \
- dataset.get_type() == "str3ds":
- return self.spatial_extent.spatial_relation(dataset.spatial_extent)
- else:
- return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
- def spatial_intersection(self, dataset):
- """Return the three or two dimensional intersection as spatial_extent
- object or None in case no intersection was found.
- :param dataset: The abstract dataset to intersect with
- :return: The intersection spatial extent or None
- """
- if self.get_type() == dataset.get_type() or dataset.get_type() == "raster3d":
- return self.spatial_extent.intersect(dataset.spatial_extent)
- else:
- return self.spatial_extent.intersect_2d(dataset.spatial_extent)
- def spatial_union(self, dataset):
- """Return the three or two dimensional union as spatial_extent
- object or None in case the extents does not overlap or meet.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent or None
- """
- if self.get_type() == dataset.get_type() or dataset.get_type() == "raster3d":
- return self.spatial_extent.union(dataset.spatial_extent)
- else:
- return self.spatial_extent.union_2d(dataset.spatial_extent)
- def spatial_disjoint_union(self, dataset):
- """Return the three or two dimensional union as spatial_extent object.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent
- """
- if self.get_type() == dataset.get_type() or dataset.get_type() == "raster3d":
- return self.spatial_extent.disjoint_union(dataset.spatial_extent)
- else:
- return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.base = STR3DSBase(ident=ident)
- self.base.set_creator(str(getpass.getuser()))
- self.absolute_time = STR3DSAbsoluteTime(ident=ident)
- self.relative_time = STR3DSRelativeTime(ident=ident)
- self.spatial_extent = STR3DSSpatialExtent(ident=ident)
- self.metadata = STR3DSMetadata(ident=ident)
- ###############################################################################
- class SpaceTimeVectorDataset(AbstractSpaceTimeDataset):
- """Space time vector dataset class
- """
- def __init__(self, ident):
- AbstractSpaceTimeDataset.__init__(self, ident)
- def is_stds(self):
- """Return True if this class is a space time dataset
- :return: True if this class is a space time dataset, False otherwise
- """
- return True
- def get_type(self):
- return "stvds"
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return SpaceTimeVectorDataset(ident)
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated
- with the type of this class"""
- return VectorDataset(ident)
- def get_map_register(self):
- """Return the name of the map register table"""
- return self.metadata.get_vector_register()
- def set_map_register(self, name):
- """Set the name of the map register table"""
- self.metadata.set_vector_register(name)
- def spatial_overlapping(self, dataset):
- """Return True if the spatial extents 2d overlap"""
- return self.spatial_extent.overlapping_2d(dataset.spatial_extent)
- def spatial_relation(self, dataset):
- """Return the two dimensional spatial relation"""
- return self.spatial_extent.spatial_relation_2d(dataset.spatial_extent)
- def spatial_intersection(self, dataset):
- """Return the two dimensional intersection as spatial_extent
- object or None in case no intersection was found.
- :param dataset: The abstract dataset to intersect with
- :return: The intersection spatial extent or None
- """
- return self.spatial_extent.intersect_2d(dataset.spatial_extent)
- def spatial_union(self, dataset):
- """Return the two dimensional union as spatial_extent
- object or None in case the extents does not overlap or meet.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent or None
- """
- return self.spatial_extent.union_2d(dataset.spatial_extent)
- def spatial_disjoint_union(self, dataset):
- """Return the two dimensional union as spatial_extent object.
- :param dataset: The abstract dataset to create a union with
- :return: The union spatial extent
- """
- return self.spatial_extent.disjoint_union_2d(dataset.spatial_extent)
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.base = STVDSBase(ident=ident)
- self.base.set_creator(str(getpass.getuser()))
- self.absolute_time = STVDSAbsoluteTime(ident=ident)
- self.relative_time = STVDSRelativeTime(ident=ident)
- self.spatial_extent = STVDSSpatialExtent(ident=ident)
- self.metadata = STVDSMetadata(ident=ident)
- ###############################################################################
- if __name__ == "__main__":
- import doctest
- doctest.testmod()
|