docs: def findOutlet(self, shapefile_path):
          """
          Calculate outlet location
          """
          # determine outlet from shapefile
          # by getting outlet from first point in polygon
  
          # make sure the boundary geometry is valid
          check_watershed_boundary_geometry(shapefile_path)
  
          shapefile = ogr.Open(shapefile_path)
          source_layer = shapefile.GetLayer(0)
          source_lyr_proj = source_layer.GetSpatialRef()
          osr_geographic_proj = osr.SpatialReference()
          osr_geographic_proj.ImportFromEPSG(4326)
          proj_transform = osr.CoordinateTransformation(source_lyr_proj,
                                                        osr_geographic_proj)
          boundary_feature = source_layer.GetFeature(0)
          feat_geom = boundary_feature.GetGeometryRef()
          feat_geom.Transform(proj_transform)
          polygon = shapely_loads(feat_geom.ExportToWkb())
  
          # make lowest point on boundary outlet
          mask_grid = self.getGrid()
          elevation_grid = self.getGrid(use_mask=False)
          elevation_array = elevation_grid.np_array()
          ma_elevation_array = np.ma.array(elevation_array,
                                           mask=mask_grid.np_array()==0)
          min_elevation = sys.maxsize
          outlet_pt = None
          for coord in list(polygon.exterior.coords):
              try:
                  col, row = mask_grid.lonlat2pixel(*coord)
              except IndexError:
                  # out of bounds
                  continue
  
              elevation_value = ma_elevation_array[row, col]
              if elevation_value is np.ma.masked:
                  # search for closest value in mask to this point
                  # elevation within 5 pixels in any direction
                  actual_value = elevation_array[row, col]
                  max_diff = sys.maxsize
                  nrow = None
                  ncol = None
                  nval = None
                  for row_ix in range(max(row-5, 0), min(row+5, mask_grid.y_size)):
                      for col_ix in range(max(col-5, 0), min(col+5, mask_grid.x_size)):
                          val = ma_elevation_array[row_ix, col_ix]
                          if not val is np.ma.masked:
                              val_diff = abs(val-actual_value)
                              if val_diff < max_diff:
                                  max_diff = val_diff
                                  nval = val
                                  nrow = row_ix
                                  ncol = col_ix
  
                  if None not in (nrow, ncol, nval):
                      row = nrow
                      col = ncol
                      elevation_value = nval
  
              if elevation_value < min_elevation:
                  min_elevation = elevation_value
                  outlet_pt = (col, row)
  
          if outlet_pt is None:
              raise IndexError('No valid outlet points found on boundary ...')
  
          outcol, outrow = outlet_pt
          self.setOutlet(col=outcol+1, row=outrow+1)