'Update this Map\'s details by parsing a JSON object as produced by
a GXP Viewer.
This method automatically persists to the database!'

def update_from_viewer(self, conf):

    if isinstance(conf, basestring):
        conf = json.loads(conf)
    self.title = conf['about']['title']
    self.abstract = conf['about']['abstract']
    self.set_bounds_from_center_and_zoom(conf['map']['center'][0], conf['map']['center'][1], conf['map']['zoom'])
    self.projection = conf['map']['projection']
    if ((self.uuid is None) or (self.uuid == '')):
        self.uuid = str(uuid.uuid1())
    def source_for(layer):
        return conf['sources'][layer['source']]
    layers = [l for l in conf['map']['layers']]
    layer_names = set([l.alternate for l in self.local_layers])
    for layer in self.layer_set.all():
        layer.delete()
    self.keywords.add(*conf['map'].get('keywords', []))
    for (ordering, layer) in enumerate(layers):
        self.layer_set.add(layer_from_viewer_config(MapLayer, layer, source_for(layer), ordering))
    self.save()
    if (layer_names != set([l.alternate for l in self.local_layers])):
        map_changed_signal.send_robust(sender=self, what_changed='layers')
