def test_write(): s = """MAP NAME "TEST" END""" fn = tempfile.mktemp() d = mappyfile.loads(s) mappyfile.write(d, fn) d = mappyfile.open(fn) assert d["name"] == "TEST" mappyfile.write(d, fn, indent=2, spacer="\t", quote="'", newlinechar="") d = mappyfile.open(fn) assert d["name"] == "TEST"
def test_open(): fn = './tests/sample_maps/256_overlay_res.map' d = mappyfile.open(fn) assert d["name"] == "TEST" d = mappyfile.open(fn, expand_includes=False) assert d["name"] == "TEST" d = mappyfile.open(fn, include_position=True) assert d["name"] == "TEST" d = mappyfile.open(fn, include_comments=True) assert d["name"] == "TEST"
def update_from_mapfile(input_layers, mapproxy_config, mapfile_dir): layer_list = input_layers.split(",") layers_to_update = {} for layer_name in layer_list: filepath = os.path.join(mapfile_dir, 'geomet-{}-en.map'.format(layer_name)) f = mappyfile.open(filepath) if layer_name not in layers_to_update.keys(): layers_to_update[layer_name] = {} if ('wms_timeextent' in f['layers'][0]['metadata'].keys()): layers_to_update[layer_name]['time'] = { 'default': f['layers'][0]['metadata']['wms_timedefault'], 'values': [f['layers'][0]['metadata']['wms_timeextent']] } if ('wms_reference_time_default' in f['layers'][0]['metadata'].keys()): layers_to_update[layer_name]['reference_time'] = { 'default': f['layers'][0]['metadata']['wms_reference_time_default'], 'values': [f['layers'][0]['metadata']['wms_reference_time_extent']] } dict_ = update_config(mapproxy_config, layers_to_update) return dict_
def format(ctx, input_mapfile, output_mapfile, indent, spacer, quote, newlinechar, expand, comments): """ Format a the input-mapfile and save as output-mapfile. Note output-mapfile will be overwritten if it already exists. Example of formatting a single Mapfile: mappyfile format C:/Temp/valid.map C:/Temp/valid_formatted.map Example of formatting a single Mapfile with single quotes and tabs for indentation: mappyfile format C:/Temp/valid.map C:/Temp/valid_formatted.map --quote=\\' --indent=1 --spacer=\t Example of formatting a single Mapfile without expanding includes, but including comments: mappyfile format C:/Temp/valid.map C:/Temp/valid_formatted.map --no-expand --comments """ quote = codecs.decode(quote, 'unicode_escape') # ensure \t is handled as a tab spacer = codecs.decode(spacer, 'unicode_escape') # ensure \t is handled as a tab newlinechar = codecs.decode(newlinechar, 'unicode_escape') # ensure \n is handled as a newline d = mappyfile.open(input_mapfile, expand_includes=expand, include_comments=comments, include_position=True) mappyfile.save(d, output_mapfile, indent=indent, spacer=spacer, quote=quote, newlinechar=newlinechar) sys.exit(0)
def set_key(ctx, key, mapfile, map_, raw): """populate store""" if all([key is None, mapfile is None]): raise click.ClickException('Missing --key/-k or --mapfile/-m option') provider_def = {'type': STORE_TYPE, 'url': STORE_URL} st = load_plugin('store', provider_def) mapfile_ = mappyfile.open(mapfile, expand_includes=False) try: value = (mappyfile.dumps(mapfile_) if map_ else mappyfile.dumps(mapfile_['layers'])) if raw: click.echo(f'Setting {key} in store ({st.url})') st.set_key(key, value, raw=True) else: click.echo(f'Setting geomet-mapfile_{key} in store ({st.url})') st.set_key(key, value) except StoreError as err: raise click.ClickException(err) click.echo('Done')
def from_mapfile(layers): """ Derives temporal information from a MapServer mapfile :param mapfile: filepath to mapfile on disk :param layers: `list` of layer names :returns: `dict` of layer temporal configuration """ if GEOMET_MAPPROXY_CACHE_MAPFILE is None: raise RuntimeError('GEOMET_MAPPROXY_CACHE_MAPFILE not set') ltu = {} all_layers = False if len(layers) == 0 or layers == 'all': LOGGER.debug('Processing all layers') all_layers = True LOGGER.debug('Reading global mapfile from disk') f = mappyfile.open(GEOMET_MAPPROXY_CACHE_MAPFILE) for layer in layers: if not all_layers: filepath = '{}/geomet-{}-en.map'.format( os.path.dirname(GEOMET_MAPPROXY_CACHE_MAPFILE), layer) LOGGER.debug('Reading layer mapfile from disk') f = mappyfile.open(filepath) if layer not in ltu.keys(): ltu[layer] = {} if ('wms_timeextent' in f['layers'][0]['metadata'].keys()): ltu[layer]['time'] = { 'default': f['layers'][0]['metadata']['wms_timedefault'], 'values': [f['layers'][0]['metadata']['wms_timeextent']] } if ('wms_reference_time_default' in f['layers'][0]['metadata'].keys()): ltu[layer]['reference_time'] = { 'default': f['layers'][0]['metadata']['wms_reference_time_default'], 'values': [f['layers'][0]['metadata']['wms_reference_time_extent']] } return ltu
def readMapFile(self): """docstring for readMapFile""" try: if self.isSetPath(): self.mapfile = mappyfile.open(self.mapfilepath) return True return False except Exception as e: self.iface.messageBar().pushWarning(u'Error', str(e)) return False
def validate(ctx, mapfiles, expand, version): """ Validate Mapfile(s) against the Mapfile schema The MAPFILES argument is a list of paths, either to individual Mapfiles, or a folders containing Mapfiles. Wildcards are supported (natively on Linux, and up to one level deep on Windows). Validation errors are reported to the console. The program returns the error count - this will be 0 if no validation errors are encountered. Example of validating a single Mapfile: mappyfile validate C:/Temp/valid.map Example of validating two folders containing Mapfiles, without expanding INCLUDES: mappyfile validate C:/Temp/*.map D:/GitHub/mappyfile/tests/mapfiles/*.map --no-expand """ all_mapfiles = get_mapfiles(mapfiles) if len(all_mapfiles) == 0: click.echo("No Mapfiles found at the following paths: {}".format( ",".join(mapfiles))) return validation_count = 0 errors = 0 for fn in all_mapfiles: fn = click.format_filename(fn) try: d, trace_o_incl = mappyfile.open(fn, output_trace=True, expand_includes=expand, include_position=True) except Exception as ex: logger.exception(ex) click.echo("{} failed to parse successfully".format(fn)) continue validation_messages = mappyfile.validate(d, trace_o_incl, version) if validation_messages: for v in validation_messages: v["fn"] = fn msg = "{fn} (File: {file} Line: {line} Column: {column}) {message} - {error}".format( **v) click.echo(msg) errors += 1 else: click.echo("{} validated successfully".format(fn)) validation_count += 1 click.echo("{} file(s) validated ({} successfully)".format( len(all_mapfiles), validation_count)) sys.exit(errors)
def getSymbolSet(self): """docstring for getSymbolSet""" symbols = [] try: if self.symbolsetpath != "": symbolset = mappyfile.open(self.symbolsetpath) symbols = symbolset.get("symbols", []) except Exception as e: self.iface.messageBar().pushWarning(u'Error', str(e)) return symbols
def main(): mf = "./docs/examples/geometry/geometry.map" mapfile = mappyfile.open(mf) mapfile["size"] = [600, 600] output_folder = os.path.join(os.getcwd(), "docs/images") dilated = dilation(mapfile) create_image("dilated", mapfile, output_folder=output_folder) erosion(mapfile, dilated) create_image("erosion", mapfile, output_folder=output_folder)
def parse(mf): m = mappyfile.open(mf, expand_includes=False) s = mappyfile.dumps(m) # if PY2: # s = mappyfile.dumps(m) # f = tempfile.NamedTemporaryFile(delete=False) # f.write(s.encode("utf-8")) # else: # f = tempfile.NamedTemporaryFile(delete=False, mode="w", encoding="utf-8") # mappyfile.dump(m, f) # f.close() return s
def test(): # START OF API EXAMPLE # load will accept a filename (loads will accept a string) mapfile = mappyfile.open("./docs/examples/raster.map") # search for a layer by name layer = mappyfile.find(mapfile['layers'], 'name', 'sea') print(layer['name']) # "sea" # search for all layers in a group for layer in mappyfile.findall(mapfile['layers'], 'group', 'my_group'): print(layer['name']) # END OF API EXAMPLE assert(layer['name'] == 'sea')
def readMainMapFile(self, mapfilepath): """docstring for readMapFile""" try: mapyfile = mappyfile.open(mapfilepath, expand_includes=False) _type = mapyfile.get("__type__") if _type == 'map': self.mapfile = mapyfile self.setMapfilePath(mapfilepath) self.__setMainPaths() self.__savePaths() self.from_paths = self.FROM_PATHS_MAPFILE return True else: return False except Exception as e: self.iface.messageBar().pushWarning(u'Error', str(e)) return False
def changeLayerRange(layer, layerRange, userFString): userInitMap = f'{os.path.join(current_app.config["PERSONAL_FOLDERS_LOCATION"], userFString, "mapFiles/sentinel_index.map")}' userModifiedMap = f'{os.path.join(current_app.config["PERSONAL_FOLDERS_LOCATION"], userFString, "mapFiles/mapFilesModified", "sentinel_index_modified.map")}' layerRangeJSON = json.loads(layerRange.replace("\'", "\"")) mapfile = mappyfile.open(userInitMap) # update the map name mapfile['name'] = 'sentinel_index_modified.map' ## Check for existing map file and delete in it exists. if os.path.exists(userModifiedMap): os.remove(userModifiedMap) # find a layer using its name layer = mappyfile.find(mapfile["layers"], "name", layer) # get class breaks and class colours from layerRange classBreaks = layerRangeJSON['classBreaks'] classColours = layerRangeJSON['classColours'] # define new mapfile classes empty string completeNewClassString = '' # iteraterate over class breaks and colours and insert their values to default class string. At the end append current string to string containing all classes for breaks,colours in zip(classBreaks,classColours): newClassString = f""" CLASS EXPRESSION ([pixel] >= {breaks[0]} AND [pixel] < {breaks[1]}) STYLE COLORRANGE {colours[0][0]} {colours[0][1]} {colours[0][2]} {colours[1][0]} {colours[1][1]} {colours[1][2]} RANGEITEM 'pixel' END END """ completeNewClassString += newClassString # load class string to map object newClasses = mappyfile.loads(completeNewClassString) layer["classes"] = newClasses # save new map file to disk and return path to it modifiedMapFile = mappyfile.dumps(mapfile) with open(userModifiedMap, "w")as mf: for li in modifiedMapFile: mf.write(li) mf.close return {"modifiedMapFile": userModifiedMap}
def test(): # START OF API EXAMPLE # load will accept a filename (loads will accept a string) mapfile = mappyfile.open("./docs/examples/raster.map") # print the map name print(mapfile["name"]) # "MyMap" # access layers layers = mapfile["layers"] layer2 = layers[1] # access by index # access classes in a layer classes = layer2["classes"] for c in classes: print(c["name"]) # END OF API EXAMPLE assert(mapfile["name"] == 'MyMap')
def test(): mapfile = mappyfile.open("./docs/examples/raster.map") # START OF API EXAMPLE # update the map name mapfile["name"] = "MyNewMap" # update a layer name layers = mapfile["layers"] layer = layers[0] layer["name"] = "MyLayer" # update the error file path in the map config section # note key names can be lower or upper case mapfile["config"]["ms_errorfile"] = "/ms4w/tmp/ms_error.txt" # update the web metadata settings mapfile["web"]["metadata"]["wms_format"] = "image/png" print(mappyfile.dumps(mapfile["web"])) # print out just the WEB section # alternatively we can parse the Mapfile syntax and load it directly s = """ METADATA 'wms_enable_request' '*' 'wms_feature_info_mime_type' 'text/html' 'wms_format' 'image/jpg' END""" metadata = mappyfile.loads(s) mapfile["web"]["metadata"] = metadata print(mappyfile.dumps(mapfile)) # END OF API EXAMPLE assert (layer["name"] == "MyLayer") assert (mapfile["web"]["metadata"]["wms_format"] == "image/jpg")
import mappyfile mf = mappyfile.open("./docs/examples/before.map") mappyfile.write(mf, "./docs/examples/after.map")
import mappyfile import json mf = mappyfile.open("./docs/examples/after.map") with open("./docs/examples/sample.json", "w") as f: json.dump(mf, f, indent=4)
import mappyfile mapfile = mappyfile.open("./docs/examples/raster.map") def test_layer(): # START OF ADD LAYER EXAMPLE layers = mapfile["layers"] new_layer_string = """ LAYER NAME 'land' TYPE POLYGON DATA '../data/vector/naturalearth/ne_110m_land' CLASS STYLE COLOR 107 208 107 OUTLINECOLOR 2 2 2 WIDTH 1 END END END """ new_layer = mappyfile.loads(new_layer_string) layers.insert(0, new_layer) # can insert the new layer at any index # END OF ADD LAYER EXAMPLE assert (layers[0]['name'] == "land") def test_class():
def parse(mf): m = mappyfile.open(mf, expand_includes=False) s = mappyfile.dumps(m) return s
import mappyfile mapfile = mappyfile.open("./docs/examples/raster.map") def test_layer(): # START OF ADD LAYER EXAMPLE layers = mapfile["layers"] new_layer_string = """ LAYER NAME 'land' TYPE POLYGON DATA '../data/vector/naturalearth/ne_110m_land' CLASS STYLE COLOR 107 208 107 OUTLINECOLOR 2 2 2 WIDTH 1 END END END """ new_layer = mappyfile.loads(new_layer_string) layers.insert(0, new_layer) # can insert the new layer at any index # END OF ADD LAYER EXAMPLE assert(layers[0]['name'] == "land") def test_class(): # START OF ADD CLASS EXAMPLE # find a layer using its name
def mapForDir(dir, dir_out): if not dir_out: dir_out = dir print('Creating a mapfile for dir ' + dir) try: # Open the file and load the file with open(os.path.join(dir, 'index.yml')) as f: cnf = yaml.load(f, Loader=SafeLoader) print(cnf) except FileNotFoundError: cnf = { "name": os.path.basename(os.path.normpath(dir)), "abstract": "", "mode": "dir", "contact": { "name": "", "organisation": "", "email": "" }, "keywords": [""], "license": "", "mode": "index" } try: with open(os.path.join(dir, 'index.yml'), 'w') as f: yaml.dump(cnf, f) except Exception as e: print(e) except Exception as e: print(e) # initalise default mapfile mf = mappyfile.open(os.path.join('templates', 'default.map')) lyrs = mf['layers'] # set up header mf["name"] = cnf.get("name", "default") mf["web"]["metadata"]["ows_title"] = cnf.get("name", "default") mf["web"]["metadata"]["ows_abstract"] = cnf.get("abstract", "default") if ("abstract" in cnf): mf["web"]["metadata"]["ows_abstract"] = cnf.get("abstract") # if mode=tree/dir, build the index # todo # loop over index for ly in cnf['index']: # fetch layer details sf = ly.get("path", '') base, ext = sf.rsplit('.', 1) if not sf.startswith("/"): sf = os.path.join(dir, sf) cnt = indexSpatialFile(sf, ext) if cnt: cnt['name'] = ly.get('name', cnt.get('name', 'unknown')) print("Processing layer {0}".format(cnt['name'])) cnt['title'] = ly.get('title', cnt.get('title', cnt['name'])) cnt['crs'] = ly.get('crs', cnt.get('crs', '')) if (cnt['crs'] == ''): cnt['crs'] = cnf.get("crs", 'epsg:4326') print("Original type is '{0}'".format(cnt['type'])) if (cnt['type'].lower() == "raster"): cnt['type'] = 'raster' elif (cnt['type'].lower() in [ "linestring", "line", "multiline", "polyline", "wkblinestring" ]): cnt['type'] = 'polygon' elif (cnt['type'].lower() in [ "point", "multipoint", "wkbpoint", "table" ]): # table is suggested for CSV, which is usually point (or none) cnt['type'] = 'point' else: cnt['type'] = 'polygon' try: cnt['extent'] = "{0} {1} {2} {3}".format( cnt['bounds'][0], cnt['bounds'][1], cnt['bounds'][2], cnt['bounds'][3]) except: cnt['extent'] = "-180 -90 180 90" cf = ly.get("style", '') if not cf.startswith("/"): cf = os.path.join(dir, sf) try: with open(cf) as f1: new_class_string = f1.read() print("Failed opening '{0}', use default style for '{1}'". format(ly.get("style", ''), cnt['type'])) except: with open( os.path.join('templates', 'class-' + cnt['type'] + '.tpl')) as f2: new_class_string2 = f2.read() if (cnt['type'] == 'raster' ): #fetch nodata from meta in file properties new_class_string2 = 'PROCESSING "NODATA=' + str( cnt.get('meta', {}).get( 'nodata', -32768)) + '"\n' + new_class_string2 # prepare layer with open(os.path.join('templates', 'layer.tpl')) as f3: new_layer_string = f3.read() strLr = new_layer_string.format( name=cnt['name'], title=cnt['name'], abstract=ly.get('abstract', ''), type=cnt['type'], path=ly["path"], template=ly.get('template', 'info.html'), projection=cnt['crs'], projections=ly.get('projections', 'epsg:4326 epsg:3857'), extent=cnt['extent'], mdurl=cnf.get('mdUrlPattern', '').format(ly.get('uuid', '')), classes=new_class_string2) try: mslr = mappyfile.loads(strLr) lyrs.insert(len(lyrs) + 1, mslr) except Exception as e: print("Failed creation of layer {0}; {1}".format( cnt['name'], e)) # map should have initial layer, remove it lyrs.pop(0) # print(mappyfile.dumps(mf)) mappyfile.save(mf, os.path.join(dir_out, cnf['name'] + ".map"), indent=4, spacer=' ', quote='"', newlinechar='\n', end_comment=False, align_values=False)