[Community] Adding fieldname parsing to WFS

Dominic Lowe dominic.lowe at stfc.ac.uk
Fri Mar 13 17:30:20 EET 2009


Jim,

Many thanks for this contribution. I'm glad you are finding OWSLib useful.

I'm not that familiar with all the details of WFS so it's great to get these 
gaps in OWSlib filled - could you point me to a server where I can see 
the "fieldnames" so I can get a better idea of what your code does and we 
have something to test it against? 

One thing I would say is that in owslib we've made extensive use of the python 
property() method. This provides a mechanism to populate attributes as we 
need them and to silently call methods. So ideally we shouldn't be 
introducing new methods such as getFieldnames(), just introduce new 
attributes.

An approach more in keeping would be:

>>> layer=wfs['wfs:LEVEL1']       #I think this selection approach is 
implemented in the wfs module now?
>>> print layer.fieldnames   #i.e. fieldnames is another attribute of the 
contents layers

So you don't need to populate all the 'fieldnames' attributes up front as this 
is done on the fly with the python property() method.

This could be implemented as part of the ContentMetadata (??) class using 
something like:

def _getFieldnames(self)
   # call your functions to get the fieldnames:
   return self._fieldnames
fieldnames = property(_getcapproperty, None)

For an example see lines 88-95 here:
http://trac.gispython.org/lab/browser/OWSLib/trunk/owslib/wms.py

The question mark after "ContentMetadata" above is because I'm still not quite 
sure where in WFS fieldnames comes in so if you could possibly send me a 
suitable WFS URL to test your code on that would be great. 

Cheers,
Dom


On Thursday 12 March 2009 16:11:38 Jim Strevinas wrote:
> Hello, a part of my web-app needed the implementation of a client that can
> connect to OWS datastores in order to fetch layers that can be used
> directly in MapServer mapfiles (Being that my web app is written in python
> OWSLib is ideal) The nature of this requirement includes WFS, thus a
> mapserver mapfile could need a LABEL and subsequently a fieldname. Thus I
> added some support to the WFS module that does it.
>
> The first diff modifies the WebFeatureService class, while the seconds adds
> a new class named FieldnameReader(). (i attach this to in case it does not
> display quite right)
>
> 	  111a112,121
>
> >     def requestFieldnames(self,method='{http://www.opengis.net/wfs}Get'):
> >         base_url =
> > self.getOperationByName('{http://www.opengis.net/wfs}DescribeFeatureType'
> >).methods[method]['url'] request = {'service': 'WFS', 'version':
> > self.version, 'request': 'DescribeFeatureType'}
> >
> >         fieldReader = FieldnameReader(base_url,request)
> >         self._fielddict = fieldReader.requestFieldnames()
> >
> >     def getLayerFieldnames(self,typename):
> >         return self._fielddict[typename.rpartition(":")[2]]
>
> 196a207,228
>
> > class FieldnameReader():
> >     def __init__(self,url,request):
> >         self._infoset = None
> >         data = urlencode(request)
> >         self._infoset = self.read(url,data)
> >
> >     def read(self, url, data):
> >         u = urlopen(url+data)
> >         return etree.fromstring(u.read())
> >
> >     def requestFieldnames(self):
> >         complexMappings={}
> >         for elem in
> > self._infoset.findall(nspath('element',ns='http://www.w3.org/2001/XMLSche
> >ma')): complexMappings[elem.attrib.get('type',
> > '').rpartition(":")[2]]=elem.attrib.get('name', '') fieldDict={}
> >         for elem in
> > self._infoset.findall(nspath('complexType',ns='http://www.w3.org/2001/XML
> >Schema')): fieldListing=[]
> >             for field in
> > elem.findall(nspath('complexContent/extension/sequence/element',ns='http:
> >//www.w3.org/2001/XMLSchema')):
> > fieldListing.append(field.attrib.get('name', ''))
> > fieldDict[complexMappings[elem.attrib.get('name', '')]]=fieldListing
> > return fieldDict
>
> One can use it like:
>
> wfs.requestFieldnames()
> layers = list(wfs.contents)    # layers -> ['wfs:LEVEL1', 'wfs:Airport',
> 'wfs:LEVEL3', 'wfs:LEVEL4', 'wfs:LEVEL2'] for elem in layers:
>      print wfs.getLayerFieldnames(elem)
>
> I would like to know whether it would be useful, thus it could be included
> to a next version.
>
>
> _________________________________________________________________
> News, entertainment and everything you care about at Live.com. Get it now!
> http://www.live.com/getstarted.aspx





More information about the Community mailing list