示例#1
0
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)
示例#2
0
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)
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#8
0
    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)
示例#9
0
    # 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,
示例#10
0
    # 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,