From 210619dce472a9ae5480f71c0e2fd3238d208f41 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 25 Aug 2026 14:26:46 -0700 Subject: [PATCH 1/9] use QGIS server urls for report images --- landmapper/app/map_layers/views.py | 129 +++++++++++++++++++---------- landmapper/landmapper/settings.py | 128 +++++++++++++++++++++++++--- 2 files changed, 203 insertions(+), 54 deletions(-) diff --git a/landmapper/app/map_layers/views.py b/landmapper/app/map_layers/views.py index d37247b..d0b9457 100644 --- a/landmapper/app/map_layers/views.py +++ b/landmapper/app/map_layers/views.py @@ -11,23 +11,46 @@ import io, pyproj, shapely, json from imageio import imread import numpy as np -from PIL import Image, ImageDraw, ImageFont +from PIL import Image from math import pi, log, tan, exp, atan, log2, log10, floor -from matplotlib import patches, ticker +from matplotlib import ticker from matplotlib import pyplot as plt from matplotlib import patheffects as pe -from matplotlib.collections import PatchCollection from rasterio import transform from rasterio.plot import show, reshape_as_raster import requests from shapely.geometry import Point as shp_Point from shapely.ops import transform as shp_transform -import urllib.request ################################ # Map Layer Getter Functions ### ################################ +def get_wms_image_layer(layer_dict, property_specs, bbox=False): + wms_params = dict( + REQUEST='GetMap', + SERVICE='WMS', + version=layer_dict['WMS_VERSION'], + format='image/png', + STYLES='', + TRANSPARENT=True, + LAYERS=layer_dict['TILE_LAYER'], + CRS='EPSG:3857', + WIDTH=property_specs['width'], + HEIGHT=property_specs['height'], + BBOX=bbox + ) + image_data = lm_views.unstable_request_wrapper(layer_dict['URL'], params=wms_params) + base_image = image_result_to_PIL(image_data) + + attribution = layer_dict['ATTRIBUTION'] + + return { + 'type': 'image', + 'data': base_image, + 'attribution': attribution + } + def get_property_image_layer(property, property_specs, bbox=False): """ Produce an image of the taxlots belonging to a property. @@ -119,6 +142,9 @@ def get_taxlot_image_layer(property_specs, bbox=False): 'data': base_image, 'attribution': attribution } + elif 'TECHNOLOGY' in taxlot_dict and taxlot_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(taxlot_dict, property_specs, bbox=bbox) + return wms_image else: taxlots = Taxlot.objects.filter(geometry__intersects=bbox_poly) taxlot_collection = get_collection_from_objects(taxlots, 'geometry', bbox) @@ -427,7 +453,9 @@ def get_soil_image_layer(property_specs, bbox=False, zoom=True ): 'data': base_image, 'attribution': attribution } - + elif 'TECHNOLOGY' in soil_dict and soil_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(soil_dict, property_specs, bbox=bbox) + return wms_image else: bbox_poly = get_bbox_as_polygon(bbox) @@ -463,7 +491,7 @@ def get_forest_types_image_layer(property_specs, bbox=False): bbox_poly = get_bbox_as_polygon(bbox) forest_types_dict = settings.FOREST_TYPES_URLS[settings.FOREST_TYPES_SOURCE] - if forest_types_dict['TECHNOLOGY'] == 'arcgis_mapserver': + if 'TECHNOLOGY' in forest_types_dict and forest_types_dict['TECHNOLOGY'] == 'arcgis_mapserver': bboxSR = 3857 width = property_specs['width'] height = property_specs['height'] @@ -507,10 +535,10 @@ def get_forest_types_image_layer(property_specs, bbox=False): 'attribution': attribution } - + elif 'TECHNOLOGY' in forest_types_dict and forest_types_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(forest_types_dict, property_specs, bbox=bbox) + return wms_image else: - - forest_types = ForestType.objects.filter(geometry__intersects=bbox_poly) forest_types_collection = get_collection_from_objects(forest_types, 'geometry', bbox, attrs=['symbol']) forest_types_gdf = get_gdf_from_features(forest_types_collection) @@ -587,6 +615,10 @@ def get_forest_size_image_layer(property_specs, bbox=False): 'attribution': attribution } + elif 'TECHNOLOGY' in forest_size_dict and forest_size_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(forest_size_dict, property_specs, bbox=bbox) + return wms_image + # TODO: Add LOCAL option in settings and finish this else statement # # else: @@ -667,6 +699,9 @@ def get_forest_density_image_layer(property_specs, bbox=False): 'data': base_image, 'attribution': attribution } + elif 'TECHNOLOGY' in forest_density_dict and forest_density_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(forest_density_dict, property_specs, bbox=bbox) + return wms_image # TODO: Add LOCAL option in settings and finish this else statement # @@ -748,6 +783,9 @@ def get_forest_canopy_image_layer(property_specs, bbox=False): 'data': base_image, 'attribution': attribution } + elif 'TECHNOLOGY' in forest_canopy_dict and forest_canopy_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(forest_canopy_dict, property_specs, bbox=bbox) + return wms_image # TODO: Add LOCAL option in settings and finish this else statement # @@ -978,48 +1016,51 @@ def get_stream_image_layer(property_specs, bbox=False): image = get_mapbox_image_data(request_dict, property_specs, bbox) elif request_dict['TECHNOLOGY'] == 'arcgis_mapserver': - bboxSR = 3857 - width = property_specs['width'] - height = property_specs['height'] + bboxSR = 3857 + width = property_specs['width'] + height = property_specs['height'] - if 'ZOOM' in request_dict.keys(): - zoom = request_dict['ZOOM'] + if 'ZOOM' in request_dict.keys(): + zoom = request_dict['ZOOM'] - if 'DPI' in request_dict.keys(): - dpi = request_dict['DPI'] - else: - dpi = None + if 'DPI' in request_dict.keys(): + dpi = request_dict['DPI'] + else: + dpi = None - if zoom: - width = 2*property_specs['width'] - height = 2*property_specs['height'] + if zoom: + width = 2*property_specs['width'] + height = 2*property_specs['height'] - params =dict( - bbox=bbox, - bboxSR=str(bboxSR), - layers='show:{}'.format(request_dict['LAYERS']), - layerDefs=None, - size=",".join([str(width), str(height)]), - imageSR=request_dict['SPATIAL_REFERENCE'], - format='png', - f='image', - dpi=dpi, - transparent=True, - ) + params =dict( + bbox=bbox, + bboxSR=str(bboxSR), + layers='show:{}'.format(request_dict['LAYERS']), + layerDefs=None, + size=",".join([str(width), str(height)]), + imageSR=request_dict['SPATIAL_REFERENCE'], + format='png', + f='image', + dpi=dpi, + transparent=True, + ) - image_data = lm_views.unstable_request_wrapper(request_dict['URL'], params=params) - base_image = image_result_to_PIL(image_data) + image_data = lm_views.unstable_request_wrapper(request_dict['URL'], params=params) + base_image = image_result_to_PIL(image_data) - if zoom: - base_image = base_image.resize((property_specs['width'], property_specs['height']), Image.LANCZOS) - - attribution = request_dict['ATTRIBUTION'] + if zoom: + base_image = base_image.resize((property_specs['width'], property_specs['height']), Image.LANCZOS) + + attribution = request_dict['ATTRIBUTION'] - return { - 'type': 'image', - 'data': base_image, - 'attribution': attribution - } + return { + 'type': 'image', + 'data': base_image, + 'attribution': attribution + } + elif 'TECHNOLOGY' in request_dict and request_dict['TECHNOLOGY'] == 'wms': + wms_image = get_wms_image_layer(request_dict, property_specs, bbox=bbox) + return wms_image else: print('settings.STREAMS_SOURCE value "%s" is not currently supported.' % settings.STREAMS_SOURCE) image = None diff --git a/landmapper/landmapper/settings.py b/landmapper/landmapper/settings.py index 24ef8e3..6c95404 100644 --- a/landmapper/landmapper/settings.py +++ b/landmapper/landmapper/settings.py @@ -707,6 +707,22 @@ 'online at http://datagateway.nrcs.usda.gov/. 20221110 (202301 official release).' } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_soils', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_soils_2025', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/wa_soils', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_soils_2025', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Soils_WA/MapServer/export', 'LAYERS': '0', @@ -735,11 +751,7 @@ # SOIL_DATA_LAYER = 'mapunitpolyextended' # SOIL_ID_FIELD = 'musym' - - - - -SOIL_SOURCE = 'ECOTRUST_OR' +SOIL_SOURCE = 'ECOTRUST_OR_QGIS' # https://sdmdataaccess.sc.egov.usda.gov/Citation.htm SOIL_SSURGO_ATTRIBUTION = SOILS_URLS['USDA_WMS']['ATTRIBUTION'] @@ -1085,6 +1097,14 @@ 'attribution':'' } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_streams', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_streams', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Streams_WA/MapServer/export', 'LAYERS': '0', @@ -1098,9 +1118,17 @@ 'attribution':'Washington State Department of Natural Resources, Forest Practices Division' } }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_streams', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_streams_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, } -STREAMS_SOURCE = 'MAPBOX_TILE' +STREAMS_SOURCE = 'ECOTRUST_OR_QGIS' STREAM_ZOOM_OVERLAY_2X = False ########################################### @@ -1150,6 +1178,14 @@ 'attribution': '', } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_taxlots', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_taxlots_2026', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Taxlot_WA/MapServer/export', 'LAYERS': '0', @@ -1163,6 +1199,14 @@ 'attribution': 'Washington State Department of Natural Resources', } }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/wa_taxlots', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_taxlots_2026', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, } TAXLOTS_SOURCE = 'DATABASE' TAXLOTS_TILES_SOURCE_FOR_DATABASE = 'MAPBOX_TILE' @@ -1298,6 +1342,14 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_forest_type', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_foresttype_2026', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/ForestClass_WA/MapServer/export', 'LAYERS': '0,1', @@ -1310,9 +1362,17 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/wa_forest_type', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_foresttype_2025', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, } -FOREST_TYPES_SOURCE = 'ECOTRUST_OR' +FOREST_TYPES_SOURCE = 'ECOTRUST_OR_QGIS' ########################################### ## Forest Size ### @@ -1343,6 +1403,14 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_forest_size', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_forest_size_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/QMD_WA/MapServer/export', 'LAYERS': '0', @@ -1355,9 +1423,17 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/wa_forest_size', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_forestsize_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, } -FOREST_SIZE_SOURCE = 'ECOTRUST_OR' +FOREST_SIZE_SOURCE = 'ECOTRUST_OR_QGIS' ########################################### ## Forest Density ### @@ -1388,6 +1464,14 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_forest_density', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_forest_density_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Basal_Area_WA/MapServer/export', 'LAYERS': '0', @@ -1400,9 +1484,17 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/wa_forest_density', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_forest_density_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, } -FOREST_DENSITY_SOURCE = 'ECOTRUST_OR' +FOREST_DENSITY_SOURCE = 'ECOTRUST_OR_QGIS' ########################################### ## Forest Canopy Cover ### @@ -1433,6 +1525,14 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_OR_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/or_canopy_cover', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'or_canopy_cover_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/CanopyCover_WA/MapServer/export', 'LAYERS': '0', @@ -1445,9 +1545,17 @@ 'attribution':'Ecotrust 2023' } }, + 'ECOTRUST_WA_QGIS': { + 'URL': 'http://44.238.61.80:8080/ogc/wa_canopy_cover', + 'TECHNOLOGY': 'wms', + 'WMS_VERSION': '1.3.0', + 'TILE_LAYER': 'wa_canopy_cover_2023', + 'ZOOM_OVERLAY_2X': False, + 'ATTRIBUTION': '' + }, } -FOREST_CANOPY_SOURCE = 'ECOTRUST_OR' +FOREST_CANOPY_SOURCE = 'ECOTRUST_OR_QGIS' ########################################### ## Map Info ### From 23fb4baed5a00d499292b6b7557c1c97f2d4c20d Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 25 Aug 2026 16:22:17 -0700 Subject: [PATCH 2/9] add attribution for QGIS layers --- landmapper/landmapper/settings.py | 74 ++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/landmapper/landmapper/settings.py b/landmapper/landmapper/settings.py index 6c95404..2f1e020 100644 --- a/landmapper/landmapper/settings.py +++ b/landmapper/landmapper/settings.py @@ -713,7 +713,12 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_soils_2025', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'NRCS', + 'attribution':'Soil Survey Staff. Gridded Soil Survey Geographic (gSSURGO) Database for Oregon. ' + + 'United States Department of Agriculture, Natural Resources Conservation Service. Available ' + + 'online at http://datagateway.nrcs.usda.gov/. 20221110 (202301 official release).' + } }, 'ECOTRUST_WA_QGIS': { 'URL': 'http://44.238.61.80:8080/ogc/wa_soils', @@ -721,7 +726,13 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_soils_2025', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'NRCS', + 'attribution':'Soil Survey Staff. Gridded Soil Survey Geographic (gSSURGO) Database for ' + + 'Washington. United States Department of Agriculture, Natural Resources Conservation ' + + 'Service. Available online at http://datagateway.nrcs.usda.gov/. 20220912 (202301 ' + + 'official release).' + } }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Soils_WA/MapServer/export', @@ -1103,7 +1114,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_streams', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'ODF', + 'attribution':'' + } }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Streams_WA/MapServer/export', @@ -1119,12 +1133,15 @@ } }, 'ECOTRUST_WA_QGIS': { - 'URL': 'http://44.238.61.80:8080/ogc/or_streams', + 'URL': 'http://44.238.61.80:8080/ogc/wa_streams', 'TECHNOLOGY': 'wms', 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_streams_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'WA DNR', + 'attribution':'Washington State Department of Natural Resources, Forest Practices Division' + } }, } @@ -1184,7 +1201,7 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_taxlots_2026', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': {'source': 'ORMAP', 'attribution': None} }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Taxlot_WA/MapServer/export', @@ -1205,7 +1222,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_taxlots_2026', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'WaTech GIS', + 'attribution': 'Washington State Geospatial Portal' + } }, } TAXLOTS_SOURCE = 'DATABASE' @@ -1348,7 +1368,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_foresttype_2026', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2026' + } }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/ForestClass_WA/MapServer/export', @@ -1368,7 +1391,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_foresttype_2025', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2026' + } }, } @@ -1409,7 +1435,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_forest_size_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2023' + } }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/QMD_WA/MapServer/export', @@ -1429,7 +1458,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_forestsize_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2023' + } }, } @@ -1470,7 +1502,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_forest_density_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2023' + } }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/Basal_Area_WA/MapServer/export', @@ -1490,7 +1525,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_forest_density_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2023' + } }, } @@ -1531,7 +1569,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_canopy_cover_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2023' + } }, 'ECOTRUST_WA': { 'URL': 'https://arcgis.ecotrust.org/server/rest/services/Landmapper/CanopyCover_WA/MapServer/export', @@ -1551,7 +1592,10 @@ 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_canopy_cover_2023', 'ZOOM_OVERLAY_2X': False, - 'ATTRIBUTION': '' + 'ATTRIBUTION': { + 'source': 'Ecotrust', + 'attribution':'Ecotrust 2023' + } }, } From 1b9759e8f139d7da8159f4e153626ae723d4f254 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 25 Aug 2026 16:52:23 -0700 Subject: [PATCH 3/9] update forest type legend --- .../img/legend_images/or_fortypba.png | Bin 0 -> 62489 bytes landmapper/landmapper/settings.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 landmapper/app/static/landmapper/img/legend_images/or_fortypba.png diff --git a/landmapper/app/static/landmapper/img/legend_images/or_fortypba.png b/landmapper/app/static/landmapper/img/legend_images/or_fortypba.png new file mode 100644 index 0000000000000000000000000000000000000000..b15ef6f3abaa26ceeea7ac24b51b8a5034e590f4 GIT binary patch literal 62489 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 c|EaPi Date: Wed, 26 Aug 2026 11:51:19 -0700 Subject: [PATCH 4/9] use qgis server layer for taxlots --- landmapper/landmapper/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/landmapper/landmapper/settings.py b/landmapper/landmapper/settings.py index af59956..f4d287e 100644 --- a/landmapper/landmapper/settings.py +++ b/landmapper/landmapper/settings.py @@ -1228,7 +1228,7 @@ } }, } -TAXLOTS_SOURCE = 'DATABASE' +TAXLOTS_SOURCE = 'ECOTRUST_OR_QGIS' TAXLOTS_TILES_SOURCE_FOR_DATABASE = 'MAPBOX_TILE' TAXLOT_ZOOM_OVERLAY_2X = False @@ -1715,7 +1715,7 @@ # STUDY_REGIONS[STUDY_REGION_ID]['pdf_template'] = APP_DIR + '/pdf_templates/Test_LM_Form.pdf' if not TAXLOTS_SOURCE == 'DATABASE': - TAXLOTS_TILES_SOURCE_FOR_DATABASE = TAXLOTS_SOURCE + TAXLOTS_TILES_SOURCE_FOR_DATABASE = 'MAPBOX_TILE' LIVE_TAXLOT_LAYER = TAXLOTS_URLS[TAXLOTS_TILES_SOURCE_FOR_DATABASE] if TAXLOTS_TILES_SOURCE_FOR_DATABASE == 'MAPBOX_TILE': STUDY_REGION['taxlot_url'] = LIVE_TAXLOT_LAYER['URL'].format( From b91df085b45fb5dda08e5fce1851b81bfbdf819d Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 27 Aug 2026 14:11:04 -0700 Subject: [PATCH 5/9] clean up logs --- landmapper/app/static/landmapper/js/map.js | 20 ++++++++++++++++++++ landmapper/landmapper/settings.py | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/landmapper/app/static/landmapper/js/map.js b/landmapper/app/static/landmapper/js/map.js index dffe136..57bfee2 100644 --- a/landmapper/app/static/landmapper/js/map.js +++ b/landmapper/app/static/landmapper/js/map.js @@ -8,6 +8,26 @@ var mapView = new ol.View({ rotation: landmapper.rotation }); +var taxlotSource; +if (landmapper.taxlot_layer['technology'] === 'TileWMS') { + taxlotSource = new ol.source.TileWMS({ + url: landmapper.taxlot_layer['url'], + params: landmapper.taxlot_layer['params'], + serverType: landmapper.taxlot_layer['server_type'], + attributions: landmapper.taxlot_layer['attribution'], + projection: 'EPSG:3857', + }); + +} else { + taxlotSource = new ol.source[landmapper.taxlot_layer['technology']]({ + url: landmapper.taxlot_layer['url'], + params: landmapper.taxlot_layer['params'], + serverType: landmapper.taxlot_layer['server_type'], + attributions: landmapper.taxlot_layer['attribution'], + projection: 'EPSG:3857', + }); +} + landmapper.taxlotLayer = new ol.layer.Tile({ visible: true, title: 'Taxlots', diff --git a/landmapper/landmapper/settings.py b/landmapper/landmapper/settings.py index f4d287e..6ec537d 100644 --- a/landmapper/landmapper/settings.py +++ b/landmapper/landmapper/settings.py @@ -1200,6 +1200,8 @@ 'TECHNOLOGY': 'wms', 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'or_taxlots_2026', + 'OL_TECHNOLOGY': 'TileWMS', + 'SERVER_TYPE': 'qgis', 'ZOOM_OVERLAY_2X': False, 'ATTRIBUTION': {'source': 'ORMAP', 'attribution': None} }, @@ -1221,6 +1223,8 @@ 'TECHNOLOGY': 'wms', 'WMS_VERSION': '1.3.0', 'TILE_LAYER': 'wa_taxlots_2026', + 'OL_TECHNOLOGY': 'TileWMS', + 'SERVER_TYPE': 'qgis', 'ZOOM_OVERLAY_2X': False, 'ATTRIBUTION': { 'source': 'WaTech GIS', @@ -1730,6 +1734,10 @@ STUDY_REGION['taxlot_url'] = LIVE_TAXLOT_LAYER['URL'] if LIVE_TAXLOT_LAYER['TECHNOLOGY'] == 'arcgis_mapserver': STUDY_REGION['taxlot_technology'] = 'TileArcGISRest' +elif LIVE_TAXLOT_LAYER['TECHNOLOGY'] == 'wms': + STUDY_REGION['taxlot_technology'] = LIVE_TAXLOT_LAYER['OL_TECHNOLOGY'] + STUDY_REGION['params'] = {'LAYERS': LIVE_TAXLOT_LAYER['TILE_LAYER']} + STUDY_REGION['server_type'] = LIVE_TAXLOT_LAYER['SERVER_TYPE'] else: STUDY_REGION['taxlot_technology'] = 'XYZ' STUDY_REGION['taxlot_attribution'] = LIVE_TAXLOT_LAYER['ATTRIBUTION']['attribution'] From 6e0f55f8bbd9b5492ddf881c4be96b2e4a23d771 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 27 Aug 2026 14:22:44 -0700 Subject: [PATCH 6/9] use taxlotSource in map.js --- landmapper/app/static/landmapper/js/map.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/landmapper/app/static/landmapper/js/map.js b/landmapper/app/static/landmapper/js/map.js index 57bfee2..e655165 100644 --- a/landmapper/app/static/landmapper/js/map.js +++ b/landmapper/app/static/landmapper/js/map.js @@ -32,11 +32,7 @@ landmapper.taxlotLayer = new ol.layer.Tile({ visible: true, title: 'Taxlots', minZoom: 10, - source: new ol.source[landmapper.taxlot_layer['technology']]({ - url: landmapper.taxlot_layer['url'], - attributions: landmapper.taxlot_layer['attribution'], - projection: 'EPSG:3857', - }) + source: taxlotSource, }); /** From 09baeacbe1f950565b49c1e18d100d16a5c5100d Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 27 Aug 2026 14:26:10 -0700 Subject: [PATCH 7/9] use TAXLOT_SOURCE for TAXLOTS_TILES_SOURCE_FOR_DATABASE --- landmapper/landmapper/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/landmapper/landmapper/settings.py b/landmapper/landmapper/settings.py index 6ec537d..fb04193 100644 --- a/landmapper/landmapper/settings.py +++ b/landmapper/landmapper/settings.py @@ -1719,7 +1719,7 @@ # STUDY_REGIONS[STUDY_REGION_ID]['pdf_template'] = APP_DIR + '/pdf_templates/Test_LM_Form.pdf' if not TAXLOTS_SOURCE == 'DATABASE': - TAXLOTS_TILES_SOURCE_FOR_DATABASE = 'MAPBOX_TILE' + TAXLOTS_TILES_SOURCE_FOR_DATABASE = TAXLOTS_SOURCE LIVE_TAXLOT_LAYER = TAXLOTS_URLS[TAXLOTS_TILES_SOURCE_FOR_DATABASE] if TAXLOTS_TILES_SOURCE_FOR_DATABASE == 'MAPBOX_TILE': STUDY_REGION['taxlot_url'] = LIVE_TAXLOT_LAYER['URL'].format( From 200dd1c1f5fd7d3661d8dee6d0f9c325dd98b5f2 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 27 Aug 2026 15:27:34 -0700 Subject: [PATCH 8/9] pass params in two-pane.html --- landmapper/app/templates/landmapper/two-pane.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/landmapper/app/templates/landmapper/two-pane.html b/landmapper/app/templates/landmapper/two-pane.html index 47691ca..9eecf03 100644 --- a/landmapper/app/templates/landmapper/two-pane.html +++ b/landmapper/app/templates/landmapper/two-pane.html @@ -48,6 +48,8 @@ url: '{{ STUDY_REGION.taxlot_url }}', technology: '{{ STUDY_REGION.taxlot_technology }}', attribution: '{{ STUDY_REGION.taxlot_attribution }}', + params: {{ STUDY_REGION.params_json|default:'{}'|safe }}, + server_type: '{{ STUDY_REGION.server_type|default:"" }}' }, taxlot_ids: '', getLocationHashParts: function() { From 89485400c696cd4e5cd222a676739c2e5a9decdd Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 27 Aug 2026 15:34:29 -0700 Subject: [PATCH 9/9] process dicts to json for study_region --- landmapper/app/processor.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/landmapper/app/processor.py b/landmapper/app/processor.py index 8b2f537..e890b94 100644 --- a/landmapper/app/processor.py +++ b/landmapper/app/processor.py @@ -1,12 +1,17 @@ from django.conf import settings from app.models import MenuPage +import json def menus(request): return {'menu_items': MenuPage.objects.all().order_by('order')} def study_region(request): + study_region_data = settings.STUDY_REGION.copy() + # Convert params dict to JSON string for JavaScript consumption + if 'params' in study_region_data: + study_region_data['params_json'] = json.dumps(study_region_data['params']) return { - 'STUDY_REGION': settings.STUDY_REGION + 'STUDY_REGION': study_region_data } def google_analytics(request):