def generate(self, kml_filename=None, wrs_shapefile='WRS-2_bound_world.kml'):
        def write_xml_file(filename, dom_tree, save_backup=False):
            """Function write the metadata contained in self._metadata_dict to an XML file
            Argument:
                filename: Metadata file to be written
                uses_attributes: Boolean flag indicating whether to write values to tag attributes
            """
            logger.debug('write_file(%s) called', filename)
    
            if save_backup and os.path.exists(filename + '.bck'):
                os.remove(filename + '.bck')
    
            if os.path.exists(filename):
                if save_backup:
                    os.rename(filename, filename + '.bck')
                else:
                    os.remove(filename)
    
            # Open XML document
            try:
                outfile = open(filename, 'w')
                assert outfile is not None, 'Unable to open XML file ' + filename + ' for writing'
    
                logger.debug('Writing XML file %s', filename)
    
                # Strip all tabs and EOLs from around values, remove all empty lines
                outfile.write(re.sub('\>(\s+)(\n\t*)\<',
                                     '>\\2<',
                                     re.sub('(\<\w*[^/]\>)\n(\t*\n)*(\t*)([^<>\n]*)\n\t*\n*(\t+)(\</\w+\>)',
                                            '\\1\\4\\6',
                                            dom_tree.toprettyxml(encoding='utf-8')
                                            )
                                     )
                              )
    
            finally:
                outfile.close()
    
        def get_wrs_placemark_node(wrs_document_node, placemark_name):
            """
            Return a clone of the WRS placemark node with the specified name
            """ 
            try:
                return [placemark_node for placemark_node in self.getChildNodesByName(wrs_document_node, 'Placemark') 
                    if self.getChildNodesByName(placemark_node, 'name')[0].childNodes[0].nodeValue == placemark_name][0].cloneNode(True)
            except:
                return None
                

        
        def create_placemark_node(wrs_document_node, acquisition_info):
            """
            Create a new placemark node for the specified acquisition
            """
            logger.info('Processing %s', acquisition_info['dataset_name'])
            
            wrs_placemark_name = '%d_%d' % (acquisition_info['path'], acquisition_info['row'])
            
            kml_placemark_name = acquisition_info['dataset_name']
            
            placemark_node = get_wrs_placemark_node(wrs_document_node, wrs_placemark_name)
            
            self.getChildNodesByName(placemark_node, 'name')[0].childNodes[0].nodeValue = kml_placemark_name
            
            kml_time_span_node = kml_dom_tree.createElement('TimeSpan')
            placemark_node.appendChild(kml_time_span_node)
            
            kml_time_begin_node = kml_dom_tree.createElement('begin')
            kml_time_begin_text_node = kml_dom_tree.createTextNode(acquisition_info['start_datetime'].isoformat())
            kml_time_begin_node.appendChild(kml_time_begin_text_node)
            kml_time_span_node.appendChild(kml_time_begin_node)
            
            kml_time_end_node = kml_dom_tree.createElement('end')
            kml_time_end_text_node = kml_dom_tree.createTextNode(acquisition_info['end_datetime'].isoformat())
            kml_time_end_node.appendChild(kml_time_end_text_node)
            kml_time_span_node.appendChild(kml_time_end_node)
            
            description_node = self.getChildNodesByName(placemark_node, 'description')[0]
            description_node.childNodes[0].data = '''<strong>Geoscience Australia ARG25 Dataset</strong> 
<table cellspacing="1" cellpadding="1">
    <tr>
        <td>Satellite:</td>
        <td>%(satellite)s</td>
    </tr>
    <tr>
        <td>Sensor:</td>
        <td>%(sensor)s</td>
    </tr>
    <tr>
        <td>Start date/time (UTC):</td>
        <td>%(start_datetime)s</td>
    </tr>
    <tr>
        <td>End date/time (UTC):</td>
        <td>%(end_datetime)s</td>
    </tr>
    <tr>
        <td>WRS Path-Row:</td>
        <td>%(path)03d-%(row)03d</td>
    </tr>
    <tr>
        <td>Bounding Box (LL,UR):</td>
        <td>(%(ll_lon)f,%(lr_lat)f),(%(ur_lon)f,%(ul_lat)f)</td>
    </tr>
    <tr>
        <td>Est. Cloud Cover (USGS):</td>
        <td>%(cloud_cover)s%%</td>
    </tr>
    <tr>
        <td>GCP Count:</td>
        <td>%(gcp_count)s</td>
    </tr>
    <tr>
        <td>
            <a href="http://eos.ga.gov.au/thredds/wms/LANDSAT/%(year)04d/%(month)02d/%(dataset_name)s_BX.nc?REQUEST=GetMap&SERVICE=WMS&VERSION=1.3.0&LAYERS=FalseColour741&STYLES=&FORMAT=image/png&TRANSPARENT=TRUE&CRS=CRS:84&BBOX=%(ll_lon)f,%(lr_lat)f,%(ur_lon)f,%(ul_lat)f&WIDTH=%(thumbnail_size)d&HEIGHT=%(thumbnail_size)d">View thumbnail</a>
        </td>
        <td>
            <a href="http://eos.ga.gov.au/thredds/fileServer/LANDSAT/%(year)04d/%(month)02d/%(dataset_name)s_BX.nc">Download full NetCDF file</a>
        </td>
    </tr>
</table>''' % acquisition_info
            
            return placemark_node
            
            
        kml_filename = kml_filename or self.output_file
        assert kml_filename, 'Output filename must be specified'
        
        wrs_dom_tree = xml.dom.minidom.parse(wrs_shapefile)
        wrs_document_element = wrs_dom_tree.documentElement
        wrs_document_node = self.getChildNodesByName(wrs_document_element, 'Document')[0]
        
        kml_dom_tree = xml.dom.minidom.getDOMImplementation().createDocument(wrs_document_element.namespaceURI, 
                                                                             'kml', 
                                                                             wrs_dom_tree.doctype)
        kml_document_element = kml_dom_tree.documentElement
        
        # Copy document attributes
        for attribute_value in wrs_document_element.attributes.items():
            kml_document_element.setAttribute(attribute_value[0], attribute_value[1])
            
        kml_document_node = kml_dom_tree.createElement('Document')
        kml_document_element.appendChild(kml_document_node)
        
        
        # Copy all child nodes of the "Document" node except placemarks
        for wrs_child_node in [child_node for child_node in wrs_document_node.childNodes 
                               if child_node.nodeName != 'Placemark']:
                                   
            kml_child_node = kml_dom_tree.importNode(wrs_child_node, True)                                   
            kml_document_node.appendChild(kml_child_node)
            
        # Update document name 
        doc_name = 'Geoscience Australia ARG-25 Landsat Scenes'
        if self.satellite or self.sensor:
            doc_name += ' for'
            if self.satellite:
                doc_name += ' %s' % self.satellite
            if self.sensor:
                doc_name += ' %s' % self.sensor
        if self.start_date:
            doc_name += ' from %s' % self.start_date
        if self.end_date:
            doc_name += ' to %s' % self.end_date
            
        logger.debug('Setting document name to "%s"', doc_name)
        self.getChildNodesByName(kml_document_node, 'name')[0].childNodes[0].data = doc_name
         
        # Update style nodes as specified in self.style_dict
        for style_node in self.getChildNodesByName(kml_document_node, 'Style'):
            logger.debug('Style node found')
            for tag_name in self.style_dict.keys():
                tag_nodes = self.getChildNodesByName(style_node, tag_name)
                if tag_nodes:
                    logger.debug('\tExisting tag node found for %s', tag_name)
                    tag_node = tag_nodes[0]
                else:
                    logger.debug('\tCreating new tag node for %s', tag_name)
                    tag_node = kml_dom_tree.createElement(tag_name)
                    style_node.appendChild(tag_node)
                    
                for attribute_name in self.style_dict[tag_name].keys():
                    attribute_nodes = self.getChildNodesByName(tag_node, attribute_name)
                    if attribute_nodes:
                        logger.debug('\t\tExisting attribute node found for %s', attribute_name)
                        attribute_node = attribute_nodes[0]
                        text_node = attribute_node.childNodes[0]
                        text_node.data = str(self.style_dict[tag_name][attribute_name])
                    else:
                        logger.debug('\t\tCreating new attribute node for %s', attribute_name)
                        attribute_node = kml_dom_tree.createElement(attribute_name)
                        tag_node.appendChild(attribute_node)
                        text_node = kml_dom_tree.createTextNode(str(self.style_dict[tag_name][attribute_name]))
                        attribute_node.appendChild(text_node)
    
           
        self.db_cursor = self.db_connection.cursor()
        
        sql = """-- Find all NBAR acquisitions
select satellite_name as satellite, sensor_name as sensor, 
x_ref as path, y_ref as row, 
start_datetime, end_datetime,
dataset_path,
ll_lon, ll_lat,
lr_lon, lr_lat,
ul_lon, ul_lat,
ur_lon, ur_lat,
cloud_cover::integer, gcp_count::integer
from 
    (
    select *
    from dataset
    where level_id = 2 -- NBAR
    ) dataset
inner join acquisition a using(acquisition_id)
inner join satellite using(satellite_id)
inner join sensor using(satellite_id, sensor_id)

where (%(start_date)s is null or end_datetime::date >= %(start_date)s)
  and (%(end_date)s is null or end_datetime::date <= %(end_date)s)
  and (%(satellite)s is null or satellite_tag = %(satellite)s)
  and (%(sensor)s is null or sensor_name = %(sensor)s)

order by end_datetime
;
"""
        params = {
                  'start_date': self.start_date,
                  'end_date': self.end_date,
                  'satellite': self.satellite,
                  'sensor': self.sensor
                  }
        
        log_multiline(logger.debug, self.db_cursor.mogrify(sql, params), 'SQL', '\t')
        self.db_cursor.execute(sql, params)
        
        field_list = ['satellite',
                      'sensor', 
                      'path',
                      'row', 
                      'start_datetime', 
                      'end_datetime',
                      'dataset_path',
                      'll_lon',
                      'll_lat',
                      'lr_lon',
                      'lr_lat',
                      'ul_lon',
                      'ul_lat',
                      'ur_lon',
                      'ur_lat',
                      'cloud_cover', 
                      'gcp_count'
                      ]
        
        for record in self.db_cursor:
            
            acquisition_info = {}
            for field_index in range(len(field_list)):
                acquisition_info[field_list[field_index]] = record[field_index]
                
            acquisition_info['year'] = acquisition_info['end_datetime'].year    
            acquisition_info['month'] = acquisition_info['end_datetime'].month    
            acquisition_info['thumbnail_size'] = self.thumbnail_size   
            acquisition_info['dataset_name'] = re.search('[^/]+$', acquisition_info['dataset_path']).group(0)
            
            log_multiline(logger.debug, acquisition_info, 'acquisition_info', '\t')
                
            placemark_node = create_placemark_node(wrs_document_node, acquisition_info)
            kml_document_node.appendChild(placemark_node)
            
        logger.info('Writing KML to %s', kml_filename)
        write_xml_file(kml_filename, kml_dom_tree)
Generate a KML file
dataset/ETHPy150Open GeoscienceAustralia/agdc/deprecated/scene_kml_generator.py/SceneKMLGenerator.generate