diff --git a/install.yml b/install.yml index 0214f17..7f815c5 100644 --- a/install.yml +++ b/install.yml @@ -17,6 +17,7 @@ requirements: - geopandas - jinja2 - geomatics + - hs_restclient pip: - geoserver-restconfig diff --git a/tethysapp/geoglows_hydroviewer/app.py b/tethysapp/geoglows_hydroviewer/app.py index 62bcf65..53330bb 100644 --- a/tethysapp/geoglows_hydroviewer/app.py +++ b/tethysapp/geoglows_hydroviewer/app.py @@ -61,6 +61,10 @@ def url_maps(self): UrlMap(name='project_overview', url=f'{self.root_url}/creator/project', controller=f'{self.package}.controllers_creator.project_overview'), + UrlMap(name='render_hydroviewer', + url=f'{self.root_url}/creator/render', + controller=f'{self.package}.controllers_creator.render_hydroviewer'), + # creator pages and urls for adding/deleting projects UrlMap(name='add_new_project', url=f'{self.root_url}/creator/add-new-project', @@ -94,16 +98,19 @@ def url_maps(self): url=f'{self.root_url}/creator/project/edit/retrieve_boundaries', controller=f'{self.package}.controllers_creator.retrieve_hydroviewer_boundaries'), - # project exporting options - UrlMap(name='shapefile_export_zipfile', - url=f'{self.root_url}/creator/project/export/shapefile_export_zipfile', - controller=f'{self.package}.controllers_creator.shapefile_export_zipfile'), - UrlMap(name='shapefile_export_geoserver', - url=f'{self.root_url}/creator/project/export/shapefile_export_geoserver', - controller=f'{self.package}.controllers_creator.shapefile_export_geoserver'), - UrlMap(name='project_export_html', - url=f'{self.root_url}/creator/project/export/project_export_html', - controller=f'{self.package}.controllers_creator.project_export_html'), + # project and shapefile exporting options + UrlMap(name='export_zipfile', + url=f'{self.root_url}/creator/project/export/zipfile', + controller=f'{self.package}.controllers_creator_export.export_zipfile'), + UrlMap(name='export_geoserver', + url=f'{self.root_url}/creator/project/export/geoserver', + controller=f'{self.package}.controllers_creator_export.export_geoserver'), + UrlMap(name='export_hydroshare', + url=f'{self.root_url}/creator/project/export/hydroshare', + controller=f'{self.package}.controllers_creator_export.export_hydroshare'), + UrlMap(name='export_html', + url=f'{self.root_url}/creator/project/export/html', + controller=f'{self.package}.controllers_creator_export.export_html'), ) def custom_settings(self): diff --git a/tethysapp/geoglows_hydroviewer/controllers_creator.py b/tethysapp/geoglows_hydroviewer/controllers_creator.py index 5afe1d6..8d0de85 100644 --- a/tethysapp/geoglows_hydroviewer/controllers_creator.py +++ b/tethysapp/geoglows_hydroviewer/controllers_creator.py @@ -3,16 +3,12 @@ import os import shutil import urllib.parse -from zipfile import ZipFile import geomatics import geopandas as gpd -import geoserver.util -import jinja2 from django.contrib import messages -from django.http import JsonResponse, HttpResponse -from django.shortcuts import render, redirect -from geoserver.catalog import Catalog +from django.http import JsonResponse +from django.shortcuts import render, redirect, reverse from tethys_sdk.gizmos import SelectInput from tethys_sdk.permissions import login_required @@ -21,6 +17,9 @@ SHAPE_DIR = App.get_custom_setting('global_delineation_shapefiles_directory') +EXPORT_CONFIGS_DICT = {'url': '', 'workspace': '', 'dl': '', 'ctch': '', 'resource_id': '', 'exported': False, + 'export_destination': '', 'exported_by_app': False} + WARN_DOWNLOAD_SHAPEFILES = 'GEOGloWS Shapefile data not found. You can continue to work on projects who have created ' \ 'shapefiles but will be unable to create shapefiles for new projects. Check the custom ' \ 'settings and contact the server admin for help downloading this data.' @@ -33,36 +32,21 @@ def home(request): projects_path = os.path.join(App.get_app_workspace().path, 'projects') projects = os.listdir(projects_path) - - projects = [prj for prj in projects if os.path.isdir(os.path.join(projects_path, prj))] - finished_prjs = [prj for prj in projects if os.path.exists(os.path.join(projects_path, prj, 'hydroviewer.html'))] - - projects = [(prj.replace('_', ' '), prj) for prj in projects] - finished_prjs = [(prj.replace('_', ' '), prj) for prj in finished_prjs] + projects = [(prj.replace('_', ' '), prj) for prj in projects if os.path.isdir(os.path.join(projects_path, prj))] if len(projects) > 0: show_projects = True else: show_projects = False - if len(finished_prjs) > 0: - show_finished_projects = True - else: - show_finished_projects = False projects = SelectInput(display_text='Existing Hydroviewer Projects', name='project', multiple=False, options=projects) - downloadable_projects = SelectInput(display_text='Download Finished Hydroviewer', - name='downloadable_projects', - multiple=False, - options=finished_prjs) context = { 'projects': projects, - 'downloadable_projects': downloadable_projects, 'show_projects': show_projects, - 'show_finished_projects': show_finished_projects, } return render(request, 'geoglows_hydroviewer/geoglows_hydroviewer_creator.html', context) @@ -73,16 +57,21 @@ def add_new_project(request): project = request.GET.get('new_project_name', False) if not project: messages.error(request, 'Please provide a name for the new project') - return redirect('..') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) project = str(project).replace(' ', '_') - new_proj_dir = os.path.join(App.get_app_workspace().path, 'projects', project) + new_proj_dir = get_project_directory(project) try: + # make a new folder os.mkdir(new_proj_dir) + # make the configs json + with open(os.path.join(new_proj_dir, 'export_configs.json'), 'w') as ec: + ec.write(json.dumps(EXPORT_CONFIGS_DICT)) messages.success(request, 'Project Successfully Created') - return redirect(f'../project/?{urllib.parse.urlencode(dict(project=project))}') + return redirect( + reverse('geoglows_hydroviewer:project_overview') + f'?{urllib.parse.urlencode(dict(project=project))}') except Exception as e: messages.error(request, f'Failed to Create Project: {project} ({e})') - return redirect('..') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) @login_required() @@ -96,7 +85,7 @@ def delete_existing_project(request): messages.success(request, f'Successfully Deleted Project: {project}') except Exception as e: messages.error(request, f'Failed to Delete Project: {project} ({e})') - return redirect('..') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) @login_required() @@ -104,30 +93,20 @@ def project_overview(request): project = request.GET.get('project', False) if not project: messages.error(request, 'Project not found, please pick from list of projects or make a new one') - return redirect('..') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) proj_dir = get_project_directory(project) - # check to see what data has been created (i.e. which of the steps have been completed) boundaries_created = os.path.exists(os.path.join(proj_dir, 'boundaries.json')) - shapefiles_created = bool( - os.path.exists(os.path.join(proj_dir, 'selected_catchment')) and - os.path.exists(os.path.join(proj_dir, 'selected_drainageline')) - ) + shapefiles_created = bool(os.path.exists(os.path.join(proj_dir, 'selected_catchment')) and + os.path.exists(os.path.join(proj_dir, 'selected_drainageline'))) - geoserver_configs = os.path.exists(os.path.join(proj_dir, 'geoserver_config.json')) - if geoserver_configs: - with open(os.path.join(proj_dir, 'geoserver_config.json')) as a: - configs = json.loads(a.read()) - geoserver_url = configs['url'] - workspace = configs['workspace'] - drainagelines_layer = configs['dl_layer'] - catchment_layer = configs['ctch_layer'] - else: - geoserver_url = '' - workspace = '' - drainagelines_layer = '' - catchment_layer = '' + with open(os.path.join(proj_dir, 'export_configs.json')) as a: + configs = json.loads(a.read()) + geoserver_url = configs['url'] + workspace = configs['workspace'] + drainagelines_layer = configs['dl'] + catchment_layer = configs['ctch'] context = { 'project': project, @@ -139,8 +118,9 @@ def project_overview(request): 'shapefiles': shapefiles_created, 'shapefilesJS': json.dumps(shapefiles_created), - 'geoserver': geoserver_configs, - 'geoserverJS': json.dumps(geoserver_configs), + 'exported': configs['exported'], + 'exportedJS': json.dumps(configs['exported']), + 'geoserver_url': geoserver_url, 'workspace': workspace, 'drainagelines_layer': drainagelines_layer, @@ -150,12 +130,53 @@ def project_overview(request): return render(request, 'geoglows_hydroviewer/creator_project_overview.html', context) +@login_required() +def render_hydroviewer(request): + project = request.POST.get('project', False) + project_title = False + url = '' + workspace = '' + dl = '' + ctch = '' + + projects_path = os.path.join(App.get_app_workspace().path, 'projects') + projects = os.listdir(projects_path) + projects = [(prj.replace('_', ' '), prj) for prj in projects if os.path.isdir(os.path.join(projects_path, prj))] + projects = SelectInput(display_text='Get values from a Hydroviewer project', + name='project', + multiple=False, + options=projects) + + if project: + exports_config_file_path = os.path.join(get_project_directory(project), 'export_configs.json') + if os.path.exists(exports_config_file_path): + project_title = project.replace('_', ' ') + with open(exports_config_file_path, 'r') as ec: + configs = json.loads(ec.read()) + url = configs['url'] + workspace = configs['workspace'] + dl = configs['dl'] + ctch = configs['ctch'] + + context = { + 'project': project, + 'projects': projects, + 'project_title': project_title, + 'url': url, + 'workspace': workspace, + 'dl': dl, + 'ctch': ctch, + } + + return render(request, 'geoglows_hydroviewer/creator_render_hydroviewer.html', context) + + @login_required() def draw_hydroviewer_boundaries(request): project = request.GET.get('project', False) if not project: messages.error(request, 'Unable to find this project') - return redirect('../..') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) watersheds_select_input = SelectInput( display_text='Select A Watershed', @@ -185,7 +206,7 @@ def draw_hydroviewer_boundaries(request): 'watersheds_select_input': watersheds_select_input, 'geojson': bool(os.path.exists(os.path.join(get_project_directory(project), 'boundaries.json'))), } - return render(request, 'geoglows_hydroviewer/creator_draw_hydroviewer_boundaries.html', context) + return render(request, 'geoglows_hydroviewer/creator_boundaries_draw.html', context) @login_required() @@ -213,7 +234,7 @@ def choose_hydroviewer_boundaries(request): project = request.GET.get('project', False) if not project: messages.error(request, 'Unable to find this project') - return redirect('../..') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) regions = SelectInput( display_text='Pick A World Region (ESRI Living Atlas)', @@ -254,7 +275,7 @@ def choose_hydroviewer_boundaries(request): 'regions': regions, 'geojson': bool(os.path.exists(os.path.join(get_project_directory(project), 'boundaries.json'))), } - return render(request, 'geoglows_hydroviewer/creator_choose_hydroviewer_boundaries.html', context) + return render(request, 'geoglows_hydroviewer/creator_boundaries_choose_predefined.html', context) @login_required() @@ -354,129 +375,3 @@ def geoprocess_hydroviewer_clip(request): else: raise ValueError('illegal shapefile type specified') - - -@login_required() -def shapefile_export_geoserver(request): - project = request.GET.get('project', False) - url = request.GET.get('gs_url') - username = request.GET.get('gs_username', 'admin') - password = request.GET.get('gs_password', 'geoserver') - workspace_name = request.GET.get('workspace', 'geoglows_hydroviewer_creator') - dl_name = request.GET.get('dl_name', 'drainagelines') - ct_name = request.GET.get('ct_name', 'catchments') - if not project: - return JsonResponse({'error': 'unable to find the project'}) - proj_dir = get_project_directory(project) - - try: - cat = Catalog(url, username=username, password=password) - - # identify the geoserver stores - workspace = cat.get_workspace(workspace_name) - - try: - # create geoserver store and upload the catchments - shapefile_plus_sidecars = geoserver.util.shapefile_and_friends( - os.path.join(proj_dir, 'selected_catchment', 'catchment_select')) - cat.create_featurestore(ct_name, workspace=workspace, data=shapefile_plus_sidecars, overwrite=True) - except Exception as e: - print('failed to upload catchments') - print(e) - - try: - # create geoserver store and upload the drainagelines - shapefile_plus_sidecars = geoserver.util.shapefile_and_friends( - os.path.join(proj_dir, 'selected_drainageline', 'drainageline_select')) - cat.create_featurestore(dl_name, workspace=workspace, data=shapefile_plus_sidecars, overwrite=True) - except Exception as e: - print('failed to upload drainagelines') - print(e) - - # geoserver_configs keys to be added to geoserver_configs dictionary - geoserver_configs = { - 'url': url.replace('/rest/', '/wms'), - 'workspace': workspace_name, - 'dl_layer': dl_name, - 'ctch_layer': ct_name, - } - - with open(os.path.join(proj_dir, 'geoserver_config.json'), 'w') as configfile: - configfile.write(json.dumps(geoserver_configs)) - except Exception as e: - print(e) - return JsonResponse({'status': 'failed'}) - - return JsonResponse({'status': 'success'}) - - -@login_required() -def shapefile_export_zipfile(request): - project = request.GET.get('project', False) - if not project: - return JsonResponse({'error': 'unable to find the project'}) - proj_dir = get_project_directory(project) - zip_path = os.path.join(proj_dir, 'hydroviewer_shapefiles.zip') - - # if there is already a zip file, serve it for download - if os.path.exists(zip_path): - zip_file = open(zip_path, 'rb') - response = HttpResponse(zip_file, content_type='application/zip') - response['Content-Disposition'] = 'attachment; filename="hydroviewer_shapefiles.zip"' - return response - - catchment_shapefile = os.path.join(proj_dir, 'selected_catchment', 'catchment_select.shp') - drainageline_shapefile = os.path.join(proj_dir, 'selected_drainageline', 'drainageline_select.shp') - if not os.path.exists(catchment_shapefile): - raise FileNotFoundError('selected catchment shapefile does not exist') - if not os.path.exists(drainageline_shapefile): - raise FileNotFoundError('selected drainageline shapefile does not exist') - - try: - with ZipFile(zip_path, 'w') as zipfile: - catchment_components = glob.glob(os.path.join(proj_dir, 'selected_catchment', 'catchment_select.*')) - for component in catchment_components: - zipfile.write(component, arcname=os.path.join('selected_catchment', os.path.basename(component))) - dl_components = glob.glob(os.path.join(proj_dir, 'selected_drainageline', 'drainageline_select.*')) - for component in dl_components: - zipfile.write(component, arcname=os.path.join('selected_drainageline', os.path.basename(component))) - except Exception as e: - shutil.rmtree(zip_path) - raise e - - zip_file = open(zip_path, 'rb') - response = HttpResponse(zip_file.read(), content_type='application/zip') - response['Content-Disposition'] = 'attachment; filename="hydroviewer_shapefiles.zip"' - return response - - -@login_required() -def project_export_html(request): - project = request.GET.get('project', False) - if not project: - return JsonResponse({'error': 'unable to find the project'}) - proj_dir = get_project_directory(project) - html_path = os.path.join(proj_dir, 'hydroviewer.html') - - with open(os.path.join(proj_dir, 'geoserver_config.json')) as configfile: - geoserver_configs = json.loads(configfile.read()) - with open(os.path.join(proj_dir, 'boundaries.json')) as bndsgj: - boundaries_json = json.loads(bndsgj.read()) - with open(os.path.join(App.get_app_workspace().path, 'hydroviewer_interactive.html'), 'r') as template: - with open(html_path, 'w') as hydrohtml: - hydrohtml.write( - jinja2.Template(template.read()).render( - title=project.replace('_', ' '), - api_endpoint='https://tethys2.byu.edu/localsptapi/api/', - geoserver_wms_url=geoserver_configs['url'], - workspace=geoserver_configs['workspace'], - catchment_layer=geoserver_configs['ctch_layer'], - drainage_layer=geoserver_configs['dl_layer'], - boundaries_json=json.dumps(boundaries_json), - ) - ) - - with open(html_path, 'r') as htmlfile: - response = HttpResponse(htmlfile, content_type='text/html') - response['Content-Disposition'] = f'attachment; filename="{project}_hydroviewer.html"' - return response diff --git a/tethysapp/geoglows_hydroviewer/controllers_creator_export.py b/tethysapp/geoglows_hydroviewer/controllers_creator_export.py new file mode 100644 index 0000000..62198f6 --- /dev/null +++ b/tethysapp/geoglows_hydroviewer/controllers_creator_export.py @@ -0,0 +1,179 @@ +import json +import os +import urllib.parse + +import geoglows +import geoserver.util +import hs_restclient +import jinja2 +from django.contrib import messages +from django.http import JsonResponse, HttpResponse +from django.shortcuts import redirect, reverse +from geoserver.catalog import Catalog +from tethys_sdk.permissions import login_required + +from .app import GeoglowsHydroviewer as App +from .hydroviewer_creator_tools import get_project_directory +from .hydroviewer_creator_tools import zip_project_shapefiles + +SHAPE_DIR = App.get_custom_setting('global_delineation_shapefiles_directory') + + +@login_required() +def export_geoserver(request): + project = request.GET.get('project', False) + url = request.GET.get('gs_url') + username = request.GET.get('gs_username', 'admin') + password = request.GET.get('gs_password', 'geoserver') + workspace_name = request.GET.get('workspace', 'geoglows_hydroviewer_creator') + dl_name = request.GET.get('dl_name', 'drainagelines') + ct_name = request.GET.get('ct_name', 'catchments') + if not project: + return JsonResponse({'error': 'unable to find the project'}) + proj_dir = get_project_directory(project) + + try: + cat = Catalog(url, username=username, password=password) + + # identify the geoserver stores + workspace = cat.get_workspace(workspace_name) + + try: + # create geoserver store and upload the catchments + shapefile_plus_sidecars = geoserver.util.shapefile_and_friends( + os.path.join(proj_dir, 'selected_catchment', 'catchment_select')) + cat.create_featurestore(ct_name, workspace=workspace, data=shapefile_plus_sidecars, overwrite=True) + except Exception as e: + print('failed to upload catchments') + print(e) + + try: + # create geoserver store and upload the drainagelines + shapefile_plus_sidecars = geoserver.util.shapefile_and_friends( + os.path.join(proj_dir, 'selected_drainageline', 'drainageline_select')) + cat.create_featurestore(dl_name, workspace=workspace, data=shapefile_plus_sidecars, overwrite=True) + except Exception as e: + print('failed to upload drainagelines') + print(e) + + # add keys to the export_configs.json + with open(os.path.join(proj_dir, 'export_configs.json'), 'r') as configfile: + geoserver_configs = json.loads(configfile.read()) + geoserver_configs['url'] = url.replace('/rest/', '/wms') + geoserver_configs['workspace'] = workspace_name + geoserver_configs['dl'] = dl_name + geoserver_configs['ctch'] = ct_name + with open(os.path.join(proj_dir, 'export_configs.json'), 'w') as configfile: + configfile.write(json.dumps(geoserver_configs)) + except Exception as e: + print(e) + return JsonResponse({'status': 'failed'}) + + return JsonResponse({'status': 'success'}) + + +@login_required() +def export_zipfile(request): + project = request.GET.get('project', False) + if not project: + return JsonResponse({'error': 'unable to find the project'}) + proj_dir = get_project_directory(project) + zip_path = os.path.join(proj_dir, 'hydroviewer_shapefiles.zip') + + # if there is already a zip file, serve it for download + if not os.path.exists(zip_path): + try: + zip_project_shapefiles(project) + except Exception as e: + raise e + zip_file = open(zip_path, 'rb') + response = HttpResponse(zip_file, content_type='application/zip') + response['Content-Disposition'] = 'attachment; filename="hydroviewer_shapefiles.zip"' + return response + + +@login_required() +def export_hydroshare(request): + project = request.POST.get('project', False) + if project is False: + messages.error(request, 'Project not found. Please pick a valid project.') + return redirect(reverse('geoglows_hydroviewer:geoglows_hydroviewer_creator')) + proj_dir = get_project_directory(project) + zip_path = os.path.join(proj_dir, 'hydroviewer_shapefiles.zip') + + # make the zip file of shapefiles if it doesn't already exist + if not os.path.exists(zip_path): + try: + zip_project_shapefiles(project) + except Exception as e: + raise e + + # hs = hs_restclient.get_oauth_hs(request) + auth = hs_restclient.HydroShareAuthBasic(username=request.POST.get('username'), + password=request.POST.get('password')) + hs = hs_restclient.HydroShare(auth=auth) + + try: + resource_id = hs.createResource('GenericResource', + request.POST.get('title'), + resource_file=zip_path, + keywords=request.POST.get('keywords').split(', '), + abstract=request.POST.get('abstract'), ) + hs.resource(resource_id).functions.unzip( + payload={'zip_with_rel_path': 'hydroviewer_shapefiles.zip', 'remove_original_zip': True}) + + hs.setAccessRules(resource_id, public=True) + messages.success(request, f'Successfully Exported To New Hydroshare Resource (ID: {resource_id})') + + # add keys to the export_configs.json + with open(os.path.join(proj_dir, 'export_configs.json'), 'w') as configfile: + geoserver_configs = json.loads(configfile.read()) + geoserver_configs['url'] = 'https://geoserver.hydroshare.org/geoserver/wms' + geoserver_configs['workspace'] = f'HS-{resource_id}' + geoserver_configs['dl'] = 'selected_drainageline drainageline_select' + geoserver_configs['ctch'] = 'selected_catchment catchment_select' + with open(os.path.join(proj_dir, 'export_configs.json'), 'w') as configfile: + configfile.write(json.dumps(geoserver_configs)) + return redirect(reverse('geoglows_hydroviewer:project_overview') + + f'?{urllib.parse.urlencode(dict(project=project))}') + except hs_restclient.HydroShareArgumentException as e: + print('invalid parameter') + print(e) + raise e + except hs_restclient.HydroShareNotAuthorized as e: + print('hydroshare not authorized') + print(e) + raise e + except hs_restclient.HydroShareHTTPException as e: + print('unanticipated HTTP error') + print(e) + raise e + + +@login_required() +def export_html(request): + template_path = os.path.join(App.get_app_workspace().path, 'hydroviewer_interactive_template.html') + + title = request.GET.get('title') + html_path = os.path.join(App.get_app_workspace().path, f'{title}.html') + + with open(template_path) as template: + with open(html_path, 'w') as hydrohtml: + hydrohtml.write( + jinja2.Template(template.read()).render( + title=title, + api_endpoint=geoglows.streamflow.ENDPOINT, + geoserver_wms_url=request.GET.get('url'), + workspace=request.GET.get('workspace'), + catchment_layer=request.GET.get('ctch'), + drainage_layer=request.GET.get('dl'), + boundaries_json=request.GET.get('bounds', ''), + ) + ) + + with open(html_path, 'r') as htmlfile: + response = HttpResponse(htmlfile, content_type='text/html') + response['Content-Disposition'] = f'attachment; filename="{title}_hydroviewer.html"' + + os.remove(html_path) + return response diff --git a/tethysapp/geoglows_hydroviewer/hydroviewer_creator_tools.py b/tethysapp/geoglows_hydroviewer/hydroviewer_creator_tools.py index 8cda582..07ba006 100644 --- a/tethysapp/geoglows_hydroviewer/hydroviewer_creator_tools.py +++ b/tethysapp/geoglows_hydroviewer/hydroviewer_creator_tools.py @@ -1,4 +1,7 @@ +import glob import os +import shutil +from zipfile import ZipFile from .app import GeoglowsHydroviewer as App @@ -12,7 +15,29 @@ def get_project_directory(project): def shapefiles_downloaded(): - shape_dir_contents = [i for i in os.listdir(SHAPE_DIR) if os.path.isdir(i)] - if len(shape_dir_contents) == 13: + shape_dir_contents = glob.glob(os.path.join(SHAPE_DIR, '*.zip')) + if len(shape_dir_contents) == 39: return True return False + + +def zip_project_shapefiles(project): + proj_dir = get_project_directory(project) + zip_path = os.path.join(proj_dir, 'hydroviewer_shapefiles.zip') + catchment_shapefile = os.path.join(proj_dir, 'selected_catchment', 'catchment_select.shp') + drainageline_shapefile = os.path.join(proj_dir, 'selected_drainageline', 'drainageline_select.shp') + if not os.path.exists(catchment_shapefile): + raise FileNotFoundError('selected catchment shapefile does not exist') + if not os.path.exists(drainageline_shapefile): + raise FileNotFoundError('selected drainageline shapefile does not exist') + try: + with ZipFile(zip_path, 'w') as zipfile: + catchment_components = glob.glob(os.path.join(proj_dir, 'selected_catchment', 'catchment_select.*')) + for component in catchment_components: + zipfile.write(component, arcname=os.path.join('selected_catchment', os.path.basename(component))) + dl_components = glob.glob(os.path.join(proj_dir, 'selected_drainageline', 'drainageline_select.*')) + for component in dl_components: + zipfile.write(component, arcname=os.path.join('selected_drainageline', os.path.basename(component))) + except Exception as e: + shutil.rmtree(zip_path) + return diff --git a/tethysapp/geoglows_hydroviewer/public/js/geoglows_hydroviewer.js b/tethysapp/geoglows_hydroviewer/public/js/geoglows_hydroviewer.js index dd0fb16..f488988 100644 --- a/tethysapp/geoglows_hydroviewer/public/js/geoglows_hydroviewer.js +++ b/tethysapp/geoglows_hydroviewer/public/js/geoglows_hydroviewer.js @@ -81,4 +81,5 @@ const globalLayer = L.esri.dynamicMapLayer({ from: startDateTime, to: endDateTime, }).addTo(mapObj); -L.control.layers(basemapsJson, {'Stream Network': globalLayer, 'Gauge Network': gaugeNetwork, 'VIIRS Imagery': VIIRSlayer}, {'collapsed': false}).addTo(mapObj); \ No newline at end of file +L.control.layers(basemapsJson, {'Stream Network': globalLayer, 'Gauge Network': gaugeNetwork, 'VIIRS Imagery': VIIRSlayer}, {'collapsed': false}).addTo(mapObj); + diff --git a/tethysapp/geoglows_hydroviewer/public/js/geoprocessShapefiles.js b/tethysapp/geoglows_hydroviewer/public/js/geoprocessShapefiles.js index 88e42ec..e3e2441 100644 --- a/tethysapp/geoglows_hydroviewer/public/js/geoprocessShapefiles.js +++ b/tethysapp/geoglows_hydroviewer/public/js/geoprocessShapefiles.js @@ -1,11 +1,7 @@ -if (shapefiles) { - $("#process-callback-list").html('
  • Shapefiles already created
  • ') -} function processShapefiles() { let load_bar = $("#loading-bar-div"); let progress_list = $("#process-callback-list"); if (shapefiles) { - progress_list.html('
  • Shapefiles already created
  • ') if (!confirm('Shapefiles have already been created for this project, would you like to delete them then, ' + 'recreate them for the current project boundaries?')) { return diff --git a/tethysapp/geoglows_hydroviewer/public/js/projectOverview.js b/tethysapp/geoglows_hydroviewer/public/js/projectOverview.js index 01e0bb8..de39919 100644 --- a/tethysapp/geoglows_hydroviewer/public/js/projectOverview.js +++ b/tethysapp/geoglows_hydroviewer/public/js/projectOverview.js @@ -31,7 +31,7 @@ if (boundaries) { let drainagelines; let catchments; -if (geoserver) { +if (exported) { catchments = L.tileLayer.wms(geoserver_wms, {"format": "image/png", "transparent": true, "layers": workspace + ":" + catchmentLayer}); drainagelines = L.tileLayer.wms(geoserver_wms, diff --git a/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/base.html b/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/base.html index b32bcad..681576a 100644 --- a/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/base.html +++ b/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/base.html @@ -16,6 +16,7 @@ {% url 'geoglows_hydroviewer:home' as hydroviewer %} {% url 'geoglows_hydroviewer:geoglows_hydroviewer_creator' as creator %} {% url 'geoglows_hydroviewer:project_overview' as overview %} + {% url 'geoglows_hydroviewer:render_hydroviewer' as render %} {% url 'geoglows_hydroviewer:hydroshare_view' as hydroshare %} {% if request.path == hydroviewer %} @@ -87,22 +88,14 @@ Hydroviewer Creator {% endif %} {% else %} -
  • Return to Hydroviewer Main Page
  • -
  • Select A Project
  • - {% if request.path == overview %} -
  • Hydroviewer Project Overview
  • -
  • -
  • Steps to create a hydroviewer
  • -
  • 1. Define Project Boundaries
  • -
  • 2. Create and Export Shapefiles
  • -
  • 3. Export Hydroviewer
  • - {% else %} -
  • Edit Hydroviewer
  • - {% endif %} +
  • Hydroviewer Creation Tools
  • +
  • Project Selection
  • +
  • Project Overview
  • +
  • Render Hydroviewer
  • {% endif %} diff --git a/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_choose_hydroviewer_boundaries.html b/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_boundaries_choose_predefined.html similarity index 100% rename from tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_choose_hydroviewer_boundaries.html rename to tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_boundaries_choose_predefined.html diff --git a/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_draw_hydroviewer_boundaries.html b/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_boundaries_draw.html similarity index 100% rename from tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_draw_hydroviewer_boundaries.html rename to tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_boundaries_draw.html diff --git a/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_project_overview.html b/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_project_overview.html index 5bb8b18..cbfe43e 100644 --- a/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_project_overview.html +++ b/tethysapp/geoglows_hydroviewer/templates/geoglows_hydroviewer/creator_project_overview.html @@ -3,69 +3,86 @@ {% load static %} {% block app_content %} -

    Project: {{ project_title }}

    -
    -
    +
    +

    Project: {{ project_title }}

    +
      -

    1. Define Hydroviewer Boundaries
    2. +

      +
    3. Define Boundaries {% if boundaries %} + {% endif %}
    4. +

      + Draw Project Boundaries on a Map +
      + Choose Country or Region Boundaries +
      - {% if boundaries %} -

      Project Boundaries Already Defined

      - {% endif %} + Upload a Shapefile (beta) +
      {% if boundaries %} -

    5. Create and Export Shapefiles
    6. +

      +
    7. Create Shapefiles {% if shapefiles %} + {% endif %}
    8. +

      - -

        +

        +

          {% endif %} {% if shapefiles %} - +
        • Export Shapefiles {% if exported %} + {% endif %}
        • + +
          Download Zipfiles
          - {% if geoserver %} -

          Data already successfully uploaded to a geoserver - {% endif %} +
          + {% endif %} - {% if geoserver %} + {% if exported %}

        • Download Hydroviewer
        • -
          + + {% csrf_token %}
          -
          {% endif %} + + +
        @@ -84,69 +101,83 @@