0

Revised syntax/method for specifying POIs

This commit is contained in:
Andrew Chin
2012-04-14 22:09:12 -04:00
parent 85e2ac202f
commit 2a6769c5ac
4 changed files with 57 additions and 34 deletions

View File

@@ -20,32 +20,30 @@ Filter Functions
----------------
A filter function is a python function that is used to figure out if a given POI
should be part of a markerSet of not. The function should accept one argument
(a dictionary, also know as an associative array), and return a boolean::
should be part of a markerSet of not, and to control how it is displayed.
The function should accept one argument (a dictionary, also know as an associative
array), and return a string representing the text to be displayed. For example::
def signFilter(poi):
"All signs"
return poi['id'] == 'Sign'
if poi['id'] == 'Sign':
return "\n".join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']])
If a POI doesn't match, the filter can return None (which is the default if a python
functions runs off the end without an explicit 'return').
The single argument will either a TileEntity, or an Entity taken directly from
the chunk file. In this example, this function returns true only if the type
of entity is a sign. For more information of TileEntities and Entities, see
the chunk file. In this example, this function returns all 4 lines from the sign
if the entity is a sign.
For more information of TileEntities and Entities, see
the `Chunk Format <http://www.minecraftwiki.net/wiki/Chunk_format>`_ page on
the Minecraft Wiki.
.. note::
The doc string ("All signs" in this example) is important. It is the label
that appears in your rendered map
A more complicated filter function can construct a more customized display text::
A more advanced filter may also look at other entity fields, such as the sign text::
def chestFilter(poi):
if poi['id'] == "Chest":
return "Chest with %d items" % len(poi['Items'])
def goldFilter(poi):
"Gold"
return poi['id'] == 'Sign' and (\
'gold' in poi['Text1'] or
'gold' in poi['Text2'])
This looks for the word 'gold' in either the first or second line of the signtext.
Since writing these filters can be a little tedious, a set of predefined filters
functions are provided. See the :ref:`predefined_filter_functions` section for
@@ -56,15 +54,29 @@ Render Dictionary Key
Each render can specify a list of zero or more filter functions. Each of these
filter functions become a selectable item in the 'Signs' drop-down menu in the
rendered map. For example::
rendered map. Previously, this used to be a list of functions. Now it is a list
of dictionaries. For example::
renders['myrender'] = {
'world': 'myworld',
'title': "Example",
'markers': [allFilter, anotherFilter],
'markers': [dict(name="All signs", filterFunction=signFilter),
dict(name="Chests", filterFunction=chestFilter, icon="chest.png")]
}
The following keys are accepted in the marker dictionary:
``name``
This is the text that is displayed in the 'Signs' dropdown.
``filterFunction``
This is the filter function. It must accept at least 1 argument (the POI to filter),
and it must return either None or a string.
``icon``
Optional. Specifies the icon to use for POIs in this group. If omitted, it defaults
to a signpost icon.
Generating the POI Markers

View File

@@ -26,6 +26,7 @@ from overviewer_core import configParser, world
def handleSigns(rset, outputdir, render, rname):
# if we're already handled the POIs for this region regionset, do nothing
if hasattr(rset, "_pois"):
return
@@ -39,6 +40,7 @@ def handleSigns(rset, outputdir, render, rname):
rset._pois['TileEntities'] += data['TileEntities']
rset._pois['Entities'] += data['Entities']
print "Done."
def main():
helptext = """genPOI
@@ -97,13 +99,15 @@ def main():
return 1
for f in render['markers']:
markersets.add((f, rset))
name = f.__name__ + hex(hash(f))[-4:] + "_" + hex(hash(rset))[-4:]
d = dict(icon="signpost_icon.png")
d.update(f)
markersets.add(((d['name'], d['filterFunction']), rset))
name = f['name']+ hex(hash(f['filterFunction']))[-4:] + "_" + hex(hash(rset))[-4:]
try:
l = markers[rname]
l.append(dict(groupName=name, displayName = f.__doc__))
l.append(dict(groupName=name, displayName = f['name'], icon=d['icon']))
except KeyError:
markers[rname] = [dict(groupName=name, displayName=f.__doc__),]
markers[rname] = [dict(groupName=name, displayName=f['name'], icon=d['icon']),]
handleSigns(rset, os.path.join(destdir, rname), render, rname)
@@ -112,11 +116,15 @@ def main():
markerSetDict = dict()
for (flter, rset) in markersets:
# generate a unique name for this markerset. it will not be user visible
name = flter.__name__ + hex(hash(flter))[-4:] + "_" + hex(hash(rset))[-4:]
markerSetDict[name] = dict(created=False, raw=[])
filter_name = flter[0]
filter_function = flter[1]
name = filter_name + hex(hash(filter_function))[-4:] + "_" + hex(hash(rset))[-4:]
markerSetDict[name] = dict(created=False, raw=[], name=filter_name)
for poi in rset._pois['TileEntities']:
if flter(poi):
markerSetDict[name]['raw'].append(poi)
result = filter_function(poi)
if result:
markerSetDict[name]['raw'].append(dict(x=poi['x'], y=poi['y'], z=poi['z'], text=result, createInfoWindow=True))
#print markerSetDict
with open(os.path.join(destdir, "markersDB.js"), "w") as output:

View File

@@ -430,7 +430,6 @@ overviewer.views.SignControlView = Backbone.View.extend({
}});
}
iconURL = overviewerConfig.CONST.image.signMarker;
//dataRoot['markers'] = [];
//
for (i in dataRoot) {
@@ -442,11 +441,11 @@ overviewer.views.SignControlView = Backbone.View.extend({
'position': overviewer.util.fromWorldToLatLng(entity.x,
entity.y, entity.z, overviewer.mapView.options.currentTileSet),
'map': overviewer.map,
'title': jQuery.trim(entity.Text1 + "\n" + entity.Text2 + "\n" + entity.Text3 + "\n" + entity.Text4),
'icon': iconURL,
'title': jQuery.trim(entity.text),
'icon': dataRoot[i].icon,
'visible': false
});
if (entity['id'] == 'Sign') {
if (entity.createInfoWindow) {
overviewer.util.createMarkerInfoWindow(marker);
}
jQuery.extend(entity, {markerObj: marker});

View File

@@ -47,8 +47,12 @@ def validateMarkers(filterlist):
if type(filterlist) != list:
raise ValidationException("Markers must specify a list of filters")
for x in filterlist:
if not callable(x):
raise ValidationException("%r must be a function"% x)
if "name" not in x:
raise ValidationException("Must define a name")
if "filterFunction" not in x:
raise ValidationException("Must define a filter function")
if not callable(x['filterFunction']):
raise ValidationException("%r must be a function"% x['filterFunction'])
return filterlist
def validateOverlays(renderlist):