[GRASS-SVN] r65507 - in grass-addons/grass7/gui/wxpython/wx.metadata: config g.gui.metadata mdlib profiles

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jun 21 11:50:14 PDT 2015


Author: krejcmat
Date: 2015-06-21 11:50:14 -0700 (Sun, 21 Jun 2015)
New Revision: 65507

Added:
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/temporalProfile.xml
Modified:
   grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py
   grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/g.gui.metadata.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py
   grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdutil.py
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml
   grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml
Log:
temporal metadata support- alpha

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/config/init_md	2015-06-21 18:50:14 UTC (rev 65507)
@@ -1,4 +1,4 @@
-self.md.identification = MD_DataIdentification()
+self.md.identification = mdutil.MD_DataIdentification_MOD()
 self.md.dataquality = DQ_DataQuality()
 self.md.distribution = MD_Distribution()
 self.md.identification.extent = EX_Extent()

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/editor.py	2015-06-21 18:50:14 UTC (rev 65507)
@@ -64,7 +64,7 @@
         @return: initialized md object by input xml
         '''
         if path is None:
-            self.md = MD_Metadata(md=None)
+            self.md = mdutil.MD_MetadataMOD(md=None)
             return self.md
         else:
             io = open(path, 'r')
@@ -79,7 +79,7 @@
             try:
                 tree = etree.parse(path)
                 root = tree.getroot()
-                self.md = MD_Metadata(root)
+                self.md = mdutil.MD_MetadataMOD(root)
 
                 return self.md
 
@@ -441,12 +441,24 @@
 
     def fillComboDB(self,label):
         if label == 'language':
-            lang=["Afrikaans","Albanian","Arabic","Armenian","Basque","Bengali","Bulgarian","Catalan","Cambodian","Chinese","Croatian","Czech","Danish","Dutch","English","Estonian","Fiji","Finnish","French","Georgian","German","Greek","Gujarati","Hebrew","Hindi","Hungarian","Icelandic","Indonesian","Irish","Italian","Japanese","Javanese","Korean","Latin","Latvian","Lithuanian","Macedonian","Malay","Malayalam","Maltese","Maori","Marathi","Mongolian","Nepali","Norwegian","Persian","Polish","Portuguese","Punjabi","Quechua","Romanian","Russian","Samoan","Serbian","Slovak","Slovenian","Spanish","Swahili","Swedish","Tamil","Tatar","Telugu","Thai","Tibetan","Tonga","Turkish","Ukrainian","Urdu","Uzbek","Vietnamese","Welsh","Xhosa"]
+            lang=["Afrikaans","Albanian","Arabic","Armenian","Basque","Bengali",
+                  "Bulgarian","Catalan","Cambodian","Chinese","Croatian","Czech",
+                  "Danish","Dutch","English","Estonian","Fiji","Finnish","French",
+                  "Georgian","German","Greek","Gujarati","Hebrew","Hindi","Hungarian",
+                  "Icelandic","Indonesian","Irish","Italian","Japanese","Javanese","Korean",
+                  "Latin","Latvian","Lithuanian","Macedonian","Malay","Malayalam","Maltese",
+                  "Maori","Marathi","Mongolian","Nepali","Norwegian","Persian","Polish","Portuguese",
+                  "Punjabi","Quechua","Romanian","Russian","Samoan","Serbian","Slovak","Slovenian",
+                  "Spanish","Swahili","Swedish","Tamil","Tatar","Telugu","Thai","Tibetan","Tonga",
+                  "Turkish","Ukrainian","Urdu","Uzbek","Vietnamese","Welsh","Xhosa"]
             self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
             for lng in lang:
                 self.valueCtrl.Append(lng)
         if label == 'topicCategory':
-            lang= ['farming','biota','boundaries','climatologyMeteorologyAtmosphere','economy','elevation','enviroment','geoscientificInformation','health','imageryBaseMapsEarthCover','intelligenceMilitary','inlandWaters','location','planningCadastre','society','structure','transportation','utilitiesCommunication']
+            lang= ['farming','biota','boundaries','climatologyMeteorologyAtmosphere','economy',
+                   'elevation','enviroment','geoscientificInformation','health','imageryBaseMapsEarthCover',
+                   'intelligenceMilitary','inlandWaters','location','planningCadastre','society','structure',
+                   'transportation','utilitiesCommunication']
             self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
             for lng in lang:
                 self.valueCtrl.Append(lng)
@@ -461,7 +473,8 @@
             for lng in lang:
                 self.valueCtrl.Append(lng)
         if label == 'role':
-            lang=['Author','Custodian','Distributor','Originator','Owner','Point of contact','Principal Investigation','Processor','Publisher','Resource provider','User']
+            lang=['Author','Custodian','Distributor','Originator','Owner','Point of contact','Principal Investigation',
+                  'Processor','Publisher','Resource provider','User']
             self.valueCtrl=wx.ComboBox(self.parent, id=wx.ID_ANY,)
             for lng in lang:
                 self.valueCtrl.Append(lng)
@@ -1158,6 +1171,7 @@
             elif 'for' not in str(tagStringLst[self.c]).split() and 'if' not in str(tagStringLst[self.c]).split():
                 it = MdItem(parent=self.nbPage, item=mdDescrObj[self.c], chckBox=self.templateEditor)
                 value = 'self.' + str(self.mdOWSTagStrList[self.c]).replace('\n', '')
+                print value
                 value = eval(value)
                 if value is None:
                     value = ''
@@ -1283,6 +1297,7 @@
         templateOut.write(finalTemplate)
         templateOut.close()
 
+
         return owsTagList
     #----------------------------------------- FILL OWSLib BY EDITED METADATA IN GUI
 
@@ -1294,19 +1309,19 @@
         exec stri
 
     def getKeywordsFromRepositoryWidget(self,md):
+        if  self.keywords is not None:
+            for item in self.keywords.GetKws():
+                titles=item.getKyewordObj()
 
-        for item in self.keywords.GetKws():
-            titles=item.getKyewordObj()
-
-            kw = {}
-            kw['keywords'] = []
-            kw['keywords'].append(titles['keywords'])
-            kw['type'] = None
-            kw['thesaurus'] = {}
-            kw['thesaurus']['title']=titles['title']
-            kw['thesaurus']['date']=titles['date']
-            kw['thesaurus']['datetype']=titles['type']
-            md.identification.keywords.append(kw)
+                kw = {}
+                kw['keywords'] = []
+                kw['keywords'].append(titles['keywords'])
+                kw['type'] = None
+                kw['thesaurus'] = {}
+                kw['thesaurus']['title']=titles['title']
+                kw['thesaurus']['date']=titles['date']
+                kw['thesaurus']['datetype']=titles['type']
+                md.identification.keywords.append(kw)
         return md
 
     def saveMDfromGUI(self, evt=None):

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/g.gui.metadata.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/g.gui.metadata.py	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/g.gui.metadata/g.gui.metadata.py	2015-06-21 18:50:14 UTC (rev 65507)
@@ -53,7 +53,8 @@
 from editor import MdMainEditor
 from lmgr import datacatalog
 from core.gcmd import RunCommand, GError, GMessage
-
+import grass.temporal as tgis
+from core.utils import GetListOfLocations, ListOfMapsets
 #===============================================================================
 # MAIN FRAME
 #===============================================================================
@@ -274,8 +275,10 @@
             if self.profileChoice == 'INSPIRE':
                 self.mdCreator.createGrassInspireISO()
             elif self.profileChoice == 'GRASS BASIC':
+                self.mdCreator.createGrassBasicISO()
+            elif self.profileChoice == 'TEMPORAL':
+                self.mdCreator.createTemporalISO()
 
-                self.mdCreator.createGrassBasicISO()
             self.jinjaPath = self.mdCreator.profilePathAbs
             self.xmlPath = self.mdCreator.saveXML(self.mdDestination, self.nameTMPteplate, self)
             self.onInitEditor()
@@ -480,22 +483,127 @@
         super(MdDataCatalog, self).__init__(parent=parent,
                                             style=wx.TR_MULTIPLE | wx.TR_HIDE_ROOT | wx.TR_HAS_BUTTONS |
                                             wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_COLUMN_LINES)
+        tgis.init(True)
+        self.dbif = tgis.SQLDatabaseInterfaceConnection()
+        self.dbif.connect()
         self.InitTreeItems()
         self.map = None
         self.mapType = None
 
+    def __del__(self):
+        """Close the database interface and stop the messenger and C-interface
+           subprocesses.
+        """
+        if self.dbif.connected is True:
+            self.dbif.close()
+        tgis.stop_subprocesses()
+
+
     def InitTreeItems(self):
+
         """Add locations and layers to the tree"""
+        self.rootTmp=self.root
+        var=self.AppendItem(self.root,'Grass maps')
+        self.root=var
+
         gisenv = grass.gisenv()
         location = gisenv['LOCATION_NAME']
+        #GMessage(location)
         self.mapset = gisenv['MAPSET']
-        #TODO remove auto add permanent to catalogue
+        #GMessage(self.mapset)
+        self.initGrassTree(location=location, mapset=self.mapset)
+        self.initTemporalTree(location=location, mapset=self.mapset)
 
-        self._initTreeItems(locations=[location], mapsets=[self.mapset])
-        self.ExpandAll()
+
+    def initGrassTree(self,location , mapset):
+        """Add locations, mapsets and layers to the tree."""
+
+        self.ChangeEnvironment(location)
+
+        varloc = self.AppendItem(self.root, location)
+        self.AppendItem(varloc, mapset)
+
+        # get list of all maps in location
+        maplist = RunCommand('g.list', flags='mt', type='raster,vector', mapset=mapset,
+                             quiet=True, read=True)
+        maplist = maplist.splitlines()
+
+        for ml in maplist:
+            # parse
+            parts1 = ml.split('/')
+            parts2 = parts1[1].split('@')
+            mapset = parts2[1]
+            mlayer = parts2[0]
+            ltype = parts1[0]
+
+            # add mapset
+            if self.itemExists(mapset, varloc) == False:
+                varmapset = self.AppendItem(varloc, mapset)
+            else:
+                varmapset = self.getItemByName(mapset, varloc)
+
+            # add type node if not exists
+            if self.itemExists(ltype, varmapset) == False:
+                vartype = self.AppendItem(varmapset, ltype)
+
+            self.AppendItem(vartype, mlayer)
+
+    def initTemporalTree(self,location , mapset ):
+        varloc = self.AppendItem(self.rootTmp, 'Temporal maps')
+        tDict = tgis.tlist_grouped('stds', group_type=True, dbif=self.dbif)
+        # nested list with '(map, mapset, etype)' items
+        allDatasets = [[[(map, mapset, etype) for map in maps]
+                        for etype, maps in etypesDict.iteritems()]
+                       for mapset, etypesDict in tDict.iteritems()]
+        if allDatasets:
+            allDatasets = reduce(lambda x, y: x + y, reduce(lambda x, y: x + y,
+                                                            allDatasets))
+            mapsets = tgis.get_tgis_c_library_interface().available_mapsets()
+            allDatasets = [i for i in sorted(allDatasets,
+                                             key=lambda l: mapsets.index(l[1]))]
+        #print allDatasets
+        #if not location:
+        #    location = GetListOfLocations(self.gisdbase)
+        #if not self.mapset:
+        #    mapsets = ['*']
+
+        first = True
+        #for loc in location:
+            #location = loc
+            #self.ChangeEnvironment(location)
+        loc=location
+        varloc = self.AppendItem(varloc, loc)
+        #self.ChangeEnvironment(loc)
+        # add all mapsets
+        self.AppendItem(varloc, mapset)
+
+        # get list of all maps in location
+        for ml in allDatasets:
+
+            # add mapset
+            if self.itemExists(ml[1], varloc) == False:
+                varmapset = self.getItemByName(ml[1], varloc)
+            else:
+                varmapset = self.getItemByName(ml[1], varloc)
+            # add type node if not exists
+            if self.itemExists(ml[2], varmapset) == False:
+                vartype = self.AppendItem(varmapset, ml[2])
+
+            self.AppendItem(vartype, ml[0])
+
+
+        #self.ExpandAll()
+
         self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onChanged)
         self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onChanged)
+        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRClickAllChildren)
 
+    def OnRClickAllChildren(self, evt):
+        if not self.IsExpanded(evt.Item):
+            self.ExpandAllChildren(evt.Item)
+        else:
+            self.CollapseAllChildren(evt.Item)
+
     def onChanged(self, evt=None):
         '''
         @var ListOfMapTypeDict: list of dic with maps and map-type values
@@ -523,12 +631,15 @@
 
         else:
             self.Unselect()
-            GMessage('Please select map')
 
+            #pub.sendMessage('bttEdit.disable')
+            #pub.sendMessage('bttCreateTemplate.disable')
+            #GMessage('Please select map')
+
         if len(maps) == 0:
             pub.sendMessage('bttEdit.disable')
             pub.sendMessage('bttCreateTemplate.disable')
-
+            return
         status = ''
         for map in maps:
             status += map + '  '
@@ -756,6 +867,10 @@
             result = mdutil.grassProfileValidator(md)
             str1 = 'GRASS BASIC PROFILE VALIDATOR\n'
 
+        if profile == 'TEMPORAL':
+            result = mdutil.isnpireValidator(md)
+            str1 = 'INSPIRE VALIDATOR\n'
+
         str1 += 'Status of validation: ' + result["status"] + '\n'
         str1 += 'Numbers of errors: ' + result["num_of_errors"] + '\n'
 
@@ -785,7 +900,7 @@
         self.rbGrass = wx.RadioButton(self, id=wx.ID_ANY, label='Metadata map editor', style=wx.RB_GROUP)
         self.rbExternal = wx.RadioButton(self, id=wx.ID_ANY, label='Metadata external editor')
 
-        self.comboBoxProfile = wx.ComboBox(self, choices=['INSPIRE', 'GRASS BASIC', 'Load Custom'])
+        self.comboBoxProfile = wx.ComboBox(self, choices=['INSPIRE', 'GRASS BASIC', 'TEMPORAL','Load Custom'])
         pub.subscribe(self.onComboboxDisable, "comboBoxProfile.disable")
         pub.subscribe(self.onComboboxEnable, "comboBoxProfile.enable")
         pub.subscribe(self.onSetProfile, "SET_PROFILE.update")
@@ -893,8 +1008,6 @@
         self.toolbar.AddControl(control=self.bttLoadXml)
         self.bttLoadXml.Disable()
         self.toolbar.AddSeparator()
-
-
     #-------------------------------------------------------------------------- export xml
         self.bttsave = BitmapBtnTxt(self.toolbar, -1, bitmapSave, "xml")
         self.bttsave.Disable()
@@ -921,6 +1034,7 @@
         self._layout()
 
         self.bttLoad.Bind(wx.EVT_BUTTON, self.OnLoadTemplate)
+
         pub.subscribe(self.onBttSaveEnable, "bttLoad.enable")
         pub.subscribe(self.onBttSaveDisable, "bttLoad.disable")
 

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdgrass.py	2015-06-21 18:50:14 UTC (rev 65507)
@@ -44,7 +44,7 @@
     def __init__(self, map, type):
         self.map = map
         self.type = type
-        self.isMapExist()  # function to check if map exist
+          # function to check if map exist
         self.md_grass = {}
         self.md_abstract = ''
         self.md_vinfo_h = ''  # v.info flag=h" - parse
@@ -54,17 +54,20 @@
         self.profileName='GRASS BASIC'
         self.dirpath = os.path.join(os.getenv('GRASS_ADDON_BASE'), 'etc')
         # metadata object from OWSLIB ( for define md values)
-        self.md = MD_Metadata(md=None)
+        self.md = mdutil.MD_MetadataMOD(md=None)
         self.profilePath = None  # path to file with xml templates
 
-
         if self.type == "raster":
+            self.isMapExist()
             self.parseRast()
         elif self.type == "vector":
+            self.isMapExist()
             self.parseVect()
         elif self.type == "r3??":
             # TODO
             self.parseRast3D()
+        elif self.type=='strds' or self.type=='stvds':
+            self.parseTemporal()
 
     def isMapExist(self):
         '''Check if the map is in current mapset'''
@@ -72,6 +75,30 @@
         if not self.mapset:
             grass.fatal(_("Map <%s> does not exist in current mapset") % self.map)
 
+    def parseTemporal(self):
+        tinfo = Module('t.info',
+                        input=self.map,
+                        flags='g',
+                        type=self.type,
+                        stdout_=PIPE)
+
+        self.md_grass = parse_key_val(tinfo.outputs.stdout)
+        tinfoHist = Module('t.info',
+                            input=self.map,
+                            quiet=True,
+                            flags='h',
+                            type=self.type,
+                            stdout_=PIPE)
+        md_h_grass = tinfoHist.outputs.stdout
+        buf = StringIO.StringIO(md_h_grass)
+        line = buf.readline().splitlines()
+
+        while line:
+            if str(line[0]).strip() != "":
+                self.md_vinfo_h += line[0] + '\n'
+            line = buf.readline().splitlines()
+        buf.close()
+
     def parseRast3D(self):
         pass
 
@@ -149,6 +176,83 @@
             self.md_grass['min'] + '  max: ' + self.md_grass['max']
         self.md_abstract.translate(None, """&<>"'""")
 
+    def createTemporalISO(self, profile=None):
+        '''Create GRASS Temporal profile based on ISO
+        - unknown values are filling by n = '$NULL'
+        '''
+
+        n = '$NULL'
+        # jinja templates
+        if profile is None:
+            self.profilePath = os.path.join('profiles', 'temporalProfile.xml')
+        else:
+            self.profilePath = profile
+        self.schema_type = '_temporal.xml'
+        self.profileName='TEMPORAL'
+
+        # OWSLib md object
+        self.md.identification = mdutil.MD_DataIdentification_MOD()
+        self.md.dataquality = DQ_DataQuality()
+        self.md.distribution = MD_Distribution()
+        self.md.identification.extent = EX_Extent()
+        self.md.identification.extent.boundingBox = EX_GeographicBoundingBox()
+
+        # Metadata on metadata
+        val = CI_ResponsibleParty()
+        val.organization = mdutil.replaceXMLReservedChar(self.md_grass['creator'])
+        val.role = 'creator'
+        self.md.contact.append(val)
+
+        # Identification/Resource Title
+        self.md.identification.title = mdutil.replaceXMLReservedChar(self.md_grass['name'])
+        self.md.datestamp = mdutil.replaceXMLReservedChar(date.today().isoformat())
+
+        # Identification/Resource Type
+        self.md.identification.identtype = 'dataset'
+
+        # Identification/Unique Resource Identifier
+        self.md.identifier = mdutil.replaceXMLReservedChar(self.md_grass['id'])
+        self.md.identification.uricode.append(mdutil.replaceXMLReservedChar(self.md_grass['id']))
+        self.md.identification.uricodespace.append(n)
+
+        self.md.identification.resourcelanguage.append('English')
+        self.md.languagecode ='English'
+
+        val = CI_Date()
+        val.date = mdutil.replaceXMLReservedChar(self.md_grass['creation_time'])
+        val.type = 'Date of creation'
+        self.md.identification.date.append(val)
+        val = CI_Date()
+        val.date = mdutil.replaceXMLReservedChar(self.md_grass['modification_time'])
+        val.type = 'Date of last revision'
+        self.md.identification.date.append(val)
+        # Geographic/BB
+        self.md.identification.extent.boundingBox.minx = mdutil.replaceXMLReservedChar(self.md_grass['north'])
+        self.md.identification.extent.boundingBox.maxx = mdutil.replaceXMLReservedChar(self.md_grass['south'])
+        self.md.identification.extent.boundingBox.miny = mdutil.replaceXMLReservedChar(self.md_grass['east'])
+        self.md.identification.extent.boundingBox.maxy = mdutil.replaceXMLReservedChar(self.md_grass['west'])
+
+        # Temporal/Temporal Extent
+        self.md.identification.temporalextent_start = mdutil.replaceXMLReservedChar(self.md_grass['start_time'])
+        self.md.identification.temporalextent_end = mdutil.replaceXMLReservedChar(self.md_grass['end_time'])
+
+        self.md.identification.temporalType = mdutil.replaceXMLReservedChar(self.md_grass['temporal_type'])
+
+        try:
+            gran=self.md_grass['granularity'].split(' ')
+            self.md.identification.timeUnit = mdutil.replaceXMLReservedChar(gran[1])
+            self.md.identification.radixT = mdutil.replaceXMLReservedChar(gran[0])
+            self.md.identification.factor = mdutil.replaceXMLReservedChar('1')
+        except:
+            self.md.identification.timeUnit = mdutil.replaceXMLReservedChar(None)
+            self.md.identification.radixT = mdutil.replaceXMLReservedChar(None)
+            self.md.identification.factor = mdutil.replaceXMLReservedChar(None)
+
+
+
+        self.md.dataquality.lineage= "TODO"
+        self.profilePathAbs = os.path.join(self.dirpath, self.profilePath)
+
     def createGrassBasicISO(self, profile=None):
         '''Create basic/essential profile based on ISO
         - unknown values are filling by n = '$NULL'
@@ -166,7 +270,7 @@
             self.profilePath = profile
 
         # OWSLib md object
-        self.md.identification = MD_DataIdentification()
+        self.md.identification = mdutil.MD_DataIdentification_MOD()
         self.md.dataquality = DQ_DataQuality()
         self.md.distribution = MD_Distribution()
         self.md.identification.extent = EX_Extent()
@@ -320,7 +424,7 @@
 
     def readXML(self, xml_file):
         '''create instance of metadata(owslib) from xml file'''
-        self.md = MD_Metadata(etree.parse(xml_file))
+        self.md = util.MD_MetadataMOD(etree.parse(xml_file))
 
 
     def getMapInfo(self):

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdutil.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdutil.py	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/mdlib/mdutil.py	2015-06-21 18:50:14 UTC (rev 65507)
@@ -20,6 +20,10 @@
 
 @author Matej Krejci <matejkrejci gmail.com> (GSoC 2014)
 """
+from owslib.iso import *
+from owslib.namespaces import Namespaces
+from owslib.etree import etree
+from owslib import util
 
 import string
 import os
@@ -394,3 +398,68 @@
         result["num_of_errors"] = str(errors)
 
     return result
+
+
+
+class MD_DataIdentification_MOD(MD_DataIdentification):
+    def __init__(self,md=None,identtype=None):
+        MD_DataIdentification.__init__(self,md,identtype)
+        if md is None:
+            self.timeUnit = None
+            self.temporalType = None
+            self.timeUnit = None
+            self.factor = None
+            self.radixT = None
+        else:
+            val2 = None
+            val1 = None
+            val3 = None
+            val4 = None
+            extents = md.findall(util.nspath_eval('gmd:extent', namespaces))
+            extents.extend(md.findall(util.nspath_eval('srv:extent', namespaces)))
+            for extent in extents:
+                if val2 is None:
+                    val2 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TM_PeriodDuration/gml:duration', namespaces))#TODO
+                self.temporalType = util.testXMLValue(val2)
+
+                if val1 is None:
+                    val1 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:timeLength/gml:timeInterval/gml:unit/gml:TimeUnitType', namespaces))
+                self.timeUnit = util.testXMLValue(val1)
+                if val3 is None:
+                    val3 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:timeLength/gml:timeInterval/gml:radix/gco:positiveInteger', namespaces))
+                self.radixT = util.testXMLValue(val3)
+
+                if val4 is None:
+                    val4 = extent.find(util.nspath_eval('gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:timeLength/gml:timeInterval/gml:factor/gco:Integer', namespaces))
+                self.factor = util.testXMLValue(val4)
+
+class MD_MetadataMOD(MD_Metadata):
+    """ Process gmd:MD_Metadata """
+    def __init__(self, md=None):
+        MD_Metadata.__init__(self,md)
+        if md is not None:
+            val = md.find(util.nspath_eval('gmd:identificationInfo/gmd:MD_DataIdentification', namespaces))
+            val2 = md.find(util.nspath_eval('gmd:identificationInfo/srv:SV_ServiceIdentification', namespaces))
+
+            if val is not None:
+                self.identification = MD_DataIdentification_MOD(val, 'dataset')
+                self.serviceidentification = None
+            elif val2 is not None:
+                self.identification = MD_DataIdentification_MOD(val2, 'service')
+                self.serviceidentification = SV_ServiceIdentification(val2)
+            else:
+                self.identification = None
+                self.serviceidentification = None
+
+            self.identificationinfo = []
+            for idinfo in md.findall(util.nspath_eval('gmd:identificationInfo', namespaces)):
+                val = list(idinfo)[0]
+                tagval = util.xmltag_split(val.tag)
+                if tagval == 'MD_DataIdentification':
+                    self.identificationinfo.append(MD_DataIdentification_MOD(val, 'dataset'))
+                elif tagval == 'MD_ServiceIdentification':
+                    self.identificationinfo.append(MD_DataIdentification_MOD(val, 'service'))
+                elif tagval == 'SV_ServiceIdentification':
+                    self.identificationinfo.append(SV_ServiceIdentification(val))
+
+            val = md.find(util.nspath_eval('gmd:distributionInfo/gmd:MD_Distribution', namespaces))
\ No newline at end of file

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/profiles/basicProfile.xml	2015-06-21 18:50:14 UTC (rev 65507)
@@ -139,3 +139,4 @@
     </gmd:DQ_DataQuality>
   </gmd:dataQualityInfo>
         </gmd:MD_Metadata>
+        
\ No newline at end of file

Modified: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml	2015-06-20 21:42:54 UTC (rev 65506)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/profiles/inspireProfile.xml	2015-06-21 18:50:14 UTC (rev 65507)
@@ -8,12 +8,12 @@
     <gmd:fileIdentifier>
         <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "string", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
     </gmd:fileIdentifier>
-    <gmd:language>
+     <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "MD_ScopeCode", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
+    </gmd:hierarchyLevel>
+        <gmd:language>
         <gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ md.languagecode }}{# tag="md.languagecode", name ="Metadata language", desc ="Language(s) used within the datasets", example ="eng", type = "string", multi = 0, group = "Metadata",multiline=False #}">{{ md.languagecode }}</gmd:LanguageCode>
     </gmd:language>
-    <gmd:hierarchyLevel>
-        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
-    </gmd:hierarchyLevel>
   {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
     <gmd:contact>
         <gmd:CI_ResponsibleParty>

Added: grass-addons/grass7/gui/wxpython/wx.metadata/profiles/temporalProfile.xml
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.metadata/profiles/temporalProfile.xml	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.metadata/profiles/temporalProfile.xml	2015-06-21 18:50:14 UTC (rev 65507)
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd"
+    xmlns:gmd="http://www.isotc211.org/2005/gmd"
+    xmlns:gco="http://www.isotc211.org/2005/gco"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:gml="http://www.opengis.net/gml"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:gts="http://www.opengis.net/gts">
+    <gmd:fileIdentifier>
+        <gco:CharacterString>{{ md.identifier }}{# tag="md.identifier",ref="Part B 1.5",  name ="Resource Identifier", desc ="Unique Resource Identifier", example ="286c0725-046e-4533-b0bf-d6e367f6c342", type = "string", multi = 0, group = "Identification", multiline=False #}</gco:CharacterString>
+    </gmd:fileIdentifier>
+    <gmd:language>
+        <gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ md.languagecode }}{# tag="md.languagecode", name ="Metadata language", desc ="Language(s) used within the datasets", example ="eng", type = "string",database="language", multi = 0, group = "Metadata",multiline=False #}">{{ md.languagecode }}</gmd:LanguageCode>
+    </gmd:language>
+    <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="dataset" codeSpace="ISOTC211/19115">{{ md.identification.identtype }}{# tag="md.identification.identtype", name ="Resource Type", desc ="Scope to which metadata applies", example ="dataset", type = "string", multi = 0, group = "Identification",multiline=False #}</gmd:MD_ScopeCode>
+    </gmd:hierarchyLevel>
+  {% for co in md.contact -%}{# tag="for co in md.contact",  inboxmulti = 1, group = "Metadata",inbox="Metadata point of contact",object="CI_ResponsibleParty()" #}
+    <gmd:contact>
+        <gmd:CI_ResponsibleParty>
+            <gmd:organisationName>
+                <gco:CharacterString>{{ co.organization }}{# tag="co.organization",ref="Part B 9.1",  inboxmulti = 1,multi = 0,type = "string",group = "Metadata",object="CI_ResponsibleParty()", inbox="Metadata point of contact",name="Organisation name",example="SDI Unit, Institute for Environment and Sustainability, Joint ResearchCentre",desc="identification of, and means of communication with, person(s) and organization(s) associated with theresource(s)" #}</gco:CharacterString>
+            </gmd:organisationName>
+            <gmd:role>
+                <gmd:CI_RoleCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode" codeListValue="{{ co.role }}{# tag="co.role",name="Responsible party role",ref="Part B 9.2" , multi = 0,type = "CI_RoleCode", inboxmulti = 1,group = "Responsible party",object="CI_ResponsibleParty()", inbox="Metadata pointt of contact",example="custodian", desc="function performed by the responsible party",database="role" #}" codeSpace="ISOTC211/19115">{{ co.role }}</gmd:CI_RoleCode>
+            </gmd:role>
+        </gmd:CI_ResponsibleParty>
+    </gmd:contact>
+  {% endfor -%}
+<gmd:dateStamp>
+        <gco:Date>{{ md.datestamp }}{# tag="md.datestamp" , name="Metadata date" , ref= "Part B 10.2" , desc= "Date that the metadata was created." , example = "2005-03-27" , type ="date" , multi= 0 , group= "Metadata" , multiline= False #}</gco:Date>
+    </gmd:dateStamp>
+    <gmd:metadataStandardName>
+        <gco:CharacterString>ISO 19115</gco:CharacterString>
+    </gmd:metadataStandardName>
+    <gmd:metadataStandardVersion>
+        <gco:CharacterString>2003/Cor.1:2006</gco:CharacterString>
+    </gmd:metadataStandardVersion>
+  <gmd:identificationInfo>
+        <gmd:MD_DataIdentification>
+            <gmd:citation>
+                <gmd:CI_Citation>
+                    <gmd:title>
+                        <gco:CharacterString>{{ md.identification.title }}{# tag="md.identification.title", ref="Part B 1.1", name ="Resource title", desc ="Name by which the cited resource is known.", example ="Image2000 Product 1 (nl2) MultispectB 10.1" , multi = 0, group ="Identification", type = "string", multiline=True #}</gco:CharacterString>
+                    </gmd:title>
+          {% for d in md.identification.date -%}{# tag="for d in md.identification.date" ,name="",object="CI_Date()",group= "Temporal" , inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False #}
+                    <gmd:date>
+                        <gmd:CI_Date>
+                            <gmd:date>
+                                <gco:DateTime>{{ d.date }}{# tag="d.date" , group= "Temporal" ,object="CI_Date()",type = "date", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="Date of: type(below)",desc="reference date for the cited resource - publication/creation/revision",example="2007-09-15" #}</gco:DateTime>
+                            </gmd:date>
+                            <gmd:dateType>
+                                <gmd:CI_DateTypeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode" codeListValue= "{{ d.type }}{# tag="d.type" , group= "Temporal" ,object="CI_Date()",type = "CI_DateTypeCode", inbox= "Date of creation/publication/revision",  inboxmulti=1, multiline= False, name="type: creation/publication/revision",desc="reference date for the cited resource - publication/creation/revision",example="creation",database="dateType" #}" codeSpace="ISOTC211/19115">{{ d.type }}</gmd:CI_DateTypeCode>
+                            </gmd:dateType>
+                        </gmd:CI_Date>
+                    </gmd:date>
+          {% endfor -%}
+{% for (cod,code) in zip(md.identification.uricode,md.identification.uricodespace) -%}{# tag="for (cod,code) in zip(md.identification.uricode,md.identification.uricodespace)", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" #}
+                                     <gmd:identifier>
+                                        <gmd:RS_Identifier>
+                                            <gmd:code>
+                                                <gco:CharacterString>{{ cod }}{# tag="cod", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" ,ref="Part B 1.5",  name ="Idetifier- code", desc ="A value uniquely identifying the resource.The value domain of this metadata element is a mandatory character string code, generally assigned by the data owner, and a character string namespace uniquely identifying the context of the identifier code (for example, the data owner).", example ="http://image2000.jrc.it # image2000_1_nl2_multi", type = "string", multi = 0  #}</gco:CharacterString>
+                                            </gmd:code>
+                                            <gmd:codeSpace>
+                                                <gco:CharacterString>{{ code }}{# tag="code", inboxmulti=1, group = "Identification",inbox="Unique resource identifier" ,ref="Part B 1.5",  name ="Idetifier- code space", desc ="A value uniquely identifying the resource.The value domain of this metadata element is a mandatory character string code, generally assigned by the data owner, and a character string namespace uniquely identifying the context of the identifier code (for example, the data owner).", example ="http://image2000.jrc.it", type = "string", multi = 0 #}</gco:CharacterString>
+                                            </gmd:codeSpace>
+                                        </gmd:RS_Identifier>
+                                  </gmd:identifier>
+                      {% endfor -%}
+                </gmd:CI_Citation>
+            </gmd:citation>
+            <gmd:abstract>
+                <gco:CharacterString>{{ md.identification.abstract }}{# tag="md.identification.abstract ",ref="Part B 1.2",  name ="Resource Abstract", desc ="Brief narrative summary of the content of the resource(s).", example ="IMAGE2000 product 1 individual orthorectified scenes. IMAGE2000 was produced from ETM+ Landsat 7 satellite data and provides a consistent European coverage of individual orthorectified scenes in national map projection systems. The year 2000 was targeted as reference year, but a deviation of maximum 1-year was allowed to obtain a full coverage of Europe, which involves approximately 450 Landsat TM Frames. Where Landsat 7 data were not available, Landsat 5 data have been used instead. The spatial resolution is 25 metres for multispectral and 12.5 metres for panchromatic imagery", type = "string", multi = 0, group = "Identification", multiline=True #}</gco:CharacterString>
+            </gmd:abstract>
+      {% for lan in md.identification.resourcelanguage -%}{# tag="for lan in md.identification.resourcelanguage" , group= "Identification" ,inbox='Languages',inboxmulti=1, multiline= False, database="language" #}
+            <gmd:language>
+                <gmd:LanguageCode codeList="http://www.isotc211.org/2005/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="{{ lan }}{# tag="lan" , name="Metadata language" , ref= "Part B 10.3" , desc= "Language used for documenting metadata." , example = "eng" , type ="LanguageCode (ISO/TS 19139)" ,multi=0,inbox='Languages',inboxmulti=1, group= "Identification" , multiline= False, database="language" #}">{{ lan }}</gmd:LanguageCode>
+            </gmd:language>
+      {% endfor -%}
+               <gmd:extent>
+                <gmd:EX_Extent>
+                    <gmd:geographicElement>
+                        <gmd:EX_GeographicBoundingBox>
+                            <gmd:westBoundLongitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.minx }}{# tag="md.identification.extent.boundingBox.minx" , name="West Bound Longitude" , ref= "Part B 4.1" , desc= "Western-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "3.93" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:westBoundLongitude>
+                            <gmd:eastBoundLongitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxx }}{# tag="md.identification.extent.boundingBox.maxx" , name="East Bound Longitude" , ref= "Part B 4.1" , desc= "Eastern-most coordinate of the limit of the dataset extent, expressed in longitude in decimal degrees (positive east)." , example = "7.57" , type ="decimal" , group= "Geographic" ,  multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:eastBoundLongitude>
+                            <gmd:southBoundLatitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.miny }}{# tag="md.identification.extent.boundingBox.miny" , name="South Bound Latitude" , ref= "Part B 4.1" , desc= "Southern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "52.10" , type ="decimal" , group= "Geographic" ,multi=0 , multiline= False #}</gco:Decimal>
+                            </gmd:southBoundLatitude>
+                            <gmd:northBoundLatitude>
+                                <gco:Decimal>{{ md.identification.extent.boundingBox.maxy }}{# tag="md.identification.extent.boundingBox.maxy" , name="North Bound Latitude" , ref= "Part B 4.1" , desc= "Northern-most coordinate of the limit of the dataset extent, expressed in latitude in decimal degrees (positive north)." , example = "54.10" , type ="decimal" , group= "Geographic" , multi=0 ,  multiline= False #}</gco:Decimal>
+                            </gmd:northBoundLatitude>
+                        </gmd:EX_GeographicBoundingBox>
+                    </gmd:geographicElement>
+                </gmd:EX_Extent>
+            </gmd:extent>
+      {% if md.identification.temporalextent_start != None -%}{# tag="if md.identification.temporalextent_start != None", group = "Temporal", inbox="Temporal Extent",inboxmulti= 0 #}
+            <gmd:extent>
+                <gmd:EX_Extent>
+                    <gmd:temporalElement>
+                        <gmd:EX_TemporalExtent>
+                            <gmd:extent>
+                                <gml:TimePeriod xsi:type="gml:TimePeriodType">
+                                    <gml:beginPosition>{{ md.identification.temporalextent_start }}{# tag="md.identification.temporalextent_start" , name="Starting date" , ref= "Part B 5.1" , desc= "Time period covered by the content of the dataset." , example = "2000-11-30" , type ="date" , group= "Temporal" , inbox= "Temporal extent", multi=0 , inboxmulti= 0, multiline= False #}</gml:beginPosition>
+                                    <gml:endPosition>{{ md.identification.temporalextent_end }}{# tag="md.identification.temporalextent_end" , name="Ending date" , ref= "Part B 5.1" , desc= "Time period covered by the content of the dataset." , example = "2000-11-30" , type ="date" , group= "Temporal" , inbox= "Temporal extent", multi=0 , inboxmulti= 0, multiline= False #}</gml:endPosition>
+                                </gml:TimePeriod>
+                            </gmd:extent>
+                        </gmd:EX_TemporalExtent>
+                    </gmd:temporalElement>
+                </gmd:EX_Extent>
+            </gmd:extent>
+      {% endif -%}
+           <gmd:extent>
+            <gmd:EX_Extent>
+               <gmd:temporalElement>
+                  <gmd:EX_TemporalExtent>
+                     <gmd:extent>
+                        <gts:TM_PeriodDuration xsi:type="gts:TM_PeriodDuration_PropertyType">
+                        <gml:duration>
+                        {{ md.identification.temporalType }}{# tag="md.identification.temporalType" , name="Temporal type" , ref= "-" , desc= "Type of temporal dataset" , example = "absolute or relative" , type ="string" , group= "Temporal" ,multi=0 , inboxmulti= 0, multiline= False #}
+                        </gml:duration>
+                        </gts:TM_PeriodDuration>
+                     </gmd:extent>
+                  </gmd:EX_TemporalExtent>
+               </gmd:temporalElement>
+            </gmd:EX_Extent>
+         </gmd:extent>
+         {% if md.identification.timeUnit != None -%}{# tag="if md.identification.radixT != None", group = "Temporal", inbox="Temporal Resolution",inboxmulti= 0 #}
+           <gmd:extent>
+            <gmd:EX_Extent>
+               <gmd:temporalElement>
+                  <gmd:EX_TemporalExtent>
+                     <gmd:extent>
+                        <gml:timeLength xsi:type="gml:TimePeriodType">	
+                        	<gml:timeInterval xsi:type="gml:TimeIntervalLengthType">
+                        	<gml:unit>
+                							<gml:TimeUnitType>{{ md.identification.timeUnit }}{# tag="md.identification.timeUnit" , name="Granularity" , ref= "ISO/DIS 19108" , desc= "CharacterString is the name of the unit of measure used to express the length of the interval" ,inbox="Temporal Resolution", example = "month" , type ="string" , group= "Temporal" ,multi=0 , inboxmulti= 0, multiline= False #}</gml:TimeUnitType>
+                							</gml:unit>
+                							<radix>
+                							<gco:positiveInteger>{{ md.identification.radixT }}{# tag="md.identification.radixT" , name="Multiplier" , ref= "ISO/DIS 19108" , desc= "Integer is a positive integer that is the base of the multiplier of the unit" ,inbox="Temporal Resolution", example = "10" , type ="integer" , group= "Temporal" ,multi=0 , inboxmulti= 0, multiline= False #}</gco:positiveInteger>
+                							</radix>	
+                							<factor>
+                							<gco:Integer>{{ md.identification.factor }}{# tag="md.identification.factor" , name="Factor" , ref= "ISO/DIS 19108" , desc= "Factor is an integer that is the exponent of the base" , example = "3" , type ="string" ,inbox="Temporal Resolution", group= "Temporal" ,multi=0 , inboxmulti= 0, multiline= False #}</gco:Integer>
+                							</factor>	
+							</gml:timeInterval>			
+						</gml:timeLength>
+                     </gmd:extent>
+                  </gmd:EX_TemporalExtent>
+               </gmd:temporalElement>
+            </gmd:EX_Extent>
+         </gmd:extent>
+         {% endif -%}
+      </gmd:MD_DataIdentification>
+   </gmd:identificationInfo>
+ <gmd:dataQualityInfo>
+      <gmd:DQ_DataQuality>
+       <gmd:lineage>
+        <gmd:LI_Lineage>
+          <gmd:statement>
+            <gco:CharacterString>{{ md.dataquality.lineage }}{# tag="md.dataquality.lineage" , name="Lineage" , ref= "Part B 6.1" , desc= "General explanation of the data producers knowledge about the lineage of a dataset." , example = "Product 1 scenes correspond to the path/row of the Landsat orbit.." , type ="string" , group= "Quality and Validity" ,  multiline= True #}</gco:CharacterString>
+          </gmd:statement>
+        </gmd:LI_Lineage>
+      </gmd:lineage>
+    </gmd:DQ_DataQuality>
+  </gmd:dataQualityInfo>
+</gmd:MD_Metadata>



More information about the grass-commit mailing list