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") ]
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')]
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") ]
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')]
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')]
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