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
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())
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
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())
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
def getCoverage(self, identifier=None, bbox=None, time=None, format=None, crs=None, width=None, height=None, resx=None, resy=None, resz=None, parameter=None, method='Get', **kwargs): """Request and return a coverage from the WCS as a file-like object note: additional **kwargs helps with multi-version implementation core keyword arguments should be supported cross version example: cvg=wcs.getCoverage(identifier=['TuMYrRQ4'], timeSequence=['2792-06-01T00:00:00.0'], bbox=(-112,36,-106,41),format='cf-netcdf') is equivalent to: http://myhost/mywcs?SERVICE=WCS&REQUEST=GetCoverage&IDENTIFIER=TuMYrRQ4&VERSION=1.1.0&BOUNDINGBOX=-180,-90,180,90&TIME=2792-06-01T00:00:00.0&FORMAT=cf-netcdf """ if log.isEnabledFor(logging.DEBUG): log.debug('''WCS 1.0.0 DEBUG: Parameters passed to GetCoverage: identifier=%s, bbox=%s, time=%s, format=%s, crs=%s, width=%s, height=%s, resx=%s, resy=%s, resz=%s, parameter=%s, method=%s, other_arguments=%s''' % ( identifier, bbox, time, format, crs, width, height, resx, resy, resz, parameter, method, str(kwargs) ) ) try: base_url = next( ( m.get('url') for m in self.getOperationByName('GetCoverage').methods if m.get('type').lower() == method.lower() ) ) except StopIteration: base_url = self.url if log.isEnabledFor(logging.DEBUG): log.debug('WCS 1.0.0 DEBUG: base url of server: %s' % base_url) # process kwargs request = {'version': self.version, 'request': 'GetCoverage', 'service': 'WCS'} assert len(identifier) > 0 request['Coverage'] = identifier # request['identifier'] = ','.join(identifier) if bbox: request['BBox'] = ','.join([self.__makeString(x) for x in bbox]) else: request['BBox'] = None if time: request['time'] = ','.join(time) if crs: request['crs'] = crs request['format'] = format if width: request['width'] = width if height: request['height'] = height if resx: request['resx'] = resx if resy: request['resy'] = resy if resz: request['resz'] = resz # anything else e.g. vendor specific parameters must go through kwargs if kwargs: for kw in kwargs: request[kw] = kwargs[kw] # encode and request data = urlencode(request) if log.isEnabledFor(logging.DEBUG): log.debug('WCS 1.0.0 DEBUG: Second part of URL: %s' % data) u = openURL(base_url, data, method, self.cookies) return u
def getCoverage(self, identifier=None, bbox=None, time=None, format=None, store=False, rangesubset=None, gridbaseCRS=None, gridtype=None, gridCS=None, gridorigin=None, gridoffsets=None, method='Get', **kwargs): """Request and return a coverage from the WCS as a file-like object note: additional **kwargs helps with multi-version implementation core keyword arguments should be supported cross version example: cvg=wcs.getCoverageRequest(identifier=['TuMYrRQ4'], time=['2792-06-01T00:00:00.0'], bbox=(-112,36,-106,41),format='application/netcdf', store='true') is equivalent to: http://myhost/mywcs?SERVICE=WCS&REQUEST=GetCoverage&IDENTIFIER=TuMYrRQ4&VERSION=1.1.0&BOUNDINGBOX= -180,-90,180,90&TIMESEQUENCE=2792-06-01T00:00:00.0&FORMAT=application/netcdf if store = true, returns a coverages XML file if store = false, returns a multipart mime """ if log.isEnabledFor(logging.DEBUG): log.debug('''WCS 1.1.0 DEBUG: Parameters passed to GetCoverage: identifier=%s, bbox=%s, time=%s, format=%s, rangesubset=%s, gridbaseCRS=%s, gridtype=%s, gridCS=%s, gridorigin=%s, gridoffsets=%s, method=%s, other_arguments=%s''' % ( identifier, bbox, time, format, rangesubset, gridbaseCRS, gridtype, gridCS, gridorigin, gridoffsets, method, str(kwargs) )) if method == 'Get': method = '{http://www.opengis.net/wcs/1.1/ows}Get' try: base_url = next( (m.get('url') for m in self.getOperationByName('GetCoverage').methods if m.get('type').lower() == method.lower()) ) except StopIteration: base_url = self.url # process kwargs request = {'version': self.version, 'request': 'GetCoverage', 'service': 'WCS'} assert len(identifier) > 0 request['identifier'] = identifier # request['identifier'] = ','.join(identifier) if bbox: request['boundingbox'] = ','.join([repr(x) for x in bbox]) if time: request['timesequence'] = ','.join(time) request['format'] = format request['store'] = store # rangesubset: untested - require a server implementation if rangesubset: request['RangeSubset'] = rangesubset # GridCRS structure: untested - require a server implementation if gridbaseCRS: request['gridbaseCRS'] = gridbaseCRS if gridtype: request['gridtype'] = gridtype if gridCS: request['gridCS'] = gridCS if gridorigin: request['gridorigin'] = gridorigin if gridoffsets: request['gridoffsets'] = gridoffsets # anything else e.g. vendor specific parameters must go through kwargs if kwargs: for kw in kwargs: request[kw] = kwargs[kw] # encode and request data = urlencode(request) u = openURL(base_url, data, method, self.cookies) return u
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
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
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
def getCoverage(self, identifier=None, bbox=None, time=None, format=None, store=False, rangesubset=None, gridbaseCRS=None, gridtype=None, gridCS=None, gridorigin=None, gridoffsets=None, method='Get', **kwargs): """Request and return a coverage from the WCS as a file-like object note: additional **kwargs helps with multi-version implementation core keyword arguments should be supported cross version example: cvg=wcs.getCoverageRequest(identifier=['TuMYrRQ4'], time=['2792-06-01T00:00:00.0'], bbox=(-112,36,-106,41),format='application/netcdf', store='true') is equivalent to: http://myhost/mywcs?SERVICE=WCS&REQUEST=GetCoverage&IDENTIFIER=TuMYrRQ4&VERSION=1.1.0&BOUNDINGBOX= -180,-90,180,90&TIMESEQUENCE=2792-06-01T00:00:00.0&FORMAT=application/netcdf if store = true, returns a coverages XML file if store = false, returns a multipart mime """ if log.isEnabledFor(logging.DEBUG): log.debug( '''WCS 1.1.0 DEBUG: Parameters passed to GetCoverage: identifier=%s, bbox=%s, time=%s, format=%s, rangesubset=%s, gridbaseCRS=%s, gridtype=%s, gridCS=%s, gridorigin=%s, gridoffsets=%s, method=%s, other_arguments=%s''' % (identifier, bbox, time, format, rangesubset, gridbaseCRS, gridtype, gridCS, gridorigin, gridoffsets, method, str(kwargs))) if method == 'Get': method = '{http://www.opengis.net/wcs/1.1/ows}Get' try: base_url = next( (m.get('url') for m in self.getOperationByName('GetCoverage').methods if m.get('type').lower() == method.lower())) except StopIteration: base_url = self.url # process kwargs request = { 'version': self.version, 'request': 'GetCoverage', 'service': 'WCS' } assert len(identifier) > 0 request['identifier'] = identifier # request['identifier'] = ','.join(identifier) if bbox: request['boundingbox'] = ','.join([repr(x) for x in bbox]) if time: request['timesequence'] = ','.join(time) request['format'] = format request['store'] = store # rangesubset: untested - require a server implementation if rangesubset: request['RangeSubset'] = rangesubset # GridCRS structure: untested - require a server implementation if gridbaseCRS: request['gridbaseCRS'] = gridbaseCRS if gridtype: request['gridtype'] = gridtype if gridCS: request['gridCS'] = gridCS if gridorigin: request['gridorigin'] = gridorigin if gridoffsets: request['gridoffsets'] = gridoffsets # anything else e.g. vendor specific parameters must go through kwargs if kwargs: for kw in kwargs: request[kw] = kwargs[kw] # encode and request data = urlencode(request) u = openURL(base_url, data, method, self.cookies) return u
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
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
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
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
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
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