123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- """!
- @brief GDAL WMS driver.
- List of classes:
- - wms_drv::NullDevice
- - wms_drv::WMSGdalDrv
- (C) 2012-2021 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Stepan Turek <stepan.turek seznam.cz> (Mentor: Martin Landa)
- """
- import grass.script as grass
- try:
- from osgeo import gdal
- except:
- grass.fatal(
- _(
- "Unable to load GDAL Python bindings (requires package 'python-gdal' being installed)"
- )
- )
- import xml.etree.ElementTree as etree
- from wms_base import WMSBase, GetSRSParamVal
- class NullDevice:
- def write(self, s):
- pass
- class WMSGdalDrv(WMSBase):
- def __init__(self, createopt):
- super(WMSGdalDrv, self).__init__()
- self.proxy = None
- self.proxy_user_pw = None
- self.createopt = createopt
- def setProxy(self, proxy, proxy_user_pw=None):
- """Set the HTTP proxy and its user and password
- @input proxy HTTP proxy with [IP address]:[port]
- @input proxy_user_pw with [user name]:[password]
- """
- self.proxy = proxy
- self.proxy_user_pw = proxy_user_pw
- def _createXML(self):
- """!Create XML for GDAL WMS driver
- @return path to XML file
- """
- self._debug("_createXML", "started")
- gdal_wms = etree.Element("GDAL_WMS")
- service = etree.SubElement(gdal_wms, "Service")
- name = etree.Element("name")
- service.set("name", "WMS")
- version = etree.SubElement(service, "Version")
- version.text = self.params["wms_version"]
- server_url = etree.SubElement(service, "ServerUrl")
- server_url.text = self.params["url"]
- srs = etree.SubElement(service, self.params["proj_name"])
- srs.text = GetSRSParamVal(self.params["srs"])
- image_format = etree.SubElement(service, "ImageFormat")
- image_format.text = self.params["format"]
- image_format = etree.SubElement(service, "Transparent")
- image_format.text = self.params["transparent"]
- layers = etree.SubElement(service, "Layers")
- layers.text = self.params["layers"]
- styles = etree.SubElement(service, "Styles")
- styles.text = self.params["styles"]
- data_window = etree.SubElement(gdal_wms, "DataWindow")
- upper_left_x = etree.SubElement(data_window, "UpperLeftX")
- upper_left_x.text = str(self.bbox["minx"])
- upper_left_y = etree.SubElement(data_window, "UpperLeftY")
- upper_left_y.text = str(self.bbox["maxy"])
- lower_right_x = etree.SubElement(data_window, "LowerRightX")
- lower_right_x.text = str(self.bbox["maxx"])
- lower_right_y = etree.SubElement(data_window, "LowerRightY")
- lower_right_y.text = str(self.bbox["miny"])
- size_x = etree.SubElement(data_window, "SizeX")
- size_x.text = str(self.region["cols"])
- size_y = etree.SubElement(data_window, "SizeY")
- size_y.text = str(self.region["rows"])
- # RGB + alpha
- self.temp_map_bands_num = 4
- block_size_x = etree.SubElement(gdal_wms, "BandsCount")
- block_size_x.text = str(self.temp_map_bands_num)
- block_size_x = etree.SubElement(gdal_wms, "BlockSizeX")
- block_size_x.text = str(self.tile_size["cols"])
- block_size_y = etree.SubElement(gdal_wms, "BlockSizeY")
- block_size_y.text = str(self.tile_size["rows"])
- if self.params["username"] and self.params["password"]:
- user_password = etree.SubElement(gdal_wms, "UserPwd")
- user_password.text = "%s:%s" % (
- self.params["username"],
- self.params["password"],
- )
- xml_file = self._tempfile()
- etree.ElementTree(gdal_wms).write(xml_file)
- self._debug("_createXML", "finished -> %s" % xml_file)
- return xml_file
- def _download(self):
- """!Downloads data from WMS server using GDAL WMS driver
- @return temp_map with stored downloaded data
- """
- grass.message("Downloading data from WMS server...")
- # GDAL WMS driver does not flip geographic coordinates
- # according to WMS standard 1.3.0.
- if (
- "+proj=latlong" in self.proj_srs or "+proj=longlat" in self.proj_srs
- ) and self.params["wms_version"] == "1.3.0":
- grass.warning(
- _(
- "If module will not be able to fetch the data in this "
- + "geographic projection, \n try 'WMS_GRASS' driver or use WMS version 1.1.1."
- )
- )
- self._debug("_download", "started")
- temp_map = self._tempfile()
- xml_file = self._createXML()
- # print xml file content for debug level 1
- file = open(xml_file, "r")
- grass.debug("WMS request XML:\n%s" % file.read(), 1)
- file.close()
- if self.proxy:
- gdal.SetConfigOption("GDAL_HTTP_PROXY", str(self.proxy))
- if self.proxy_user_pw:
- gdal.SetConfigOption("GDAL_HTTP_PROXYUSERPWD", str(self.proxy_user_pw))
- wms_dataset = gdal.Open(xml_file, gdal.GA_ReadOnly)
- grass.try_remove(xml_file)
- if wms_dataset is None:
- grass.fatal(_("Unable to open GDAL WMS driver"))
- self._debug("_download", "GDAL dataset created")
- driver = gdal.GetDriverByName(self.gdal_drv_format)
- if driver is None:
- grass.fatal(_("Unable to find %s driver" % format))
- metadata = driver.GetMetadata()
- if (
- gdal.DCAP_CREATECOPY not in metadata
- or metadata[gdal.DCAP_CREATECOPY] == "NO"
- ):
- grass.fatal(
- _("Driver %s supports CreateCopy() method.") % self.gdal_drv_name
- )
- self._debug("_download", "calling GDAL CreateCopy...")
- if self.createopt is None:
- temp_map_dataset = driver.CreateCopy(temp_map, wms_dataset, 0)
- else:
- self._debug("_download", "Using GDAL createopt <%s>" % str(self.createopt))
- temp_map_dataset = driver.CreateCopy(
- temp_map, wms_dataset, 0, self.createopt
- )
- if temp_map_dataset is None:
- grass.fatal(_("Incorrect WMS query"))
- temp_map_dataset = None
- wms_dataset = None
- self._debug("_download", "finished")
- return temp_map
|