Example #1
0
    def _buildMetadata(self, parse_remote_metadata=False):
        """set up capabilities metadata objects: """

        self.updateSequence = self._capabilities.attrib.get("updateSequence")

        # ServiceIdentification
        val = self._capabilities.find(
            nspath_eval("ows:ServiceIdentification", namespaces))
        if val is not None:
            self.identification = ServiceIdentification(
                val, self.owscommon.namespace)
        # ServiceProvider
        val = self._capabilities.find(
            nspath_eval("ows:ServiceProvider", namespaces))
        if val is not None:
            self.provider = ServiceProvider(val, self.owscommon.namespace)
        # ServiceOperations metadata
        self.operations = []
        for elem in self._capabilities.findall(
                nspath_eval("ows:OperationsMetadata/ows:Operation",
                            namespaces)):
            self.operations.append(
                OperationsMetadata(elem, self.owscommon.namespace))
        self.constraints = {}
        for elem in self._capabilities.findall(
                nspath_eval("ows:OperationsMetadata/ows:Constraint",
                            namespaces)):
            self.constraints[elem.attrib["name"]] = Constraint(
                elem, self.owscommon.namespace)
        self.parameters = {}
        for elem in self._capabilities.findall(
                nspath_eval("ows:OperationsMetadata/ows:Parameter",
                            namespaces)):
            self.parameters[elem.attrib["name"]] = Parameter(
                elem, self.owscommon.namespace)

        # FilterCapabilities
        val = self._capabilities.find(
            nspath_eval("ogc:Filter_Capabilities", namespaces))
        self.filters = FilterCapabilities(val)

        # serviceContents metadata: our assumption is that services use a top-level
        # layer as a metadata organizer, nothing more.

        self.contents = {}
        features = self._capabilities.findall(
            nspath_eval("wfs:FeatureTypeList/wfs:FeatureType", namespaces))
        if features is not None:
            for feature in features:
                cm = ContentMetadata(feature,
                                     parse_remote_metadata,
                                     headers=self.headers,
                                     auth=self.auth)
                self.contents[cm.id] = cm

        # exceptions
        self.exceptions = [
            f.text
            for f in self._capabilities.findall("Capability/Exception/Format")
        ]
Example #2
0
    def _buildMetadata(self, parse_remote_metadata=False):
        '''set up capabilities metadata objects: '''

        self.updateSequence = self._capabilities.attrib.get('updateSequence')

        #serviceIdentification metadata
        serviceidentelem = self._capabilities.find(
            nspath('ServiceIdentification'))
        self.identification = ServiceIdentification(serviceidentelem)
        #need to add to keywords list from featuretypelist information:
        featuretypelistelem = self._capabilities.find(
            nspath('FeatureTypeList', ns=WFS_NAMESPACE))
        featuretypeelems = featuretypelistelem.findall(
            nspath('FeatureType', ns=WFS_NAMESPACE))
        for f in featuretypeelems:
            kwds = f.findall(nspath('Keywords/Keyword', ns=OWS_NAMESPACE))
            if kwds is not None:
                for kwd in kwds[:]:
                    if kwd.text not in self.identification.keywords:
                        self.identification.keywords.append(kwd.text)

        #TODO: update serviceProvider metadata, miss it out for now
        serviceproviderelem = self._capabilities.find(
            nspath('ServiceProvider'))
        self.provider = ServiceProvider(serviceproviderelem)

        #serviceOperations metadata
        self.operations = []

        for elem in self._capabilities.find(nspath('OperationsMetadata'))[:]:
            if elem.tag != nspath('ExtendedCapabilities'):
                self.operations.append(OperationsMetadata(elem))
        self.constraints = {}
        for elem in self._capabilities.findall(
                nspath('OperationsMetadata/Constraint', ns=WFS_NAMESPACE)):
            self.constraints[elem.attrib['name']] = Constraint(
                elem, self.owscommon.namespace)
        self.parameters = {}
        for elem in self._capabilities.findall(
                nspath('OperationsMetadata/Parameter', ns=WFS_NAMESPACE)):
            self.parameters[elem.attrib['name']] = Parameter(
                elem, self.owscommon.namespace)

        #serviceContents metadata: our assumption is that services use a top-level
        #layer as a metadata organizer, nothing more.

        self.contents = {}
        featuretypelist = self._capabilities.find(
            nspath('FeatureTypeList', ns=WFS_NAMESPACE))
        features = self._capabilities.findall(
            nspath('FeatureTypeList/FeatureType', ns=WFS_NAMESPACE))
        for feature in features:
            cm = ContentMetadata(feature, featuretypelist,
                                 parse_remote_metadata)
            self.contents[cm.id] = cm

        #exceptions
        self.exceptions = [f.text for f \
                in self._capabilities.findall('Capability/Exception/Format')]
Example #3
0
    def __init__(self, url, xml, cookies, auth=None, timeout=30, headers=None):
        super(WebCoverageService_2_0_0, self).__init__(auth=auth,
                                                       timeout=timeout,
                                                       headers=headers)
        self.version = "2.0.0"
        self.url = url
        self.cookies = cookies
        self.timeout = timeout
        self.ows_common = OwsCommon(version="2.0.0")
        # initialize from saved capability document or access the server
        reader = WCSCapabilitiesReader(self.version,
                                       self.cookies,
                                       self.auth,
                                       headers=self.headers)
        if xml:
            self._capabilities = reader.readString(xml)
        else:
            self._capabilities = reader.read(self.url, self.timeout)

        # check for exceptions
        se = self._capabilities.find("ServiceException")

        if se is not None:
            err_message = str(se.text).strip()
            raise ServiceException(err_message, xml)

        # serviceIdentification metadata
        subelem = self._capabilities.find(ns("ServiceIdentification"))
        self.identification = ServiceIdentification(
            subelem, namespace=self.ows_common.namespace)

        # serviceProvider metadata
        serviceproviderelem = self._capabilities.find(ns("ServiceProvider"))
        self.provider = ServiceProvider(serviceproviderelem,
                                        namespace=self.ows_common.namespace)

        # serviceOperations metadata
        self.operations = []
        for elem in self._capabilities.find(ns("OperationsMetadata"))[:]:
            if elem.tag != ns("ExtendedCapabilities"):
                self.operations.append(
                    OperationsMetadata(elem,
                                       namespace=self.ows_common.namespace))

        # serviceContents metadata
        self.contents = {}
        for elem in self._capabilities.findall(
                nsWCS2("Contents/") + nsWCS2("CoverageSummary")):
            cm = ContentMetadata(elem, self)
            self.contents[cm.id] = cm

        # exceptions
        self.exceptions = [
            f.text
            for f in self._capabilities.findall("Capability/Exception/Format")
        ]
Example #4
0
    def __init__(self, url, xml, cookies, auth=None):
        super(WebCoverageService_2_0_1, self).__init__(auth=auth)
        self.version = '2.0.1'
        self.url = url
        self.cookies = cookies
        self.ows_common = OwsCommon(version='2.0.1')
        # initialize from saved capability document or access the server
        reader = WCSCapabilitiesReader(self.version, self.cookies, self.auth)
        if xml:
            self._capabilities = reader.readString(xml)
        else:
            self._capabilities = reader.read(self.url)

        # check for exceptions
        se = self._capabilities.find('ServiceException')

        if se is not None:
            err_message = str(se.text).strip()
            raise ServiceException(err_message, xml)

        #serviceIdentification metadata
        subelem = self._capabilities.find(ns('ServiceIdentification'))
        self.identification = ServiceIdentification(
            subelem, namespace=self.ows_common.namespace)

        #serviceProvider metadata
        serviceproviderelem = self._capabilities.find(ns('ServiceProvider'))
        self.provider = ServiceProvider(serviceproviderelem,
                                        namespace=self.ows_common.namespace)

        #serviceOperations metadata
        self.operations = []
        for elem in self._capabilities.find(ns('OperationsMetadata'))[:]:
            if elem.tag != ns('ExtendedCapabilities'):
                self.operations.append(
                    OperationsMetadata(elem,
                                       namespace=self.ows_common.namespace))

        #serviceContents metadata
        self.contents = {}
        for elem in self._capabilities.findall(
                nsWCS2('Contents/') + nsWCS2('CoverageSummary')):
            cm = ContentMetadata(elem, self)
            self.contents[cm.id] = cm

        #exceptions
        self.exceptions = [f.text for f \
                in self._capabilities.findall('Capability/Exception/Format')]
Example #5
0
    def _build_metadata(self, parse_remote_metadata=False):
        '''set up capabilities metadata objects: '''
        
        #serviceIdentification metadata
        serviceidentelem=self._capabilities.find(nsp_ows('ows:ServiceIdentification'))
        self.identification=ServiceIdentification(serviceidentelem)  
        #need to add to keywords list from featuretypelist information:
        featuretypelistelem=self._capabilities.find(nspath('FeatureTypeList', ns.get_namespace('wfs')))
        featuretypeelems=featuretypelistelem.findall(nspath('FeatureType', ns.get_namespace('wfs')))
        for f in featuretypeelems:  
            kwds=f.findall(nspath('Keywords/Keyword',ns=OWS_NAMESPACE))
            if kwds is not None:
                for kwd in kwds[:]:
                    if kwd.text not in self.identification.keywords:
                        self.identification.keywords.append(kwd.text)
	
   
        #TODO: update serviceProvider metadata, miss it out for now
        #print vars(self._capabilities)
        #return
        serviceproviderelem=self._capabilities.find(nsp_ows('ows:ServiceProvider'))
        self.provider=ServiceProvider(serviceproviderelem)
        #serviceOperations metadata 
        op = self._capabilities.find(nspath_eval('ows:OperationsMetadata', _ows_version))
        self.operations = OperationsMetadata(op, _ows_version).operations
                   
        #serviceContents metadata: our assumption is that services use a top-level 
        #layer as a metadata organizer, nothing more. 
        
        self.contents={} 
        featuretypelist=self._capabilities.find(nspath('FeatureTypeList',ns.get_namespace('wfs')))
        features = self._capabilities.findall(nspath('FeatureTypeList/FeatureType',ns.get_namespace('wfs')))
        for feature in features:
            cm=ContentMetadata(feature, featuretypelist, parse_remote_metadata)
            self.contents[cm.id]=cm       
        
        #exceptions
        self.exceptions = [f.text for f \
                in self._capabilities.findall('Capability/Exception/Format')]
Example #6
0
class WebFeatureService_2_0_0(object):
    """Abstraction for OGC Web Feature Service (WFS).

    Implements IWebFeatureService.
    """
    def __new__(self,url, version, xml, parse_remote_metadata=False):
        """ overridden __new__ method 
        
        @type url: string
        @param url: url of WFS capabilities document
        @type xml: string
        @param xml: elementtree object
        @type parse_remote_metadata: boolean
        @param parse_remote_metadata: whether to fully process MetadataURL elements
        @return: initialized WebFeatureService_2_0_0 object
        """
        obj=object.__new__(self)
        obj.__init__(url, version, xml, parse_remote_metadata)
        self.log = logging.getLogger()
        consoleh  = logging.StreamHandler()
        self.log.addHandler(consoleh)    
        return obj
    
    def __getitem__(self,name):
        ''' check contents dictionary to allow dict like access to service layers'''
        if name in self.__getattribute__('contents').keys():
            return self.__getattribute__('contents')[name]
        else:
            raise KeyError, "No content named %s" % name
    
    
    def __init__(self, url,  version, xml=None, parse_remote_metadata=False):
        """Initialize."""
        log.debug('building WFS %s'%url)
        self.url = url
        self.version = version
        self._capabilities = None
        reader = WFSCapabilitiesReader(self.version)
        if xml:
            self._capabilities = reader.read_string(xml)
        else:
            self._capabilities = reader.read(self.url)
        self._build_metadata(parse_remote_metadata)
    
    def _build_metadata(self, parse_remote_metadata=False):
        '''set up capabilities metadata objects: '''
        
        #serviceIdentification metadata
        serviceidentelem=self._capabilities.find(nsp_ows('ows:ServiceIdentification'))
        self.identification=ServiceIdentification(serviceidentelem)  
        #need to add to keywords list from featuretypelist information:
        featuretypelistelem=self._capabilities.find(nspath('FeatureTypeList', ns.get_namespace('wfs')))
        featuretypeelems=featuretypelistelem.findall(nspath('FeatureType', ns.get_namespace('wfs')))
        for f in featuretypeelems:  
            kwds=f.findall(nspath('Keywords/Keyword',ns=OWS_NAMESPACE))
            if kwds is not None:
                for kwd in kwds[:]:
                    if kwd.text not in self.identification.keywords:
                        self.identification.keywords.append(kwd.text)
	
   
        #TODO: update serviceProvider metadata, miss it out for now
        #print vars(self._capabilities)
        #return
        serviceproviderelem=self._capabilities.find(nsp_ows('ows:ServiceProvider'))
        self.provider=ServiceProvider(serviceproviderelem)
        #serviceOperations metadata 
        op = self._capabilities.find(nspath_eval('ows:OperationsMetadata', _ows_version))
        self.operations = OperationsMetadata(op, _ows_version).operations
                   
        #serviceContents metadata: our assumption is that services use a top-level 
        #layer as a metadata organizer, nothing more. 
        
        self.contents={} 
        featuretypelist=self._capabilities.find(nspath('FeatureTypeList',ns.get_namespace('wfs')))
        features = self._capabilities.findall(nspath('FeatureTypeList/FeatureType',ns.get_namespace('wfs')))
        for feature in features:
            cm=ContentMetadata(feature, featuretypelist, parse_remote_metadata)
            self.contents[cm.id]=cm       
        
        #exceptions
        self.exceptions = [f.text for f \
                in self._capabilities.findall('Capability/Exception/Format')]
      
    def getcapabilities(self):
        """Request and return capabilities document from the WFS as a 
        file-like object.
        NOTE: this is effectively redundant now"""
        reader = WFSCapabilitiesReader(self.version)
        return urlopen(reader.capabilities_url(self.url))
    
    def items(self):
        '''supports dict-like items() access'''
        items=[]
        for item in self.contents:
            items.append((item,self.contents[item]))
        return items
    
    def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
                   featureversion=None, propertyname=None, maxfeatures=None,storedQueryID=None, storedQueryParams={},
                   method='Get'):
        """Request and return feature data as a file-like object.
        #TODO: NOTE: have changed property name from ['*'] to None - check the use of this in WFS 2.0
        Parameters
        ----------
        typename : list
            List of typenames (string)
        filter : string 
            XML-encoded OGC filter expression.
        bbox : tuple
            (left, bottom, right, top) in the feature type's coordinates == (minx, miny, maxx, maxy)
        featureid : list
            List of unique feature ids (string)
        featureversion : string
            Default is most recent feature version.
        propertyname : list
            List of feature property names. '*' matches all.
        maxfeatures : int
            Maximum number of features to be returned.
        method : string
            Qualified name of the HTTP DCP method to use.

        There are 3 different modes of use

        1) typename and bbox (simple spatial query)
        2) typename and filter (==query) (more expressive)
        3) featureid (direct access to known features)
        """
        #log.debug(self.getOperationByName('GetFeature'))
        base_url = self.getOperationByName('GetFeature').methods[method]['url']

        if method.upper() == "GET":
            base_url = base_url if base_url.endswith("?") else base_url+"?"
        request = {'service': 'WFS', 'version': self.version, 'request': 'GetFeature'}
        
        # check featureid
        if featureid:
            request['featureid'] = ','.join(featureid)
        elif bbox:
#            request['bbox'] = ','.join([str(x) for x in bbox])
            request['query'] ='<Query xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" xmlns:csml="http://ndg.nerc.ac.uk/csml"><ogc:Filter><ogc:BBOX><gml:Envelope srsName="WGS84"><gml:lowerCorner>%s %s</gml:lowerCorner><gml:upperCorner>%s %s</gml:upperCorner></gml:Envelope></ogc:BBOX></ogc:Filter></Query>'%(bbox[1],bbox[0],bbox[3],bbox[2])
        elif filter:
            request['query'] = str(filter)
        if typename:
            typename = [typename] if type(typename) == type("") else typename
            request['typename'] = ','.join(typename)
        if propertyname: 
            request['propertyname'] = ','.join(propertyname)
        if featureversion: 
            request['featureversion'] = str(featureversion)
        if maxfeatures: 
            request['maxfeatures'] = str(maxfeatures)
        if storedQueryID: 
            request['storedQuery_id']=str(storedQueryID)
            for param in storedQueryParams:
                request[param]=storedQueryParams[param]
                
        data = urlencode(request)

        if method == 'Post':
            u = urlopen(base_url, data=data)
        else:
            u = urlopen(base_url + data)
        
        # check for service exceptions, rewrap, and return
        # We're going to assume that anything with a content-length > 32k
        # is data. We'll check anything smaller.
        try:
            length = int(u.info()['Content-Length'])
            have_read = False
        except KeyError:
            data = u.read()
            have_read = True
            length = len(data)
     
        if length < 32000:
            if not have_read:
                data = u.read()
            tree = etree.fromstring(data)
            if tree.tag == "{%s}ServiceExceptionReport" % ns.get_versioned_namespace('ogc'):
                se = tree.find(nspath('ServiceException', ns.get_versioned_namespace('ogc')))
                raise ServiceException, str(se.text).strip()

            return StringIO(data)
        else:
            if have_read:
                return StringIO(data)
            return u

    def getpropertyvalue(self, query=None, storedquery_id=None, valuereference=None, typename=None, method=nspath('Get'),**kwargs):
        ''' the WFS GetPropertyValue method'''     
        base_url = self.get_operation_by_name('GetPropertyValue').methods[method]['url']

        request = {'service': 'WFS', 'version': self.version, 'request': 'GetPropertyValue'}
        if query:
            request['query'] = str(query)
        if valuereference: 
            request['valueReference'] = str(valuereference)
        if storedquery_id: 
            request['storedQuery_id'] = str(storedquery_id)
        if typename:
            request['typename']=str(typename)
        if kwargs:
            for kw in kwargs.keys():
                request[kw]=str(kwargs[kw])
        data=urlencode(request)
        u = urlopen(base_url + data)
        return u.read()
        
        
    def _getStoredQueries(self):
        ''' gets descriptions of the stored queries available on the server '''
        sqs=[]
        #This method makes two calls to the WFS - one ListStoredQueries, and one DescribeStoredQueries. The information is then
        #aggregated in 'StoredQuery' objects
        method=nspath('Get')
        
        #first make the ListStoredQueries response and save the results in a dictionary if form {storedqueryid:(title, returnfeaturetype)}
        base_url = self.get_operation_by_name('ListStoredQueries').methods[method]['url']
        request = {'service': 'WFS', 'version': self.version, 'request': 'ListStoredQueries'}
        data = urlencode(request)
        u = urlopen(base_url + data)
        tree=etree.fromstring(u.read())
        base_url = self.get_operation_by_name('ListStoredQueries').methods[method]['url']
        tempdict={}       
        for sqelem in tree[:]:
            title=rft=id=None
            id=sqelem.get('id')
            for elem in sqelem[:]:
                if elem.tag==nspath('Title',ns.get_namespace('wfs')):
                    title=elem.text
                elif elem.tag==nspath('ReturnFeatureType',ns.get_namespace('wfs')):
                    rft=elem.text
            tempdict[id]=(title,rft)        #store in temporary dictionary
        
        #then make the DescribeStoredQueries request and get the rest of the information about the stored queries 
        base_url = self.get_operation_by_name('DescribeStoredQueries').methods[method]['url']
        request = {'service': 'WFS', 'version': self.version, 'request': 'DescribeStoredQueries'}
        data = urlencode(request)
        u = urlopen(base_url + data)
        tree=etree.fromstring(u.read())
        tempdict2={} 
        for sqelem in tree[:]:
            params=[] #list to store parameters for the stored query description
            id =sqelem.get('id')
            for elem in sqelem[:]:
                if elem.tag==nspath('Abstract',ns.get_namespace('wfs')):
                    abstract=elem.text
                elif elem.tag==nspath('Parameter',ns.get_namespace('wfs')):
                    newparam=Parameter(elem.get('name'), elem.get('type'))
                    params.append(newparam)
            tempdict2[id]=(abstract, params) #store in another temporary dictionary
        
        #now group the results into StoredQuery objects:
        for key in tempdict.keys(): 
            abstract='blah'
            parameters=[]
            sqs.append(StoredQuery(key, tempdict[key][0], tempdict[key][1], tempdict2[key][0], tempdict2[key][1]))
        return sqs
    storedqueries = property(_getStoredQueries, None)

    def get_operation_by_name(self, name): 
        """
            Return a Operation item by name, case insensitive
        """
        for item in self.operations.keys():
            if item.lower() == name.lower():
                return self.operations[item]
        raise KeyError, "No Operation named %s" % name