[GRASS-SVN] r61117 - in sandbox/krejcmat/src: . data

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Jul 2 07:52:33 PDT 2014


Author: krejcmat
Date: 2014-07-02 07:52:33 -0700 (Wed, 02 Jul 2014)
New Revision: 61117

Added:
   sandbox/krejcmat/src/data/jinjatest.xml
   sandbox/krejcmat/src/editor1.py
   sandbox/krejcmat/src/g.gui.metadata.py
   sandbox/krejcmat/src/jinjainfo.py
   sandbox/krejcmat/src/series.xml
   sandbox/krejcmat/src/test.py
   sandbox/krejcmat/src/test2.py
Modified:
   sandbox/krejcmat/src/data/grassInspireTemplate01.xml
   sandbox/krejcmat/src/mdgrass.py
   sandbox/krejcmat/src/r.info.iso.py
   sandbox/krejcmat/src/v.info.iso.py
Log:
gui editor etc 

Modified: sandbox/krejcmat/src/data/grassInspireTemplate01.xml
===================================================================
--- sandbox/krejcmat/src/data/grassInspireTemplate01.xml	2014-07-02 12:05:37 UTC (rev 61116)
+++ sandbox/krejcmat/src/data/grassInspireTemplate01.xml	2014-07-02 14:52:33 UTC (rev 61117)
@@ -2,13 +2,13 @@
 <!-- ISO 19115:2003 file created from OWSLib object model -->
 <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">
   <gmd:fileIdentifier>
-    <gco:CharacterString>{{ md.identifier }}{# name ='Resource Identifier', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Metadata' #}</gco:CharacterString>
+    <gco:CharacterString>{{ md.identifier }}{# tag='md.identifier',  name ='Resource Identifier', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Metadata',inbox='inboxtest', inboxmulti=True, multiline=True #}</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="eng">{{ md.languagecode }}{# name ='Resource language', desc ='Language(s) used within the datasets', example ='eng', type = 'CharacterString', multi = '0-*', group = 'Metadata' #}</gmd:LanguageCode>
+    <gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">{{ md.languagecode }}{# tag='md.languagecode', name ='Resource language', desc ='Language(s) used within the datasets', example ='eng', type = 'CharacterString', multi = '0-*', group = 'Metadata',inbox='inboxtest',inboxmulti=True,multiline=False #}</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 }}{# name ='Resource Type', desc ='Scope to which metadata applies', example ='dataset', type = 'CharacterString', multi = '1', group = 'Identification' #}</gmd:MD_ScopeCode>
+    <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 = 'CharacterString', multi = '1', group = 'Identification',multiline=True #}</gmd:MD_ScopeCode>
   </gmd:hierarchyLevel>
   {% for co in md.contact -%}
   <gmd:contact>

Added: sandbox/krejcmat/src/data/jinjatest.xml
===================================================================
--- sandbox/krejcmat/src/data/jinjatest.xml	                        (rev 0)
+++ sandbox/krejcmat/src/data/jinjatest.xml	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,24 @@
+{# tag='md.identifier',  name ='Resource Identifier', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 0, group = 'Metadata',inbox='inboxtest', inboxmulti=True, multiline=False #}
+
+{# tag='md.identifier1',  name ='Resource Identifier1', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Metadata',inbox='inboxtest', inboxmulti=True, multiline=True #}
+
+{# tag='md.identifier',  name ='Resource Identifier2', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 0, group = 'Metadata',inbox='inboxtest3', inboxmulti=False, multiline=True #}
+
+{# tag='md.identifier1',  name ='Resource Identifier3', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Metadata',inbox='inboxtest3', inboxmulti=False, multiline=True #}
+
+{# tag='md.identifier2',  name ='a Identifier', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Metadata',  multiline=False #}
+
+{# tag='md.identifier2',  name ='aa Identifier', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Metadata',  multiline=False #}
+
+
+
+{# tag='md.identifier1',  name ='Identifier', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Info', multiline=True #}
+{# tag='md.languagecode', name ='Identifier0', desc ='Language(s) used within the datasets', example ='eng', type = 'CharacterString', multi = '0', group = 'Info',inbox='inboxtest1',inboxmulti=True,multiline=False #}
+
+{# tag='md.identifier',  name ='Identifier1', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 1, group = 'Info',inbox='inboxtest1', inboxmulti=True, multiline=False #}
+
+{# tag='md.identifier1',  name ='Identifier2', desc ='Unique Resource Identifier', example ='286c0725-146e-4533-b1bf-d6e367f6c342', type = 'CharacterString', multi = 0, group = 'Info',inbox='inboxtest1', inboxmulti=True, multiline=True #}
+
+
+
+

Added: sandbox/krejcmat/src/editor1.py
===================================================================
--- sandbox/krejcmat/src/editor1.py	                        (rev 0)
+++ sandbox/krejcmat/src/editor1.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,235 @@
+
+import wx 
+from wx import ID_ANY
+from wx import EVT_BUTTON
+import wx.lib.scrolledpanel as scrolled
+
+from owslib.iso import *
+from jinjainfo  import JinjaTemplateInfo as jt
+
+#===============================================================================
+#EDITOR                               
+#===============================================================================
+class MD():
+    def __init__(self):
+        pass
+    def intSubMD(self):
+        self.md.identification = MD_DataIdentification()
+        self.md.dataquality = DQ_DataQuality()
+        self.md.distribution = MD_Distribution()
+        self.md.identification.extent = EX_Extent()
+        self.md.identification.extent.boundingBox = EX_GeographicBoundingBox() 
+        
+    def initMD(self,path):
+        tree = ET.parse('series.xml')
+        root = tree.getroot()
+        md = MD_Metadata(root)
+        self.md = MD_Metadata(md=None)  
+    
+class Editor(wx.Panel):
+    def __init__(self,parent):
+        wx.Panel.__init__(self, parent=parent,id=wx.ID_ANY)
+        
+        self.wxIdTag={} #dict with id and tag from ows lib
+        self.mdcreator=MD()
+        #self.wxIdBox={}
+        self._layout()    
+        self.nb_panels=[] #panels in notebook
+        self.templatePath='data/grassInspireTemplate01.xml'
+        #self.templatePath='data/jinjatest.xml'
+        self.MDinfoList=[]
+        self._getInfoJinja() 
+    
+        self.addNotebook()
+        self.initCreator()
+#------------------------------------------- REGISTER OWSlib TAG TO CTRL TEXT ID
+    def regIdTag(self,tag):
+        id=self.valueCtrl.GetId()
+        print 'tag: ' +tag + ' id: ' +str(id) 
+        self.wxIdTag[self.valueCtrl.GetId()]=tag
+
+    def readXML(self,schemaPath):
+        pass
+#------------------------------------------------------------------------ EVENTS
+    def cloneCtrl(self,evt):
+        print 'pes'
+        
+    def mdBuilder(self,evt):
+        string=evt.GetString()
+        id=evt.GetId() 
+        print self.wxIdTag[id]
+        
+        print id
+        print string
+        #=======================================================================
+        # children = self.sizer.GetChildren() 
+        # for child in children:
+        #     widget = child.GetWindow()
+        #     print widget
+        #     if isinstance(widget, wx.TextCtrl):
+        #         widget.Clear()
+        #=======================================================================
+           
+#-------------------------------------------------------------------- CREATE BOX
+    def addBox(self,multi,label):
+        self.stbox=wx.StaticBox(self.nbPanel, label=label,id=ID_ANY, style=wx.RAISED_BORDER)
+
+        if multi:
+            self.addBoxButt=wx.Button(self.nbPanel,-1,size=(20,20),label='+') 
+        self._addBoxLay(multi)
+        
+    def _addBoxLay(self,multi):
+        self.boxButtonSizer=wx.BoxSizer(wx.HORIZONTAL)
+        self.nbPanelSizer.Add(self.boxButtonSizer,flag=wx.EXPAND,proportion=0)
+        self.stBoxSizer = wx.StaticBoxSizer( self.stbox, wx.VERTICAL)
+        self.boxButtonSizer.Add(item=self.stBoxSizer,flag=wx.EXPAND,proportion=1)
+             
+        if multi:
+            self.boxButtonSizer.Add(self.addBoxButt,0)
+
+#---------------------------------------------------------------------- FILL BOX
+    def fillBox(self,item):
+        self.addItem(item,True)
+
+#--------------------------------------------------------------------- ADD ITEM
+    def addItem(self,item,box=False):
+        label=item.name
+        multiple=item.multiplicity
+        multiline=item.multiline
+        info=self.createInfo(item)  
+        tag=item.tag
+    
+        if box:
+            self.place=self.nbPanel
+            self.sizer=self.stBoxSizer
+        else:
+            self.place=self.nbPanel
+            self.sizer=self.nbPanelSizer
+            
+        self.tagText= wx.StaticText(parent=self.place,id=ID_ANY,label=label)
+        if multiline is True:
+                self.valueCtrl = wx.TextCtrl(self.place, id=ID_ANY,  size=(0, 55),
+                                       style=wx.VSCROLL | 
+                                       wx.TE_MULTILINE | wx.TE_DONTWRAP | wx.ST_NO_AUTORESIZE|
+                                       wx.TAB_TRAVERSAL|wx.RAISED_BORDER|wx.HSCROLL)       
+        else:
+                self.valueCtrl = wx.TextCtrl(self.place, id=wx.ID_ANY,  
+                                       style=wx.VSCROLL |  wx.TE_DONTWRAP | 
+                                       wx.TAB_TRAVERSAL|wx.RAISED_BORDER|wx.HSCROLL)  
+        #register tag to created wx.id
+        self.regIdTag(tag)
+        
+        if multiple:
+            self.addItemButt=wx.Button(self.place,-1,size=(20,20),label='+')
+            #self.addInfoButt=wx.Button(self,-1,size=(20,20),label='I')
+        #BINDS    
+            self.addItemButt.Bind(EVT_BUTTON, self.cloneCtrl)          
+        self.valueCtrl.Bind(wx.EVT_TEXT,self.mdBuilder )
+        
+        self._addItemLay(multiline,multiple)
+
+                        
+    def _addItemLay(self,multiline,multiple): 
+        
+        if multiline is True:
+            self.textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)  
+            self.textFieldSizer.Add(self.valueCtrl,proportion=1,flag=wx.EXPAND)
+            if multiple:
+                self.textFieldSizer.Add(self.addItemButt,0)
+            self.sizer.Add(item=self.tagText,proportion=0)
+            self.sizer.Add(item=self.textFieldSizer,proportion=0,flag=wx.EXPAND)
+        else:
+            self.textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)  
+            self.textFieldSizer.Add(self.valueCtrl,proportion=1)
+            if multiple:
+                self.textFieldSizer.Add(self.addItemButt,0)
+            self.sizer.Add(item=self.tagText,proportion=0)
+            self.sizer.Add(item=self.textFieldSizer,proportion=0,flag=wx.EXPAND)
+          
+#---------------------------------------------------------------------- NOTEBOOK
+    def addNotebook(self):
+        self.notebook=wx.Notebook(self,id=wx.ID_ANY|wx.HSCROLL)
+        self._addNotebookLay()
+        
+    def _addNotebookLay(self):
+        noteSizer=wx.BoxSizer(wx.VERTICAL)
+        self.notebook.SetSizer(noteSizer)
+        self.mainSizer.Add(self.notebook,proportion=1,flag=wx.EXPAND)   
+              
+#----------------------------------------------------------------- NOTEBOOK PAGE
+    def addNotebookPage(self,label):
+        self.nbPanel=scrolled.ScrolledPanel(self.notebook,id=wx.ID_ANY)
+        self.nbPanel.SetupScrolling()
+        self.notebook.AddPage(self.nbPanel,label)
+        self._addNotebookPageLay()
+
+    def _addNotebookPageLay(self):   
+        self.nbPanelSizer=wx.BoxSizer(wx.VERTICAL)
+        self.nbPanel.SetSizer(self.nbPanelSizer)
+       
+#----------------------------------------------------------------------- CREATOR
+    def initCreator(self):
+        for item in self.MDinfoList:
+            try:
+                group=item[0][0].group
+            except:
+                group=item[0].group
+                
+            self.addNotebookPage(group)
+            
+            for currItem in item:          #loop for items in maingroup(notebook list) 
+                if type(currItem) is list: #if items are in "box"
+                    label=currItem[0].inbox
+                    multi=currItem[0].inboxmulti
+                    self.addBox(multi, label)
+                    for inBox in currItem: #for items in box
+                        #print inBox.name
+                        self.fillBox(inBox)
+                else:
+                    self.addItem(currItem)
+                    
+#-------------------------------------------------------------------- JINJA INFO
+    def _getInfoJinja(self):
+        jinj=jt(self.templatePath)
+        self.MDinfoList=jinj.getMdInfoGroupByGroupsList()
+    
+#------------------------------------------------------------- MAIN PANEL LAYOUT
+    def _layout(self):
+        #main sizer in frame
+        self.mainSizer=wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(self.mainSizer)
+        
+#-------------------------------------------------------------------------- INFO
+    def createInfo(self,item):
+        string='name: '+ item.name + '\n' 
+        string+='description: ' + item.desc + '\n'
+        string+='example: ' + item.example + '\n'   
+        return string
+
+#===============================================================================
+# MAIN FRAME                        
+#===============================================================================
+class MainFrame(wx.Frame):
+    def __init__(self, parent, ID, title):
+        wx.Frame.__init__(self, parent, ID, title,
+                          wx.DefaultPosition, wx.Size(600, 400))
+        self.panel = Editor(self)
+        self._layout()
+ 
+    def _layout(self):
+        topSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(topSizer)
+        topSizer.Add(item=self.panel, proportion=1,flag=wx.EXPAND)
+  
+class MyApp(wx.App): 
+    def OnInit(self): 
+        Frame = MainFrame(None, -1, "Frame") 
+        Frame.Show(True) 
+        self.SetTopWindow(Frame) 
+        return True 
+
+if __name__ == '__main__': 
+    App = MyApp(0) 
+    App.MainLoop() 
+
+     
\ No newline at end of file

Added: sandbox/krejcmat/src/g.gui.metadata.py
===================================================================
--- sandbox/krejcmat/src/g.gui.metadata.py	                        (rev 0)
+++ sandbox/krejcmat/src/g.gui.metadata.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,245 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+MODULE:    g.gui.metadata
+
+AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+
+PURPOSE:   Module for editing metadata based on ISO
+
+COPYRIGHT: (C) 2014 Matej Krejci, and 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.
+"""
+
+#from grass.pygrass.gis import Mapset
+from lxml import etree as et
+from wx.lib.splitter import MultiSplitterWindow
+import wx
+import editor
+########################################################################
+class MapTree(wx.Panel):
+    def __init__(self, parent):    
+        wx.Panel.__init__(self, parent)
+        
+        self.panel1 = wx.Panel(self, -1)
+        self.tree = wx.TreeCtrl(self.panel1, 1, wx.DefaultPosition, (-1,-1), wx.TR_HIDE_ROOT|wx.TR_HAS_BUTTONS)
+        self.initMaps()
+        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)
+        self._layout()
+        
+    def _layout(self):
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        vbox = wx.BoxSizer(wx.VERTICAL)
+        vbox.Add(self.tree, 1, wx.EXPAND)
+        hbox.Add(self.panel1, 1, wx.EXPAND)
+        self.panel1.SetSizer(vbox)
+        self.SetSizer(hbox)
+        self.Centre()
+        
+    def OnSelChanged(self, event):
+        item =  event.GetItem()
+        self.display.SetLabel(self.tree.GetItemText(item))
+ 
+    def initMaps(self):
+        
+        #-------------------------------------- root = self.tree.AddRoot('Maps')
+        #--------------------------- rast = self.tree.AppendItem(root, 'raster')
+        #--------------------------- vect = self.tree.AppendItem(root, 'vector')
+        #----------------------------- rast3d = self.tree.AppendItem(root, 'r3')
+#------------------------------------------------------------------------------ 
+        #----------------------------------------------------- mapset = Mapset()
+        #---------------------------------------- rast_maps=mapset.glist('rast')
+        #------------------------------------------------ for rmap in rast_maps:
+            #---------------------------------- self.tree.AppendItem(rast, rmap)
+#------------------------------------------------------------------------------ 
+        #---------------------------------------- vect_maps=mapset.glist('vect')
+        #------------------------------------------------ for vmap in vect_maps:
+            #---------------------------------- self.tree.AppendItem(vect, vmap)
+            
+            
+         self.tree = wx.TreeCtrl(self.panel1, wx.TR_HIDE_ROOT|wx.TR_HAS_BUTTONS)
+         root = self.tree.AddRoot('Programmer')
+         os = self.tree.AppendItem(root, 'Operating Systems')
+         self.tree.AppendItem(os, 'Linux')
+         self.tree.AppendItem(os, 'FreeBSD')
+         self.tree.AppendItem(os, 'OpenBSD')
+         self.tree.AppendItem(os, 'NetBSD') 
+             
+         self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)
+         self.display = wx.StaticText(self, style=wx.ALIGN_CENTRE) 
+ 
+        
+class Html(wx.Panel):
+    def __init__(self, parent):
+        pass
+        
+class RandomPanel(wx.Panel):
+    def __init__(self, parent, color):
+        wx.Panel.__init__(self, parent)
+        self.SetBackgroundColour(color)
+
+class TreeEditor(wx.TreeCtrl):
+    def __init__(self,parent):
+        wx.TreeCtrl.__init__(self, parent=parent,id=wx.ID_ANY, style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS)
+        
+        self.parent=parent
+        self.fpath = '/home/matt/Dropbox/gsoc/gsoc2014-krejci/src/series.xml'
+        self.xml = et.parse(self.fpath)
+        
+        #wx.TreeCtrl(parent=self.parent,
+        root = self.fillmeup()
+        self.Expand(root)
+
+        self.Bind(wx.EVT_CLOSE, self.OnClose)
+        self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEdit)
+        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRClickAllChildren)
+   
+    def fillmeup(self):
+        xml = self.xml.getroot()
+        tree = self
+        root = tree.AddRoot(xml.tag)
+        
+        def add(parent, elem):
+            count=0                                                                         # do not make empty field after  <appointment> or <item> etc
+            for e in elem:
+                if str(e).find("<!--")!=-1:     #skip comments
+                    continue
+                tag = et.QName(e)
+                item = tree.AppendItem(parent, tag.localname, data = None)
+                if e.text:
+                    text = e.text.strip()
+                else:
+                    text = e.text
+                if text:
+                    val = tree.AppendItem(item, text)
+                    tree.SetPyData(val, e)
+                    count+=1
+                
+                add(item, e) 
+        add(root, xml)
+        return root
+
+    def OnEdit(self, evt):
+        elm = self.GetPyData(evt.Item)
+        
+        print elm 
+        if elm is not None:
+            elm.text = evt.Label
+            self.xml.write(self.fpath, encoding="UTF-8",xml_declaration=True)
+            #self.validate()
+            
+    def OnClose(self, evt):
+        self.Destroy()
+        
+    def OnRClickAllChildren(self,evt):
+        if not self.IsExpanded(evt.Item):
+            self.ExpandAllChildren(evt.Item)
+        else:
+            self.CollapseAllChildren(evt.Item)
+    
+    #------------------------------------------------------- def printLog(self):
+        #------------------------------------------------------------ print self
+        #-------------------------------------------------------- if self.error:
+            #------------------------------------------ print(self.error.column)
+            #------------------------------------------ print(self.error.domain)
+            #------------------------------------- print(self.error.domain_name)
+#------------------------------------------------------------------------------ 
+            #---------------------------------------- print(self.error.filename)
+            #------------------------------------------- print(self.error.level)
+            #-------------------------------------- print(self.error.level_name)
+            #-------------------------------------------- print(self.error.line)
+#------------------------------------------------------------------------------ 
+            #----------------------------------------- print(self.error.message)
+            #-------------------------------------------- print(self.error.type)
+            #--------------------------------------- print(self.error.type_name)
+            #-------------------------------------------- print(self.error.line)
+#------------------------------------------------------------------------------ 
+    #------------------------------------------------------- def validate(self):
+        #------------------------------------------- self.xsd.validate(self.xml)
+        #----------------------------------------- self.log = self.xsd.error_log
+        #-------------------------------------- self.error = self.log.last_error
+        #------------------------------------------------------- self.printLog()
+    
+
+class Toolbar(wx.Panel): 
+        def __init__(self, parent):
+            wx.Panel.__init__(self, parent)
+            
+            self.toolbar = wx.ToolBar(self, 1, wx.DefaultPosition,(-1,-1),  wx.NO_BORDER)
+            self.toolbar.AddSimpleTool(1, wx.Image('icon/create.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'New', '')
+            self.toolbar.AddSimpleTool(2, wx.Image('icon/open-trad.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Open', '')
+            self.toolbar.AddSimpleTool(3, wx.Image('icon/save-trad.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Save', '')
+            self.toolbar.AddSeparator()
+            #toolbar.AddSimpleTool(4, wx.Image('stock_exit.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Exit', '')
+            self.toolbar.Realize()
+            
+
+            self._layout(self)
+    
+            self.Bind(wx.EVT_TOOL, self.OnNew, id=1)
+            self.Bind(wx.EVT_TOOL, self.OnOpen, id=2)
+            self.Bind(wx.EVT_TOOL, self.OnSave, id=3)
+            #self.Bind(wx.EVT_TOOL, self.OnExit, id=4)
+            
+        def _layout(self):
+            vbox = wx.BoxSizer(wx.VERTICAL)
+            vbox.Add(self.toolbar, 0, border=5)
+            self.SetSizer(vbox)
+            self.Centre()
+            
+        def OnNew(self, event):
+            self.statusbar.SetStatusText('New Command')
+    
+        def OnOpen(self, event):
+            self.statusbar.SetStatusText('Open Command')
+    
+        def OnSave(self, event):
+            self.statusbar.SetStatusText('Save Command')
+
+class NotebookRight(wx.Notebook):
+    def __init__(self, parent):        
+        wx.Notebook.__init__(self, parent=parent,id=wx.ID_ANY, style=0)
+        #first panel
+        self.notebook_panel1 = wx.Panel(self, wx.ID_ANY)
+        self.tree =  TreeEditor(self.notebook_panel1 )
+        
+        #second panel
+        self.notebook_panel2 =  wx.Panel(self, wx.ID_ANY, style=0)
+
+        #self.notebook_panel1.SetSizer(sizer_2)
+        self.AddPage(self.notebook_panel1, "Tree editor")
+        self.AddPage(self.notebook_panel2, "Help")
+
+        self._layout()
+        
+    def _layout(self):
+        panelSizer1 = wx.BoxSizer(wx.VERTICAL)
+        self.notebook_panel1.SetSizer(panelSizer1)
+        panelSizer1.Add(self.tree, 1, wx.EXPAND, 0)
+        
+        panelSizer2 = wx.BoxSizer(wx.VERTICAL)
+        self.notebook_panel2.SetSizer(panelSizer2)
+        
+class MainFrame(wx.Frame):
+
+    def __init__(self):
+        """Constructor"""
+        wx.Frame.__init__(self, None, title="Metadata Editor",
+                          size=(1000,1000))
+
+        splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
+        
+        splitter.AppendWindow(MapTree(splitter))
+        splitter.AppendWindow(RandomPanel(splitter,'gray'))
+        splitter.AppendWindow(NotebookRight(splitter))   
+
+        self.Show()
+
+#----------------------------------------------------------------------
+if __name__ == "__main__":
+    app = wx.App(False)
+    frame = MainFrame()
+    app.MainLoop()
\ No newline at end of file


Property changes on: sandbox/krejcmat/src/g.gui.metadata.py
___________________________________________________________________
Added: svn:executable
   + *

Added: sandbox/krejcmat/src/jinjainfo.py
===================================================================
--- sandbox/krejcmat/src/jinjainfo.py	                        (rev 0)
+++ sandbox/krejcmat/src/jinjainfo.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+MODULE:    g.gui.metadata
+
+AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+
+PURPOSE:   Module for editing metadata based on ISO
+
+COPYRIGHT: (C) 2014 Matej Krejci, and 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.
+"""
+
+#from grass.pygrass.gis import Mapset
+from lxml import etree as et
+import os
+from jinja2 import Environment, FileSystemLoader
+
+class MdDescription():
+     def __init__(self,tag, name = None, desc = None, example = None, type = None, multi = 1, inboxmulti=None, group = None, inbox = None, multiline = None ):
+         
+         self.tag=tag
+         self.name = name
+         self.desc = desc
+         self.example = example
+         self.type = type
+         self.multiplicity = multi #multiplicity of MD item
+         self.group = group
+         self.inbox = inbox
+         self.inboxmulti=inboxmulti #multiplicity in subrotoup (in static box)
+         self.multiline=multiline       #type of ctrl text
+
+class JinjaTemplateInfo():
+    def __init__(self,template):
+        
+        self.md_info=[]
+        self.md_sources=[]
+        self.template=template
+        self.objectstr=''
+           
+        self.setupMdInfo()
+        self.setupMdSources()
+        
+    def getMdInfoGroupByGroupsDict(self):
+        dict={}
+        for md in self.md_info:
+            key = md.group
+            if key not in dict:
+                dict.setdefault(key, [])
+            dict[key].append(md)
+        return dict
+    
+    def getMdInfoGroupByGroupsList(self):
+        #make dict with key=inbox(staticbox in gui)
+        box={}
+        for md in self.md_info:
+            key = md.inbox
+            if key is not None:
+                if key not in box:
+                    box.setdefault(key, [])
+                box[key].append(md)
+                
+        #gruped by inbox
+        boxGroup=[]
+        boxList=[]
+        for key in box:
+            boxGroup = box[key]
+            fgroup=[]
+            for item in boxGroup:
+                fgroup.append(item)
+            boxList.append(fgroup)
+
+        #sort boxes by group()  
+        groupDict={}
+        for item in boxList:
+            key=item[0].group
+            if key not in groupDict:
+                groupDict.setdefault(key, [])
+            groupDict[key].append(item)
+            
+        #add items without box  
+        for md in self.md_info:
+            ibox=md.inbox
+            key=md.group
+            if ibox is None:
+                if key not in groupDict:
+                    groupDict.setdefault(key, [])
+                groupDict[key].append(md)
+
+        #create final list of groups which include boxes and single items.
+        #The boxes include items. 
+        #-----group
+                #---box
+                    #---item in box
+                #---item     
+        group=[]
+        finalList=[]
+        for key in groupDict:   
+            group = groupDict[key]
+            fgroup=[]
+            for item in group:
+                fgroup.append(item)
+            finalList.append(fgroup)
+
+        return  finalList
+        
+    def getObjectsString(self):
+        self.objectstr=""
+        tab=0
+        for item in self.md_sources:
+            if str(item).find(" endfor ")!=-1 or str(item).find(" endif ")!=-1 or str(item).find(" endwhile ")!=-1:
+                tab-=1
+                continue
+            
+            tabstr='\t'*tab         
+            self.objectstr+=tabstr + item + '\n'
+            if str(item).find(" for ")!=-1 or str(item).find(" if ")!=-1 or str(item).find(" while ")!=-1:
+                tab+=1
+                
+        return self.objectstr
+    
+    def setupMdSources(self):
+            try:
+                with open( self.template, "r") as f:
+                    for line in f:
+
+                        if str(line).find("{{")!=-1:#if found start of comments
+                            object = self._findBetween(line,"{{","}}")
+                            self.md_sources.append(object)
+                                
+                        if str(line).find("{%")!=-1:
+                            object = self._findBetween(line,"{%","-%}")
+                            self.md_sources.append(object)
+                                   
+            except IOError as e:
+                print "I/O error({0}): {1}".format(e.errno, e.strerror)
+                
+    def _findBetween(self, s, first, last ):
+        try:
+            start = s.index( first ) + len( first )
+            end = s.index( last, start )
+            return s[start:end]
+        except ValueError:
+            return ""
+    
+    def setupMdInfo(self):
+            #template = 'data/grassBasicISOTemplate01.xml'
+            try:
+                with open( self.template, "r") as f:
+                    for line in f:
+                            if str(line).find("{#")!=-1:#if found start of comments
+                                values = self._findBetween(line,"{#","#}")
+                                exe_str = "self.md_info.append(MdDescription(%s))"%values
+                                eval(exe_str)
+                                
+            except IOError as e:
+                print "I/O error({0}): {1}".format(e.errno, e.strerror)
+
+        
+        
+if __name__ == "__main__":
+
+    main()        
\ No newline at end of file

Modified: sandbox/krejcmat/src/mdgrass.py
===================================================================
--- sandbox/krejcmat/src/mdgrass.py	2014-07-02 12:05:37 UTC (rev 61116)
+++ sandbox/krejcmat/src/mdgrass.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -6,68 +6,65 @@
 
 PURPOSE:   Library for creating ISO metadata for GRASS GIS
 
-COPYRIGHT: (C) 2014 Matej Krejci, and by the GRASS Development Team
+COPYRIGHT: (C) 2007 Matej Krejci, and 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.
 """
 
-import os
-import sys
-import getpass # whoami for linux and  ms-win
-import StringIO
-
-from subprocess import PIPE
-from datetime import date, datetime
-
-
 from owslib.iso import *
 from lxml import etree
-from jinja2 import Environment, FileSystemLoader           # TODO: remove this dependency?
+from jinja2 import Environment, FileSystemLoader
 
+import os
+import sys
 from grass.pygrass.modules.shortcuts import general as g
 from grass.pygrass.gis import Mapset
 from grass.pygrass import raster
 from grass.pygrass.modules import Module
-
-from grass.script import parse_key_val, parser
+from grass.script import parse_key_val
+from subprocess import PIPE
+from datetime import date,datetime
+import getpass # whoami for linux and  ms-win
+from grass.script import parser
 from grass.script import core as grass
+import StringIO
+import subprocess as sub
 
+
 class GrassMD():
     def __init__(self, map, type):
 
-        self.map = map                    # name of choosen map by user
-        self.type = type                  # typ of map representation(cell, vector, r3)
-        self.isMapExist()                 # function to check if map exist
-        
-        self.md_grass = {}                # dict with metadata from r.info v.info  except "r.info flag=h"        
-        self.md_abstract = ''             # create abstract from self.md_grass - key: source1, source2 and descriptio etc.
-        self.md_vinfo_h = ''              # v.info flag=h" - parse
-        
-        self.gisenv_grass = grass.gisenv()# dict with gisenv information
-        
-        self.schema_type='_md_GRASS.xml'  # postfix of output xml file (variables)
+        self.map = map                    #name of choosen map by user
+        self.type = type                  #typ of map representation(cell, vector, r3)
+        self.isMapExist()                 #function to check if map exist
+        self.md_grass = {}                #dict with metadata from r.info v.info  except "r.info flag=h"        
+        self.md_abstract = ''             #create abstract from self.md_grass - key: source1, source2 and descriptio etc.
+        self.md_vinfo_h = ''              #v.info flag=h" - parse
+        self.gisenv_grass = grass.gisenv()#dict with gisenv information
+        self.schema_type='_md_GRASS.xml'  #postfix of output xml file (variables)
         self.dirpath = os.path.dirname(os.path.realpath(__file__))
-        self.md = MD_Metadata()            # metadata object from OWSLIB ( for define md values)
+        self.md = MD_Metadata(md=None)            #metadata object from OWSLIB ( for define md values)
+        self.template = None               #path to file with xml templates
         
-        self.template = None               # path to file with xml templates
-        
         if self.type == "cell":
             self.parseRast()
         elif self.type == "vector":
             self.parseVect()
-        elif self.type == "g3dcell":
-            self.parseRast3D() # TODO
-                        
+        elif self.type == "r3??":
+            #TODO   
+            self.parseRast3D()
+            
+            
     def isMapExist(self):
         '''Check if is the map in working mapset'''    
         self.mapset = grass.find_file(self.map, self.type)['mapset']
         if not self.mapset:
-            grass.fatal(_("Map <%s> not found"), self.map)
+            grass.fatal(_("Map <%s> doesn't exist"), self.map)
                    
     def readXML(self,xml_file):
-        '''Create instance of metadata(owslib) from xml file'''
+        '''create instance of metadata(owslib) from xml file'''
         self.md = MD_Metadata(etree.parse(xml_file))
         
     def parseRast3D(self):
@@ -77,11 +74,11 @@
         '''Read metadata from v.info
         #self.md_grass dictionary of metadata from v.info '''
         
-        # parse md from v.info -get (basic metadata)
+        #parse md from v.info flags=-g -e -t
         vinfo = Module('v.info', self.map, flags='get', quiet = True, stdout_=PIPE)
         self.md_grass = parse_key_val(vinfo.outputs.stdout)
         
-        # parse md from v.info flag -h (history of map in grass)
+        #parse md from v.info flag h (history of map in grass)
         rinfo_h = Module('v.info', self.map, flags='h', quiet = True, stdout_=PIPE)
         md_h_grass = rinfo_h.outputs.stdout
         buf = StringIO.StringIO(md_h_grass)
@@ -92,18 +89,19 @@
             line = buf.readline().splitlines()
         buf.close()
         
-        # change grass generated date format to iso format
-        # if date format is diverse from standard, use them
+        #change grass generated date format to iso format
+        #if date format is diverse from standard, use them
         self._createISODate('source_date')
             
     def _createISODate(self, key):
         '''Function for convert grass-generated date to iso format
            if the format of date is different to grass-generated format - use them and print warning  '''
+        
         try:
             date = datetime.strptime(self.md_grass[key], '%a %b %d %H:%M:%S %Y')
             self.md_grass['dateofcreation'] = date.strftime('%Y-%m-%d')
         except:
-            grass.warning(_('date of creation: unknown date format'))
+            grass.warning('date of creation: unknown date format')
             self.md_grass['dateofcreation'] = self.md_grass[key]
                                 
     def parseRast(self):
@@ -114,10 +112,10 @@
         rinfo = Module('r.info', self.map, flags='gre', quiet = True, stdout_=PIPE)
         self.md_grass = parse_key_val(rinfo.outputs.stdout)
                    
-        # convert date to iso format
+        #convert date to iso format
         self._createISODate('date')
             
-        # create abstract
+        #create abstract
         if self.md_grass['description'] != '""':
             self.md_abstract = self.md_grass['description'] + '\n'
         if self.md_grass['source1'] != '""':
@@ -127,6 +125,7 @@
         self.md_abstract += 'Total cells: '+ self.md_grass['cells']
         self.md_abstract += 'A range of values: min: ' + self.md_grass['min'] + '  max: ' + self.md_grass['max']
         
+
     def createGrassInspireISO(self):
         '''Create valid INSPIRE profile and fill it as much as possible by GRASS metadata. Missing values is $NULL
         -create basic md profile and add INSPIRE mandatory attributes
@@ -156,9 +155,7 @@
         self.md.identification.keywords.append(kw)
         # Conformity/Title 
         self.md.dataquality.conformancetitle.pop() #remove value from basic profile
-        self.md.dataquality.conformancetitle.append('Commission Regulation (EU) No 1089/2010 of 23 November 2010 implementing '
-                                                    'Directive 2007/2/EC of the European Parliament and of the Council as regards '
-                                                    'interoperability of spatial data sets and services')
+        self.md.dataquality.conformancetitle.append('Commission Regulation (EU) No 1089/2010 of 23 November 2010 implementing Directive 2007/2/EC of the European Parliament and of the Council as regards interoperability of spatial data sets and services')
         
         # Conformity/Date 
         self.md.dataquality.conformancedate.append(n)
@@ -183,9 +180,9 @@
         '''
         
         n = '$NULL'
-        # jinja templates
+        #jinja templates
         self.template = 'data/grassBasicISOTemplate.xml'
-        # OWSLib md object 
+        #OWSLib md object 
         self.md.identification = MD_DataIdentification()
         self.md.dataquality = DQ_DataQuality()
         self.md.distribution = MD_Distribution()
@@ -213,11 +210,11 @@
         self.md.identification.identtype = 'dataset'
         
         # Identification/Unique Resource Identifier 
-        # TODO GENERATOR
-        self.md.identifier = '286c0725-146e-4533-b1bf-d6e367f6c342' 
-        self.md.identification.uricode.append('286c0725-146e-4533-b1bf-d6e367f6c342')
+        #TODO GENERATOR
+        self.md.identifier = n 
+        self.md.identification.uricode.append(n)
         
-        # Geographic/BB
+        #Geographic/BB
         self.md.identification.extent.boundingBox.minx = self.md_grass['south']
         self.md.identification.extent.boundingBox.maxx = self.md_grass['north']
         self.md.identification.extent.boundingBox.miny = self.md_grass['west']
@@ -234,7 +231,7 @@
         val.type = 'creation'
         self.md.identification.date.append(val)
 
-        # Different metadata sources for vector and raster 
+        #different metadata sources for vector and raster 
         if self.type == 'cell':
             # Identification/Resource Abstract 
             self.md.identification.abstract = self.md_abstract
@@ -270,31 +267,31 @@
             xml_out_name = str(self.map) + self.schema_type
         if not xml_out_name.lower().endswith('.xml'):
             xml_out_name +='.xml'
-        # if path is None, use lunch. dir
-        # TODO change default folder to mapset location
+        #if path is None, use lunch. dir
+        #TODO change default folder to mapset location
         if not path:
-            path = os.path.join(os.getcwd(),xml_out_name)
+            path = os.path.join(self.dirpath,xml_out_name)
         else:
-            path = os.path.join(path, xml_out_name)
+            path = os.path.join(path,xml_out_name)
 
         #generate xml using jinja tempaltes
-        env = Environment(loader=FileSystemLoader(self.dirpath))
+        env = Environment(loader = FileSystemLoader(self.dirpath))
         env.globals.update(zip=zip)
         template = env.get_template(self.template)
         iso_xml = template.render(md=self.md)
         xml_file = xml_out_name
         
-        # write xml to flat file
+        #write xml to flat file
         try:
             xml_file = open(path, "w")
             xml_file.write(iso_xml)
             xml_file.close()
-            grass.message(_('Metadata exported: %s') % (str(path)))
+            Module('g.message', message='metadata exported: \n\
+                                         %s'%(str(path)))
         except IOError as e:
             print "I/O error({0}): {1}".format(e.errno, e.strerror)
-            grass.fatal(_('Unable to write xml file'))
-
-        return path
+            grass.fatal('error: cannot write xml file')
+        return  path
     
     def validate_inspire(self):
         '''function for validation INSPIRE XML file'''

Modified: sandbox/krejcmat/src/r.info.iso.py
===================================================================
--- sandbox/krejcmat/src/r.info.iso.py	2014-07-02 12:05:37 UTC (rev 61116)
+++ sandbox/krejcmat/src/r.info.iso.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -27,20 +27,20 @@
 #% answer: basic
 #%end
 
-#%option G_OPT_F_OUTPUT
-#% label: Name for output metadata file
-#% description: Default: /path/to/current/directory/<map>.xml
+#%option G_OPT_R_MAP
+#% key: mdout
+#% label: Name of output metadata file
 #% required: no
 #%end
 
 #%option G_OPT_M_DIR 
 #% key: destination
-#% description: Path to destination directory
+#% label: Path to destination folder
 #% required: no
 #%end
 
 from grass.script import parser
-from mdgrass import *
+from mdgrass import  *
 
 def main():
 
@@ -49,11 +49,12 @@
     else:
         destination = options['destination']
         
-    if not options['output']:
+    if not options['mdout']:
         mdout = None
     else:
-        mdout=options['output']    
-    
+        mdout=options['mdout']    
+  
+  
     md = GrassMD(options['map'], 'cell')        
     if options['profil']=='inspire':
         md.createGrassInspireISO()
@@ -63,9 +64,8 @@
     else:    
         md.createGrassBasicISO()
         md.saveXML(destination,mdout)
+    
 
-    return 0
-
 if __name__ == "__main__":
     options, flags = parser()
-    sys.exit(main())
+    main()

Added: sandbox/krejcmat/src/series.xml
===================================================================
--- sandbox/krejcmat/src/series.xml	                        (rev 0)
+++ sandbox/krejcmat/src/series.xml	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,562 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<gmd:MD_Metadata xmlns:gsr="http://www.isotc211.org/2005/gsr" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://eden.ign.fr/xsd/isotc211/isofull/20090316/gmx/gmx.xsd http://www.isotc211.org/2005/srv http://eden.ign.fr/xsd/isotc211/isofull/20090316/srv/srv.xsd">
+<gmd:fileIdentifier>
+<gco:CharacterString>d2bb041c-54c0-4808-bba8-268f474a9b37</gco:CharacterString>
+</gmd:fileIdentifier>
+<gmd:language>
+<LanguageCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng"/>
+</gmd:language>
+<gmd:hierarchyLevel>
+<MD_ScopeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_ScopeCode" codeListValue="series"/>
+</gmd:hierarchyLevel>
+<gmd:hierarchyLevelName>
+<gco:CharacterString>series</gco:CharacterString>
+</gmd:hierarchyLevelName>
+<gmd:contact>
+<gmd:CI_ResponsibleParty>
+<gmd:organisationName>
+<gco:CharacterString>Centre for Ecology & Hydrology</gco:CharacterString>
+</gmd:organisationName>
+<gmd:contactInfo>
+<gmd:CI_Contact>
+<gmd:address>
+<gmd:CI_Address>
+<gmd:deliveryPoint>
+<gco:CharacterString>Lancaster Environment Centre,  Library Avenue, Bailrigg</gco:CharacterString>
+</gmd:deliveryPoint>
+<gmd:city>
+<gco:CharacterString>Lancaster</gco:CharacterString>
+</gmd:city>
+<gmd:administrativeArea>
+<gco:CharacterString>Lancashire</gco:CharacterString>
+</gmd:administrativeArea>
+<gmd:postalCode>
+<gco:CharacterString>LA1 4AP</gco:CharacterString>
+</gmd:postalCode>
+<gmd:country>
+<gco:CharacterString>United Kingdom</gco:CharacterString>
+</gmd:country>
+<gmd:electronicMailAddress>
+<gco:CharacterString>enquiries at ceh.ac.uk</gco:CharacterString>
+</gmd:electronicMailAddress>
+</gmd:CI_Address>
+</gmd:address>
+</gmd:CI_Contact>
+</gmd:contactInfo>
+<gmd:role>
+<gmd:CI_RoleCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_RoleCode" codeListValue="pointOfContact">pointOfContact</gmd:CI_RoleCode>
+</gmd:role>
+</gmd:CI_ResponsibleParty>
+</gmd:contact>
+<gmd:dateStamp>
+      <gco:Date>2012-10-15</gco:Date>
+  </gmd:dateStamp>
+<gmd:metadataStandardName>
+<gco:CharacterString>INSPIRE Imaplementing Rules for Metadata</gco:CharacterString>
+</gmd:metadataStandardName>
+<gmd:metadataStandardVersion>
+<gco:CharacterString>1.2</gco:CharacterString>
+</gmd:metadataStandardVersion>
+<gmd:referenceSystemInfo>
+<gmd:MD_ReferenceSystem>
+<gmd:referenceSystemIdentifier>
+<gmd:RS_Identifier>
+<gmd:code>
+<gco:CharacterString>27700</gco:CharacterString>
+</gmd:code>
+<gmd:codeSpace>
+<gco:CharacterString>urn:ogc:def:crs:EPSG</gco:CharacterString>
+</gmd:codeSpace>
+<gmd:version>
+<gco:CharacterString>6.11.2</gco:CharacterString>
+</gmd:version>
+</gmd:RS_Identifier>
+</gmd:referenceSystemIdentifier>
+</gmd:MD_ReferenceSystem>
+</gmd:referenceSystemInfo>
+<gmd:identificationInfo>
+      <gmd:MD_DataIdentification>
+<gmd:citation>
+            <gmd:CI_Citation>
+<gmd:title>
+                  <gco:CharacterString>Candidate exemplar well-encoded series</gco:CharacterString>
+               </gmd:title>
+<gmd:alternateTitle>
+<gco:CharacterString>Source of testing template for series records</gco:CharacterString>
+</gmd:alternateTitle>
+<gmd:date>
+<gmd:CI_Date>
+<gmd:date>
+<gco:Date>2011-04-08</gco:Date>
+</gmd:date>
+<gmd:dateType>
+<CI_DateTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue="publication"/>
+</gmd:dateType>
+</gmd:CI_Date>
+</gmd:date>
+<gmd:identifier>
+<gmd:RS_Identifier>
+<gmd:code>
+<gco:CharacterString>1300392329602</gco:CharacterString>
+</gmd:code>
+<gmd:codeSpace>
+<gco:CharacterString>CEH:EIDC:</gco:CharacterString>
+</gmd:codeSpace>
+<gmd:version>
+<gco:CharacterString>1</gco:CharacterString>
+</gmd:version>
+</gmd:RS_Identifier>
+</gmd:identifier>
+<gmd:otherCitationDetails>
+<gco:CharacterString>R.D. Morton, C. Rowland, C. Wood, L. Meek, C. Marston, G. Smith, R. Wadsworth, I. Simpson.  July 2011  CS Technical Report No 11/07: Final Report for LCM2007 - the new UK land cover map.  NERC/Centre for Ecology & Hydrology (CEH Project Number NEC03259).</gco:CharacterString>
+</gmd:otherCitationDetails>
+</gmd:CI_Citation>
+         </gmd:citation>
+<gmd:abstract>
+            <gco:CharacterString>This test record should pass XSD, ISO19139 Schematron, and GEMINI2.1 Schematron validation. Please note that this record is only for testing software and encoding of XML - it is not an example of a well-described dataset series, and must not be used as an example of how to document data series! This record is referenced by the record with UUID 9e7790ab-a37d-4918-8107-5c427798ca68 catalogues that enable Metadata Parent Identifier can exploit that element to navigate between series and dataset.</gco:CharacterString>
+         </gmd:abstract>
+<gmd:status>
+<MD_ProgressCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_ProgressCode" codeListValue="completed"/>
+</gmd:status>
+<gmd:pointOfContact>
+<gmd:CI_ResponsibleParty>
+<gmd:individualName>
+<gco:CharacterString>Morton, D</gco:CharacterString>
+</gmd:individualName>
+<gmd:organisationName>
+<gco:CharacterString>Centre for Ecology & Hydrology</gco:CharacterString>
+</gmd:organisationName>
+<gmd:contactInfo>
+<gmd:CI_Contact>
+<gmd:address>
+<gmd:CI_Address>
+<gmd:deliveryPoint>
+<gco:CharacterString>Lancaster Environment Centre,  Library Avenue, Bailrigg</gco:CharacterString>
+</gmd:deliveryPoint>
+<gmd:city>
+<gco:CharacterString>Lancaster</gco:CharacterString>
+</gmd:city>
+<gmd:administrativeArea>
+<gco:CharacterString>Lancashire</gco:CharacterString>
+</gmd:administrativeArea>
+<gmd:postalCode>
+<gco:CharacterString>LA1 4AP</gco:CharacterString>
+</gmd:postalCode>
+<gmd:country>
+<gco:CharacterString>United Kingdom</gco:CharacterString>
+</gmd:country>
+<gmd:electronicMailAddress>
+<gco:CharacterString>danm at ceh.ac.uk </gco:CharacterString>
+</gmd:electronicMailAddress>
+</gmd:CI_Address>
+</gmd:address>
+</gmd:CI_Contact>
+</gmd:contactInfo>
+<gmd:role>
+<gmd:CI_RoleCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_RoleCode" codeListValue="pointOfContact">pointOfContact</gmd:CI_RoleCode>
+</gmd:role>
+</gmd:CI_ResponsibleParty>
+</gmd:pointOfContact>
+<gmd:pointOfContact>
+<gmd:CI_ResponsibleParty>
+<gmd:organisationName>
+<gco:CharacterString>Parr Section</gco:CharacterString>
+</gmd:organisationName>
+<gmd:contactInfo>
+<gmd:CI_Contact>
+<gmd:address>
+<gmd:CI_Address>
+<gmd:electronicMailAddress>
+<gco:CharacterString>enquiries at ceh.ac.uk</gco:CharacterString>
+</gmd:electronicMailAddress>
+</gmd:CI_Address>
+</gmd:address>
+</gmd:CI_Contact>
+</gmd:contactInfo>
+<gmd:role>
+<gmd:CI_RoleCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_RoleCode" codeListValue="resourceProvider">resourceProvider</gmd:CI_RoleCode>
+</gmd:role>
+</gmd:CI_ResponsibleParty>
+</gmd:pointOfContact>
+<gmd:resourceMaintenance>
+<gmd:MD_MaintenanceInformation>
+<gmd:maintenanceAndUpdateFrequency>
+<MD_MaintenanceFrequencyCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_MaintenanceFrequencyCode" codeListValue="notPlanned"/>
+</gmd:maintenanceAndUpdateFrequency>
+<gmd:maintenanceNote>
+<gco:CharacterString>There are no plans to update this series</gco:CharacterString>
+</gmd:maintenanceNote>
+</gmd:MD_MaintenanceInformation>
+</gmd:resourceMaintenance>
+<gmd:graphicOverview>
+<gmd:MD_BrowseGraphic>
+<gmd:fileName>
+<gco:CharacterString>https://gateway.ceh.ac.uk:443/smartEditor/preview/82a0f4a1-01ff-4ed1-853e-224d8404b3fd.png</gco:CharacterString>
+</gmd:fileName>
+<gmd:fileDescription>
+<gco:CharacterString>thumbnail preview</gco:CharacterString>
+</gmd:fileDescription>
+</gmd:MD_BrowseGraphic>
+</gmd:graphicOverview>
+<gmd:descriptiveKeywords>
+<gmd:MD_Keywords>
+<gmd:keyword>
+<gco:CharacterString>Habitats and biotopes</gco:CharacterString>
+</gmd:keyword>
+<gmd:type>
+<MD_KeywordTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="theme"/>
+</gmd:type>
+<gmd:thesaurusName>
+<gmd:CI_Citation>
+<gmd:title>
+<gco:CharacterString>GEMET - INSPIRE themes, version 1.0</gco:CharacterString>
+</gmd:title>
+<gmd:date>
+<gmd:CI_Date>
+<gmd:date>
+<gco:Date>2008-06-01</gco:Date>
+</gmd:date>
+<gmd:dateType>
+<CI_DateTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="CI_DateTypeCode" codeListValue="publication"/>
+</gmd:dateType>
+</gmd:CI_Date>
+</gmd:date>
+</gmd:CI_Citation>
+</gmd:thesaurusName>
+</gmd:MD_Keywords>
+</gmd:descriptiveKeywords>
+<gmd:descriptiveKeywords>
+<gmd:MD_Keywords>
+<gmd:keyword>
+<gco:CharacterString>Great Britain</gco:CharacterString>
+</gmd:keyword>
+<gmd:keyword>
+<gco:CharacterString>England</gco:CharacterString>
+</gmd:keyword>
+<gmd:keyword>
+<gco:CharacterString>Scotland Wales</gco:CharacterString>
+</gmd:keyword>
+<gmd:type>
+<MD_KeywordTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="place"/>
+</gmd:type>
+</gmd:MD_Keywords>
+</gmd:descriptiveKeywords>
+<gmd:descriptiveKeywords>
+<gmd:MD_Keywords>
+<gmd:keyword>
+<gco:CharacterString>CEH Biodiversity Programme</gco:CharacterString>
+</gmd:keyword>
+<gmd:type>
+<MD_KeywordTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="discipline"/>
+</gmd:type>
+</gmd:MD_Keywords>
+</gmd:descriptiveKeywords>
+<gmd:descriptiveKeywords>
+<gmd:MD_Keywords>
+<gmd:keyword>
+<gco:CharacterString>CEH Project NEC03259</gco:CharacterString>
+</gmd:keyword>
+<gmd:keyword>
+<gco:CharacterString>NERC_DDC</gco:CharacterString>
+</gmd:keyword>
+<gmd:keyword>
+<gco:CharacterString>LCM2007</gco:CharacterString>
+</gmd:keyword>
+<gmd:type>
+<MD_KeywordTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="discipline"/>
+</gmd:type>
+</gmd:MD_Keywords>
+</gmd:descriptiveKeywords>
+<gmd:descriptiveKeywords>
+<gmd:MD_Keywords>
+<gmd:keyword>
+<gmx:Anchor xlink:href="http://vocabs.lter-europe.net/EnvThes/EUNIS_FA">Hedgerows</gmx:Anchor>
+</gmd:keyword>
+<gmd:type>
+<MD_KeywordTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_KeywordTypeCode" codeListValue="theme"/>
+</gmd:type>
+</gmd:MD_Keywords>
+</gmd:descriptiveKeywords>
+<gmd:resourceConstraints>
+<gmd:MD_LegalConstraints>
+<gmd:useLimitation>
+<gco:CharacterString>Refer to: R.D. Morton, C. Rowland, C. Wood, L. Meek, C. Marston, G. Smith, R. Wadsworth, I. Simpson.  July 2011  CS Technical Report No 11/07: Final Report for LCM2007 - the new UK land cover map.  NERC/Centre for Ecology & Hydrology (CEH Project Number NEC03259).</gco:CharacterString>
+</gmd:useLimitation>
+<gmd:accessConstraints>
+<MD_RestrictionCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_RestrictionCode" codeListValue="license"/>
+</gmd:accessConstraints>
+<gmd:accessConstraints>
+<MD_RestrictionCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_RestrictionCode" codeListValue="otherRestrictions"/>
+</gmd:accessConstraints>
+<gmd:otherConstraints>
+<gco:CharacterString>Licence terms and conditions apply</gco:CharacterString>
+</gmd:otherConstraints>
+<gmd:otherConstraints>
+<gmx:Anchor xlink:href="http://www.ceh.ac.uk">Test Link</gmx:Anchor>
+</gmd:otherConstraints>
+</gmd:MD_LegalConstraints>
+</gmd:resourceConstraints>
+<gmd:spatialRepresentationType>
+<MD_SpatialRepresentationTypeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_SpatialRepresentationTypeCode" codeListValue="grid"/>
+</gmd:spatialRepresentationType>
+<gmd:spatialResolution>
+<gmd:MD_Resolution>
+<gmd:distance>
+<gco:Distance uom="m">1</gco:Distance>
+</gmd:distance>
+</gmd:MD_Resolution>
+</gmd:spatialResolution>
+<gmd:language>
+<LanguageCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng"/>
+</gmd:language>
+<gmd:topicCategory>
+<gmd:MD_TopicCategoryCode>environment</gmd:MD_TopicCategoryCode>
+</gmd:topicCategory>
+<gmd:topicCategory>
+<gmd:MD_TopicCategoryCode>imageryBaseMapsEarthCover</gmd:MD_TopicCategoryCode>
+</gmd:topicCategory>
+<gmd:extent>
+<gmd:EX_Extent>
+<gmd:geographicElement>
+<gmd:EX_GeographicDescription>
+<gmd:geographicIdentifier>
+<gmd:RS_Identifier>
+<gmd:code>
+<gco:CharacterString>ENG</gco:CharacterString>
+</gmd:code>
+<gmd:codeSpace>
+<gco:CharacterString>ISO 3166</gco:CharacterString>
+</gmd:codeSpace>
+<gmd:version>
+<gco:CharacterString>2006, edition 2</gco:CharacterString>
+</gmd:version>
+</gmd:RS_Identifier>
+</gmd:geographicIdentifier>
+</gmd:EX_GeographicDescription>
+</gmd:geographicElement>
+</gmd:EX_Extent>
+</gmd:extent>
+<gmd:extent>
+<gmd:EX_Extent>
+<gmd:geographicElement>
+<gmd:EX_GeographicDescription>
+<gmd:geographicIdentifier>
+<gmd:RS_Identifier>
+<gmd:code>
+<gco:CharacterString>WLS</gco:CharacterString>
+</gmd:code>
+<gmd:codeSpace>
+<gco:CharacterString>ISO 3166</gco:CharacterString>
+</gmd:codeSpace>
+<gmd:version>
+<gco:CharacterString>2006, edition 2</gco:CharacterString>
+</gmd:version>
+</gmd:RS_Identifier>
+</gmd:geographicIdentifier>
+</gmd:EX_GeographicDescription>
+</gmd:geographicElement>
+</gmd:EX_Extent>
+</gmd:extent>
+<gmd:extent>
+<gmd:EX_Extent>
+<gmd:geographicElement>
+<gmd:EX_GeographicDescription>
+<gmd:geographicIdentifier>
+<gmd:RS_Identifier>
+<gmd:code>
+<gco:CharacterString>SCT</gco:CharacterString>
+</gmd:code>
+<gmd:codeSpace>
+<gco:CharacterString>ISO 3166</gco:CharacterString>
+</gmd:codeSpace>
+<gmd:version>
+<gco:CharacterString>2006, edition 2</gco:CharacterString>
+</gmd:version>
+</gmd:RS_Identifier>
+</gmd:geographicIdentifier>
+</gmd:EX_GeographicDescription>
+</gmd:geographicElement>
+</gmd:EX_Extent>
+</gmd:extent>
+<gmd:extent>
+<gmd:EX_Extent>
+<gmd:temporalElement>
+<gmd:EX_TemporalExtent>
+<gmd:extent>
+<gml:TimePeriod gml:id="w5839aaa">
+<gml:beginPosition>2000-10-01</gml:beginPosition>
+<gml:endPosition>2012-10-01</gml:endPosition>
+</gml:TimePeriod>
+</gmd:extent>
+</gmd:EX_TemporalExtent>
+</gmd:temporalElement>
+</gmd:EX_Extent>
+</gmd:extent>
+<gmd:extent>
+<gmd:EX_Extent>
+<gmd:geographicElement>
+<gmd:EX_GeographicBoundingBox>
+<gmd:extentTypeCode>
+<gco:Boolean>true</gco:Boolean>
+</gmd:extentTypeCode>
+<gmd:westBoundLongitude>
+<gco:Decimal>-9.227701</gco:Decimal>
+</gmd:westBoundLongitude>
+<gmd:eastBoundLongitude>
+<gco:Decimal>2.687637</gco:Decimal>
+</gmd:eastBoundLongitude>
+<gmd:southBoundLatitude>
+<gco:Decimal>49.83726</gco:Decimal>
+</gmd:southBoundLatitude>
+<gmd:northBoundLatitude>
+<gco:Decimal>60.850441</gco:Decimal>
+</gmd:northBoundLatitude>
+</gmd:EX_GeographicBoundingBox>
+</gmd:geographicElement>
+</gmd:EX_Extent>
+</gmd:extent>
+<gmd:supplementalInformation>
+<gco:CharacterString>For further information about this test record, please contact eidchub at ceh.ac.uk</gco:CharacterString>
+</gmd:supplementalInformation>
+</gmd:MD_DataIdentification>
+  </gmd:identificationInfo>
+<gmd:distributionInfo>
+      <gmd:MD_Distribution>
+<gmd:distributionFormat>
+<gmd:MD_Format>
+<gmd:name>
+<gco:CharacterString>GeoTIFF</gco:CharacterString>
+</gmd:name>
+<gmd:version>
+<gco:CharacterString>1.0</gco:CharacterString>
+</gmd:version>
+</gmd:MD_Format>
+</gmd:distributionFormat>
+<gmd:distributor>
+<gmd:MD_Distributor>
+<gmd:distributorContact>
+<gmd:CI_ResponsibleParty>
+<gmd:organisationName>
+<gco:CharacterString>Centre for Ecology & Hydrology</gco:CharacterString>
+</gmd:organisationName>
+<gmd:contactInfo>
+<gmd:CI_Contact>
+<gmd:address>
+<gmd:CI_Address>
+<gmd:deliveryPoint>
+<gco:CharacterString>Maclean Building, Benson Lane, Crowmarsh Gifford</gco:CharacterString>
+</gmd:deliveryPoint>
+<gmd:city>
+<gco:CharacterString>Wallingford</gco:CharacterString>
+</gmd:city>
+<gmd:administrativeArea>
+<gco:CharacterString>Oxfordshire </gco:CharacterString>
+</gmd:administrativeArea>
+<gmd:postalCode>
+<gco:CharacterString>OX10 8BB</gco:CharacterString>
+</gmd:postalCode>
+<gmd:country>
+<gco:CharacterString>United Kingdom</gco:CharacterString>
+</gmd:country>
+<gmd:electronicMailAddress>
+<gco:CharacterString>enquiries at ceh.ac.uk</gco:CharacterString>
+</gmd:electronicMailAddress>
+</gmd:CI_Address>
+</gmd:address>
+</gmd:CI_Contact>
+</gmd:contactInfo>
+<gmd:role>
+<gmd:CI_RoleCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_RoleCode" codeListValue="distributor">distributor</gmd:CI_RoleCode>
+</gmd:role>
+</gmd:CI_ResponsibleParty>
+</gmd:distributorContact>
+</gmd:MD_Distributor>
+</gmd:distributor>
+<gmd:transferOptions>
+<gmd:MD_DigitalTransferOptions>
+<gmd:onLine>
+<gmd:CI_OnlineResource>
+<gmd:linkage>
+<gmd:URL>http://www.ceh.ac.uk/LandCoverMap2007.html</gmd:URL>
+</gmd:linkage>
+<gmd:name>
+<gco:CharacterString>Essential technical details</gco:CharacterString>
+</gmd:name>
+<gmd:description>
+<gco:CharacterString>Link to further technical details about this data</gco:CharacterString>
+</gmd:description>
+<gmd:function>
+<CI_OnLineFunctionCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_OnLineFunctionCode" codeListValue="information"/>
+</gmd:function>
+</gmd:CI_OnlineResource>
+</gmd:onLine>
+</gmd:MD_DigitalTransferOptions>
+</gmd:transferOptions>
+<gmd:transferOptions>
+<gmd:MD_DigitalTransferOptions>
+<gmd:onLine>
+<gmd:CI_OnlineResource>
+<gmd:linkage>
+<gmd:URL>http://www.countrysidesurvey.org.uk/</gmd:URL>
+</gmd:linkage>
+<gmd:name>
+<gco:CharacterString>Countryside Survey website</gco:CharacterString>
+</gmd:name>
+<gmd:description>
+<gco:CharacterString>Countryside Survey website</gco:CharacterString>
+</gmd:description>
+<gmd:function>
+<CI_OnLineFunctionCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_OnLineFunctionCode" codeListValue="information"/>
+</gmd:function>
+</gmd:CI_OnlineResource>
+</gmd:onLine>
+</gmd:MD_DigitalTransferOptions>
+</gmd:transferOptions>
+<gmd:transferOptions>
+<gmd:MD_DigitalTransferOptions>
+<gmd:onLine>
+<gmd:CI_OnlineResource>
+<gmd:linkage>
+<gmd:URL>http://cs2007.ceh.ac.uk/sites/default/files/LCM2007%20Final%20Report%20-%20vCS%20Web.pdf</gmd:URL>
+</gmd:linkage>
+<gmd:name>
+<gco:CharacterString>CS Technical Report</gco:CharacterString>
+</gmd:name>
+<gmd:description>
+<gco:CharacterString>Final Report for LCM2007 - the new UK Land Cover Map</gco:CharacterString>
+</gmd:description>
+<gmd:function>
+<CI_OnLineFunctionCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_OnLineFunctionCode" codeListValue="information"/>
+</gmd:function>
+</gmd:CI_OnlineResource>
+</gmd:onLine>
+</gmd:MD_DigitalTransferOptions>
+</gmd:transferOptions>
+</gmd:MD_Distribution>
+   </gmd:distributionInfo>
+<gmd:dataQualityInfo>
+<gmd:DQ_DataQuality>
+<gmd:scope>
+<gmd:DQ_Scope>
+<gmd:level>
+<MD_ScopeCode xmlns="http://www.isotc211.org/2005/gmd" codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_ScopeCode" codeListValue="series"/>
+</gmd:level>
+<gmd:levelDescription>
+<gmd:MD_ScopeDescription>
+<gmd:other>
+<gco:CharacterString>series</gco:CharacterString>
+</gmd:other>
+</gmd:MD_ScopeDescription>
+</gmd:levelDescription>
+</gmd:DQ_Scope>
+</gmd:scope>
+<gmd:lineage>
+<gmd:LI_Lineage>
+<gmd:statement>
+<gco:CharacterString>LCM2007 uses a spatial framework based on OS MasterMap (R). MasterMap was generalised to remove unnecessary detail, then the framework was segmented according to the underlying satellite data to split areas of non-uniform landscape. The data was classified according to a parcel-based supervised maximum likelihood classification procedure. The raster products are derived from the vector products. </gco:CharacterString>
+</gmd:statement>
+</gmd:LI_Lineage>
+</gmd:lineage>
+</gmd:DQ_DataQuality>
+</gmd:dataQualityInfo>
+</gmd:MD_Metadata>
\ No newline at end of file


Property changes on: sandbox/krejcmat/src/series.xml
___________________________________________________________________
Added: svn:executable
   + *

Added: sandbox/krejcmat/src/test.py
===================================================================
--- sandbox/krejcmat/src/test.py	                        (rev 0)
+++ sandbox/krejcmat/src/test.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+"""
+MODULE:    g.gui.metadata
+
+AUTHOR(S): Matej Krejci <matejkrejci gmail.com>
+
+PURPOSE:   Module for editing metadata based on ISO
+
+COPYRIGHT: (C) 2014 Matej Krejci, and 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.
+"""
+
+import wx 
+
+class MDItem(wx.Panel):
+    def __init__(self,parent,  label, info=None, multiple=False): 
+        wx.Panel.__init__(self, parent=parent,id=wx.ID_ANY)
+        self.label=label
+        self.multiple=multiple
+        self.info=info
+    
+        self._initWidgets()
+        self._layout()
+        
+    def _initWidgets(self):
+        self.tagText= wx.StaticText(parent=self,id=wx.ID_ANY,label=self.label)
+        self.valueCtrl = wx.TextCtrl(self, id=wx.ID_ANY,  
+                                   style=wx.VSCROLL | 
+                                   wx.TE_MULTILINE | wx.TE_DONTWRAP | 
+                                   wx.TAB_TRAVERSAL|wx.RAISED_BORDER|wx.HSCROLL) 
+        if self.multiple:
+
+            self.addItemButt=wx.Button(self,-1,size=(20,20),label='+')
+        #self.addInfoButt=wx.Button(self,-1,size=(20,20),label='I')
+        
+    def _layout(self):
+        #add V-sizer to panel
+        panelSizer=wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(panelSizer)
+        
+        #add text-ctrl and button to H-sizer
+        textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)  
+        textFieldSizer.Add(self.valueCtrl,proportion=1,flag=wx.EXPAND)
+        if self.multiple:
+            textFieldSizer.Add(self.addItemButt,0)
+        
+        #add staticText, textFieldSizer to static box sizer
+        panelSizer.Add(item=self.tagText,proportion=0)
+        panelSizer.Add(item=textFieldSizer,proportion=1,flag=wx.EXPAND)
+
+class Box(wx.Panel):
+    def __init__(self,parent, boxLabel,boxMultiplicity=False): 
+        wx.Panel.__init__(self,parent=parent,id= wx.ID_ANY)
+
+        self.stboxLabel=boxLabel
+        self.boxMultiplicity=boxMultiplicity
+
+        self.stbox=wx.StaticBox(self, label=boxLabel, style=wx.RAISED_BORDER)
+        if boxMultiplicity:
+            self.boxMultiplicity=boxMultiplicity  
+            self.addBoxButt=wx.Button(self,-1,size=(20,20),label='+') 
+        self.fill()
+        self._layout()              
+        self._fillBox()
+    
+    def fill(self):
+        list=['1','2','3']
+        self.MDitems=[]
+        for i in list:
+            it=MDItem(self ,i, True,True)
+            self.MDitems.append(it)
+    
+    def _layout(self):
+        panelSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.SetSizer(panelSizer)
+        
+        self.stBoxSizer = wx.StaticBoxSizer( self.stbox, wx.VERTICAL)
+        panelSizer.Add(item=self.stBoxSizer,flag=wx.EXPAND,proportion=1)
+        
+        if self.boxMultiplicity:
+            panelSizer.Add(self.addBoxButt,0)
+            
+    def _fillBox(self):
+        for item in self.MDitems:
+
+            self.stBoxSizer.Add(item=item,proportion=1,flag=wx.EXPAND)
+          
+            
+class MainFrame(wx.Frame):
+    def __init__(self, parent, ID, title):
+        wx.Frame.__init__(self, parent, ID,title,
+                          wx.DefaultPosition, wx.Size(600, 400)) 
+        
+        self.panel = wx.Panel(self, -1) 
+        
+        self.bb=Box(self.panel,"boxLabel", True)
+            
+        self._layout()
+        self._boxLayout()
+          
+    def _layout(self):
+        topSizer = wx.BoxSizer(wx.VERTICAL)
+        self.SetSizer(topSizer)
+        topSizer.Add(item=self.panel, proportion=1,flag=wx.EXPAND)
+        
+    def _boxLayout(self):        
+        panelSizer=wx.BoxSizer(wx.HORIZONTAL)
+        self.panel.SetSizer(panelSizer)
+        panelSizer.Add(self.bb,proportion=1,flag=wx.EXPAND)  
+        #panelSizer.Add(self.MDitems[0],proportion=1,flag=wx.EXPAND)
+
+         
+#===============================================================================
+# class MainFrame(wx.Frame):
+#     def __init__(self, parent, ID, title):
+#         wx.Frame.__init__(self, parent, ID, title,
+#                           wx.DefaultPosition, wx.Size(600, 400))
+# 
+#         self.numgroup=2
+#         self.namegroup='Identifiacation'
+#         tag='resource title'
+# 
+#         self.panel = wx.Panel(self, -1)
+#         self.tagText= wx.StaticText(parent=self.panel,id=wx.ID_ANY,label=tag)
+#         self.valueCtrl = wx.TextCtrl(self.panel, id=wx.ID_ANY,
+#                                    style=wx.VSCROLL |
+#                                    wx.TE_MULTILINE | wx.TE_DONTWRAP |
+#                                     wx.TAB_TRAVERSAL|wx.RAISED_BORDER|wx.HSCROLL)
+#         self.addItemButt=wx.Button(self.panel,-1,size=(20,20),label='+')
+#         self.addInfoButt=wx.Button(self.panel,-1,size=(20,20),label='i')
+#         self.addBoxButt=wx.Button(self.panel,-1,size=(20,20),label='+')
+#         self._layout()
+# 
+#     def _layout(self):
+#         add panel to V-sizer
+#         topSizer = wx.BoxSizer(wx.VERTICAL)
+#         self.SetSizer(topSizer)
+#         topSizer.Add(item=self.panel, proportion=1,flag=wx.EXPAND)
+# 
+#         add V-sizer to panel
+#         panelSizer=wx.BoxSizer(wx.HORIZONTAL)
+#         self.panel.SetSizer(panelSizer)
+# 
+#         add text-ctrl and button to H-sizer
+#         textFieldSizer = wx.BoxSizer(wx.HORIZONTAL)
+#         textFieldSizer.Add(self.valueCtrl,proportion=1,flag=wx.EXPAND)
+#         textFieldSizer.Add(self.addItemButt,0)
+#         textFieldSizer.Add(self.addInfoButt,0)
+# 
+#         create StaticBox
+#         stBox = wx.StaticBox(self.panel, wx.ID_ANY, label=self.namegroup, style=wx.RAISED_BORDER)
+#         stBoxSizer = wx.StaticBoxSizer(stBox, wx.VERTICAL)
+# 
+# 
+#         add staticText, textFieldSizer to static box sizer
+#         stBoxSizer.Add(item=self.tagText,proportion=0)
+#         stBoxSizer.Add(item=textFieldSizer,proportion=1,flag=wx.EXPAND)
+#         panelSizer.Add(stBoxSizer, proportion=1,flag=wx.EXPAND)
+#         panelSizer.Add(self.addBoxButt,0)
+#===============================================================================
+        
+class MyApp(wx.App): 
+    def OnInit(self): 
+        Frame = MainFrame(None, -1, "Frame") 
+        Frame.Show(True) 
+        self.SetTopWindow(Frame) 
+        return True 
+
+if __name__ == '__main__': 
+    App = MyApp(0) 
+    App.MainLoop() 
+
+     
\ No newline at end of file


Property changes on: sandbox/krejcmat/src/test.py
___________________________________________________________________
Added: svn:executable
   + *

Added: sandbox/krejcmat/src/test2.py
===================================================================
--- sandbox/krejcmat/src/test2.py	                        (rev 0)
+++ sandbox/krejcmat/src/test2.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -0,0 +1,147 @@
+from owslib.iso import *
+from owslib.util import xml_to_dict
+from lxml import etree as ET
+import xml.etree.ElementTree as ElementTree
+from jinjainfo  import JinjaTemplateInfo as jt
+
+from jinja2 import Environment, FileSystemLoader
+import jinja2
+
+from jinja2 import BaseLoader, TemplateNotFound
+from os.path import join, exists, getmtime
+import os
+
+    
+def jinja():
+        dirpath =os.path.dirname(os.path.realpath(__file__))
+        
+        env = Environment(loader=FileSystemLoader(dirpath))
+        
+        template=jinja2.Template('data/grassInspireTemplate01.xml')
+        #template.globals['context'] = get_context
+        #print template.debug_info()
+        #loader.get_source(env, 'data/grassInspireTemplate01.xml')
+        #------------------------------------------- env.globals.update(zip=zip)
+        #--------------------------------- template = env.get_template(template)
+        #--------------------------------- iso_xml = template.render(md=self.md)
+        #----------------------------------------------- xml_file = xml_out_name
+    
+
+def main():
+    jinj = jt('data/grassInspireTemplate01.xml')
+    #print jinj.md_info[0].name
+    print jinj.getObjectsString()
+    
+    
+    tree = ET.parse('series.xml')
+    root = tree.getroot()
+    md = MD_Metadata(root)
+    #print md.identification.extent.boundingBox.maxy 
+
+    string=util.xml_to_dict(root)
+
+
+def printDict(tel):
+    for key in tel:
+        for num in tel[key]:
+            print ''.join(str(n) for n in num)
+def xml(root,):    
+    #print "tag=%s, attrib=%s" % (root.tag, root.attrib)
+    for child in root:
+        print child.tag, child.attrib
+        if child.tag == "appointment":
+            for step_child in child:
+                print step_child.tag
+    
+    #iterate over the entire tree
+    print "-" * 40
+    print "Iterating using a tree iterator"
+    print "-" * 40
+    iter_ = tree.getiterator()
+    for elem in iter_:
+        print elem.tag
+
+
+    # get the information via the children!
+    print "-" * 40
+    print "Iterating using getchildren()"
+    print "-" * 40
+    appointments = root.getchildren()
+    for appointment in appointments:
+        appt_children = appointment.getchildren()
+        for appt_child in appt_children:
+            print "%s=%s" % (appt_child.tag, appt_child.text)    
+   # print md.identification
+    
+ ##############################################################################################################   
+ ##############################################################################################################   
+def xmltodict(element):
+    if not isinstance(element, ElementTree.Element):
+        raise ValueError("must pass xml.etree.ElementTree.Element object")
+
+    def xmltodict_handler(parent_element):
+        result = dict()
+        for element in parent_element:
+            if len(element):
+                obj = xmltodict_handler(element)
+            else:
+                obj = element.text
+
+            if result.get(element.tag):
+                if hasattr(result[element.tag], "append"):
+                    result[element.tag].append(obj)
+                else:
+                    result[element.tag] = [result[element.tag], obj]
+            else:
+                result[element.tag] = obj
+        return result
+
+    return {element.tag: xmltodict_handler(element)}
+
+
+def dicttoxml(element):
+    if not isinstance(element, dict):
+        raise ValueError("must pass dict type")
+    if len(element) != 1:
+        raise ValueError("dict must have exactly one root key")
+
+    def dicttoxml_handler(result, key, value):
+        if isinstance(value, list):
+            for e in value:
+                dicttoxml_handler(result, key, e)
+        elif isinstance(value, basestring):
+            elem = ElementTree.Element(key)
+            elem.text = value
+            result.append(elem)
+        elif isinstance(value, int) or isinstance(value, float):
+            elem = ElementTree.Element(key)
+            elem.text = str(value)
+            result.append(elem)
+        elif value is None:
+            result.append(ElementTree.Element(key))
+        else:
+            res = ElementTree.Element(key)
+            for k, v in value.items():
+                dicttoxml_handler(res, k, v)
+            result.append(res)
+
+    result = ElementTree.Element(element.keys()[0])
+    for key, value in element[element.keys()[0]].items():
+        dicttoxml_handler(result, key, value)
+    return result
+
+def xmlfiletodict(filename):
+    return xmltodict(ElementTree.parse(filename).getroot())
+
+def dicttoxmlfile(element, filename):
+    ElementTree.ElementTree(dicttoxml(element)).write(filename)
+
+def xmlstringtodict(xmlstring):
+    return xmltodict(ElementTree.fromstring(xmlstring).getroot())
+
+def dicttoxmlstring(element):
+    return ElementTree.tostring(dicttoxml(element))        
+        
+        
+if __name__ == "__main__":
+    main() 
\ No newline at end of file

Modified: sandbox/krejcmat/src/v.info.iso.py
===================================================================
--- sandbox/krejcmat/src/v.info.iso.py	2014-07-02 12:05:37 UTC (rev 61116)
+++ sandbox/krejcmat/src/v.info.iso.py	2014-07-02 14:52:33 UTC (rev 61117)
@@ -27,21 +27,20 @@
 #% answer: basic
 #%end
 
-#%option G_OPT_F_OUTPUT
-#% label: Name for output metadata file
-#% description: Default: /path/to/current/directory/<map>.xml
+#%option G_OPT_V_MAP
+#% key: mdout
+#% label: Name of output metadata file
 #% required: no
 #%end
 
 #%option G_OPT_M_DIR 
 #% key: destination
-#% description: Path to destination directory
+#% label: Path to destination folder
 #% required: no
 #%end
 
 from grass.script import parser
 from mdgrass import  *
-
 def main():
 
     if not options['destination']:
@@ -49,24 +48,23 @@
     else:
         destination = options['destination']
         
-    if not options['output']:
+    if not options['mdout']:
         mdout = None
     else:
-        mdout=options['output']   
+        mdout=options['mdout']   
     
-    # create instance of metadata in owslib
+    #create instance of metadata in owslib
     md = GrassMD(options['map'], 'vector') 
            
     if options['profil']=='inspire':
         md.createGrassInspireISO()
-        xml_file=md.saveXML(options['destination'],mdout)
+        xml_file=md.saveXML(options['destination'],options['mdout'])
         md.readXML(xml_file)
+        print md.validate_inspire()
     else:    
         md.createGrassBasicISO()
-        md.saveXML(options['destination'],mdout)
+        md.saveXML(options['destination'],options['mdout'])
     
-    return 0
-
 if __name__ == "__main__":
     options, flags = parser()
-    sys.exit(main())
+    main()



More information about the grass-commit mailing list