2021-11-18 11:06:21 +13:00
import csv
from os import write
from pathlib import Path
import right_tree . api . data
from . filters import *
from . wms_utils import get_address_from_coordinates , get_point_from_coordinates
import pdfkit
import pandas as pd
from PyPDF2 import PdfFileMerger
CSV_FILENAME = ' plants.csv '
PLANTING_GUIDE_PDF_FILENAME = ' planting_guide.pdf '
HEADER_FIELDS = [ ' Names ' , ' Growth Form / Max Height (m) / Spacing (m) / Forest Position ' , ' Moisture Preferences ' ,
' Tolerances (Water / Drought / Frost / Salinity) ' , ' Ecosystem Services ' , ' Carbon Sequestration Rate ' , ' Planting Stage ' ]
def get_plant_resource_filepath ( filename = CSV_FILENAME , resource_dir = ' generated_resources ' ) :
""" Retrives the filepath for the plant csv file.
"""
return Path ( right_tree . api . data . __file__ ) . resolve ( ) . parent / resource_dir / filename
def get_location_filters ( request ) :
""" Retrives the selected location data from the request.
"""
2021-11-23 14:16:52 +13:00
filter_rows = [ [ ' LOCATION FILTERS: ' , ' ' ] ]
2021-11-18 11:06:21 +13:00
coordinates = request . query_params . get ( ' coordinates ' )
if coordinates is not None :
eco_district_layer = ecological_district_coordinate_filter (
coordinates ) . first ( )
point = get_point_from_coordinates ( coordinates )
2021-11-23 14:16:52 +13:00
address = get_address_from_coordinates ( coordinates )
2021-11-18 11:06:21 +13:00
filter_rows . append ( [ ' Point coordinates: ' , point ] )
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ ' Ecological region: ' , eco_district_layer . ecologic_1 or ' ' ] )
filter_rows . append ( [ ' Ecological district: ' , eco_district_layer . ecologic_2 or ' ' ] )
filter_rows . append ( [ ' Property address: ' , address [ ' full_address ' ] if address is not None else ' ' ] )
2021-11-18 11:06:21 +13:00
else :
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ " None specified " , " " ] )
2021-11-18 11:06:21 +13:00
return filter_rows
def get_soil_filters ( request ) :
""" Retrives the selected soil type data from the request.
"""
2021-11-23 14:16:52 +13:00
filter_rows = [ [ ' SOIL FILTERS: ' , ' ' ] ]
2021-11-18 11:06:21 +13:00
soil_variant = request . query_params . get ( ' soilVariant ' )
coordinates = request . query_params . get ( ' coordinates ' )
if soil_variant is not None and coordinates is not None :
soil_order_obj = soil_order_coordinate_filter ( coordinates ) . first ( )
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ ' Soil Order: ' , f " { soil_order_obj . name or ' ' } ( { soil_order_obj . code or ' ' } ) " ] )
2021-11-18 11:06:21 +13:00
filter_rows . append ( [ ' Soil Variant: ' , soil_variant ] )
else :
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ " None specified " , " " ] )
2021-11-18 11:06:21 +13:00
return filter_rows
def get_site_filters ( request ) :
""" Retrives the selected site data from the request.
"""
2021-11-23 14:16:52 +13:00
filter_rows = [ [ ' SITE FILTERS: ' , ' ' ] ]
2021-11-18 11:06:21 +13:00
habitat = request . query_params . get ( ' habitat ' )
zone = request . query_params . get ( ' zone ' )
if zone is not None and habitat is not None :
habitat_json = json . loads ( habitat )
zone_json = json . loads ( zone )
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ ' Habitat: ' , habitat_json . get ( " name " , " " ) ] )
filter_rows . append ( [ ' Zone Name: ' , zone_json . get ( " name " , " " ) ] )
filter_rows . append ( [ ' Zone Variant: ' , zone_json . get ( " variant " , " " ) ] )
filter_rows . append ( [ ' Zone Refined Variant: ' , zone_json . get ( " refined_variant " , " " ) ] )
2021-11-18 11:06:21 +13:00
else :
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ " None specified " , " " ] )
2021-11-18 11:06:21 +13:00
return filter_rows
2021-12-01 10:06:30 +13:00
def get_additional_region_info ( request ) :
""" If the location coordinates fall within the CHCH or Auckland regions then return a description of where to find more information.
"""
coordinates = request . query_params . get ( ' coordinates ' )
if coordinates is not None :
if is_in_christchurch ( coordinates ) :
return [ [ " Your location falls within the ecosystem type covered by the Christchurch Council ecosystem maps - further information can be obtained from Ōtautahi/Christchurch ecosystems map link to: https://ccc.govt.nz/environment/land/ecosystem-map " , " " ] , [ ' ' , ' ' ] ]
elif is_in_auckland ( coordinates ) :
return [ [ " Your location falls within the ecosystem type covered by the Auckland Council Tiaki Tāmaki Makaurau Conservation map - further information can be obtained from tiaki Tāmaki Makaurau conservation Auckland - link to https://www.tiakitamakimakaurau.nz/conservation-map/ " , " " ] , [ ' ' , ' ' ] ]
return [ ]
2021-11-18 11:06:21 +13:00
def get_filter_values ( request ) :
""" Retrives all selected values/filters from the request.
"""
filter_rows = [ ]
# Add all the location filters
filter_rows + = get_location_filters ( request )
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ ' ' , ' ' ] )
2021-11-18 11:06:21 +13:00
# Add the soil filters
filter_rows + = get_soil_filters ( request )
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ ' ' , ' ' ] )
2021-11-18 11:06:21 +13:00
# Add the project site filters
filter_rows + = get_site_filters ( request )
2021-11-23 14:16:52 +13:00
filter_rows . append ( [ ' ' , ' ' ] )
2021-12-01 10:06:30 +13:00
filter_rows + = get_additional_region_info ( request )
2021-11-18 11:06:21 +13:00
return filter_rows
def write_csv_filter_info ( request , writer ) :
""" Retrieves and writes filter information to a CSV file given a writer.
"""
for filter_row in get_filter_values ( request ) :
writer . writerow ( filter_row )
def write_csv_plant_info ( plant_data , writer ) :
""" Writes plant list information to a CSV file given a writer.
"""
writer . writerow ( HEADER_FIELDS )
for plant in plant_data :
plant_data_row = [
plant . display_name ,
plant . display_growth_form ,
plant . moisture_preferences ,
plant . plant_tolerances ,
plant . ecosystem_services ,
plant . carbon_sequestration ,
plant . stage
]
writer . writerow ( plant_data_row )
def create_plant_csv_file ( request , plant_data ) :
""" Constructs a csv file that contains selected filter values and the resulting plant list.
"""
with open ( get_plant_resource_filepath ( ) , ' w ' , encoding = ' UTF8 ' ) as f :
writer = csv . writer ( f )
# Write filter/selected values
write_csv_filter_info ( request , writer )
# Write the plant data
write_csv_plant_info ( plant_data , writer )
def generate_pdf ( data_name , data , csv_generation_function ) :
""" Generates a pdf from a csv given data and a csv generation method.
Requires an html file to be generated as an intermediate step .
"""
# Define filepaths - some are required as intermediate files
csv_filepath = get_plant_resource_filepath ( f ' { data_name } .csv ' )
html_filepath = get_plant_resource_filepath ( f ' { data_name } .html ' )
pdf_filepath = get_plant_resource_filepath ( f ' { data_name } .pdf ' )
# Create an initial csv file with the data
with open ( csv_filepath , ' w ' , encoding = ' UTF8 ' ) as f :
writer = csv . writer ( f )
csv_generation_function ( data , writer )
# Convert the csv to and html file then to a pdf
CSV = pd . read_csv ( csv_filepath )
CSV . to_html ( html_filepath )
pdfkit . from_file ( str ( html_filepath ) , str ( pdf_filepath ) )
def create_planting_guide_pdf ( request , plant_data ) :
""" Creates a planting guide pdf document with a pre-generated planting guide with
filter and plant list tabular informtation appended .
"""
# Define the names of the resource files as used in multiple places
filter_file_prefix = " filters "
plant_list_file_prefix = " plant_list "
# Generate the filters and plant list pdf files
generate_pdf ( filter_file_prefix , request , write_csv_filter_info ) # TODO: space values appear as NaN... this should be fixed
generate_pdf ( plant_list_file_prefix , plant_data , write_csv_plant_info )
# Create a list of pdfs that need to be merged
planting_guide_pdf_filepath = get_plant_resource_filepath ( PLANTING_GUIDE_PDF_FILENAME , ' resources ' )
filter_pdf_filepath = get_plant_resource_filepath ( f ' { filter_file_prefix } .pdf ' )
plant_list_pdf_filepath = get_plant_resource_filepath ( f ' { plant_list_file_prefix } .pdf ' )
pdfs = [ planting_guide_pdf_filepath , filter_pdf_filepath , plant_list_pdf_filepath ]
# Merge pdfs
merger = PdfFileMerger ( )
for pdf in pdfs :
merger . append ( str ( pdf ) )
# Create the final output pdf with all merged documents
output_pdf_filepath = get_plant_resource_filepath ( PLANTING_GUIDE_PDF_FILENAME )
merger . write ( str ( output_pdf_filepath ) )
merger . close ( )