def create_mapproxy_image(yaml_file, img_file): with open(yaml_file, 'rb') as f: yaml_text = yaml.load(f) captured = [] # Inline function that accesses captured. Do not refactor out of this function. def start_response(status, headers, exc_info=None): captured[:] = [status, headers, exc_info] return output.append output = [] bbox_req, lay_name = get_path_info_params(yaml_text) path_info = ( '/service?LAYERS={0}&FORMAT=image%2Fpng&SRS=EPSG%3A4326' '&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&TRANSPARENT=TRUE&SERVICE=WMS&VERSION=1.1.1&' 'REQUEST=GetMap&STYLES=&BBOX={1}&WIDTH=200&HEIGHT=150').format( lay_name, bbox_req) conf_options = load_default_config() # Merge both load_config(conf_options, config_dict=yaml_text) conf = ProxyConfiguration(conf_options, seed=False, renderd=False) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Get a response from MapProxyAppy as if it was running standalone. environ = environ_from_url(path_info) app_iter = None try: app_iter = app(environ, start_response) except: return 1 if app_iter is None: return 1 try: with open(img_file, 'wb') as img: img.write(app_iter.next()) except: return 1 content = 'error' with open(img_file, 'rb') as img: content = img.read() if 'error' in content: os.remove(img_file) return 1 return 0
def mapit(mapproxy_conf, layername, outputmimeformat, lonlatbbox, imagesize, outputfilename=None, time=None): """ This automates the creation of a map image. :param mapproxy_conf: The mapproxy in-memory configuration dictionary. :param layername: The name of the layer to image. :param outputmimeformat: The mime format (i.e. image/png, image/jpeg) of the output :param lonlatbbox: The bounding box as a tuple, (west, south, east, north) :param imagesize: The images size as a tuple, (width, height) :param outputfilename: An optional output filename, if None, then no file will be written. :param time: An optional time string for layers that have the time dimension :return: The binary data for the image generated. """ if time is None: time = '' mapproxy_conf = copy.deepcopy(mapproxy_conf) # dup it for replacing time for source in mapproxy_conf['sources']: mapproxy_conf['sources'][source]['url'] = mapproxy_conf['sources'][ source]['url'].replace("{Time}", time) transparent = 'false' if 'png' in outputmimeformat.lower(): transparent = 'true' querystring = "LAYERS=%s&FORMAT=%s&SRS=EPSG:4326&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&TRANSPARENT=%s&STYLES=&BBOX=%f,%f,%f,%f&WIDTH=%d&HEIGHT=%d" % ( layername, outputmimeformat, transparent, lonlatbbox[0], lonlatbbox[1], lonlatbbox[2], lonlatbbox[3], imagesize[0], imagesize[1]) conf = ProxyConfiguration(mapproxy_conf, conf_base_dir='', seed=False, renderd=False) services = conf.configured_services() myreq = { 'QUERY_STRING': querystring, 'SERVER_NAME': '', 'SERVER_PORT': '', 'wsgi.url_scheme': '', } response = services[0].handle(Request(myreq)) data = response.data if outputfilename: f = open(outputfilename, "w") f.write(data) return data
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False): """Creates a mapproxy config for a given layers """ bbox = [ float(layer.bbox_x0), float(layer.bbox_y0), float(layer.bbox_x1), float(layer.bbox_y1) ] url = str(layer.service.url) layer_name = simple_name(layer.name) srs = 'EPSG:4326' bbox_srs = 'EPSG:4326' grid_srs = 'EPSG:3857' if layer.type == 'ESRI:ArcGIS:MapServer' or layer.type == 'ESRI:ArcGIS:ImageServer': url = str(layer.service.url).split('?')[0] + 'WMSServer?' # blindly replace it with /arcgis/ url = url.replace("/ArcGIS/rest/", "/arcgis/") # same for uppercase url = url.replace("/arcgis/rest/", "/arcgis/") # and for old versions url = url.replace("ArcX/rest/services", "arcx/services") # in uppercase or lowercase url = url.replace("arcx/rest/services", "arcx/services") srs = 'EPSG:3857' bbox_srs = 'EPSG:3857' if layer.type == 'Hypermap:WARPER': url = str(layer.url.replace("maps//wms", "maps/wms")) grid_srs = 'EPSG:900913' if layer.type == 'Hypermap:WorldMap': url = str(layer.url.replace("maps//wms", "maps/wms")) default_source = { 'type': 'wms', 'coverage': { 'bbox': bbox, 'srs': srs, 'bbox_srs': bbox_srs, 'supported_srs': ['EPSG:4326', 'EPSG:900913', 'EPSG:3857'], }, 'req': { 'layers': layer_name, 'url': url, 'transparent': True, }, } if layer.type == 'ESRI:ArcGIS:MapServer': default_source = { 'type': 'tile', 'url': str(layer.service.url).split('?')[0] + 'tile/%(z)s/%(y)s/%(x)s', 'grid': 'default_grid', 'transparent': True, } # A source is the WMS config sources = {'default_source': default_source} # A grid is where it will be projects (Mercator in our case) grids = { 'default_grid': { 'tile_size': [256, 256], 'srs': grid_srs, 'origin': 'nw', } } # A cache that does not store for now. It needs a grid and a source. caches = { 'default_cache': { 'cache': { 'type': 'file', 'directory_layout': 'tms', 'directory': os.path.join( tempfile.gettempdir(), 'mapproxy', 'layer', '%s' % layer.id, 'map', 'wmts', layer_name, 'default_grid', ), }, 'grids': ['default_grid'], 'sources': ['default_source'] }, } # The layer is connected to the cache layers = [ { 'name': layer_name, 'sources': ['default_cache'], 'title': str(layer.title), }, ] # Services expose all layers. # WMS is used for reprojecting # TMS is used for easy tiles # Demo is used to test our installation, may be disabled in final version services = { 'wms': { 'image_formats': ['image/png'], 'md': { 'abstract': 'This is the Harvard HyperMap Proxy.', 'title': 'Harvard HyperMap Proxy' }, 'srs': ['EPSG:4326', 'EPSG:3857'], 'versions': ['1.1.1'] }, 'wmts': { 'restful': True, 'restful_template': '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png', }, 'tms': { 'origin': 'nw', }, 'demo': None, } global_config = { 'http': { 'ssl_no_cert_checks': True }, } # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Populate a dictionary with custom config changes extra_config = { 'caches': caches, 'grids': grids, 'layers': layers, 'services': services, 'sources': sources, 'globals': global_config, } yaml_config = yaml.dump(extra_config, default_flow_style=False) # If you want to test the resulting configuration. Turn on the next # line and use that to generate a yaml config. # assert False # Merge both load_config(conf_options, config_dict=extra_config) # Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: log.warn(error) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError('invalid configuration') errors = validate_references(conf_options) for error in errors: log.warn(error) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Wrap it in an object that allows to get requests by path as a string. return TestApp(app), yaml_config
def create_mapproxy_app(slug: str, user: User = None) -> TestApp: mapproxy_config_key = get_mapproxy_config_template(slug, user=user) mapproxy_config = cache.get(mapproxy_config_key) conf_dict = cache.get_or_set(f"base-config-{slug}", lambda: get_conf_dict(slug), 360) if not mapproxy_config: # TODO: place this somewhere else consolidate settings. base_config: Dict[str, Any] = { "services": { "demo": None, "tms": None, "wmts": { "featureinfo_formats": [ {"mimetype": "application/json", "suffix": "json"}, {"mimetype": "application/gml+xml; version=3.1", "suffix": "gml"}, ] }, }, # Cache based on slug so that the caches don't overwrite each other. "caches": {slug: {"cache": {"type": "file"}, "sources": ["default"], "grids": ["default"]}}, "layers": [{"name": slug, "title": slug, "sources": [slug]}], "globals": {"cache": {"base_dir": getattr(settings, "TILE_CACHE_DIR")}}, } if conf_dict["sources"].get("info"): base_config["caches"][slug]["sources"] += ["info"] if conf_dict["sources"].get("footprint"): base_config["caches"][get_footprint_layer_name(slug)] = { "cache": {"type": "file"}, "sources": ["footprint"], "grids": ["default"], } base_config["layers"] += [ { "name": get_footprint_layer_name(slug), "title": get_footprint_layer_name(slug), "sources": [get_footprint_layer_name(slug)], } ] base_config, conf_dict = add_restricted_regions_to_config(base_config, conf_dict, slug, None) try: mapproxy_config = load_default_config() load_config(mapproxy_config, config_dict=base_config) load_config(mapproxy_config, config_dict=conf_dict) mapproxy_configuration = ProxyConfiguration(mapproxy_config) if settings.REGIONAL_JUSTIFICATION_TIMEOUT_DAYS: regional_justification_timeout = settings.REGIONAL_JUSTIFICATION_TIMEOUT_DAYS * 86400 else: regional_justification_timeout = None mapproxy_configs_set = cache.get_or_set(mapproxy_config_keys_index, set()) mapproxy_configs_set.add(mapproxy_config_key) cache.set(mapproxy_config_keys_index, mapproxy_configs_set) cache.set(mapproxy_config_key, mapproxy_config, regional_justification_timeout) except ConfigurationError as e: logger.error(e) raise else: try: mapproxy_configuration = ProxyConfiguration(mapproxy_config) except ConfigurationError as e: logger.error(e) raise cert_info = conf_dict.get("cert_info") auth_requests.patch_https(cert_info=cert_info) cred_var = conf_dict.get("cred_var") auth_requests.patch_mapproxy_opener_cache(slug=slug, cred_var=cred_var) app = MapProxyApp(mapproxy_configuration.configured_services(), mapproxy_config) return TestApp(app)
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False): """Creates a mapproxy config for a given layer-like object. Compatible with django-registry and GeoNode. """ bbox = list(wkt2geom(layer.wkt_geometry)) # TODO: Check for correct url url = 'http://test.registry.org' # url = str(layer.service.url) layer_name = str(layer.title) srs = 'EPSG:4326' bbox_srs = 'EPSG:4326' grid_srs = 'EPSG:3857' default_source = { 'type': 'wms', 'coverage': { 'bbox': bbox, 'srs': srs, 'bbox_srs': bbox_srs, 'supported_srs': ['EPSG:4326', 'EPSG:900913', 'EPSG:3857'], }, 'req': { 'layers': str(layer.title), 'url': url, 'transparent': True, }, } if layer.type == 'ESRI:ArcGIS:MapServer' or layer.type == 'ESRI:ArcGIS:ImageServer': # blindly replace it with /arcgis/ url = url.replace("/ArcGIS/rest/", "/arcgis/") # same for uppercase url = url.replace("/arcgis/rest/", "/arcgis/") # and for old versions url = url.replace("ArcX/rest/services", "arcx/services") # in uppercase or lowercase url = url.replace("arcx/rest/services", "arcx/services") srs = 'EPSG:3857' bbox_srs = 'EPSG:3857' default_source = { 'type': 'arcgis', 'req': { 'url': url, 'grid': 'default_grid', 'transparent': True, }, } # A source is the WMS config sources = {'default_source': default_source} # A grid is where it will be projects (Mercator in our case) grids = { 'default_grid': { 'tile_size': [256, 256], 'srs': grid_srs, 'origin': 'nw', } } # A cache that does not store for now. It needs a grid and a source. caches = { 'default_cache': { 'disable_storage': True, 'grids': ['default_grid'], 'sources': ['default_source'] }, } # The layer is connected to the cache layers = [ { 'name': layer_name, 'sources': ['default_cache'], 'title': str(layer.title), }, ] # Services expose all layers. # WMS is used for reprojecting # TMS is used for easy tiles # Demo is used to test our installation, may be disabled in final version services = { 'wms': { 'image_formats': ['image/png'], 'md': { 'abstract': 'This is the Harvard HyperMap Proxy.', 'title': 'Harvard HyperMap Proxy' }, 'srs': ['EPSG:4326', 'EPSG:3857'], 'versions': ['1.1.1'] }, 'wmts': { 'restful': True, 'restful_template': '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png', }, 'tms': { 'origin': 'nw', }, 'demo': None, } global_config = { 'http': { 'ssl_no_cert_checks': True }, } # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Populate a dictionary with custom config changes extra_config = { 'caches': caches, 'grids': grids, 'layers': layers, 'services': services, 'sources': sources, 'globals': global_config, } yaml_config = yaml.dump(extra_config, default_flow_style=False) # If you want to test the resulting configuration. Turn on the next # line and use that to generate a yaml config. # assert False # Merge both load_config(conf_options, config_dict=extra_config) # TODO: Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: LOGGER.warn(error) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError('invalid configuration') errors = validate_references(conf_options) for error in errors: LOGGER.warn(error) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) return app, yaml_config
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False): """Creates a mapproxy config for a given layers """ bbox = [float(layer.bbox_x0), float(layer.bbox_y0), float(layer.bbox_x1), float(layer.bbox_y1)] url = str(layer.service.url) layer_name = simple_name(layer.name) srs = 'EPSG:4326' bbox_srs = 'EPSG:4326' grid_srs = 'EPSG:3857' if layer.type == 'ESRI:ArcGIS:MapServer' or layer.type == 'ESRI:ArcGIS:ImageServer': url = str(layer.service.url).split('?')[0] + 'WMSServer?' # blindly replace it with /arcgis/ url = url.replace("/ArcGIS/rest/", "/arcgis/") # same for uppercase url = url.replace("/arcgis/rest/", "/arcgis/") # and for old versions url = url.replace("ArcX/rest/services", "arcx/services") # in uppercase or lowercase url = url.replace("arcx/rest/services", "arcx/services") srs = 'EPSG:3857' bbox_srs = 'EPSG:3857' if layer.type == 'Hypermap:WARPER': url = str(layer.url.replace("maps//wms", "maps/wms")) grid_srs = 'EPSG:900913' if layer.type == 'Hypermap:WorldMap': url = str(layer.url.replace("maps//wms", "maps/wms")) default_source = { 'type': 'wms', 'coverage': { 'bbox': bbox, 'srs': srs, 'bbox_srs': bbox_srs, 'supported_srs': ['EPSG:4326', 'EPSG:900913', 'EPSG:3857'], }, 'req': { 'layers': layer_name, 'url': url, 'transparent': True, }, } if layer.type == 'ESRI:ArcGIS:MapServer': default_source = { 'type': 'tile', 'url': str(layer.service.url).split('?')[0] + 'tile/%(z)s/%(y)s/%(x)s', 'grid': 'default_grid', 'transparent': True, } # A source is the WMS config sources = { 'default_source': default_source } # A grid is where it will be projects (Mercator in our case) grids = { 'default_grid': { 'tile_size': [256, 256], 'srs': grid_srs, 'origin': 'nw', } } # A cache that does not store for now. It needs a grid and a source. caches = {'default_cache': { 'cache': { 'type': 'file', 'directory_layout': 'tms', 'directory': os.path.join(tempfile.gettempdir(), 'mapproxy', 'layer', '%s' % layer.id, 'map', 'wmts', layer_name, 'default_grid', ), }, 'grids': ['default_grid'], 'sources': ['default_source']}, } # The layer is connected to the cache layers = [ {'name': layer_name, 'sources': ['default_cache'], 'title': str(layer.title), }, ] # Services expose all layers. # WMS is used for reprojecting # TMS is used for easy tiles # Demo is used to test our installation, may be disabled in final version services = { 'wms': {'image_formats': ['image/png'], 'md': {'abstract': 'This is the Harvard HyperMap Proxy.', 'title': 'Harvard HyperMap Proxy'}, 'srs': ['EPSG:4326', 'EPSG:3857'], 'versions': ['1.1.1']}, 'wmts': { 'restful': True, 'restful_template': '/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png', }, 'tms': { 'origin': 'nw', }, 'demo': None, } global_config = { 'http': {'ssl_no_cert_checks': True}, } # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Populate a dictionary with custom config changes extra_config = { 'caches': caches, 'grids': grids, 'layers': layers, 'services': services, 'sources': sources, 'globals': global_config, } yaml_config = yaml.dump(extra_config, default_flow_style=False) # If you want to test the resulting configuration. Turn on the next # line and use that to generate a yaml config. # assert False # Merge both load_config(conf_options, config_dict=extra_config) # Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: log.warn(error) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError('invalid configuration') errors = validate_references(conf_options) for error in errors: log.warn(error) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Wrap it in an object that allows to get requests by path as a string. return TestApp(app), yaml_config
def get_mapproxy(layer, seed=False, ignore_warnings=True, renderd=False): """Creates a mapproxy config for a given layers """ bbox = [float(layer.bbox_x0), float(layer.bbox_y0), float(layer.bbox_x1), float(layer.bbox_y1)] url = str(layer.service.url) layer_name = simple_name(layer.name) srs = "EPSG:4326" bbox_srs = "EPSG:4326" grid_srs = "EPSG:3857" if layer.service.type == "ESRI_MapServer" or layer.service.type == "ESRI_ImageServer": url = str(layer.service.url).split("?")[0] + "WMSServer?" # blindly replace it with /arcgis/ url = url.replace("/ArcGIS/rest/", "/arcgis/") # same for uppercase url = url.replace("/arcgis/rest/", "/arcgis/") # and for old versions url = url.replace("ArcX/rest/services", "arcx/services") # in uppercase or lowercase url = url.replace("arcx/rest/services", "arcx/services") srs = "EPSG:3857" bbox_srs = "EPSG:3857" if layer.service.type == "WARPER": url = str(layer.url.replace("maps//wms", "maps/wms")) grid_srs = "EPSG:900913" if layer.service.type == "WM": url = str(layer.url.replace("maps//wms", "maps/wms")) default_source = { "type": "wms", "coverage": { "bbox": bbox, "srs": srs, "bbox_srs": bbox_srs, "supported_srs": ["EPSG:4326", "EPSG:900913", "EPSG:3857"], }, "req": {"layers": layer_name, "url": url, "transparent": True}, } if layer.service.type == "ESRI_MapServer": default_source = { "type": "tile", "url": str(layer.service.url).split("?")[0] + "tile/%(z)s/%(y)s/%(x)s", "grid": "default_grid", "transparent": True, } # A source is the WMS config sources = {"default_source": default_source} # A grid is where it will be projects (Mercator in our case) grids = {"default_grid": {"tile_size": [256, 256], "srs": grid_srs, "origin": "nw"}} # A cache that does not store for now. It needs a grid and a source. caches = { "default_cache": { "cache": { "type": "file", "directory_layout": "tms", "directory": os.path.join( tempfile.gettempdir(), "mapproxy", "layer", "%s" % layer.id, "map", "wmts", layer_name, "default_grid", ), }, "grids": ["default_grid"], "sources": ["default_source"], } } # The layer is connected to the cache layers = [{"name": layer_name, "sources": ["default_cache"], "title": str(layer.title)}] # Services expose all layers. # WMS is used for reprojecting # TMS is used for easy tiles # Demo is used to test our installation, may be disabled in final version services = { "wms": { "image_formats": ["image/png"], "md": {"abstract": "This is the Harvard HyperMap Proxy.", "title": "Harvard HyperMap Proxy"}, "srs": ["EPSG:4326", "EPSG:3857"], "versions": ["1.1.1"], }, "wmts": {"restful": True, "restful_template": "/{Layer}/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png"}, "tms": {"origin": "nw"}, "demo": None, } # Start with a sane configuration using MapProxy's defaults conf_options = load_default_config() # Populate a dictionary with custom config changes extra_config = {"caches": caches, "grids": grids, "layers": layers, "services": services, "sources": sources} yaml_config = yaml.dump(extra_config, default_flow_style=False) # If you want to test the resulting configuration. Turn on the next # line and use that to generate a yaml config. # assert False # Merge both load_config(conf_options, config_dict=extra_config) # Make sure the config is valid. errors, informal_only = validate_options(conf_options) for error in errors: log.warn(error) if not informal_only or (errors and not ignore_warnings): raise ConfigurationError("invalid configuration") errors = validate_references(conf_options) for error in errors: log.warn(error) conf = ProxyConfiguration(conf_options, seed=seed, renderd=renderd) # Create a MapProxy App app = MapProxyApp(conf.configured_services(), conf.base_config) # Wrap it in an object that allows to get requests by path as a string. return TestApp(app), yaml_config