Commit 6a29b16b authored by roelo008's avatar roelo008
Browse files

added species class

parent 1fcb8ee4
"""
Determine draagkracht for species
Hans Roelofsen, mei 2020
"""
import argparse
import numpy as np
import rasterstats as rast
from mnp import helpers as hlp
# from sample.mnp import helpers as hlp
# For which species?
parser = argparse.ArgumentParser()
parser.add_argument('species', type=str, help='species name, must be a bird')
args = parser.parse_args()
sp = hlp.Species(args.species)
# Read NDFF shapefile
ndff = hlp.read_ndff_shp(sp.ndff_src)
# Path to beheertypenkaart
bt_tiff = r'c:\apps\temp_geodata\nbt\nbt_20190730_111603.tif'
# Table with pixel values, beheertypecodes etc
nbts = hlp.nbts()
# define queries that isolate the data of interest
queries = {'q1': ndff.loc[(ndff.year >= 2000) & (ndff.year.notna())].index,
'q2': ndff.loc[ndff.nl_name.isin([sp.name])].index,
'q3': ndff.loc[ndff.area < 10000].index}
sel = set.intersection(*[set(queries[x]) for x in queries.keys()]) # for query in selected_queries
assert len(sel) > 0, 'no observations remaining'
print('Found {0} NDFF observations for {1}'.format(len(sel), sp))
# Overlay NDFF observations with nbt kaart
ndff_stats = rast.zonal_stats(vectors=ndff.loc[sel, 'geometry'], raster=bt_tiff, stats='count', categorical=True,
category_map=dict(zip(nbts.pxl, nbts.bt_B)))
# Total hectare for each beheertype, assuming pixels size 25m
bt_stats = dict(zip(set(nbts.bt_B), [0]*len(set(nbts.bt_B))))
for x in ndff_stats:
bts = [s for s in x.keys() if s != 'count']
for bt in bts:
bt_stats[bt] += x[bt]
# Plot bardiagram
labs = sorted([k for k,_ in bt_stats.items()])
vals = [np.around(np.multiply(np.divide(bt_stats[x], np.sum([v for _, v in bt_stats.items()])), 100),
decimals=2) for x in labs]
hlp.plt_bar(labels=labs, values=vals, species=sp.name,
ha=np.round(np.multiply(np.sum([v for _, v in bt_stats.items()]), 0.0625), 0))
"""
Helper functions delivering information.
"""
import os
import numpy as np
import geopandas as gp
import pandas as pd
from datetime import datetime as dt
from matplotlib import pyplot as plt
def ndff_shp_src(soortgroep):
try:
return shp_src[soortgroep]
except KeyError:
raise Exception('{} is not a valid soortgroep'.format(soortgroep))
def nbts():
'''
Bron: https://git.wur.nl/roelo008/mnp-utilities/-/blob/master/docs/details_nbt/details_nbt_20190730.md
:return: dataframe with information on neergeschaalde beheertypen.
'''
df = pd.DataFrame(data={
'pxl': [101, 10228, 10269, 80269, 102, 103, 104, 201, 301, 401, 402, 10320, 10420, 50120, 403, 404, 501, 50197, 10330, 10430, 50130, 10332, 50132, 10311, 10331, 50111, 50131, 50134, 10328, 10315, 10321, 502, 601, 50116, 50133, 50150, 602, 603, 10451, 604, 605, 10426, 606, 10425, 701, 10450, 702, 10440, 801, 10242, 10260, 80260, 80297, 10240, 10261, 80240, 80261, 10262, 80262, 10263, 80263, 10264, 80217, 80218, 80264, 10266, 80266, 10210, 80210, 803, 10214, 10220, 10230, 10267, 50160, 80214, 80220, 80267, 804, 10250, 10265, 80250, 80265, 901, 10212, 10229, 10241, 10268, 1001, 1002, 1101, 10313, 1201, 1202, 10310, 10410, 50110, 1203, 1204, 10312, 1205, 1206, 1301, 1302, 1401, 10371, 1402, 10370, 50170, 1403, 1501, 10270, 80270, 80280, 1502, 10470, 1601, 1602, 1603, 1604, 1701, 1702, 1703, 1704, 1705, 1706, 10298, 10398, 10498, 50198, 80298, 10299, 10399, 10499, 50199, 80299],
'bt_A': ['N01.01', 'N01.02.28', 'N01.02.69', 'N08.02.69', 'N01.02', 'N01.03', 'N01.04', 'N02.01', 'N03.01', 'N04.01', 'N04.02', 'N01.03.20', 'N01.04.20', 'N05.01.20', 'N04.03', 'N04.04', 'N05.01', 'N05.01.97', 'N01.03.30', 'N01.04.30', 'N05.01.30', 'N01.03.32', 'N05.01.32', 'N01.03.11', 'N01.03.31', 'N05.01.11', 'N05.01.31', 'N05.01.34', 'N01.03.28', 'N01.03.15', 'N01.03.21', 'N05.02', 'N06.01', 'N05.01.16', 'N05.01.33', 'N05.01.50', 'N06.02', 'N06.03', 'N01.04.51', 'N06.04', 'N06.05', 'N01.04.26', 'N06.06', 'N01.04.25', 'N07.01', 'N01.04.50', 'N07.02', 'N01.04.40', 'N08.01', 'N01.02.42', 'N01.02.60', 'N08.02.60', 'N08.02.97', 'N01.02.40', 'N01.02.61', 'N08.02.40', 'N08.02.61', 'N01.02.62', 'N08.02.62', 'N01.02.63', 'N08.02.63', 'N01.02.64', 'N08.02.17', 'N08.02.18', 'N08.02.64', 'N01.02.66', 'N08.02.66', 'N01.02.10', 'N08.02.10', 'N08.03', 'N01.02.14', 'N01.02.20', 'N01.02.30', 'N01.02.67', 'N05.01.60', 'N08.02.14', 'N08.02.20', 'N08.02.67', 'N08.04', 'N01.02.50', 'N01.02.65', 'N08.02.50', 'N08.02.65', 'N09.01', 'N01.02.12', 'N01.02.29', 'N01.02.41', 'N01.02.68', 'N10.01', 'N10.02', 'N11.01', 'N01.03.13', 'N12.01', 'N12.02', 'N01.03.10', 'N01.04.10', 'N05.01.10', 'N12.03', 'N12.04', 'N01.03.12', 'N12.05', 'N12.06', 'N13.01', 'N13.02', 'N14.01', 'N01.03.71', 'N14.02', 'N01.03.70', 'N05.01.70', 'N14.03', 'N15.01', 'N01.02.70', 'N08.02.70', 'N08.02.80', 'N15.02', 'N01.04.70', 'N16.01', 'N16.02', 'N16.03', 'N16.04', 'N17.01', 'N17.02', 'N17.03', 'N17.04', 'N17.05', 'N17.06', 'N01.02.98', 'N01.03.98', 'N01.04.98', 'N05.01.98', 'N08.02.98', 'N01.02.99', 'N01.03.99', 'N01.04.99', 'N05.01.99', 'N08.02.99'],
'bt_B': ['N01.01', 'N01.01', 'N01.01', 'N01.01', 'N01.02', 'N01.03', 'N01.04', 'N02.01', 'N03.01', 'N04.01', 'N04.02', 'N04.02', 'N04.02', 'N04.02', 'N04.03', 'N04.04', 'N05.01', 'N05.01.00', 'N05.01.02', 'N05.01.02', 'N05.01.02', 'N05.01.03', 'N05.01.03', 'N05.01.06', 'N05.01.06', 'N05.01.06', 'N05.01.06', 'N05.01.11', 'N05.01.13', 'N05.01.14', 'N05.01.14', 'N05.02', 'N06.01', 'N06.01', 'N06.01', 'N06.01', 'N06.02', 'N06.03', 'N06.03', 'N06.04', 'N06.05', 'N06.05', 'N06.06', 'N06.06', 'N07.01', 'N07.01', 'N07.02', 'N07.02', 'N08.01', 'N08.01', 'N08.02.00', 'N08.02.00', 'N08.02.00', 'N08.02.02', 'N08.02.02', 'N08.02.02', 'N08.02.02', 'N08.02.03', 'N08.02.03', 'N08.02.07', 'N08.02.07', 'N08.02.08', 'N08.02.08', 'N08.02.08', 'N08.02.08', 'N08.02.11', 'N08.02.11', 'N08.02.15', 'N08.02.15', 'N08.03', 'N08.03', 'N08.03', 'N08.03', 'N08.03', 'N08.03', 'N08.03', 'N08.03', 'N08.03', 'N08.04', 'N08.04', 'N08.04', 'N08.04', 'N08.04', 'N09.01', 'N09.01', 'N09.01', 'N09.01', 'N09.01', 'N10.01', 'N10.02', 'N11.01', 'N11.01', 'N12.01', 'N12.02', 'N12.02', 'N12.02', 'N12.02', 'N12.03', 'N12.04', 'N12.04', 'N12.05', 'N12.06', 'N13.01', 'N13.02', 'N14.01', 'N14.01', 'N14.02', 'N14.02', 'N14.02', 'N14.03', 'N15.01', 'N15.01', 'N15.01.01', 'N15.01.02', 'N15.02', 'N15.02', 'N16.01', 'N16.02', 'N16.03', 'N16.04', 'N17.01', 'N17.02', 'N17.03', 'N17.04', 'N17.05', 'N17.06', 'W00.01', 'W00.01', 'W00.01', 'W00.01', 'W00.01', 'W00.02', 'W00.02', 'W00.02', 'W00.02', 'W00.02'],
'desc': ['Zee en wad', 'grootschalig duin, zee en wad', 'grootschalig duin, slik- en zandplaten ', 'open duin, slik- en zandplaten ', 'Duin- en kwelderlandschap', 'Rivier- en moeraslandschap', 'Zand- en kalklandschap', 'Rivier', 'Beek en Bron', 'Kranswierwater', 'Zoete Plas', 'grootschalig moeras, plas en meer', 'grootschalig zand, plas en meer', 'moeras, plas en meer', 'Brak water', 'Afgesloten zeearm', 'Moeras', 'moeras, overige natuur', 'grootschalig moeras, riet', 'grootschalig zand, riet', 'moeras, riet', 'grootschalig moeras, waterriet', 'moeras, waterriet', 'grootschalig moeras, ruigten en zoomen', 'grootschalig moeras, riet ruigten en zoomen', 'moeras, ruigten en zoomen', 'moeras, riet ruigten en zoomen', 'moeras, galigaan', 'grootschalig moeras, droogvallend, zand', 'grootschalig moeras, slikkige oever met grasvegetatie', 'grootschalig moeras, slikkige oever', 'Gemaaid rietland', 'Veenmosrietland en moerasheide', 'moeras, trilvenen en veenmosrietland', 'moeras, veenmosrietland', 'moeras, heide', 'Trilveen', 'Hoogveen', 'grootschalig zand, actieve en herstellende hoogvenen', 'Vochtige heide', 'Zwakgebufferd ven', 'grootschalig zand, zwakgebufferd ven', 'Zuur ven en hoogveenven', 'grootschalig zand, zuur ven', 'Droge heide', 'grootschalig zand, (kraai)heide', 'Zandverstuiving', 'grootschalig zand, zand ', 'Strand en embryonaal duin', 'grootschalig duin, embryonale duinen ', 'grootschalig duin, open duin', 'open duin, open duin ', 'open duin, overige natuur', 'grootschalig duin, zand ', 'grootschalig duin, embryonale duinen in open duin', 'open duin, zand ', 'open duin, embryonale duinen in open duin', 'grootschalig duin, witte duinen ', 'open duin, witte duinen ', 'grootschalig duin, grijze duinen (kalkrijk) ', 'open duin, grijze duinen (kalkrijk) ', 'grootschalig duin, grijze duinen (kalkarm) ', 'open duin, grasland in grijze duinen (kalkrijk)', 'open duin, grasland in grijze duinen', 'open duin, grijze duinen (kalkarm) ', 'grootschalig duin, duindoorn- of kruipwilgstruwelen ', 'open duin, duindoorn- of kruipwilgstruwelen ', 'grootschalig duin, grasland', 'open duin, grasland ', 'Vochtige duinvallei', 'grootschalig duin, nat grasland ', 'grootschalig duin, plas en meer', 'grootschalig duin, duinvallei met riet', 'grootschalig duin, vochtige duinvalleivegetatie', 'moeras, in duingebied', 'open duin, nat grasland ', 'open duin, plas en meer', 'open duin, vochtige duinvalleivegetatie', 'Duinheide', 'grootschalig duin, (kraai)heide', 'grootschalig duin, heidevegetatie in open duin', 'open duin, (kraai) heide ', 'open duin, heidevegetatie in open duin', 'Schor of kwelder', 'grootschalig duin, kwelder', 'grootschalig duin, zilte pioniervegetatie zee en wad ', 'grootschalig duin, zilte pioniervegetatie op zand ', 'grootschalig duin, zilte pioniervegetatie in open duin', 'Nat schraalland', 'Vochtig hooiland', 'Droog schraalgrasland', 'grootschalig moeras, stroomdalgrasland', 'Bloemdijk', 'Kruiden- en faunarijk grasland', 'grootschalig moeras, grasland', 'grootschalig zand, grasland', 'moeras, grasland', 'Glanshaverhooiland', 'Zilt- en overstromingsgrasland', 'grootschalig moeras, zilte graslanden', 'Kruiden- of faunarijke akker', 'Ruigteveld', 'Vochtig weidevogelgrasland', 'Wintergastenweide', 'Rivier- en beekbegeleidend bos', 'grootschalig moeras, rivier en beekbegeleidend bos', 'Hoog- en laagveenbos', 'grootschalig moeras, overig bos', 'moeras,overig bos', 'Haagbeuken- en essenbos', 'Duinbos', 'grootschalig duin, overig bos', 'open duin, overig bos ', 'open duin, naaldbos ', 'Dennen-, eiken- en beukenbos', 'grootschalig zand, overig bos', 'Droog bos met productie (vervallen)', 'Vochtig bos met productie (vervallen)', 'Droog bos met producties (nieuw per 01-01-2018)', 'Vochtig bos met producties (nieuw per 01-01-2018)', 'Vochtig hakhout en middenbos', 'Droog hakhout', 'Park- of stinzenbos', 'Eendenkooi', 'Wilgengriend (nieuw per 1-1-2017)', 'Vochtig en hellinghakhout (nieuw per 1-1-2017)', 'grootschalig duin, infrastructuur', 'grootschalig moeras, infrastructuur', 'grootschalig zand, infrastructuur', 'moeras, infrastructuur', 'open duin, infrastructuur ', 'grootschalig duin, overig grondgebruik', 'grootschalig moeras, overig grondgebruik', 'grootschalig zand, overig grondgebruik', 'moeras, overig grondgebruik', 'open duin, overig grondgebruik']
})
return df
def read_ndff_shp(src):
"""
:param src: path to NDFF shapefile
:return: ndff shapefile as geopandas geodataframe with additional attributes
"""
ndff = gp.read_file(src, encoding='UTF-8')
ndff['area'] = ndff.area
ndff['nl_name'] = ndff['nl_name'].str.lower()
ndff['year'] = [int(dt.strptime(x[:10], '%Y-%m-%d').strftime('%Y')) for x in ndff.periodstop]
return ndff
def hectare(x):
"""
Custom raster stats function to give output in hectares
"""
return np.multiply(np.ma.count(x), 0.0625)
def plt_bar(labels, values, species, ha):
x = np.arange(len(labels))
fig = plt.figure(figsize=(14, 8))
ax = fig.add_subplot(111)
ax.set(xlim=[-1, len(labels) + 1], ylim=[0, 100])
ax.set_xticks(x)
ax.set_xticklabels(labels, rotation='vertical', horizontalalignment='center')
ax.hlines(y=[x for x in range(0, 100, 10)], xmin=-1, xmax=len(labels) + 1, colors='lightgrey')
# ax.hlines(y=[x for x in range(0, 200, 50)], xmin=-1, xmax=len(labels) + 1, linewidths=1)
ax.bar(x, values, label='{}, tot. opp. = {:,}ha'.format(species, ha), width=0.6, align='center')
ax.set_ylabel('% van totale oppervlakte van NDFF waarnemingen sinds 2000')
fig.tight_layout()
ax.legend()
out_dir = r'c:\Users\roelo008\OneDrive - WageningenUR\a_projects\MNP\draakgracht'
out_name = 'ndff_bt_{0}.png'.format(species)
fig.savefig(os.path.join(out_dir, out_name))
print('I made a figure: {0}'.format(os.path.join(out_dir, out_name)))
plt.close()
class Species:
"""
Class holding all info related to a species
"""
def __init__(self, sp_name):
self.name = sp_name.lower()
self.soortgr = None
self.soortnr = None
self.ndff_src = None
self.nw = None
self.lpi = None
self.snl_hoogveen = None
self.snl_vheide = None
self.snl_zwakbufven = None
self.snl_zuurven = None
self.snl_dheide = None
self.snl_zandv = None
self.nulsrt = None
self.fetch_my_info()
def fetch_my_info(self):
sp_info = pd.read_csv(r'C:\Users\roelo008\OneDrive - WageningenUR\a_projects\MNP\ndff\soorten_lijst.txt',
sep=';', comment='#')
shp_src = {
'broedvogel': r'c:\Users\roelo008\OneDrive - WageningenUR\a_projects\MNP\ndff\src_shp\def_broedvogels.shp',
'dagvlinder': r'c:\Users\roelo008\OneDrive - WageningenUR\a_projects\MNP\ndff\src_shp\def_dagvlinders.shp'}
try:
self.soortgr = sp_info.loc[sp_info.sp_nm.str.lower() == self.name, 'tax_groep'].item()
self.soortnr = sp_info.loc[sp_info.sp_nm.str.lower() == self.name, 'sp_nr'].item()
self.ndff_src = shp_src[self.soortgr]
except (NameError, ValueError) as e:
print('{}: {} is not a recognized name'.format(e, self.name))
raise
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment