Commit 12bf5d43 authored by Roelofsen, Hans's avatar Roelofsen, Hans
Browse files

backlog updates. Mainly for plant draagkracht and plant key areas

parent 29cf249d
......@@ -17,9 +17,23 @@ import datetime
sys.path.append(r'c:/apps/proj_code/benb_utils')
from draagkracht_ww import draagkracht_ww as dk_ww
from fix_bt import fix_bt
from speciescode2taxon import speciescode2taxon as code2tax
from Classes.Species import TabularSpecies
def plant_dk(ffargs):
class foo:
def __init__(self):
foo.A = 5
foo.th_dk = 0.01
foo.th_f = 5
foo.th_t = 5
foo.sp_src = r'c:\apps\proj_code\mnp_utilities\sample\sample_data\species_list.csv'
foo.bt_src = r'c:\apps\proj_code\mnp_utilities\sample\sample_data\snl_Ntypen.csv'
foo.out_dir = r'c:\apps\proj_code\mnp_utilities\sample\sample_data'
args = foo()
tab_species = TabularSpecies()
def plant_dk(args):
"""
Function to calculate draagkracht, see help below.
:param A:
......@@ -41,7 +55,7 @@ def plant_dk(ffargs):
plant_associaties_src = 'vertaling_IPO_ASSO_2009_ps.xls' # Vertaling Associatie --> Beheertype
associaties = pd.read_excel(os.path.join(plant_dir, plant_associaties_src), sheet_name='vertaling_IPO_ASSO_2009')
associaties['syntaxon_gen'] = associaties.short.str.slice(stop=6).str.upper() # Generalize sub-Ass to Associatie
associaties['beheertype'] = associaties.Bc.apply(fix_bt, as_mnp=True) # Fix beheertypen codes
associaties['beheertype'] = associaties.Bc.apply(fix_bt, as_mnp=True, pass_missing_N=True) # Fix beheertypen codes
# Read plant response (Trouw/Frequentie) to Associaties, add generalized syntaxon code to plant response table
plant_responses_src = 'q_syntaxa_soorten_frequentie_trouwsoorten.xlsx' # Trouwgraad & frequentie soort/associatie
......@@ -58,13 +72,15 @@ def plant_dk(ffargs):
btcode2omschrijving = dict(zip(bt_master.bt_code, bt_master.LST_NAME))
# Get default mnp draagkracht values
mnp_dk_src = r'w:\PROJECTS\qmar\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\03_MNP_versie6_par_density_factors_BT2019_v2.csv'
#mnp_dk_src = r'w:\PROJECTS\qmar\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\03_MNP_versie6_par_density_factors_BT2019_v2.csv'
# bovenstaande bron voor MNP draagkrachten is niet de beste keuze, want daarin staan de gekke coderingen van Marlies & Henk (kolom
mnp_dk_src = r'w:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\03_MNP_versie5_par_density_factors_BT2021_v3.csv'
try:
mnp_dk = pd.read_csv(mnp_dk_src, sep=',', usecols=['Species_code', 'Land_type_code', 'Land_type_quality'])
except FileNotFoundError:
raise AssertionError('Please connect to w:\\projects\qmar')
# Read list of equested beheertypen to analyse, add mnp-style code
# Read list of requested beheertypen to analyse, add mnp-style code
try:
bts = pd.read_csv(args.bt_src, sep=',', comment='#')
bts.rename(dict(zip(list(bts), [x.capitalize() for x in list(bts)])), axis=1, inplace=True)
......@@ -81,14 +97,20 @@ def plant_dk(ffargs):
for bt in bts.bt_code:
bt2asso[bt] = list(set(associaties.loc[associaties.beheertype == bt, 'syntaxon_gen']))
# Read list of equested species, add syntax group and assert all plants
# Read list of requested species, add syntax group and assert all plants
try:
species = pd.read_csv(args.sp_src, sep=',', usecols=['Species_code', 'Local_name', 'Scientific_name'])
if args.sp_src.endswith('.csv'): # Read as CSV
species = pd.read_csv(args.sp_src, sep=',', usecols=['Species_code', 'Local_name', 'Scientific_name'])
elif args.sp_src.endswith('.xlsx'): # Read as XLSX
species = pd.read_excel(args.sp_src, sheet_name=args.sheet,
usecols=['Species_code', 'Local_name', 'Scientific_name'])
else:
raise AssertionError('provide either *.csv or *.xlsx, not {}'.format(args.sp_src))
except (ValueError, FileNotFoundError) as e:
raise AssertionError('Cannot find species list, or species list is missing "Species_code" (S09xxxxxx) '
'"Local_name" "Scientific_name" columns: {}'.format(e))
species.drop_duplicates(subset='Species_code', inplace=True)
plant_species = species.loc[species.Species_code.apply(code2tax) == "P"].index
plant_species = species.loc[species.Species_code.map(tab_species.code2taxon) == "P"].index
# assert all(species.Species_code.apply(code2tax) == 'P'), "non plants found in requested species list."
# species dicts
......@@ -97,14 +119,19 @@ def plant_dk(ffargs):
"""Loop trough alll Species/Beheertype combis. Calculate mean frequentie/trouw where possible. """
dk_lst = []
sp_enums = dict((j, i) for i, j in enumerate(species.loc[plant_species, 'Species_code'], start=1))
for (sp_code, bt) in itertools.product(species.loc[plant_species, 'Species_code'], bts.bt_code):
print('Doing {0}-{1}'.format(sp_code, bt))
print('Doing {0} ({1}/{2})'.format(sp_code, sp_enums[sp_code], len(plant_species)), end="\r")
d = {'Land_type_code': bt, 'Species_code': sp_code,
d = {'Land_type_code': bt,
'Species_code': sp_code,
'hits': responses.loc[(responses.Soortnaam == code2scientific[sp_code]) &
(responses.syntaxon_gen.isin(bt2asso[bt]))].shape[0],
'hits_gte_th': 0, 'mean_trouw': np.nan, 'mean_freq': np.nan, 'dk_ww': np.nan}
'hits_gte_th': 0,
'mean_trouw': np.nan,
'mean_freq': np.nan,
'dk_ww': np.nan}
# Continue with next if there are 0 hits for species/bt combination in the database
if d['hits'] == 0:
......@@ -168,9 +195,13 @@ def plant_dk(ffargs):
species_never = piv.loc[piv.count(axis=1) == 0].index
beheertype_never = piv.count(axis=0).loc[piv.count(axis=0) == 0].index
count_per_species = piv.count(axis=1).sort_values(ascending=False)
count_per_bt = piv.count(axis=0).sort_values(ascending=False)
# X soorten met Wieger Wamelink draagkrachten voor N beheertypen
aantal_bts, aantal_soorten = np.unique(pd.pivot_table(data=dk, index='Species_code', aggfunc='count', values='dk_ww'),
return_counts=True)
dkww_df = pd.DataFrame({'n_beheertypen': aantal_bts, 'n_soorten': aantal_soorten})
report = \
"==RAPPORT AUTOMATISCHE DRAAGKRACHT BEPALING VOOR PLANTEN TBV MNP==\n"\
......@@ -200,42 +231,39 @@ def plant_dk(ffargs):
" kept : {21}\n"\
" never : {22}\n\n" \
"Aantal soorten met draagkracht voor X beheertypen:\n" \
"{27}\n" \
"List of {23} species w/o dk\n"\
"{23}\n" \
"Aantal draagkrachten per soort\n"\
"{24}\n\n"\
"List of {25} Beheertypen w/o dk\n"\
"{26}\n\n"\
"Aantal draagkrachten per beheertype\n"\
"{25}\n\n"\
"Draaitabel:\n"\
"{28}".format(os.getenv('USERNAME'),
ts_full,
args.th_dk,
args.A,
args.th_f,
args.th_t,
args.sp_src,
args.bt_src,
os.path.join(plant_dir, plant_responses_src),
os.path.join(plant_dir, plant_associaties_src),
bt_master_src,
mnp_dk_src,
species_requested,
plants_requested,
bts_requested,
combis_potential,
combis_wo_data,
combis_w_data,
combis_meeting_th,
combis_new,
combis_lost,
combis_kept,
combis_never,
len(species_never),
'\n'.join(['{0}. {1}'.format(a, b) for (a, b) in enumerate(species_never, start=1)]),
len(beheertype_never),
'\n'.join(['{0}. {1}'.format(a, b) for (a, b) in enumerate(beheertype_never, start=1)]),
dkww_df.to_csv(index=False, sep='\t', line_terminator='\n'),
piv.to_csv(sep=',', line_terminator='\n'))
"{26}".format(os.getenv('USERNAME'), #0
ts_full, #1
args.th_dk, #2
args.A, #3
args.th_f, #4
args.th_t, #5
args.sp_src, #6
args.bt_src, #7
os.path.join(plant_dir, plant_responses_src), #8
os.path.join(plant_dir, plant_associaties_src), #9
bt_master_src, #10
mnp_dk_src, #11
species_requested, #12
plants_requested, #13
bts_requested, #14
combis_potential, #15
combis_wo_data, #16
combis_w_data, #17
combis_meeting_th, #18
combis_new, #19
combis_lost, #20
combis_kept, #21
combis_never, #22
dkww_df.to_csv(index=False, sep='\t', line_terminator='\n'), #23
count_per_species.to_csv(sep='\t', header=False, line_terminator='\n'), #24
count_per_bt.to_csv(sep='\t', header=False, line_terminator='\n'), #25
piv.to_csv(sep=',', line_terminator='\n')) #26
# Prepare output
basename = '03PlantDensityFactors{0}'.format(ts_full)
......@@ -246,38 +274,34 @@ def plant_dk(ffargs):
f.write(report)
# MNP style CSV output
dk.dropna(axis=0, subset=['dk_ww'])\
.rename(mapper={'dk_ww': 'Land_type_quality'}, axis=1)\
.loc[:, ['Species_code', 'Land_type_code', 'Land_type_quality', 'Local_name', 'Scientific_name',
# out = dk.dropna(axis=0, subset=['dk_ww'])\
out = dk.rename(mapper={'dk_ww': 'Land_type_quality_auto'}, axis=1)\
.loc[:, ['Species_code', 'Land_type_code', 'Land_type_quality_auto', 'dk_mnp', 'Local_name', 'Scientific_name',
'Land_type_omschrijving']]\
.round({'Land_type_quality': 2})\
.to_csv(os.path.join(args.out_dir, '{}.csv'.format(basename)), sep=',', header=True, index=False)
.round({'Land_type_quality_auto': 2})
if args.of == 'csv':
out.to_csv(os.path.join(args.out_dir, '{}.csv'.format(basename)), sep=',', header=True, index=False)
elif args.of == 'df':
return out
print('...done')
print('\n...done')
if __name__ == '__main__':
def test(fargs):
def test(x):
# Provide default values to the args Namespace
setattr(fargs, 'A', 5)
setattr(fargs, 'th_dk', 0.1)
setattr(fargs, 'th_f', 5)
setattr(fargs, 'th_t', 5)
setattr(fargs, 'sp_src', r'.\sample_data\species_list.csv')
setattr(fargs, 'bt_src', r'.\sample_data\bts.csv')
setattr(fargs, 'out_dir', r'.\sample_data')
print('Testing...')
try:
plant_dk(fargs)
plant_dk(x)
except AssertionError as e:
print('Error: {}'.format(e))
sys.exit(1)
def full(fargs):
def full(x):
print('Calculating draagkracht as specified...')
try:
plant_dk(fargs)
plant_dk(x)
except AssertionError as e:
print('Error: {}'.format(e))
sys.exit(1)
......@@ -297,13 +321,15 @@ if __name__ == '__main__':
' th_f treshold for f(X, Ax), usually 5\n' \
' th_t treshold for t(X, Ax), usually 5\n' \
' sp_src CSV list of plant species formatted Species_code, Local_name, Scientific_name\n' \
' bt_src CSV list of Beheertypen with at least column Land_type_code formatted NXX.YY.ZZ or NXX.YY'
' bt_src CSV list of Beheertypen with at least column Land_type_code formatted NXX.YY.ZZ or NXX.YY' \
' of output format: csv to file, or return as dataframe. Default: csv'
parser = argparse.ArgumentParser(description=model_desc, formatter_class=argparse.RawDescriptionHelpFormatter)
subparsers = parser.add_subparsers(dest='subparser_name', help=argparse.SUPPRESS)
parser_test = subparsers.add_parser("test", help='test w sample data', description=model_desc,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser_test.set_defaults(func=test)
parser_test.set_defaults(func=test, A=5, th_dk=0.1, th_f=5, th_t=5, sp_src=r'.\sample_data\species_list.csv',
bt_src=r'.\sample_data\bts.csv', out_dir=r'.\sample_data', of='csv')
parser_full = subparsers.add_parser('full', help='run with user spec data and setting', description=model_desc,
formatter_class=argparse.RawDescriptionHelpFormatter)
......@@ -313,9 +339,11 @@ if __name__ == '__main__':
parser_full.add_argument('th_t', help=argparse.SUPPRESS, type=float)
parser_full.add_argument('sp_src', help=argparse.SUPPRESS, type=str)
parser_full.add_argument('bt_src', help=argparse.SUPPRESS, type=str)
parser_full.add_argument('of', help=argparse.SUPPRESS, type=str, default='csv')
parser_full.add_argument('--out_dir', default=r'./', help='output directory', type=str)
parser_full.add_argument('--sheet', help='xls sheet name for sp_src', type=str)
parser_full.set_defaults(func=full)
args = parser.parse_args()
args.func(args)
fargs = parser.parse_args()
fargs.func(fargs)
......@@ -76,7 +76,7 @@ for i, species in enumerate(species, start=1):
csv_out_name = '03_MNP_versie7_par_density_factors_{0}'.format(sp.naam_ned)
shp_out_basename = 'draagkracht_{}X{}.shp'
areas = hlp.gen_squares(x_ul=0, y_ul=625000, ncol=57, nrow=64, size=5000) # Square grid over NL
# TODO: use benb_utils.gen_squares
'''Reduce NDFF observations to NDFF grid cells. Then couple with Areas and BT kaart'''
# Couple each NDFF observation to a Col-Row index from the bt_kaart using the Affine transformation.
# Then drop duplicates to ensure only 1 NDFF observation is counted per bt_kaart pixel.
......
......@@ -72,7 +72,7 @@ with open(os.path.join(args.out_dir, '{0}XNBT20190612_th{1}.csv'.format(args.tax
continue
areas = hlp.gen_squares(x_ul=0, y_ul=625000, ncol=57, nrow=64, size=5000) # Square grid over NL
# TODO: use benb_utils gen_squares
'''Reduce NDFF observations to NDFF grid cells. Then couple with Areas and BT kaart'''
# Couple each NDFF observation to a Col-Row index from the bt_kaart using the Affine transformation.
# Then drop duplicates to ensure only 1 NDFF observation is counted per bt_kaart pixel.
......
......@@ -329,175 +329,10 @@ class BT20190612:
tree.write(os.path.join(out_dir, '{}.qlr'.format(out_name)))
class BT20190730:
"""
Class holding everyting related to neergeschaalde Beheertypekaart v 20190730. For contents of the BT map,
see: https://git.wur.nl/roelo008/mnp-utilities/-/blob/master/docs/details_nbt/details_nbt_20190730.md
Note: btA = BT code 20190730
btB = BT Code nBT2016
btB = BT Code nBT2016 plus '.00' voor niet-neergeschaalde types, om aan te sluiten bij de MNP notatie voor BTs
"""
def __init__(self):
self.src = r'c:\apps\temp_geodata\nbt20190730\25m\nbt_20190730_111603.tif'
self.raster = rio.open(self.src)
# pixelwaarde, neer
nbt_contents = [[2147483647, 'nodata', 'nodata', 'nodata'],
[101, 'N01.01', 'N01.01', 'N01.01.00', 'Zee en wad'],
[10228, 'N01.02.28', 'N01.01', 'N01.01.00', 'grootschalig duin'],
[10269, 'N01.02.69', 'N01.01', 'N01.01.00', 'grootschalig duin'],
[80269, 'N08.02.69', 'N01.01', 'N01.01.00', 'open duin'],
[102, 'N01.02', 'N01.02', 'N01.02.00', 'Duin- en kwelderlandschap'],
[103, 'N01.03', 'N01.03', 'N01.03.00', 'Rivier- en moeraslandschap'],
[104, 'N01.04', 'N01.04', 'N01.04.00', 'Zand- en kalklandschap'],
[201, 'N02.01', 'N02.01', 'N02.01.00', 'Rivier'],
[301, 'N03.01', 'N03.01', 'N03.01.00', 'Beek en Bron'],
[401, 'N04.01', 'N04.01', 'N04.01.00', 'Kranswierwater'],
[402, 'N04.02', 'N04.02', 'N04.02.00', 'Zoete Plas'],
[10320, 'N01.03.20', 'N04.02', 'N04.02.00', 'grootschalig moeras'],
[10420, 'N01.04.20', 'N04.02', 'N04.02.00', 'grootschalig zand'],
[50120, 'N05.01.20', 'N04.02', 'N04.02.00', 'moeras'],
[403, 'N04.03', 'N04.03', 'N04.03.00', 'Brak water'],
[404, 'N04.04', 'N04.04', 'N04.04.00', 'Afgesloten zeearm'],
[501, 'N05.01', 'N05.01', 'N05.01.00', 'Moeras'],
[50197, 'N05.01.97', 'N05.01.00', 'N05.01.00', 'moeras'],
[10330, 'N01.03.30', 'N05.01.02', 'N05.01.02', 'grootschalig moeras'],
[10430, 'N01.04.30', 'N05.01.02', 'N05.01.02', 'grootschalig zand'],
[50130, 'N05.01.30', 'N05.01.02', 'N05.01.02', 'moeras'],
[10332, 'N01.03.32', 'N05.01.03', 'N05.01.03', 'grootschalig moeras'],
[50132, 'N05.01.32', 'N05.01.03', 'N05.01.03', 'moeras'],
[10311, 'N01.03.11', 'N05.01.06', 'N05.01.06', 'grootschalig moeras'],
[10331, 'N01.03.31', 'N05.01.06', 'N05.01.06', 'grootschalig moeras'],
[50111, 'N05.01.11', 'N05.01.06', 'N05.01.06', 'moeras'],
[50131, 'N05.01.31', 'N05.01.06', 'N05.01.06', 'moeras'],
[50134, 'N05.01.34', 'N05.01.11', 'N05.01.11', 'moeras'],
[10328, 'N01.03.28', 'N05.01.13', 'N05.01.13', 'grootschalig moeras'],
[10315, 'N01.03.15', 'N05.01.14', 'N05.01.14', 'grootschalig moeras'],
[10321, 'N01.03.21', 'N05.01.14', 'N05.01.14', 'grootschalig moeras'],
[502, 'N05.02', 'N05.02', 'N05.02.00', 'Gemaaid rietland'],
[601, 'N06.01', 'N06.01', 'N06.01.00', 'Veenmosrietland en moerasheide'],
[50116, 'N05.01.16', 'N06.01', 'N06.01.00', 'moeras'],
[50133, 'N05.01.33', 'N06.01', 'N06.01.00', 'moeras'],
[50150, 'N05.01.50', 'N06.01', 'N06.01.00', 'moeras'],
[602, 'N06.02', 'N06.02', 'N06.02.00', 'Trilveen'],
[603, 'N06.03', 'N06.03', 'N06.03.00', 'Hoogveen'],
[10451, 'N01.04.51', 'N06.03', 'N06.03.00', 'grootschalig zand'],
[604, 'N06.04', 'N06.04', 'N06.04.00', 'Vochtige heide'],
[605, 'N06.05', 'N06.05', 'N06.05.00', 'Zwakgebufferd ven'],
[10426, 'N01.04.26', 'N06.05', 'N06.05.00', 'grootschalig zand'],
[606, 'N06.06', 'N06.06', 'N06.06.00', 'Zuur ven en hoogveenven'],
[10425, 'N01.04.25', 'N06.06', 'N06.06.00', 'grootschalig zand'],
[701, 'N07.01', 'N07.01', 'N07.01.00', 'Droge heide'],
[10450, 'N01.04.50', 'N07.01', 'N07.01.00', 'grootschalig zand'],
[702, 'N07.02', 'N07.02', 'N07.02.00', 'Zandverstuiving'],
[10440, 'N01.04.40', 'N07.02', 'N07.02.00', 'grootschalig zand'],
[801, 'N08.01', 'N08.01', 'N08.01.00', 'Strand en embryonaal duin'],
[10242, 'N01.02.42', 'N08.01', 'N08.01.00', 'grootschalig duin'],
[10260, 'N01.02.60', 'N08.02.00', 'N08.02.00', 'grootschalig duin'],
[80260, 'N08.02.60', 'N08.02.00', 'N08.02.00', 'open duin'],
[80297, 'N08.02.97', 'N08.02.00', 'N08.02.00', 'open duin'],
[10240, 'N01.02.40', 'N08.02.02', 'N08.02.02', 'grootschalig duin'],
[10261, 'N01.02.61', 'N08.02.02', 'N08.02.02', 'grootschalig duin'],
[80240, 'N08.02.40', 'N08.02.02', 'N08.02.02', 'open duin'],
[80261, 'N08.02.61', 'N08.02.02', 'N08.02.02', 'open duin'],
[10262, 'N01.02.62', 'N08.02.03', 'N08.02.03', 'grootschalig duin'],
[80262, 'N08.02.62', 'N08.02.03', 'N08.02.03', 'open duin'],
[10263, 'N01.02.63', 'N08.02.07', 'N08.02.07', 'grootschalig duin'],
[80263, 'N08.02.63', 'N08.02.07', 'N08.02.07', 'open duin'],
[10264, 'N01.02.64', 'N08.02.08', 'N08.02.08', 'grootschalig duin'],
[80217, 'N08.02.17', 'N08.02.08', 'N08.02.08', 'open duin'],
[80218, 'N08.02.18', 'N08.02.08', 'N08.02.08', 'open duin'],
[80264, 'N08.02.64', 'N08.02.08', 'N08.02.08', 'open duin'],
[10266, 'N01.02.66', 'N08.02.11', 'N08.02.11', 'grootschalig duin'],
[80266, 'N08.02.66', 'N08.02.11', 'N08.02.11', 'open duin'],
[10210, 'N01.02.10', 'N08.02.15', 'N08.02.15', 'grootschalig duin'],
[80210, 'N08.02.10', 'N08.02.15', 'N08.02.15', 'open duin'],
[803, 'N08.03', 'N08.03', 'N08.03.00', 'Vochtige duinvallei'],
[10214, 'N01.02.14', 'N08.03', 'N08.03.00', 'grootschalig duin'],
[10220, 'N01.02.20', 'N08.03', 'N08.03.00', 'grootschalig duin'],
[10230, 'N01.02.30', 'N08.03', 'N08.03.00', 'grootschalig duin'],
[10267, 'N01.02.67', 'N08.03', 'N08.03.00', 'grootschalig duin'],
[50160, 'N05.01.60', 'N08.03', 'N08.03.00', 'moeras'],
[80214, 'N08.02.14', 'N08.03', 'N08.03.00', 'open duin'],
[80220, 'N08.02.20', 'N08.03', 'N08.03.00', 'open duin'],
[80267, 'N08.02.67', 'N08.03', 'N08.03.00', 'open duin'],
[804, 'N08.04', 'N08.04', 'N08.04.00', 'Duinheide'],
[10250, 'N01.02.50', 'N08.04', 'N08.04.00', 'grootschalig duin'],
[10265, 'N01.02.65', 'N08.04', 'N08.04.00', 'grootschalig duin'],
[80250, 'N08.02.50', 'N08.04', 'N08.04.00', 'open duin'],
[80265, 'N08.02.65', 'N08.04', 'N08.04.00', 'open duin'],
[901, 'N09.01', 'N09.01', 'N09.01.00', 'Schor of kwelder'],
[10212, 'N01.02.12', 'N09.01', 'N09.01.00', 'grootschalig duin'],
[10229, 'N01.02.29', 'N09.01', 'N09.01.00', 'grootschalig duin'],
[10241, 'N01.02.41', 'N09.01', 'N09.01.00', 'grootschalig duin'],
[10268, 'N01.02.68', 'N09.01', 'N09.01.00', 'grootschalig duin'],
[1001, 'N10.01', 'N10.01', 'N10.01.00', 'Nat schraalland'],
[1002, 'N10.02', 'N10.02', 'N10.02.00', 'Vochtig hooiland'],
[1101, 'N11.01', 'N11.01', 'N11.01.00', 'Droog schraalgrasland'],
[10313, 'N01.03.13', 'N11.01', 'N11.01.00', 'grootschalig moeras'],
[1201, 'N12.01', 'N12.01', 'N12.01.00', 'Bloemdijk'],
[1202, 'N12.02', 'N12.02', 'N12.02.00', 'Kruiden- en faunarijk grasland'],
[10310, 'N01.03.10', 'N12.02', 'N12.02.00', 'grootschalig moeras'],
[10410, 'N01.04.10', 'N12.02', 'N12.02.00', 'grootschalig zand'],
[50110, 'N05.01.10', 'N12.02', 'N12.02.00', 'moeras'],
[1203, 'N12.03', 'N12.03', 'N12.03.00', 'Glanshaverhooiland'],
[1204, 'N12.04', 'N12.04', 'N12.04.00', 'Zilt- en overstromingsgrasland'],
[10312, 'N01.03.12', 'N12.04', 'N12.04.00', 'grootschalig moeras'],
[1205, 'N12.05', 'N12.05', 'N12.05.00', 'Kruiden- of faunarijke akker'],
[1206, 'N12.06', 'N12.06', 'N12.06.00', 'Ruigteveld'],
[1301, 'N13.01', 'N13.01', 'N13.01.00', 'Vochtig weidevogelgrasland'],
[1302, 'N13.02', 'N13.02', 'N13.02.00', 'Wintergastenweide'],
[1401, 'N14.01', 'N14.01', 'N14.01.00', 'Rivier- en beekbegeleidend bos'],
[10371, 'N01.03.71', 'N14.01', 'N14.01.00', 'grootschalig moeras'],
[1402, 'N14.02', 'N14.02', 'N14.02.00', 'Hoog- en laagveenbos'],
[10370, 'N01.03.70', 'N14.02', 'N14.02.00', 'grootschalig moeras'],
[50170, 'N05.01.70', 'N14.02', 'N14.02.00', 'moeras'],
[1403, 'N14.03', 'N14.03', 'N14.03.00', 'Haagbeuken- en essenbos'],
[1501, 'N15.01', 'N15.01', 'N15.01.00', 'Duinbos'],
[10270, 'N01.02.70', 'N15.01', 'N15.01.00', 'grootschalig duin'],
[80270, 'N08.02.70', 'N15.01.01', 'N15.01.01', 'open duin'],
[80280, 'N08.02.80', 'N15.01.02', 'N15.01.02', 'open duin'],
[1502, 'N15.02', 'N15.02', 'N15.02.00', 'Dennen-, eiken- en beukenbos'],
[10470, 'N01.04.70', 'N15.02', 'N15.02.00', 'grootschalig zand'],
[1601, 'N16.01', 'N16.01', 'N16.01.00', 'Droog bos met productie (vervallen)'],
[1602, 'N16.02', 'N16.02', 'N16.02.00', 'Vochtig bos met productie (vervallen)'],
[1603, 'N16.03', 'N16.03', 'N16.03.00', 'Droog bos met producties (nieuw per 01-01-2018)'],
[1604, 'N16.04', 'N16.04', 'N16.04.00', 'Vochtig bos met producties (nieuw per 01-01-2018)'],
[1701, 'N17.01', 'N17.01', 'N17.01.00', 'Vochtig hakhout en middenbos'],
[1702, 'N17.02', 'N17.02', 'N17.02.00', 'Droog hakhout'],
[1703, 'N17.03', 'N17.03', 'N17.03.00', 'Park- of stinzenbos'],
[1704, 'N17.04', 'N17.04', 'N17.04.00', 'Eendenkooi'],
[1705, 'N17.05', 'N17.05', 'N17.05.00', 'Wilgengriend (nieuw per 1-1-2017)'],
[1706, 'N17.06', 'N17.06', 'N17.06.00', 'Vochtig en hellinghakhout (nieuw per 1-1-2017)'],
[10298, 'N01.02.98', 'W00.01', 'W00.01.00', 'grootschalig duin'],
[10398, 'N01.03.98', 'W00.01', 'W00.01.00', 'grootschalig moeras'],
[10498, 'N01.04.98', 'W00.01', 'W00.01.00', 'grootschalig zand'],
[50198, 'N05.01.98', 'W00.01', 'W00.01.00', 'moeras'],
[80298, 'N08.02.98', 'W00.01', 'W00.01.00', 'open duin'],
[10299, 'N01.02.99', 'W00.02', 'W00.02.00', 'grootschalig duin'],
[10399, 'N01.03.99', 'W00.02', 'W00.02.00', 'grootschalig moeras'],
[10499, 'N01.04.99', 'W00.02', 'W00.02.00', 'grootschalig zand'],
[50199, 'N05.01.99', 'W00.02', 'W00.02.00', 'moeras'],
[80299, 'N08.02.99', 'W00.02', 'W00.02.00', 'open duin']]
self.units = pd.DataFrame(data=nbt_contents, columns=['pxl', 'btA', 'btB', 'btC', 'desc'])
self.pxl2btA = dict(zip(self.units.pxl, self.units.btA))
self.pxl2btB = dict(zip(self.units.pxl, self.units.btB))
self.pxl2btC = dict(zip(self.units.pxl, self.units.btC))
self.btA2pxl = dict(zip(self.units.btA, self.units.pxl))
self.btB2pxl = dict(zip(self.units.btB, self.units.pxl))
self.btC2pxl = dict(zip(self.units.btC, self.units.pxl))
self.btA2btB = dict(zip(self.units.btA, self.units.btB))
self.btA2btC = dict(zip(self.units.btA, self.units.btC))
def ndff_sources():
return {'broedvogel': r'W:\PROJECTS\MNP2020\c_fases\f7_draagkracht\a_source_data\vogels_ndff_shapefiles\ndff_vogels_merged_mk2.shp',
'dagvlinder': r'W:\PROJECTS\MNP2020\c_fases\f7_draagkracht\a_source_data\vlinders_ndff_shapefiles\ndff_dagvlinders_merged_mk2.shp',
return {'broedvogel': r'W:\PROJECTS\MNP2020\MNP_2020\c_fases\f7_draagkracht\a_source_data\vogels_ndff_shapefiles\ndff_vogels_merged_mk2.shp',
'dagvlinder': r'W:\PROJECTS\MNP2020\MNP_2020\c_fases\f7_draagkracht\a_source_data\vlinders_ndff_shapefiles\ndff_dagvlinders_merged_mk2.shp',
'test': r'c:\apps\temp_geodata\ndff\ndff_vogel_sample.shp'}
class Species:
......@@ -581,122 +416,13 @@ def get_mnp_dk(species, bt):
print('Make sure to provide a Species object, thanks.')
raise
def gen_squares(x_ul, y_ul, nrow, ncol, size):
"""
Generate geodataframe with square polygons
:param x_ul: easting top-left corner
:param y_ul: northing top-left corner
:param nrow: number of rows
:param ncol: number of cols
:param size: square size in m
:return: gdf with ncol*nrow items
"""
'''
Definition affine.Affine(a, b, c, d, e, f)
a: width of a pixel
b: row rotation (typically zero)
c: x-coordinate of the upper-left of the upper-left pixel
d: column rotation (typically zero)
e: height of a pixel (negative)
f: y-coordinate of the upper-left of the upper-left pixel
https://www.perrygeo.com/python-affine-transforms.html
'''
aff = affine.Affine(size, 0, x_ul, 0, -size, y_ul)
ul_corners_indx = [indx for indx in np.ndindex(ncol, nrow)]
ul_corners_coords = [colrow_2_xy(colrow=corner, affine_in=aff) for corner in ul_corners_indx]
# [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)] == [ll, lr, ur, ul]
all_corner_coords = [[(xmin, ymax-size), (xmin+size, ymax-size), (xmin+size, ymax), (xmin, ymax)] for (xmin, ymax)
in ul_corners_coords]
shapes = [shapely.geometry.Polygon(corner) for corner in all_corner_coords]
ids = ['{0}_{1}'.format(int(x), int(y)) for x,y in ul_corners_coords]
return gp.GeoDataFrame(geometry=shapes, data={'ID': ids, 'size': str(size)},
crs={'x_0': 155000, 'proj': 'sterea', 'units': 'm', 'y_0': 463000, 'k': 0.9999079,
'lon_0': 5.38763888888889, 'no_defs': True, 'lat_0': 52.15616055555555,
'ellps': 'bessel'})
def fix_bt(code_in, as_mnp=False):
'''Parser for Beheertype codes to repair abbreviated codes and/or MNP extension
eg. 02.01 --> N02.01 if mnp==False
02.01 --> N01.01.00 if mnp==True
N05.01 --> N05.01 if mnp==False
N05.01 --> N05.01.00 if mnp==True
N04.02.01 --> N04.02.01 if mnp==False
N04.02.01 --> N04.02.01 if mnp==True
BT Code is as follows <N><AA>.<BB>.<CC>
N = letter, may be missing
A = two digits indicating top level beheertype "TOP"
B = two digits indicating sub level beheertype "SUB"
C = two digits indicating neergeschaald beheertype if > 00. Else "00" as used in MNP param notation "NEER"
N04.02.00 is equivalent to N04.02
'''
if isinstance(code_in, numbers.Number):
code_in = str(code_in)
# Identify parts of code
parts = code_in.split('.')
if len(parts) == 1:
raise Exception('Unexpected BT code: {}'.format(code_in))
elif len(parts) == 2:
top, sub = parts
neer = None
elif len(parts) == 3:
top, sub, neer = parts
# Verify TOP and add "N" is required
if top.isdigit():
top = 'N{0}'.format(top.zfill(2))
else:
assert top[0].isupper(), 'Unexpected BT Code format: {}'.format(code_in)
# Verify SUB
assert sub.isdigit and len(sub) == 2, 'Unexpected BT Code format: {}'.format(code_in)
# Verify NEER and check if it is neergeschaald or not
keep_neer = False
if neer:
assert neer.isdigit and len(neer) == 2, 'Unexpected BT Code format: {}'.format(code_in)
if int(neer) > 0:
keep_neer = True
# Construct output
head = '{}.{}'.format(top, sub)
if keep_neer:
return '{}.{}'.format(head, neer)
elif as_mnp:
return '{}.00'.format(head)
else:
return head
def draagkracht_ww(frequentie, trouw, th, mf=5):
"""
Draagkracht formule volgens Wieger Wamelink. Zie MS Teams discussie 16-07-2020 MNP2020/Fase 7 Objectivering Draagk..
min((max(frequentie, trouw)/100) * 5), 1)
:param frequentie: gemiddelde frequentie van soort X binnen beheertype Y
:param trouw: gemiddelde trouw van soort X binnen beheertype Y
:param th: minumum draagkracht value
:param mf: match factor, default 5
:return: draagkracht soort X - beheertype Y combinatie, gemaximaliseerd tot 1.
"""
dk = np.min([np.multiply(np.divide(np.max([frequentie, trouw]), 100), mf), 1])
if dk >= th:
return dk
else:
return np.nan
def valid_dir(x):
"""
Is x an existing directory?
:param x: path
:return: x if True, else argparse.ArgumentTypeError