def test_routing(): # test routing: haulDist, haulTime, coord_mill # Input landing_coords = (-124.04858, 43.12776) mill_shp = 'testdata//mills.shp' # Expected Output haulDist = 8.674960531 haulTime = 32.92 coord_mill = (-124.161246, 43.106512) assert(routing.routing(landing_coords, mill_shp=mill_shp)) == (haulDist, haulTime, coord_mill)
def test_routing(): # test routing: haulDist, haulTime, coord_mill # Input landing_coords = (-124.04858, 43.12776) mill_shp = 'testdata//mills.shp' # Expected Output haulDist = 8.674960531 haulTime = 32.92 coord_mill = (-124.161246, 43.106512) assert (routing.routing(landing_coords, mill_shp=mill_shp)) == (haulDist, haulTime, coord_mill)
def test_routing_mill_shp(): mill_shp = 'Data//mills.shp' # Landing Coordinates landing_coords = (-118.620, 44.911) haulDist, haulTime, coord_mill = r.routing(landing_coords, mill_shp=mill_shp) print "Using shapefile to find nearest mill..." print "Distance:", haulDist print "Time:", haulTime print "Landing coordinate:", landing_coords print "Mill coordinate:", coord_mill print
def test_routing_mill_coords(): mill_coords = (-119.250013, 44.429948) # Landing Coordinates landing_coords = (-118.620, 44.911) haulDist, haulTime, coord_mill = r.routing( landing_coords, mill_coords=mill_coords, ) print "Using specified mill coordinates" print "Distance:", haulDist print "Time:", haulTime print "Landing coordinate:", landing_coords print "Mill coordinate:", coord_mill print
def test_routing_mill_filter(): mill_shp = 'Data//mills.shp' mill_filter = "CITY = 'John Day'" # Landing Coordinates landing_coords = (-118.620, 44.911) haulDist, haulTime, coord_mill = r.routing( landing_coords, mill_shp=mill_shp, mill_filter=mill_filter, ) print "Using shapefile filtered for `%s`..." % mill_filter print "Distance:", haulDist print "Time:", haulTime print "Landing coordinate:", landing_coords print "Mill coordinate:", coord_mill print
def main(): scenario = Scenario.objects.get(id=122) sql = """SELECT ss.id AS sstand_id, a.cond, a.rx, a.year, a.offset, ss.acres AS acres, a.total_stand_carbon AS total_carbon, a.agl AS agl_carbon, a.removed_merch_bdft / 1000.0 AS harvested_timber, -- convert to mbf a.after_merch_bdft / 1000.0 AS standing_timber, -- convert to mbf ST_AsText(ss.geometry_final) AS stand_wkt, a.LG_CF AS LG_CF, a.LG_HW AS LG_HW, a.LG_TPA AS LG_TPA, a.SM_CF AS SM_CF, a.SM_HW AS SM_HW, a.SM_TPA AS SM_TPA, a.CH_CF AS CH_CF, a.CH_HW AS CH_HW, a.CH_TPA AS CH_TPA, stand.elevation AS elev, stand.slope AS slope, a.CUT_TYPE AS CUT_TYPE FROM trees_fvsaggregate a JOIN trees_scenariostand ss ON a.cond = ss.cond_id AND a.rx = ss.rx_internal_num AND a.offset = ss.offset JOIN trees_stand stand ON ss.stand_id = stand.id -- WHERE a.site = 2 -- TODO if we introduce multiple site classes, we need to fix WHERE var = '%s' -- get from current property AND ss.scenario_id = %d -- get from current scenario ORDER BY a.year, ss.id;""" % (scenario.input_property.variant.code, scenario.id) cursor = connection.cursor() cursor.execute(sql) data = dictfetchall(cursor) # Mill information mill_shp = 'Data/mills.shp' # Landing Coordinates center = scenario.input_property.geometry_final.point_on_surface centroid_coords = center.transform(4326, clone=True).tuple landing_coords = landing.landing(centroid_coords=centroid_coords) haulDist, haulTime, coord_mill = r.routing( landing_coords, mill_shp=mill_shp ) annual_total_cost = defaultdict(float) annual_haul_cost = defaultdict(float) annual_heli_harvest_cost = defaultdict(float) annual_ground_harvest_cost = defaultdict(float) annual_cable_harvest_cost = defaultdict(float) used_records = 0 skip_noharvest = 0 skip_error = 0 year = None years = [] for row in data: ### GIS Data stand_wkt = row['stand_wkt'] area = row['acres'] if year != int(row['year']): year = int(row['year']) print "Calculating cost per stand in year", year years.append(year) annual_total_cost[year] += 0 annual_haul_cost[year] += 0 annual_heli_harvest_cost[year] += 0 annual_ground_harvest_cost[year] += 0 annual_cable_harvest_cost[year] += 0 # NOTE: elevation and slope come directly from stand # if we use spatial contrainsts to chop scenariostands, # will need to recalc zonal stats elevation = row['elev'] slope = row['slope'] ### Tree Data ### # Cut type code indicating type of harvest implemented. # 0 = no harvest, 1 = pre-commercial thin, # 2 = commercial thin, 3 = regeneration harvest try: cut_type = int(row['cut_type']) except: # no harvest so don't attempt to calculate cut_type = 0 # PartialCut(clear cut = 0, partial cut = 1) if cut_type == 3: PartialCut = 0 elif cut_type in [1, 2]: PartialCut = 1 else: # no harvest so don't attempt to calculate skip_noharvest += 1 continue # Hardwood Fraction # Chip Trees RemovalsCT = row['ch_tpa'] TreeVolCT = row['ch_cf'] HdwdFractionCT = row['ch_hw'] # Small Log Trees RemovalsSLT = row['sm_tpa'] TreeVolSLT = row['sm_cf'] HdwdFractionSLT = row['sm_hw'] # Large Log Trees RemovalsLLT = row['lg_tpa'] TreeVolLLT = row['lg_cf'] HdwdFractionLLT = row['lg_hw'] cost_args = ( # stand info area, elevation, slope, stand_wkt, # harvest info RemovalsCT, TreeVolCT, RemovalsSLT, TreeVolSLT, RemovalsLLT, TreeVolLLT, HdwdFractionCT, HdwdFractionSLT, HdwdFractionLLT, PartialCut, # routing info landing_coords, haulDist, haulTime, coord_mill ) try: result = m.cost_func(*cost_args) annual_haul_cost[year] += result['total_haul_cost'] annual_total_cost[year] += result['total_cost'] system = result['harvest_system'] if system.startswith("Helicopter"): annual_heli_harvest_cost[year] += result['total_harvest_cost'] elif system.startswith("Ground"): annual_ground_harvest_cost[year] += result['total_harvest_cost'] elif system.startswith("Cable"): annual_cable_harvest_cost[year] += result['total_harvest_cost'] else: # TODO annual_cable_harvest_cost[year] += result['total_harvest_cost'] #raise ValueError used_records += 1 except (ZeroDivisionError, ValueError): skip_error += 1 # import traceback # print cost_args # print traceback.format_exc() def ordered_costs(x): sorted_x = sorted(x.iteritems(), key=operator.itemgetter(0)) return [-1 * z[1] for z in sorted_x] print "--------" print " var heli =", json.dumps(ordered_costs(annual_heli_harvest_cost)), ";" print " var cable =", json.dumps(ordered_costs(annual_cable_harvest_cost)), ";" print " var ground =", json.dumps(ordered_costs(annual_ground_harvest_cost)), ";" print " var haul =", json.dumps(ordered_costs(annual_haul_cost)), ";" print " var years =", json.dumps(sorted(annual_haul_cost.keys())), ";" # RANDOMLY determine a revenue w/in % of total cost; HACK rev = [-1 * x * (1.0 + (0.35 - (random.random() * 0.5))) for x in ordered_costs(annual_total_cost)] #rev = [-1 * x for x in ordered_costs(annual_total_cost)] print " var revenue =", json.dumps(rev), ";" # determine profit profit = [revenue + cost for revenue, cost in zip(rev, ordered_costs(annual_total_cost))] print " var profit =", json.dumps(profit), ";" print "--------" print "year, heliHarvestCost, cableHarvestCost, groundHarvestCost, transportationCost" for year in sorted(dict(annual_haul_cost).keys()): print ", ".join(str(x) for x in [ year, annual_heli_harvest_cost[year], annual_cable_harvest_cost[year], annual_ground_harvest_cost[year], annual_haul_cost[year] ] ) print "--------" print "used records:", used_records print "skipped (no harvest):", skip_noharvest print "skipped (errors):", skip_error
def main(): scenario = Scenario.objects.get(id=122) sql = """SELECT ss.id AS sstand_id, a.cond, a.rx, a.year, a.offset, ss.acres AS acres, a.total_stand_carbon AS total_carbon, a.agl AS agl_carbon, a.removed_merch_bdft / 1000.0 AS harvested_timber, -- convert to mbf a.after_merch_bdft / 1000.0 AS standing_timber, -- convert to mbf ST_AsText(ss.geometry_final) AS stand_wkt, a.LG_CF AS LG_CF, a.LG_HW AS LG_HW, a.LG_TPA AS LG_TPA, a.SM_CF AS SM_CF, a.SM_HW AS SM_HW, a.SM_TPA AS SM_TPA, a.CH_CF AS CH_CF, a.CH_HW AS CH_HW, a.CH_TPA AS CH_TPA, stand.elevation AS elev, stand.slope AS slope, a.CUT_TYPE AS CUT_TYPE FROM trees_fvsaggregate a JOIN trees_scenariostand ss ON a.cond = ss.cond_id AND a.rx = ss.rx_internal_num AND a.offset = ss.offset JOIN trees_stand stand ON ss.stand_id = stand.id -- WHERE a.site = 2 -- TODO if we introduce multiple site classes, we need to fix WHERE var = '%s' -- get from current property AND ss.scenario_id = %d -- get from current scenario ORDER BY a.year, ss.id;""" % (scenario.input_property.variant.code, scenario.id) cursor = connection.cursor() cursor.execute(sql) data = dictfetchall(cursor) # Mill information mill_shp = 'Data/mills.shp' # Landing Coordinates center = scenario.input_property.geometry_final.point_on_surface centroid_coords = center.transform(4326, clone=True).tuple landing_coords = landing.landing(centroid_coords=centroid_coords) haulDist, haulTime, coord_mill = r.routing(landing_coords, mill_shp=mill_shp) annual_total_cost = defaultdict(float) annual_haul_cost = defaultdict(float) annual_heli_harvest_cost = defaultdict(float) annual_ground_harvest_cost = defaultdict(float) annual_cable_harvest_cost = defaultdict(float) used_records = 0 skip_noharvest = 0 skip_error = 0 year = None years = [] for row in data: ### GIS Data stand_wkt = row['stand_wkt'] area = row['acres'] if year != int(row['year']): year = int(row['year']) print "Calculating cost per stand in year", year years.append(year) annual_total_cost[year] += 0 annual_haul_cost[year] += 0 annual_heli_harvest_cost[year] += 0 annual_ground_harvest_cost[year] += 0 annual_cable_harvest_cost[year] += 0 # NOTE: elevation and slope come directly from stand # if we use spatial contrainsts to chop scenariostands, # will need to recalc zonal stats elevation = row['elev'] slope = row['slope'] ### Tree Data ### # Cut type code indicating type of harvest implemented. # 0 = no harvest, 1 = pre-commercial thin, # 2 = commercial thin, 3 = regeneration harvest try: cut_type = int(row['cut_type']) except: # no harvest so don't attempt to calculate cut_type = 0 # PartialCut(clear cut = 0, partial cut = 1) if cut_type == 3: PartialCut = 0 elif cut_type in [1, 2]: PartialCut = 1 else: # no harvest so don't attempt to calculate skip_noharvest += 1 continue # Hardwood Fraction # Chip Trees RemovalsCT = row['ch_tpa'] TreeVolCT = row['ch_cf'] HdwdFractionCT = row['ch_hw'] # Small Log Trees RemovalsSLT = row['sm_tpa'] TreeVolSLT = row['sm_cf'] HdwdFractionSLT = row['sm_hw'] # Large Log Trees RemovalsLLT = row['lg_tpa'] TreeVolLLT = row['lg_cf'] HdwdFractionLLT = row['lg_hw'] cost_args = ( # stand info area, elevation, slope, stand_wkt, # harvest info RemovalsCT, TreeVolCT, RemovalsSLT, TreeVolSLT, RemovalsLLT, TreeVolLLT, HdwdFractionCT, HdwdFractionSLT, HdwdFractionLLT, PartialCut, # routing info landing_coords, haulDist, haulTime, coord_mill) try: result = m.cost_func(*cost_args) annual_haul_cost[year] += result['total_haul_cost'] annual_total_cost[year] += result['total_cost'] system = result['harvest_system'] if system.startswith("Helicopter"): annual_heli_harvest_cost[year] += result['total_harvest_cost'] elif system.startswith("Ground"): annual_ground_harvest_cost[year] += result[ 'total_harvest_cost'] elif system.startswith("Cable"): annual_cable_harvest_cost[year] += result['total_harvest_cost'] else: # TODO annual_cable_harvest_cost[year] += result['total_harvest_cost'] #raise ValueError used_records += 1 except (ZeroDivisionError, ValueError): skip_error += 1 # import traceback # print cost_args # print traceback.format_exc() def ordered_costs(x): sorted_x = sorted(x.iteritems(), key=operator.itemgetter(0)) return [-1 * z[1] for z in sorted_x] print "--------" print " var heli =", json.dumps( ordered_costs(annual_heli_harvest_cost)), ";" print " var cable =", json.dumps( ordered_costs(annual_cable_harvest_cost)), ";" print " var ground =", json.dumps( ordered_costs(annual_ground_harvest_cost)), ";" print " var haul =", json.dumps(ordered_costs(annual_haul_cost)), ";" print " var years =", json.dumps(sorted(annual_haul_cost.keys())), ";" # RANDOMLY determine a revenue w/in % of total cost; HACK rev = [ -1 * x * (1.0 + (0.35 - (random.random() * 0.5))) for x in ordered_costs(annual_total_cost) ] #rev = [-1 * x for x in ordered_costs(annual_total_cost)] print " var revenue =", json.dumps(rev), ";" # determine profit profit = [ revenue + cost for revenue, cost in zip(rev, ordered_costs(annual_total_cost)) ] print " var profit =", json.dumps(profit), ";" print "--------" print "year, heliHarvestCost, cableHarvestCost, groundHarvestCost, transportationCost" for year in sorted(dict(annual_haul_cost).keys()): print ", ".join( str(x) for x in [ year, annual_heli_harvest_cost[year], annual_cable_harvest_cost[year], annual_ground_harvest_cost[year], annual_haul_cost[year] ]) print "--------" print "used records:", used_records print "skipped (no harvest):", skip_noharvest print "skipped (errors):", skip_error
slope_raster = "testdata/Slope.tif" elevation_raster = "testdata/DEM.tif" costSurface = "testdata/CostSurface.tif" standfn = "testdata/test_stands.shp" # in EPSG 3857 mill_shp = "testdata/mills.shp" # in EPSG 3857 newRoadsfn = "testdata/newRoad.shp" # name of new road shapefile to be created # Create new road shapefile if os.path.exists(newRoadsfn) is not True: length, travelCost = rm.main(standfn, costSurface, newRoadsfn) # Road Landing Coordinates coords_landing_road = landing.road(newRoadsfn, standfn) # Routing haulDist, haulTime, coord_mill = r.routing(coords_landing_road, mill_coords=None, mill_shp=mill_shp) stand_shp = ogr.Open(standfn) stand_lyr = stand_shp.GetLayer() standCount = stand_lyr.GetFeatureCount() for stand in stand_lyr: stand_geom = stand.GetGeometryRef() stand_wkt = stand_geom.ExportToWkt() area = gis.area(stand_wkt) elevation = gis.zonal_stats(elevation_raster, standfn, stand_wkt) slope = gis.zonal_stats(slope_raster, standfn, stand_wkt) coords_landing_stand = landing.stand(stand_wkt, newRoadsfn)
# Small Log Trees RemovalsSLT = 100.00 TreeVolSLT = 70.0 # Large Log Trees RemovalsLLT = 20.00 TreeVolLLT = 100.00 ### Mill information mill_shp = 'testdata//mills.shp' #mill_coords = (-123.5677, 41.2564) # Landing Coordinates landing_coords = landing.landing(property_lyr) haulDist, haulTime, coord_mill = r.routing( landing_coords, mill_shp=mill_shp ) cost = m.cost_func( # stand info area, elevation, slope, stand_wkt, # harvest info RemovalsCT, TreeVolCT, RemovalsSLT, TreeVolSLT, RemovalsLLT, TreeVolLLT,
# Small Log Trees RemovalsSLT = 100.00 TreeVolSLT = 70.0 # Large Log Trees RemovalsLLT = 20.00 TreeVolLLT = 100.00 ### Mill information mill_shp = 'testdata//mills.shp' #mill_coords = (-123.5677, 41.2564) # Landing Coordinates landing_coords = landing.landing(property_lyr) haulDist, haulTime, coord_mill = r.routing(landing_coords, mill_shp=mill_shp) cost = m.cost_func( # stand info area, elevation, slope, stand_wkt, # harvest info RemovalsCT, TreeVolCT, RemovalsSLT, TreeVolSLT, RemovalsLLT, TreeVolLLT, HdwdFractionCT,