Beispiel #1
0
def openURL(url_base, data, method='Get', cookies=None, username=None, password=None, timeout=30):
    ''' function to open urls - wrapper around urllib2.urlopen but with additional checks for OGC service exceptions and url formatting, also handles cookies and simple user password authentication'''
    url_base.strip() 
    lastchar = url_base[-1]
    if lastchar not in ['?', '&']:
        if url_base.find('?') == -1:
            url_base = url_base + '?'
        else:
            url_base = url_base + '&'
            
    if username and password:
        # Provide login information in order to use the WMS server
        # Create an OpenerDirector with support for Basic HTTP 
        # Authentication...
        passman = HTTPPasswordMgrWithDefaultRealm()
        passman.add_password(None, url_base, username, password)
        auth_handler = HTTPBasicAuthHandler(passman)
        opener = urllib2.build_opener(auth_handler)
        openit = opener.open
    else:
        # NOTE: optionally set debuglevel>0 to debug HTTP connection
        #opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=0))
        #openit = opener.open
        openit = urlopen
   
    try:
        if method == 'Post':
            req = Request(url_base, data)
            # set appropriate header if posting XML
            try:
                xml = etree.fromstring(data)
                req.add_header('Content-Type', "text/xml")
            except:
                pass
        else:
            req=Request(url_base + data)
        if cookies is not None:
            req.add_header('Cookie', cookies)
        u = openit(req, timeout=timeout)
    except HTTPError as e: #Some servers may set the http header to 400 if returning an OGC service exception or 401 if unauthorised.
        if e.code in [400, 401]:
            raise ServiceException(e.read())
        else:
            raise e
    # check for service exceptions without the http header set
    if 'Content-Type' in u.info() and u.info()['Content-Type'] in ['text/xml', 'application/xml']:
        #just in case 400 headers were not set, going to have to read the xml to see if it's an exception report.
        #wrap the url stram in a extended StringIO object so it's re-readable
        u=RereadableURL(u)      
        se_xml= u.read()
        se_tree = etree.fromstring(se_xml)
        serviceException=se_tree.find('{http://www.opengis.net/ows}Exception')
        if serviceException is None:
            serviceException=se_tree.find('ServiceException')
        if serviceException is not None:
            raise ServiceException(str(serviceException.text).strip())
        u.seek(0) #return cursor to start of u      
    return u
Beispiel #2
0
    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)}
        try:
            base_url = next((m.get('url') for m in self.getOperationByName('ListStoredQueries').methods if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url

        request = {'service': 'WFS', 'version': self.version, 'request': 'ListStoredQueries'}
        encoded_request = urlencode(request)
        u = urlopen(base_url, data=encoded_request, timeout=self.timeout)
        tree=etree.fromstring(u.read())
        tempdict={}       
        for sqelem in tree[:]:
            title=rft=id=None
            id=sqelem.get('id')
            for elem in sqelem[:]:
                if elem.tag==nspath('Title', WFS_NAMESPACE):
                    title=elem.text
                elif elem.tag==nspath('ReturnFeatureType', WFS_NAMESPACE):
                    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 
        try:
            base_url = next((m.get('url') for m in self.getOperationByName('DescribeStoredQueries').methods if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {'service': 'WFS', 'version': self.version, 'request': 'DescribeStoredQueries'}
        encoded_request = urlencode(request)
        u = urlopen(base_url, data=encoded_request, timeout=to)
        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', WFS_NAMESPACE):
                    abstract=elem.text
                elif elem.tag==nspath('Parameter', WFS_NAMESPACE):
                    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
Beispiel #3
0
def cleanup_namespaces(element):
    """ Remove unused namespaces from an element """
    if etree.__name__ == 'lxml.etree':
        etree.cleanup_namespaces(element)
        return element
    else:
        return etree.fromstring(etree.tostring(element))
Beispiel #4
0
def cleanup_namespaces(element):
    """ Remove unused namespaces from an element """
    if etree.__name__ == 'lxml.etree':
        etree.cleanup_namespaces(element)
        return element
    else:
        return etree.fromstring(etree.tostring(element))
Beispiel #5
0
    def readString(self, st):
        """Parse a WMS capabilities document, returning an elementtree instance

        string should be an XML capabilities document
        """
        if not isinstance(st, str):
            raise ValueError("String must be of type string, not %s" % type(st))
        return etree.fromstring(st)
Beispiel #6
0
    def get_observation(self, responseFormat=None,
                        offerings=None,
                        observedProperties=None,
                        eventTime=None,
                        method='Get',
                        **kwargs):
        """
        Parameters
        ----------
        format : string
            Output format. Provide one that is available for all offerings
        method : string
            Optional. HTTP DCP method name: Get or Post.  Must
        **kwargs : extra arguments
            anything else e.g. vendor specific parameters
        """

        base_url = self.get_operation_by_name('GetObservation').methods[method]['url']

        request = {'service': 'SOS', 'version': self.version, 'request': 'GetObservation'}

        # Required Fields
        assert isinstance(offerings, list) and len(offerings) > 0
        request['offering'] = ','.join(offerings)

        assert isinstance(observedProperties, list) and len(observedProperties) > 0
        request['observedProperty'] = ','.join(observedProperties)

        if responseFormat is not None:
            request['responseFormat'] = responseFormat

        # Optional Fields
        if eventTime is not None:
            request['temporalFilter'] = eventTime

        url_kwargs = {}
        if 'timeout' in kwargs:
            url_kwargs['timeout'] = kwargs.pop('timeout')  # Client specified timeout value

        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        response = openURL(
            base_url, data, method, username=self.username, password=self.password, **url_kwargs
        ).read()
        try:
            tr = etree.fromstring(response)
            if tr.tag == nspath_eval("ows:ExceptionReport", namespaces):
                raise ows.ExceptionReport(tr)
            else:
                return response
        except ows.ExceptionReport:
            raise
        except BaseException:
            return response
Beispiel #7
0
 def readString(self, st):
     """Parse a WCS capabilities document, returning an
     instance of WCSCapabilitiesInfoset
     string should be an XML capabilities document
     """
     if not isinstance(st, str):
         raise ValueError("String must be of type string, not %s" %
                          type(st))
     return etree.fromstring(st)
Beispiel #8
0
    def __init__(self, element):
        if isinstance(element, str):
            self._root = etree.fromstring(element)
        else:
            self._root = element

        if hasattr(self._root, 'getroot'):
            self._root = self._root.getroot()

        self.members = [Member(x) for x in self._root.findall(nsp('sml:member'))]
Beispiel #9
0
    def read_string(self, st):
        """
            Parse a SOS capabilities document, returning an elementtree instance

            st should be an XML capabilities document
        """
        if not isinstance(st, str):
            raise ValueError("String must be of type string, not %s" %
                             type(st))
        return etree.fromstring(st)
Beispiel #10
0
    def __init__(self, element):

        if isinstance(element, str) or isinstance(element, unicode):
            self._root = etree.fromstring(str(element))
        else:
            self._root = element

        if hasattr(self._root, 'getroot'):
            self._root = self._root.getroot()

        self._ns = 'wml1.1'
Beispiel #11
0
    def __init__(self, element):

        if isinstance(element, str) or isinstance(element, unicode):
            self._root = etree.fromstring(str(element))
        else:
            self._root = element

        if hasattr(self._root, 'getroot'):
            self._root = self._root.getroot()

        self._ns = 'wml1.0'
Beispiel #12
0
    def __init__(self, element):
        if isinstance(element, str):
            self._root = etree.fromstring(element)
        else:
            self._root = element

        if hasattr(self._root, 'getroot'):
            self._root = self._root.getroot()

        self.members = [
            Member(x) for x in self._root.findall(nsp('sml:member'))
        ]
Beispiel #13
0
    def read(self, service_url):
        """
            Get and parse a WMS capabilities document, returning an
            elementtree instance

            service_url is the base url, to which is appended the service,
            version, and request parameters
        """
        getcaprequest = self.capabilities_url(service_url)
        spliturl=getcaprequest.split('?')
        u = openURL(spliturl[0], spliturl[1], method='Get', username=self.username, password=self.password)
        return etree.fromstring(u.read())
Beispiel #14
0
    def describe_sensor(self,
                        outputFormat=None,
                        procedure=None,
                        method='Get',
                        **kwargs):

        try:
            base_url = next(
                (m.get('url')
                 for m in self.getOperationByName('DescribeSensor').methods
                 if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {
            'service': 'SOS',
            'version': self.version,
            'request': 'DescribeSensor'
        }

        # Required Fields
        assert isinstance(outputFormat, str)
        request['outputFormat'] = outputFormat

        assert isinstance(procedure, str)
        request['procedure'] = procedure

        url_kwargs = {}
        if 'timeout' in kwargs:
            url_kwargs['timeout'] = kwargs.pop(
                'timeout')  # Client specified timeout value

        # Optional Fields
        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        response = openURL(base_url,
                           data,
                           method,
                           username=self.username,
                           password=self.password,
                           **url_kwargs).read()

        tr = etree.fromstring(response)

        if tr.tag == nspath_eval("ows:ExceptionReport", namespaces):
            raise ows.ExceptionReport(tr)

        return response
Beispiel #15
0
    def read(self, url, timeout=30):
        """Get and parse a WFS capabilities document, returning an
        instance of WFSCapabilitiesInfoset

        Parameters
        ----------
        url : string
            The URL to the WFS capabilities document.
        timeout : number
            A timeout value (in seconds) for the request.
        """
        request = self.capabilities_url(url)
        u = urlopen(request, timeout=timeout)
        return etree.fromstring(u.read())
Beispiel #16
0
    def read(self, url, timeout=30):
        """Get and parse a WFS capabilities document, returning an
        instance of WFSCapabilitiesInfoset

        Parameters
        ----------
        url : string
            The URL to the WFS capabilities document.
        timeout : number
            A timeout value (in seconds) for the request.
        """
        request = self.capabilities_url(url)
        u = urlopen(request, timeout=timeout)
        return etree.fromstring(u.read())
Beispiel #17
0
    def read(self, service_url, timeout=30):
        """Get and parse a WCS capabilities document, returning an
        elementtree tree

        @type service_url: string
        @param service_url: The base url, to which is appended the service,
        version, and request parameters
        @rtype: elementtree tree
        @return: An elementtree tree representation of the capabilities document
        """
        request = self.capabilities_url(service_url)
        req = Request(request)
        if self.cookies is not None:
            req.add_header('Cookie', self.cookies)   
        u = urlopen(req, timeout=timeout)
        return etree.fromstring(u.read())
Beispiel #18
0
    def read(self, service_url):
        """
            Get and parse a WMS capabilities document, returning an
            elementtree instance

            service_url is the base url, to which is appended the service,
            acceptVersions, and request parameters
        """
        getcaprequest = self.capabilities_url(service_url)
        spliturl = getcaprequest.split('?')
        u = openURL(spliturl[0],
                    spliturl[1],
                    method='Get',
                    username=self.username,
                    password=self.password)
        return etree.fromstring(u.read())
Beispiel #19
0
 def getcapabilities(self):
     """Request and return capabilities document from the WMS as a 
     file-like object.
     NOTE: this is effectively redundant now"""
     
     reader = WMSCapabilitiesReader(
         self.version, url=self.url, un=self.username, pw=self.password
         )
     u = self._open(reader.capabilities_url(self.url))
     # check for service exceptions, and return
     if u.info().gettype() == 'application/vnd.ogc.se_xml':
         se_xml = u.read()
         se_tree = etree.fromstring(se_xml)
         err_message = str(se_tree.find('ServiceException').text).strip()
         raise ServiceException(err_message, se_xml)
     return u
Beispiel #20
0
    def read(self, service_url, timeout=30):
        """Get and parse a WCS capabilities document, returning an
        elementtree tree

        @type service_url: string
        @param service_url: The base url, to which is appended the service,
        version, and request parameters
        @rtype: elementtree tree
        @return: An elementtree tree representation of the capabilities document
        """
        request = self.capabilities_url(service_url)
        req = Request(request)
        if self.cookies is not None:
            req.add_header('Cookie', self.cookies)
        u = urlopen(req, timeout=timeout)
        return etree.fromstring(u.read())
Beispiel #21
0
    def describe_sensor(self, outputFormat=None,
                        procedure=None,
                        method='Get',
                        **kwargs):

        try:
            base_url = next((
                m.get('url') for m in self.getOperationByName('DescribeSensor').methods
                if m.get('type').lower() == method.lower())
            )
        except StopIteration:
            base_url = self.url
        request = {'service': 'SOS', 'version': self.version, 'request': 'DescribeSensor'}

        # Required Fields
        assert isinstance(outputFormat, str)
        request['outputFormat'] = outputFormat

        assert isinstance(procedure, str)
        request['procedure'] = procedure

        url_kwargs = {}
        if 'timeout' in kwargs:
            url_kwargs['timeout'] = kwargs.pop('timeout')  # Client specified timeout value

        # Optional Fields
        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        response = openURL(
            base_url,
            data,
            method,
            username=self.username,
            password=self.password,
            **url_kwargs
        ).read()

        tr = etree.fromstring(response)

        if tr.tag == nspath_eval("ows:ExceptionReport", namespaces):
            raise ows.ExceptionReport(tr)

        return response
Beispiel #22
0
    def getcapabilities(self):
        """Request and return capabilities document from the WMS as a 
        file-like object.
        NOTE: this is effectively redundant now"""

        reader = WMSCapabilitiesReader(self.version,
                                       url=self.url,
                                       un=self.username,
                                       pw=self.password)
        u = self._open(reader.capabilities_url(self.url))
        # check for service exceptions, and return
        if u.info().gettype() == 'application/vnd.ogc.se_xml':
            se_xml = u.read()
            se_tree = etree.fromstring(se_xml)
            err_message = str(se_tree.find('ServiceException').text).strip()
            raise ServiceException(err_message, se_xml)
        return u
Beispiel #23
0
 def getCoverages(self, unpackdir='./unpacked'):
     if self.urlType=='XML': 
         paths=[]              
         u_xml = self.u.read()
         u_tree = etree.fromstring(u_xml)
         for ref in u_tree.findall('{http://www.opengis.net/wcs/1.1}Coverage/{http://www.opengis.net/wcs/1.1}Reference'):
             path = ref.attrib['{http://www.w3.org/1999/xlink}href']
             paths.append(path)         
         for ref in u_tree.findall('{http://www.opengis.net/wcs/1.1.0/owcs}Coverage/{{http://www.opengis.net/wcs/1.1.0/owcs}Reference'):
             path = ref.attrib['{http://www.w3.org/1999/xlink}href']
             paths.append(path)         
     elif self.urlType=='Multipart':
         #Decode multipart mime and return fileobjects
         u_mpart=self.u.read()
         mpart =MpartMime(u_mpart)
         paths= mpart.unpackToDir(unpackdir)
     return paths
Beispiel #24
0
 def getCoverages(self, unpackdir='./unpacked'):
     if self.urlType == 'XML':
         paths = []
         u_xml = self.u.read()
         u_tree = etree.fromstring(u_xml)
         for ref in u_tree.findall(
                 '{http://www.opengis.net/wcs/1.1}Coverage/{http://www.opengis.net/wcs/1.1}Reference'
         ):
             path = ref.attrib['{http://www.w3.org/1999/xlink}href']
             paths.append(path)
         for ref in u_tree.findall(
                 '{http://www.opengis.net/wcs/1.1.0/owcs}Coverage/{{http://www.opengis.net/wcs/1.1.0/owcs}Reference'
         ):
             path = ref.attrib['{http://www.w3.org/1999/xlink}href']
             paths.append(path)
     elif self.urlType == 'Multipart':
         #Decode multipart mime and return fileobjects
         u_mpart = self.u.read()
         mpart = MpartMime(u_mpart)
         paths = mpart.unpackToDir(unpackdir)
     return paths
Beispiel #25
0
    def getmap(self, layers=None, styles=None, srs=None, bbox=None,
               format=None, size=None, time=None, transparent=False,
               bgcolor='#FFFFFF',
               exceptions='application/vnd.ogc.se_xml',
               method='Get',
               **kwargs
               ):
        """Request and return an image from the WMS as a file-like object.
        
        Parameters
        ----------
        layers : list
            List of content layer names.
        styles : list
            Optional list of named styles, must be the same length as the
            layers list.
        srs : string
            A spatial reference system identifier.
        bbox : tuple
            (left, bottom, right, top) in srs units.
        format : string
            Output image format such as 'image/jpeg'.
        size : tuple
            (width, height) in pixels.
        transparent : bool
            Optional. Transparent background if True.
        bgcolor : string
            Optional. Image background color.
        method : string
            Optional. HTTP DCP method name: Get or Post.
        **kwargs : extra arguments
            anything else e.g. vendor specific parameters
        
        Example
        -------
            >>> wms = WebMapService('http://giswebservices.massgis.state.ma.us/geoserver/wms', version='1.1.1')
            >>> img = wms.getmap(layers=['massgis:GISDATA.SHORELINES_ARC'],\
                                 styles=[''],\
                                 srs='EPSG:4326',\
                                 bbox=(-70.8, 42, -70, 42.8),\
                                 size=(300, 300),\
                                 format='image/jpeg',\
                                 transparent=True)
            >>> out = open('example.jpg.jpg', 'wb')
            >>> out.write(img.read())
            >>> out.close()

        """        
        try:
            base_url = next((m.get('url') for m in self.getOperationByName('GetMap').methods if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {'version': self.version, 'request': 'GetMap'}
        
        # check layers and styles
        assert len(layers) > 0
        request['layers'] = ','.join(layers)
        if styles:
            assert len(styles) == len(layers)
            request['styles'] = ','.join(styles)
        else:
            request['styles'] = ''

        # size
        request['width'] = str(size[0])
        request['height'] = str(size[1])
        
        request['srs'] = str(srs)
        request['bbox'] = ','.join([repr(x) for x in bbox])
        request['format'] = str(format)
        request['transparent'] = str(transparent).upper()
        request['bgcolor'] = '0x' + bgcolor[1:7]
        request['exceptions'] = str(exceptions)
        
        if time is not None:
            request['time'] = str(time)
        
        if kwargs:
            for kw in kwargs:
                request[kw]=kwargs[kw]

        data = urlencode(request)
        
        u = openURL(base_url, data, method, username = self.username, password = self.password)

        # check for service exceptions, and return
        if u.info()['Content-Type'] == 'application/vnd.ogc.se_xml':
            se_xml = u.read()
            se_tree = etree.fromstring(se_xml)
            err_message = unicode(se_tree.find('ServiceException').text).strip()
            raise ServiceException(err_message, se_xml)
        return u
Beispiel #26
0
    def get_observation(self,
                        responseFormat=None,
                        offerings=None,
                        observedProperties=None,
                        eventTime=None,
                        method='Get',
                        **kwargs):
        """
        Parameters
        ----------
        format : string
            Output format. Provide one that is available for all offerings
        method : string
            Optional. HTTP DCP method name: Get or Post.  Must
        **kwargs : extra arguments
            anything else e.g. vendor specific parameters
        """
        try:
            base_url = next(
                (m.get('url')
                 for m in self.getOperationByName('GetObservation').methods
                 if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url

        request = {
            'service': 'SOS',
            'version': self.version,
            'request': 'GetObservation'
        }

        # Required Fields
        assert isinstance(offerings, list) and len(offerings) > 0
        request['offering'] = ','.join(offerings)

        assert isinstance(observedProperties,
                          list) and len(observedProperties) > 0
        request['observedProperty'] = ','.join(observedProperties)

        assert isinstance(responseFormat, str)
        request['responseFormat'] = responseFormat

        # Optional Fields
        if eventTime is not None:
            request['eventTime'] = eventTime

        url_kwargs = {}
        if 'timeout' in kwargs:
            url_kwargs['timeout'] = kwargs.pop(
                'timeout')  # Client specified timeout value

        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        response = openURL(base_url,
                           data,
                           method,
                           username=self.username,
                           password=self.password,
                           **url_kwargs).read()
        try:
            tr = etree.fromstring(response)
            if tr.tag == nspath_eval("ows:ExceptionReport", namespaces):
                raise ows.ExceptionReport(tr)
            else:
                return response
        except ows.ExceptionReport:
            raise
        except BaseException:
            return response
Beispiel #27
0
def openURL(url_base,
            data,
            method='Get',
            cookies=None,
            username=None,
            password=None,
            timeout=30):
    ''' function to open urls - wrapper around urllib2.urlopen but with additional checks for OGC service exceptions and url formatting, also handles cookies and simple user password authentication'''
    url_base.strip()
    lastchar = url_base[-1]
    if lastchar not in ['?', '&']:
        if url_base.find('?') == -1:
            url_base = url_base + '?'
        else:
            url_base = url_base + '&'

    if username and password:
        # Provide login information in order to use the WMS server
        # Create an OpenerDirector with support for Basic HTTP
        # Authentication...
        passman = HTTPPasswordMgrWithDefaultRealm()
        passman.add_password(None, url_base, username, password)
        auth_handler = HTTPBasicAuthHandler(passman)
        opener = urllib2.build_opener(auth_handler)
        openit = opener.open
    else:
        # NOTE: optionally set debuglevel>0 to debug HTTP connection
        #opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=0))
        #openit = opener.open
        openit = urlopen

    try:
        if method == 'Post':
            req = Request(url_base, data)
            # set appropriate header if posting XML
            try:
                xml = etree.fromstring(data)
                req.add_header('Content-Type', "text/xml")
            except:
                pass
        else:
            req = Request(url_base + data)
        if cookies is not None:
            req.add_header('Cookie', cookies)
        u = openit(req, timeout=timeout)
    except HTTPError as e:  #Some servers may set the http header to 400 if returning an OGC service exception or 401 if unauthorised.
        if e.code in [400, 401]:
            raise ServiceException(e.read())
        else:
            raise e
    # check for service exceptions without the http header set
    if 'Content-Type' in u.info() and u.info()['Content-Type'] in [
            'text/xml', 'application/xml'
    ]:
        #just in case 400 headers were not set, going to have to read the xml to see if it's an exception report.
        #wrap the url stram in a extended StringIO object so it's re-readable
        u = RereadableURL(u)
        se_xml = u.read()
        se_tree = etree.fromstring(se_xml)
        serviceException = se_tree.find(
            '{http://www.opengis.net/ows}Exception')
        if serviceException is None:
            serviceException = se_tree.find('ServiceException')
        if serviceException is not None:
            raise ServiceException(str(serviceException.text).strip())
        u.seek(0)  #return cursor to start of u
    return u
Beispiel #28
0
    def getmap(self,
               layers=None,
               styles=None,
               srs=None,
               bbox=None,
               format=None,
               size=None,
               time=None,
               transparent=False,
               bgcolor='#FFFFFF',
               exceptions='application/vnd.ogc.se_xml',
               method='Get',
               **kwargs):
        """Request and return an image from the WMS as a file-like object.
        
        Parameters
        ----------
        layers : list
            List of content layer names.
        styles : list
            Optional list of named styles, must be the same length as the
            layers list.
        srs : string
            A spatial reference system identifier.
        bbox : tuple
            (left, bottom, right, top) in srs units.
        format : string
            Output image format such as 'image/jpeg'.
        size : tuple
            (width, height) in pixels.
        transparent : bool
            Optional. Transparent background if True.
        bgcolor : string
            Optional. Image background color.
        method : string
            Optional. HTTP DCP method name: Get or Post.
        **kwargs : extra arguments
            anything else e.g. vendor specific parameters
        
        Example
        -------
            >>> wms = WebMapService('http://giswebservices.massgis.state.ma.us/geoserver/wms', version='1.1.1')
            >>> img = wms.getmap(layers=['massgis:GISDATA.SHORELINES_ARC'],\
                                 styles=[''],\
                                 srs='EPSG:4326',\
                                 bbox=(-70.8, 42, -70, 42.8),\
                                 size=(300, 300),\
                                 format='image/jpeg',\
                                 transparent=True)
            >>> out = open('example.jpg.jpg', 'wb')
            >>> out.write(img.read())
            >>> out.close()

        """
        try:
            base_url = next((m.get('url')
                             for m in self.getOperationByName('GetMap').methods
                             if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {'version': self.version, 'request': 'GetMap'}

        # check layers and styles
        assert len(layers) > 0
        request['layers'] = ','.join(layers)
        if styles:
            assert len(styles) == len(layers)
            request['styles'] = ','.join(styles)
        else:
            request['styles'] = ''

        # size
        request['width'] = str(size[0])
        request['height'] = str(size[1])

        request['srs'] = str(srs)
        request['bbox'] = ','.join([repr(x) for x in bbox])
        request['format'] = str(format)
        request['transparent'] = str(transparent).upper()
        request['bgcolor'] = '0x' + bgcolor[1:7]
        request['exceptions'] = str(exceptions)

        if time is not None:
            request['time'] = str(time)

        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        u = openURL(base_url,
                    data,
                    method,
                    username=self.username,
                    password=self.password)

        # check for service exceptions, and return
        if u.info()['Content-Type'] == 'application/vnd.ogc.se_xml':
            se_xml = u.read()
            se_tree = etree.fromstring(se_xml)
            err_message = unicode(
                se_tree.find('ServiceException').text).strip()
            raise ServiceException(err_message, se_xml)
        return u
Beispiel #29
0
    def getfeature(self,
                   typename=None,
                   filter=None,
                   bbox=None,
                   featureid=None,
                   featureversion=None,
                   propertyname=['*'],
                   maxfeatures=None,
                   srsname=None,
                   outputFormat=None,
                   method='{http://www.opengis.net/wfs}Get',
                   startindex=None):
        """Request and return feature data as a file-like object.

        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.
        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.
        srsname: string
            EPSG code to request the data in
        outputFormat: string (optional)
            Requested response format of the request.
        startindex: int (optional)
            Start position to return feature set (paging in combination with maxfeatures)

        There are 3 different modes of use

        1) typename and bbox (simple spatial query)
        2) typename and filter (more expressive)
        3) featureid (direct access to known features)
        """
        try:
            base_url = next(
                (m.get('url')
                 for m in self.getOperationByName('GetFeature').methods
                 if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {
            'service': 'WFS',
            'version': self.version,
            'request': 'GetFeature'
        }

        # check featureid
        if featureid:
            request['featureid'] = ','.join(featureid)
        elif bbox and typename:
            request['bbox'] = ','.join([repr(x) for x in bbox])
        elif filter and typename:
            request['filter'] = str(filter)

        if srsname:
            request['srsname'] = str(srsname)

        assert len(typename) > 0
        request['typename'] = ','.join(typename)

        if propertyname:
            request['propertyname'] = ','.join(propertyname)
        if featureversion:
            request['featureversion'] = str(featureversion)
        if maxfeatures:
            request['maxfeatures'] = str(maxfeatures)
        if startindex:
            request['startindex'] = str(startindex)

        if outputFormat is not None:
            request["outputFormat"] = outputFormat

        data = urlencode(request)
        log.debug("Making request: %s?%s" % (base_url, data))
        u = openURL(base_url, data, method, timeout=self.timeout)

        # 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, AttributeError):
            data = u.read()
            have_read = True
            length = len(data)

        if length < 32000:
            if not have_read:
                data = u.read()

            try:
                tree = etree.fromstring(data)
            except BaseException:
                # Not XML
                return StringIO(data)
            else:
                if tree.tag == "{%s}ServiceExceptionReport" % OGC_NAMESPACE:
                    se = tree.find(nspath('ServiceException', OGC_NAMESPACE))
                    raise ServiceException(str(se.text).strip())
                else:
                    return StringIO(data)
        else:
            if have_read:
                return StringIO(data)
            return u
Beispiel #30
0
    def getmap(self, layers=None, styles=None, srs=None, bbox=None,
               format=None, size=None, time=None, transparent=False,
               bgcolor='#FFFFFF',
               exceptions='XML',
               method='Get',
               **kwargs
               ):
        """Request and return an image from the WMS as a file-like object.

        Parameters
        ----------
        layers : list
            List of content layer names.
        styles : list
            Optional list of named styles, must be the same length as the
            layers list.
        srs : string
            A spatial reference system identifier.
        bbox : tuple
            (left, bottom, right, top) in srs units.
        format : string
            Output image format such as 'image/jpeg'.
        size : tuple
            (width, height) in pixels.
        transparent : bool
            Optional. Transparent background if True.
        bgcolor : string
            Optional. Image background color.
        method : string
            Optional. HTTP DCP method name: Get or Post.
        **kwargs : extra arguments
            anything else e.g. vendor specific parameters

        Example
        -------
            >>> wms = WebMapService('http://webservices.nationalatlas.gov/wms/1million',
                                    version='1.3.0')
            >>> img = wms.getmap(layers=['airports1m'],\
                                 styles=['default'],\
                                 srs='EPSG:4326',\
                                 bbox=(-176.646, 17.7016, -64.8017, 71.2854),\
                                 size=(300, 300),\
                                 format='image/jpeg',\
                                 transparent=True)
            >>> out = open('example.jpg.jpg', 'wb')
            >>> out.write(img.read())
            >>> out.close()

        """
        try:
            base_url = next((m.get('url') for m in self.getOperationByName('GetMap').methods if
                            m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {'version': self.version, 'request': 'GetMap'}

        # check layers and styles
        assert len(layers) > 0
        request['layers'] = ','.join(layers)
        if styles:
            assert len(styles) == len(layers)
            request['styles'] = ','.join(styles)
        else:
            request['styles'] = ''

        # size
        request['width'] = str(size[0])
        request['height'] = str(size[1])

        request['crs'] = str(srs)
        request['bbox'] = ','.join([repr(x) for x in bbox])
        request['format'] = str(format)
        request['transparent'] = str(transparent).upper()
        request['bgcolor'] = '0x' + bgcolor[1:7]
        request['exceptions'] = str(exceptions)

        if time is not None:
            request['time'] = str(time)

        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        print (data)

        u = openURL(base_url, data, method, username=self.username, password=self.password)

        # check for service exceptions, and return
        # error: AttributeError: 'RereadableURL' object has no attribute 'info'
        if u.info()['Content-Type'] in ['application/vnd.ogc.se_xml', 'text/xml']:
            se_xml = u.read()

            print (se_xml)

            se_tree = etree.fromstring(se_xml)
            # TODO: add the ogc namespace for this
            err_message = unicode(se_tree.find('{http://www.opengis.net/ogc}ServiceExceptionReport').text).strip()
            raise ServiceException(err_message, se_xml)
        return u
Beispiel #31
0
    def getrecords2(self, constraints=[], sortby=None, typenames='csw:Record', esn='summary', outputschema=namespaces['csw'], format=outputformat, startposition=0, maxrecords=10, cql=None, xml=None, resulttype='results'):
        """

        Construct and process a  GetRecords request

        Parameters
        ----------

        - constraints: the list of constraints (OgcExpression from owslib.fes module)
        - sortby: an OGC SortBy object (SortBy from owslib.fes module)
        - typenames: the typeNames to query against (default is csw:Record)
        - esn: the ElementSetName 'full', 'brief' or 'summary' (default is 'summary')        
        - outputschema: the outputSchema (default is 'http://www.opengis.net/cat/csw/2.0.2')
        - format: the outputFormat (default is 'application/xml')
        - startposition: requests a slice of the result set, starting at this position (default is 0)
        - maxrecords: the maximum number of records to return. No records are returned if 0 (default is 10)
        - cql: common query language text.  Note this overrides bbox, qtype, keywords
        - xml: raw XML request.  Note this overrides all other options
        - resulttype: the resultType 'hits', 'results', 'validate' (default is 'results')

        """

        if xml is not None:
            self.request = etree.fromstring(xml)
            val = self.request.find(util.nspath_eval('csw:Query/csw:ElementSetName', namespaces))
            if val is not None:
                esn = util.testXMLValue(val)
        else:
            # construct request
            node0 = self._setrootelement('csw:GetRecords')
            if etree.__name__ != 'lxml.etree':  # apply nsmap manually
                node0.set('xmlns:ows', namespaces['ows'])
                node0.set('xmlns:gmd', namespaces['gmd'])
                node0.set('xmlns:dif', namespaces['dif'])
                node0.set('xmlns:fgdc', namespaces['fgdc'])
            node0.set('outputSchema', outputschema)
            node0.set('outputFormat', format)
            node0.set('version', self.version)
            node0.set('service', self.service)
            node0.set('resultType', resulttype)
            if startposition > 0:
                node0.set('startPosition', str(startposition))
            node0.set('maxRecords', str(maxrecords))        
            node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location)

            node1 = etree.SubElement(node0, util.nspath_eval('csw:Query', namespaces))
            node1.set('typeNames', typenames)
        
            etree.SubElement(node1, util.nspath_eval('csw:ElementSetName', namespaces)).text = esn

            if any([len(constraints) > 0, cql is not None]): 
                node2 = etree.SubElement(node1, util.nspath_eval('csw:Constraint', namespaces))
                node2.set('version', '1.1.0')
                flt = fes.FilterRequest()
                if len(constraints) > 0:
                    node2.append(flt.setConstraintList(constraints))
                # Now add a CQL filter if passed in
                elif cql is not None:
                    etree.SubElement(node2, util.nspath_eval('csw:CqlText', namespaces)).text = cql
                
            if sortby is not None and isinstance(sortby, fes.SortBy):
                node1.append(sortby.toXML())

            self.request = node0

        self._invoke()
 
        if self.exceptionreport is None:
            self.results = {}
    
            # process search results attributes
            val = self._exml.find(util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('numberOfRecordsMatched')
            self.results['matches'] = int(util.testXMLValue(val, True))
            val = self._exml.find(util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('numberOfRecordsReturned')
            self.results['returned'] = int(util.testXMLValue(val, True))
            val = self._exml.find(util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('nextRecord')
            if val is not None:
                 self.results['nextrecord'] = int(util.testXMLValue(val, True))
            else:
                warnings.warn("""CSW Server did not supply a nextRecord value (it is optional), so the client
                should page through the results in another way.""")
                # For more info, see:
                # https://github.com/geopython/OWSLib/issues/100
                self.results['nextrecord'] = None

            # process list of matching records
            self.records = OrderedDict()

            self._parserecords(outputschema, esn)
Beispiel #32
0
    def transaction(self, ttype=None, typename='csw:Record', record=None, propertyname=None, propertyvalue=None, bbox=None, keywords=[], cql=None, identifier=None):
        """

        Construct and process a Transaction request

        Parameters
        ----------

        - ttype: the type of transaction 'insert, 'update', 'delete'
        - typename: the typename to describe (default is 'csw:Record')
        - record: the XML record to insert
        - propertyname: the RecordProperty/PropertyName to Filter against
        - propertyvalue: the RecordProperty Value to Filter against (for updates)
        - bbox: the bounding box of the spatial query in the form [minx,miny,maxx,maxy]
        - keywords: list of keywords
        - cql: common query language text.  Note this overrides bbox, qtype, keywords
        - identifier: record identifier.  Note this overrides bbox, qtype, keywords, cql

        """

        # construct request
        node0 = self._setrootelement('csw:Transaction')
        node0.set('version', self.version)
        node0.set('service', self.service)
        node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location)

        validtransactions = ['insert', 'update', 'delete']

        if ttype not in validtransactions:  # invalid transaction
            raise RuntimeError('Invalid transaction \'%s\'.' % ttype)

        node1 = etree.SubElement(node0, util.nspath_eval('csw:%s' % ttype.capitalize(), namespaces))

        if ttype != 'update':  
            node1.set('typeName', typename)

        if ttype == 'insert':
            if record is None:
                raise RuntimeError('Nothing to insert.')
            node1.append(etree.fromstring(record))
 
        if ttype == 'update':
            if record is not None:
                node1.append(etree.fromstring(record))
            else:
                if propertyname is not None and propertyvalue is not None:
                    node2 = etree.SubElement(node1, util.nspath_eval('csw:RecordProperty', namespaces))
                    etree.SubElement(node2, util.nspath_eval('csw:Name', namespaces)).text = propertyname
                    etree.SubElement(node2, util.nspath_eval('csw:Value', namespaces)).text = propertyvalue
                    self._setconstraint(node1, qtype, propertyname, keywords, bbox, cql, identifier)

        if ttype == 'delete':
            self._setconstraint(node1, None, propertyname, keywords, bbox, cql, identifier)

        self.request = node0

        self._invoke()
        self.results = {}

        if self.exceptionreport is None:
            self._parsetransactionsummary()
            self._parseinsertresult()
Beispiel #33
0
    def getfeature(self,
                   typename=None,
                   filter=None,
                   bbox=None,
                   featureid=None,
                   featureversion=None,
                   propertyname=['*'],
                   maxfeatures=None,
                   srsname=None,
                   outputFormat=None,
                   method='Get',
                   startindex=None):
        """Request and return feature data as a file-like object.

        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.
        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.
        srsname: string
            EPSG code to request the data in
        outputFormat: string (optional)
            Requested response format of the request.
        startindex: int (optional)
            Start position to return feature set (paging in combination with maxfeatures)

        There are 3 different modes of use

        1) typename and bbox (simple spatial query). It is assumed, that
            bbox coordinates are given *always* in the east,north order
        2) typename and filter (more expressive)
        3) featureid (direct access to known features)
        """
        try:
            base_url = next(
                (m.get('url')
                 for m in self.getOperationByName('GetFeature').methods
                 if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {
            'service': 'WFS',
            'version': self.version,
            'request': 'GetFeature'
        }

        if not isinstance(typename, list):
            typename = [typename]

        if srsname is not None:
            # check, if desired SRS is supported by the service for this typename
            if typename is not None:
                # convert srsname string to Crs object found in GetCaps
                srsnameobj = self.getSRS(srsname, typename[0])
                if srsnameobj is not None:
                    request['srsname'] = srsnameobj.id
                else:
                    options = ", ".join(
                        map(lambda x: x.id,
                            self.contents[typename[0]].crsOptions))
                    raise ServiceException(
                        "SRSNAME %s not supported.  Options: %s" %
                        (srsname, options))
            else:
                request['srsname'] = str(srsname)

        # check featureid
        if featureid:
            request['featureid'] = ','.join(featureid)

        # bbox
        elif bbox and typename:
            request["bbox"] = self.getBBOXKVP(bbox, typename)

        # or filter
        elif filter and typename:
            request['filter'] = str(filter)

        assert len(typename) > 0
        request['typename'] = ','.join(typename)

        if propertyname is not None:
            if not isinstance(propertyname, list):
                propertyname = [propertyname]
            request['propertyname'] = ','.join(propertyname)

        if featureversion is not None:
            request['featureversion'] = str(featureversion)
        if maxfeatures is not None:
            request['maxfeatures'] = str(maxfeatures)
        if startindex is not None:
            request['startindex'] = str(startindex)
        if outputFormat is not None:
            request["outputFormat"] = outputFormat

        data = urlencode(request)
        log.debug("Making request: %s?%s" % (base_url, data))
        u = openURL(base_url, data, method, timeout=self.timeout)

        # 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, AttributeError):
            data = u.read()
            have_read = True
            length = len(data)

        if length < 32000:
            if not have_read:
                data = u.read()

            try:
                tree = etree.fromstring(data)
            except BaseException:
                # Not XML
                return StringIO(data)
            else:
                if tree.tag == "{%s}ServiceExceptionReport" % namespaces["ogc"]:
                    se = tree.find(
                        nspath_eval('ServiceException', namespaces["ogc"]))
                    raise ServiceException(str(se.text).strip())
                else:
                    return StringIO(data)
        else:
            if have_read:
                return StringIO(data)
            return u
Beispiel #34
0
    def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
                   featureversion=None, propertyname=['*'], maxfeatures=None,
                   srsname=None, outputFormat=None, method='{http://www.opengis.net/wfs}Get',
                   startindex=None):
        """Request and return feature data as a file-like object.

        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.
        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.
        srsname: string
            EPSG code to request the data in
        outputFormat: string (optional)
            Requested response format of the request.
        startindex: int (optional)
            Start position to return feature set (paging in combination with maxfeatures)

        There are 3 different modes of use

        1) typename and bbox (simple spatial query)
        2) typename and filter (more expressive)
        3) featureid (direct access to known features)
        """
        try:
            base_url = next(
                (
                    m.get('url') for m in self.getOperationByName('GetFeature').methods
                    if m.get('type').lower() == method.lower()
                )
            )
        except StopIteration:
            base_url = self.url
        request = {'service': 'WFS', 'version': self.version, 'request': 'GetFeature'}

        # check featureid
        if featureid:
            request['featureid'] = ','.join(featureid)
        elif bbox and typename:
            request['bbox'] = ','.join([repr(x) for x in bbox])
        elif filter and typename:
            request['filter'] = str(filter)

        if srsname:
            request['srsname'] = str(srsname)

        assert len(typename) > 0
        request['typename'] = ','.join(typename)

        if propertyname:
            request['propertyname'] = ','.join(propertyname)
        if featureversion:
            request['featureversion'] = str(featureversion)
        if maxfeatures:
            request['maxfeatures'] = str(maxfeatures)
        if startindex:
            request['startindex'] = str(startindex)

        if outputFormat is not None:
            request["outputFormat"] = outputFormat

        data = urlencode(request)
        log.debug("Making request: %s?%s" % (base_url, data))
        u = openURL(base_url, data, method, timeout=self.timeout)

        # 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, AttributeError):
            data = u.read()
            have_read = True
            length = len(data)

        if length < 32000:
            if not have_read:
                data = u.read()

            try:
                tree = etree.fromstring(data)
            except BaseException:
                # Not XML
                return StringIO(data)
            else:
                if tree.tag == "{%s}ServiceExceptionReport" % OGC_NAMESPACE:
                    se = tree.find(nspath('ServiceException', OGC_NAMESPACE))
                    raise ServiceException(str(se.text).strip())
                else:
                    return StringIO(data)
        else:
            if have_read:
                return StringIO(data)
            return u
Beispiel #35
0
    def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
                   featureversion=None, propertyname=['*'], maxfeatures=None,
                   srsname=None, outputFormat=None, method='Get',
                   startindex=None):
        """Request and return feature data as a file-like object.

        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.
        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.
        srsname: string
            EPSG code to request the data in
        outputFormat: string (optional)
            Requested response format of the request.
        startindex: int (optional)
            Start position to return feature set (paging in combination with maxfeatures)

        There are 3 different modes of use

        1) typename and bbox (simple spatial query). It is assumed, that
            bbox coordinates are given *always* in the east,north order
        2) typename and filter (more expressive)
        3) featureid (direct access to known features)
        """
        try:
            base_url = next(
                (
                    m.get('url') for m in self.getOperationByName('GetFeature').methods
                    if m.get('type').lower() == method.lower()
                )
            )
        except StopIteration:
            base_url = self.url
        request = {'service': 'WFS', 'version': self.version, 'request': 'GetFeature'}

        if not isinstance(typename, list):
            typename = [typename]

        if srsname is not None:
            # check, if desired SRS is supported by the service for this typename
            if typename is not None:
                # convert srsname string to Crs object found in GetCaps
                srsnameobj = self.getSRS(srsname, typename[0])
                if srsnameobj is not None:
                    request['srsname'] = srsnameobj.id
                else:
                    options = ", ".join(map(lambda x: x.id, self.contents[typename[0]].crsOptions))
                    raise ServiceException(
                        "SRSNAME %s not supported.  Options: %s" % (srsname, options)
                    )
            else:
                request['srsname'] = str(srsname)

        # check featureid
        if featureid:
            request['featureid'] = ','.join(featureid)

        # bbox
        elif bbox and typename:
            request["bbox"] = self.getBBOXKVP(bbox, typename)

        # or filter
        elif filter and typename:
            request['filter'] = str(filter)

        assert len(typename) > 0
        request['typename'] = ','.join(typename)

        if propertyname is not None:
            if not isinstance(propertyname, list):
                propertyname = [propertyname]
            request['propertyname'] = ','.join(propertyname)

        if featureversion is not None:
            request['featureversion'] = str(featureversion)
        if maxfeatures is not None:
            request['maxfeatures'] = str(maxfeatures)
        if startindex is not None:
            request['startindex'] = str(startindex)
        if outputFormat is not None:
            request["outputFormat"] = outputFormat

        data = urlencode(request)
        log.debug("Making request: %s?%s" % (base_url, data))
        u = openURL(base_url, data, method, timeout=self.timeout)

        # 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, AttributeError):
            data = u.read()
            have_read = True
            length = len(data)

        if length < 32000:
            if not have_read:
                data = u.read()

            try:
                tree = etree.fromstring(data)
            except BaseException:
                # Not XML
                return StringIO(data)
            else:
                if tree.tag == "{%s}ServiceExceptionReport" % namespaces["ogc"]:
                    se = tree.find(nspath_eval('ServiceException', namespaces["ogc"]))
                    raise ServiceException(str(se.text).strip())
                else:
                    return StringIO(data)
        else:
            if have_read:
                return StringIO(data)
            return u
Beispiel #36
0
    def getfeature(self, typename=None, filter=None, bbox=None, featureid=None,
                   featureversion=None, propertyname=None, maxfeatures=None,storedQueryID=None, storedQueryParams={},
                   method='Get', outputFormat=None, startindex=None):
        """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.
        outputFormat: string (optional)
            Requested response format of the request.
        startindex: int (optional)
            Start position to return feature set (paging in combination with maxfeatures)

        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)
        """
        url = data = None
        if typename and type(typename) == type(""):
            typename = [typename]
        if method.upper() == "GET":
            (url) = self.getGETGetFeatureRequest(typename, filter, bbox, featureid,
                                                 featureversion, propertyname,
                                                 maxfeatures, storedQueryID,
                                                 storedQueryParams, outputFormat, 'Get', startindex)
            if log.isEnabledFor(logging.DEBUG):
                log.debug('GetFeature WFS GET url %s'% url)
        else:
            (url,data) = self.getPOSTGetFeatureRequest()


        # If method is 'Post', data will be None here
        u = urlopen(url, data, self.timeout)
        
        # 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()

            try:
                tree = etree.fromstring(data)
            except BaseException:
                # Not XML
                return StringIO(data)
            else:
                if tree.tag == "{%s}ServiceExceptionReport" % OGC_NAMESPACE:
                    se = tree.find(nspath('ServiceException', OGC_NAMESPACE))
                    raise ServiceException(str(se.text).strip())
                else:
                    return StringIO(data)
        else:
            if have_read:
                return StringIO(data)
            return u
Beispiel #37
0
    def getrecords(self, qtype=None, keywords=[], typenames='csw:Record', propertyname='csw:AnyText', bbox=None, esn='summary', sortby=None, outputschema=namespaces['csw'], format=outputformat, startposition=0, maxrecords=10, cql=None, xml=None, resulttype='results'):
        """

        Construct and process a  GetRecords request

        Parameters
        ----------

        - qtype: type of resource to query (i.e. service, dataset)
        - keywords: list of keywords
        - typenames: the typeNames to query against (default is csw:Record)
        - propertyname: the PropertyName to Filter against 
        - bbox: the bounding box of the spatial query in the form [minx,miny,maxx,maxy]
        - esn: the ElementSetName 'full', 'brief' or 'summary' (default is 'summary')
        - sortby: property to sort results on
        - outputschema: the outputSchema (default is 'http://www.opengis.net/cat/csw/2.0.2')
        - format: the outputFormat (default is 'application/xml')
        - startposition: requests a slice of the result set, starting at this position (default is 0)
        - maxrecords: the maximum number of records to return. No records are returned if 0 (default is 10)
        - cql: common query language text.  Note this overrides bbox, qtype, keywords
        - xml: raw XML request.  Note this overrides all other options
        - resulttype: the resultType 'hits', 'results', 'validate' (default is 'results')

        """

        warnings.warn("""Please use the updated 'getrecords2' method instead of 'getrecords'.  
        The 'getrecords' method will be upgraded to use the 'getrecords2' parameters
        in a future version of OWSLib.""")

        if xml is not None:
            self.request = etree.fromstring(xml)
            val = self.request.find(util.nspath_eval('csw:Query/csw:ElementSetName', namespaces))
            if val is not None:
                esn = util.testXMLValue(val)
        else:
            # construct request
            node0 = self._setrootelement('csw:GetRecords')
            if etree.__name__ != 'lxml.etree':  # apply nsmap manually
                node0.set('xmlns:ows', namespaces['ows'])
                node0.set('xmlns:gmd', namespaces['gmd'])
                node0.set('xmlns:dif', namespaces['dif'])
                node0.set('xmlns:fgdc', namespaces['fgdc'])
            node0.set('outputSchema', outputschema)
            node0.set('outputFormat', format)
            node0.set('version', self.version)
            node0.set('resultType', resulttype)
            node0.set('service', self.service)
            if startposition > 0:
                node0.set('startPosition', str(startposition))
            node0.set('maxRecords', str(maxrecords))
            node0.set(util.nspath_eval('xsi:schemaLocation', namespaces), schema_location)
    
            node1 = etree.SubElement(node0, util.nspath_eval('csw:Query', namespaces))
            node1.set('typeNames', typenames)
        
            etree.SubElement(node1, util.nspath_eval('csw:ElementSetName', namespaces)).text = esn
    
            self._setconstraint(node1, qtype, propertyname, keywords, bbox, cql, None)
    
            if sortby is not None:
                fes.setsortby(node1, sortby)
    
            self.request = node0

        self._invoke()
 
        if self.exceptionreport is None:
            self.results = {}
    
            # process search results attributes
            val = self._exml.find(util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('numberOfRecordsMatched')
            self.results['matches'] = int(util.testXMLValue(val, True))
            val = self._exml.find(util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('numberOfRecordsReturned')
            self.results['returned'] = int(util.testXMLValue(val, True))
            val = self._exml.find(util.nspath_eval('csw:SearchResults', namespaces)).attrib.get('nextRecord')
            self.results['nextrecord'] = int(util.testXMLValue(val, True))
    
            # process list of matching records
            self.records = OrderedDict()

            self._parserecords(outputschema, esn)
Beispiel #38
0
    def getmap(self,
               layers=None,
               styles=None,
               srs=None,
               bbox=None,
               format=None,
               size=None,
               time=None,
               transparent=False,
               bgcolor='#FFFFFF',
               exceptions='XML',
               method='Get',
               **kwargs):
        """Request and return an image from the WMS as a file-like object.

        Parameters
        ----------
        layers : list
            List of content layer names.
        styles : list
            Optional list of named styles, must be the same length as the
            layers list.
        srs : string
            A spatial reference system identifier.
        bbox : tuple
            (left, bottom, right, top) in srs units.
        format : string
            Output image format such as 'image/jpeg'.
        size : tuple
            (width, height) in pixels.
        transparent : bool
            Optional. Transparent background if True.
        bgcolor : string
            Optional. Image background color.
        method : string
            Optional. HTTP DCP method name: Get or Post.
        **kwargs : extra arguments
            anything else e.g. vendor specific parameters

        Example
        -------
            >>> wms = WebMapService('http://webservices.nationalatlas.gov/wms/1million',
                                    version='1.3.0')
            >>> img = wms.getmap(layers=['airports1m'],\
                                 styles=['default'],\
                                 srs='EPSG:4326',\
                                 bbox=(-176.646, 17.7016, -64.8017, 71.2854),\
                                 size=(300, 300),\
                                 format='image/jpeg',\
                                 transparent=True)
            >>> out = open('example.jpg.jpg', 'wb')
            >>> out.write(img.read())
            >>> out.close()

        """
        try:
            base_url = next((m.get('url')
                             for m in self.getOperationByName('GetMap').methods
                             if m.get('type').lower() == method.lower()))
        except StopIteration:
            base_url = self.url
        request = {'version': self.version, 'request': 'GetMap'}

        # check layers and styles
        assert len(layers) > 0
        request['layers'] = ','.join(layers)
        if styles:
            assert len(styles) == len(layers)
            request['styles'] = ','.join(styles)
        else:
            request['styles'] = ''

        # size
        request['width'] = str(size[0])
        request['height'] = str(size[1])

        request['crs'] = str(srs)
        request['bbox'] = ','.join([repr(x) for x in bbox])
        request['format'] = str(format)
        request['transparent'] = str(transparent).upper()
        request['bgcolor'] = '0x' + bgcolor[1:7]
        request['exceptions'] = str(exceptions)

        if time is not None:
            request['time'] = str(time)

        if kwargs:
            for kw in kwargs:
                request[kw] = kwargs[kw]

        data = urlencode(request)

        print(data)

        u = openURL(base_url,
                    data,
                    method,
                    username=self.username,
                    password=self.password)

        # check for service exceptions, and return
        # error: AttributeError: 'RereadableURL' object has no attribute 'info'
        if u.info()['Content-Type'] in [
                'application/vnd.ogc.se_xml', 'text/xml'
        ]:
            se_xml = u.read()

            print(se_xml)

            se_tree = etree.fromstring(se_xml)
            # TODO: add the ogc namespace for this
            err_message = unicode(
                se_tree.find(
                    '{http://www.opengis.net/ogc}ServiceExceptionReport').text
            ).strip()
            raise ServiceException(err_message, se_xml)
        return u