content: import csv
  import json
  import logging
  import re
  from pextant.solvers.astarMesh import astarSolver
  from pextant.analysis.loadWaypoints import JSONloader
  import matplotlib.pyplot as plt
  logger = logging.getLogger()
  
  class Pathfinder:
      """
      This class performs the A* path finding algorithm and contains the Cost Functions. Also includes
      capabilities for analysis of a path.
  
      This class still needs performance testing for maps of larger sizes. I don't believe that
      we will be doing anything extremely computationally intensive though.
  
      Current cost functions are Time, Distance, and (Metabolic) Energy. It would be useful to be able to
      optimize on other resources like battery power or water sublimated, but those are significantly more
      difficult because they depend on shadowing and was not implemented by Aaron.
      """
      def __init__(self, explorer_model, environmental_model):
          cheating = 1
          self.solver = astarSolver(environmental_model, explorer_model,
                                    optimize_on = 'Energy', heuristic_accelerate = cheating)
  
      def aStarCompletePath(self, optimize_on, waypoints, returnType="JSON", dh=None, fileName=None ):
          pass
  
      def completeSearch(self, optimize_on, waypoints, filepath=None ):
          """
          Returns a tuple representing the path and the total cost of the path.
          The path will be a list. All activity points will be duplicated in
          the returned path.
  
          waypoints is a list of activityPoint objects, in the correct order. fileName is
          used when we would like to write stuff to a file and is currently necessary
          for csv return types.
          """
          segmentsout, rawpoints, items = self.solver.solvemultipoint(waypoints)
  
          if filepath:
              extension = re.search('^(.+\/[^/]+)\.(\w+)$', filepath).group(2)
          else:
              extension = None
  
          if extension == "json":
              json.dump(segmentsout.tojson(), filepath)
          elif extension == "csv":
              header = [['isStation', 'x', 'y', 'z', 'distanceMeters', 'energyJoules', 'timeSeconds']]
              rows = header + segmentsout.tocsv()
              with open(filepath, 'wb') as csvfile:
                  writer = csv.writer(csvfile)
                  for row in rows:
                      writer.writerow(row)
              return rows
          return segmentsout, rawpoints, items
  
      def completeSearchFromJSON(self, optimize_on, jsonInput, filepath=None, algorithm="A*",
                                 numTestPoints=0):
          jloader = JSONloader.from_string(jsonInput)
          waypoints = jloader.get_waypoints()
  
          #if algorithm == "A*":
          segmentsout,_,_ = self.completeSearch(optimize_on, waypoints, filepath)
          updatedjson = jloader.add_search_sol(segmentsout.list)
  
          return updatedjson
  
  if __name__ == '__main__':
      from pextant.analysis.loadWaypoints import loadPoints
      from explorers import Astronaut
      from EnvironmentalModel import GDALMesh
  
      hi_low = GDALMesh('maps/HI_lowqual_DEM.tif')
      waypoints = loadPoints('waypoints/HI_13Nov16_MD7_A.json')
      env_model = hi_low.loadSubSection(waypoints.geoEnvelope())
      astronaut = Astronaut(80)
      pathfinder = Pathfinder(astronaut, env_model)
      out = pathfinder.aStarCompletePath('Energy', waypoints)
      print out