I'm trying to modify PyKML, which uses lxml.objectify. With a track node append, this gets turned into a string with the default str()
behavior. I'd like to catch appends of lists or tuples and convert them to proper place separated lines rather than '(xx.xxxx, yy.yyyy)'
from pykml.factory import GX_ElementMaker as GX
track = GX.Track(id='track_%d' % group_num )
for pt in group:
when = datetime.datetime.utcfromtimestamp(pt['ts'])
track.append( KML.when( when ) ) # WHEN?
for pt in group:
track.append( GX.coord( (pt['x'],pt['y'])) ) # <-- trouble here
Thanks, -kurt
Create a clean ElementMaker class with the namespace info. Then create a subclass with the node name as a method. In that method, handle all the odd cases. Then craft the string that would go in that node names place and return an instance of the clean ElementMaker class with that node name.
def indexable_levels(args):
#print 'args:',args
levels = 0
while True:
if isinstance(args,str): break
try:
args = args[0]
levels += 1
except:
break
#print ' levels ->',levels
return levels
# Create a factory object for the KML Google Extension namespace
_GX_ElementMakerSimple = objectify.ElementMaker(
annotate=False,
namespace=nsmap['gx'],
nsmap={'gx': nsmap['gx']},
)
class _GX_ElementMaker (objectify.ElementMaker):
'KML ElementMaker with overloads for custom text payloads like coordinates'
def coord(self, *args):
#print 'start coord: "%s"' % (str(args)), type(args), len(args)
levels = indexable_levels(args)
if levels == 1 and len(args) == 1:
# This case is really redundant with the next
assert isinstance(args[0],str)
return _GX_ElementMakerSimple.coord(args[0])
if levels == 1:
return _GX_ElementMakerSimple.coord(' '.join([str(item) for item in args]))
if levels == 2:
# ((-121.583851, 37.386052),)
assert(len(args)==1)
return _GX_ElementMakerSimple.coord(' '.join([str(item) for item in args[0] ]))
assert(False)
# Create a factory object for the KML Google Extension namespace
GX_ElementMaker = _GX_ElementMaker(
annotate=False,
namespace=nsmap['gx'],
nsmap={'gx': nsmap['gx']},
)