docs: def getStreamNetworkAsKml(self, session, path=None, documentName='Stream Network', withNodes=False, styles={}):
          """
          Retrieve the stream network visualization in KML format.
  
          Args:
              session (:mod:`sqlalchemy.orm.session.Session`): SQLAlchemy session object bound to PostGIS enabled database
              path (str, optional): Path to file where KML will be written. Defaults to None.
              documentName (str, optional): Name of the KML document. This will be the name that appears in the legend.
                  Defaults to 'Stream Network'.
              withNodes (bool, optional): Include nodes. Defaults to False.
              styles (dict, optional): Custom styles to apply to KML geometry. Defaults to empty dictionary.
  
                  Valid keys (styles) include:
                     * lineColor: tuple/list of RGBA integers (0-255) e.g.: (255, 0, 0, 128)
                     * lineWidth: float line width in pixels
                     * nodeIconHref: link to icon image (PNG format) to represent nodes (see: http://kml4earth.appspot.com/icons.html)
                     * nodeIconScale: scale of the icon image
  
          Returns:
              str: KML string
          """
          # Retrieve Stream Links
          links = self.getFluvialLinks()
  
          # Set Default Styles
          lineColorValue = (255, 255, 0, 0)  # Blue
          lineWidthValue = 2
          nodeIconHrefValue = 'http://maps.google.com/mapfiles/kml/paddle/red-circle.png'
          nodeIconScaleValue = 1.0
  
          if 'lineColor' in styles:
              if len(styles['lineColor']) < 4:
                  log.warning('lineColor style must be a list or a tuple of four elements containing integer RGBA values.')
              else:
                  userLineColor = styles['lineColor']
                  lineColorValue = (userLineColor[3], userLineColor[2], userLineColor[1], userLineColor[0])
  
          if 'lineWidth' in styles:
              try:
                  float(styles['lineWidth'])
                  lineWidthValue = styles['lineWidth']
  
              except ValueError:
                  log.warning('lineWidth must be a valid number containing the width of the line in pixels.')
  
          if 'nodeIconHref' in styles:
              nodeIconHrefValue = styles['nodeIconHref']
  
          if 'nodeIconScale' in styles:
              try:
                  float(styles['nodeIconScale'])
                  nodeIconScaleValue = styles['nodeIconScale']
  
              except ValueError:
                  log.warning('nodeIconScaleValue must be a valid number containing the width of the line in pixels.')
  
  
          # Initialize KML Document
          kml = ET.Element('kml', xmlns='http://www.opengis.net/kml/2.2')
          document = ET.SubElement(kml, 'Document')
          docName = ET.SubElement(document, 'name')
          docName.text = documentName
  
          for link in links:
              placemark = ET.SubElement(document, 'Placemark')
              placemarkName = ET.SubElement(placemark, 'name')
              placemarkName.text = str(link.linkNumber)
  
              # Create style tag and setup styles
              styles = ET.SubElement(placemark, 'Style')
  
              # Set line style
              lineStyle = ET.SubElement(styles, 'LineStyle')
              lineColor = ET.SubElement(lineStyle, 'color')
              lineColor.text = '%02X%02X%02X%02X' % lineColorValue
              lineWidth = ET.SubElement(lineStyle, 'width')
              lineWidth.text = str(lineWidthValue)
  
              # Add the geometry to placemark
              linkKML = link.getAsKml(session)
              if linkKML:
                  lineString = ET.fromstring(linkKML)
                  placemark.append(lineString)
              else:
                  log.warning("No geometry found for link with id {0}".format(link.id))
  
              if withNodes:
                  # Create the node styles
                  nodeStyles = ET.SubElement(document, 'Style', id='node_styles')
  
                  # Hide labels
                  nodeLabelStyle = ET.SubElement(nodeStyles, 'LabelStyle')
                  nodeLabelScale = ET.SubElement(nodeLabelStyle, 'scale')
                  nodeLabelScale.text = str(0)
  
                  # Style icon
                  nodeIconStyle = ET.SubElement(nodeStyles, 'IconStyle')
  
                  # Set icon
                  nodeIcon = ET.SubElement(nodeIconStyle, 'Icon')
                  iconHref = ET.SubElement(nodeIcon, 'href')
                  iconHref.text = nodeIconHrefValue
  
                  # Set icon scale
                  iconScale = ET.SubElement(nodeIconStyle, 'scale')
                  iconScale.text = str(nodeIconScaleValue)
  
                  for node in link.nodes:
                      # New placemark for each node
                      nodePlacemark = ET.SubElement(document, 'Placemark')
                      nodePlacemarkName = ET.SubElement(nodePlacemark, 'name')
                      nodePlacemarkName.text = str(node.nodeNumber)
  
                      # Styles for the node
                      nodeStyleUrl = ET.SubElement(nodePlacemark, 'styleUrl')
                      nodeStyleUrl.text = '#node_styles'
  
                      nodeString = ET.fromstring(node.getAsKml(session))
                      nodePlacemark.append(nodeString)
  
                      # Embed node data
                      nodeExtendedData = ET.SubElement(nodePlacemark, 'ExtendedData')
  
                      nodeNumberData = ET.SubElement(nodeExtendedData, 'Data', name='node_number')
                      nodeNumberValue = ET.SubElement(nodeNumberData, 'value')
                      nodeNumberValue.text = str(node.nodeNumber)
  
                      nodeLinkNumberData = ET.SubElement(nodeExtendedData, 'Data', name='link_number')
                      nodeLinkNumberValue = ET.SubElement(nodeLinkNumberData, 'value')
                      nodeLinkNumberValue.text = str(link.linkNumber)
  
                      nodeElevationData = ET.SubElement(nodeExtendedData, 'Data', name='elevation')
                      nodeElevationValue = ET.SubElement(nodeElevationData, 'value')
                      nodeElevationValue.text = str(node.elevation)
  
              # Create the data tag
              extendedData = ET.SubElement(placemark, 'ExtendedData')
  
              # Add value to data
              linkNumberData = ET.SubElement(extendedData, 'Data', name='link_number')
              linkNumberValue = ET.SubElement(linkNumberData, 'value')
              linkNumberValue.text = str(link.linkNumber)
  
              linkTypeData = ET.SubElement(extendedData, 'Data', name='link_type')
              linkTypeValue = ET.SubElement(linkTypeData, 'value')
              linkTypeValue.text = str(link.type)
  
              numElementsData = ET.SubElement(extendedData, 'Data', name='number_elements')
              numElementsValue = ET.SubElement(numElementsData, 'value')
              numElementsValue.text = str(link.numElements)
  
              dxData = ET.SubElement(extendedData, 'Data', name='dx')
              dxValue = ET.SubElement(dxData, 'value')
              dxValue.text = str(link.dx)
  
              erodeData = ET.SubElement(extendedData, 'Data', name='erode')
              erodeValue = ET.SubElement(erodeData, 'value')
              erodeValue.text = str(link.type)
  
              subsurfaceData = ET.SubElement(extendedData, 'Data', name='subsurface')
              subsurfaceValue = ET.SubElement(subsurfaceData, 'value')
              subsurfaceValue.text = str(link.type)
  
          kmlString = ET.tostring(kml)
  
          if path:
              with open(path, 'w') as f:
                  f.write(kmlString)
  
          return kmlString