From 4b1a798dbcd158ba9b8cde4bdb900092f4fd4f54 Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sat, 20 Jan 2024 19:11:08 -0800 Subject: [PATCH 01/11] Collapse the LayerControl for a better mobile experience --- pages/components.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/components.py b/pages/components.py index c3a88486..20d94a6a 100644 --- a/pages/components.py +++ b/pages/components.py @@ -935,7 +935,7 @@ def create_map(self): [ dl.Overlay(oil_well_layer, name="Oil Wells", checked=False) ], - collapsed=False, + collapsed=True, position='topleft' ) map.children.append(layers_control) @@ -1675,7 +1675,7 @@ def create_map(self): [ dl.Overlay(oil_well_layer, name="Oil Wells", checked=False) ], - collapsed=False, + collapsed=True, position='topleft' ) map.children.append(layers_control) From 953613796dc3f59cb4f2de232dae2a4d393c0791 Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sat, 20 Jan 2024 21:19:49 -0800 Subject: [PATCH 02/11] Remove more_info.css and more_info.js files --- assets/more_info.css | 3 --- assets/more_info.js | 13 ------------- 2 files changed, 16 deletions(-) delete mode 100644 assets/more_info.css delete mode 100644 assets/more_info.js diff --git a/assets/more_info.css b/assets/more_info.css deleted file mode 100644 index e6ec945a..00000000 --- a/assets/more_info.css +++ /dev/null @@ -1,3 +0,0 @@ -#more_info_trigger { - cursor: pointer; -} \ No newline at end of file diff --git a/assets/more_info.js b/assets/more_info.js deleted file mode 100644 index c0d68c70..00000000 --- a/assets/more_info.js +++ /dev/null @@ -1,13 +0,0 @@ -document.addEventListener('DOMContentLoaded', function() { - var trigger = document.getElementById('more_info_trigger'); - if (trigger) { - trigger.addEventListener('click', function() { - var extraInfo = document.getElementById('extra_info'); - if (extraInfo.style.display === 'none') { - extraInfo.style.display = ''; - } else { - extraInfo.style.display = 'none'; - } - }); - } -}); \ No newline at end of file From b8f92c8dde208e13a7db4539dfa57957dcc67def Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sat, 20 Jan 2024 21:21:05 -0800 Subject: [PATCH 03/11] Update .dockerignore file to include oil_well.geojson --- .dockerignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index cbfe5a78..627b3386 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,4 +4,5 @@ .github/ *.csv *.pyc -*.xlsx \ No newline at end of file +*.xlsx +assets/datasets/oil_well.geojson \ No newline at end of file From 41f0f7da7070cc76719ebab3e9942f1ecfe5931f Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:01:12 -0800 Subject: [PATCH 04/11] Add fetch_geojson_data function and create_new_geojson_layer function --- functions/geojson_processing_utils.py | 19 ++++++++++++++-- pages/components.py | 32 ++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/functions/geojson_processing_utils.py b/functions/geojson_processing_utils.py index 068bbf2f..740ffe4a 100644 --- a/functions/geojson_processing_utils.py +++ b/functions/geojson_processing_utils.py @@ -1,5 +1,6 @@ -from typing import Dict, List +from typing import Dict, List, Any import json +import requests def optimize_geojson(input_filepath: str, output_filepath: str, fields_to_keep: List[str]) -> None: """ @@ -26,4 +27,18 @@ def optimize_geojson(input_filepath: str, output_filepath: str, fields_to_keep: # Save the optimized GeoJSON data to the output file with open(output_filepath, 'w') as f: - json.dump(data, f) \ No newline at end of file + json.dump(data, f) + +def fetch_geojson_data(url: str) -> Any: + """ + Fetches GeoJSON data from a URL. + + Args: + url (str): The URL to fetch the GeoJSON data from. + + Returns: + Any: The fetched GeoJSON data. + """ + response = requests.get(url) + response.raise_for_status() # Raise an exception if the request was unsuccessful + return response.json() \ No newline at end of file diff --git a/pages/components.py b/pages/components.py index 20d94a6a..333357ab 100644 --- a/pages/components.py +++ b/pages/components.py @@ -1,6 +1,7 @@ from dash import html, dcc from dash_extensions.javascript import Namespace from datetime import date +from functions.geojson_processing_utils import fetch_geojson_data from typing import Any, ClassVar, Optional import dash_bootstrap_components as dbc import dash_leaflet as dl @@ -8,6 +9,20 @@ import pandas as pd import uuid +def create_new_geojson_layer(url: str) -> dl.GeoJSON: + """ + Creates a new Dash Leaflet GeoJSON layer with data fetched from a URL. Assumes that the data is in GeoJSON format. + + Args: + url (str): The URL to fetch the GeoJSON data from. + + Returns: + dl.GeoJSON: A Dash Leaflet GeoJSON component. + """ + data = fetch_geojson_data(url) + return dl.GeoJSON(data=data, id=str(uuid.uuid4())) + + def create_toggle_button(index, page_type, initial_label="Hide"): """Creates a toggle button with an initial label.""" return html.Button( @@ -911,8 +926,15 @@ def create_listed_date_components(self): return listed_date_components def create_map(self): - # Create a GeoJSON layer for oil wells with clustering + """ + Creates a Dash Leaflet map with multiple layers. + + Returns: + dl.Map: A Dash Leaflet Map component. + """ + # Create additional layers oil_well_layer = self.create_oil_well_geojson_layer() + crime_layer = create_new_geojson_layer('https://data.lacity.org/resource/2nrs-mtv8.json') # Create the main map with the lease layer map = dl.Map( @@ -929,11 +951,11 @@ def create_map(self): closePopupOnClick=True, style={'width': '100%', 'height': '90vh', 'margin': "auto", "display": "inline-block"} ) - - # Add layer control with the oil well layer as an overlay (unchecked by default) + # Add a layer control for the additional layers layers_control = dl.LayersControl( - [ - dl.Overlay(oil_well_layer, name="Oil Wells", checked=False) + [ # Create a list of layers to add to the control + dl.Overlay(oil_well_layer, name="Oil Wells", checked=False), + dl.Overlay(crime_layer, name="Crime", checked=False), ], collapsed=True, position='topleft' From 20ad0f4d19fa1e4f547679d598a9cc979ce4ca6a Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:32:49 -0800 Subject: [PATCH 05/11] Refactor GeoJSON layer creation to handle non-GeoJSON data --- functions/geojson_processing_utils.py | 37 +++++++++++++++++++++++---- pages/components.py | 13 +++++++--- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/functions/geojson_processing_utils.py b/functions/geojson_processing_utils.py index 740ffe4a..570b3c02 100644 --- a/functions/geojson_processing_utils.py +++ b/functions/geojson_processing_utils.py @@ -29,16 +29,43 @@ def optimize_geojson(input_filepath: str, output_filepath: str, fields_to_keep: with open(output_filepath, 'w') as f: json.dump(data, f) -def fetch_geojson_data(url: str) -> Any: +def fetch_json_data(url: str) -> Any: """ - Fetches GeoJSON data from a URL. + Fetches JSON data from a URL. Args: - url (str): The URL to fetch the GeoJSON data from. + url (str): The URL to fetch the JSON data from. Returns: - Any: The fetched GeoJSON data. + Any: The fetched JSON data. """ response = requests.get(url) response.raise_for_status() # Raise an exception if the request was unsuccessful - return response.json() \ No newline at end of file + return response.json() + +def convert_to_geojson(data: List[Dict[str, Any]]) -> Dict[str, Any]: + """ + Converts a list of dictionaries to GeoJSON format. + + Args: + data (List[Dict[str, Any]]): The data to convert. + + Returns: + Dict[str, Any]: The data in GeoJSON format. + """ + for item in data: + return { + 'type': 'FeatureCollection', + 'features': [ + { + 'type': 'Feature', + 'geometry': { + 'type': 'Point', + # Note that the coordinates are in the opposite order from the GeoJSON spec + # https://tools.ietf.org/html/rfc7946#section-3.1.1 + 'coordinates': [float(item['lon']), float(item['lat'])] + }, + 'properties': item, + } + ], + } \ No newline at end of file diff --git a/pages/components.py b/pages/components.py index 333357ab..40e3cf18 100644 --- a/pages/components.py +++ b/pages/components.py @@ -1,7 +1,7 @@ from dash import html, dcc from dash_extensions.javascript import Namespace from datetime import date -from functions.geojson_processing_utils import fetch_geojson_data +from functions.geojson_processing_utils import fetch_json_data, convert_to_geojson from typing import Any, ClassVar, Optional import dash_bootstrap_components as dbc import dash_leaflet as dl @@ -11,15 +11,20 @@ def create_new_geojson_layer(url: str) -> dl.GeoJSON: """ - Creates a new Dash Leaflet GeoJSON layer with data fetched from a URL. Assumes that the data is in GeoJSON format. + Creates a new Dash Leaflet GeoJSON layer with data fetched from a URL. If the data is not in GeoJSON format, it is converted. Args: - url (str): The URL to fetch the GeoJSON data from. + url (str): The URL to fetch the data from. Returns: dl.GeoJSON: A Dash Leaflet GeoJSON component. """ - data = fetch_geojson_data(url) + data = fetch_json_data(url) + + # Check if the data is already in GeoJSON format + if not ('type' in data and 'features' in data): + data = convert_to_geojson(data) + return dl.GeoJSON(data=data, id=str(uuid.uuid4())) From ba240d89087099457532fd72860f38a30f31bf4b Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:35:10 -0800 Subject: [PATCH 06/11] Add unique id to each feature in GeoJSON conversion --- functions/geojson_processing_utils.py | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/functions/geojson_processing_utils.py b/functions/geojson_processing_utils.py index 570b3c02..76a0ca62 100644 --- a/functions/geojson_processing_utils.py +++ b/functions/geojson_processing_utils.py @@ -1,6 +1,7 @@ from typing import Dict, List, Any import json import requests +import uuid def optimize_geojson(input_filepath: str, output_filepath: str, fields_to_keep: List[str]) -> None: """ @@ -53,19 +54,18 @@ def convert_to_geojson(data: List[Dict[str, Any]]) -> Dict[str, Any]: Returns: Dict[str, Any]: The data in GeoJSON format. """ - for item in data: - return { - 'type': 'FeatureCollection', - 'features': [ - { - 'type': 'Feature', - 'geometry': { - 'type': 'Point', - # Note that the coordinates are in the opposite order from the GeoJSON spec - # https://tools.ietf.org/html/rfc7946#section-3.1.1 - 'coordinates': [float(item['lon']), float(item['lat'])] - }, - 'properties': item, - } - ], + return { + 'type': 'FeatureCollection', + 'features': [ + { + 'type': 'Feature', + 'id': str(uuid.uuid4()), # Assign a unique id to each feature + 'geometry': { + 'type': 'Point', + 'coordinates': [float(item['lon']), float(item['lat'])] + }, + 'properties': item, + } + for item in data + ], } \ No newline at end of file From 182c455c9c1d271dd5bff5c0cdf8f56fdb0bfe54 Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:45:10 -0800 Subject: [PATCH 07/11] Refactor create_new_geojson_layer method and move it to BaseClass. And add a crime icon --- assets/crime_icon.png | Bin 0 -> 4133 bytes pages/components.py | 58 ++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 assets/crime_icon.png diff --git a/assets/crime_icon.png b/assets/crime_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..45a57b83cadae5c36c604d209ed6b9c2d7028cfd GIT binary patch literal 4133 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 dl.GeoJSON: - """ - Creates a new Dash Leaflet GeoJSON layer with data fetched from a URL. If the data is not in GeoJSON format, it is converted. - - Args: - url (str): The URL to fetch the data from. - - Returns: - dl.GeoJSON: A Dash Leaflet GeoJSON component. - """ - data = fetch_json_data(url) - - # Check if the data is already in GeoJSON format - if not ('type' in data and 'features' in data): - data = convert_to_geojson(data) - - return dl.GeoJSON(data=data, id=str(uuid.uuid4())) - - def create_toggle_button(index, page_type, initial_label="Hide"): """Creates a toggle button with an initial label.""" return html.Button( @@ -36,8 +17,8 @@ def create_toggle_button(index, page_type, initial_label="Hide"): style={'display': 'inline-block'} ) -# Create a bass class for the oil well GeoJSON data -# The oil well GeoJSON data is used on both the Lease and Buy pages, so both classes inherit from this base class +# Create a bass class for the additional layers +# The additional layers are used in both the Lease and Sale pages, so we can use inheritance to avoid code duplication class BaseClass: oil_well_data: ClassVar[Optional[Any]] = None @@ -81,6 +62,39 @@ def create_oil_well_geojson_layer(cls) -> dl.GeoJSON: pointToLayer=ns("drawCustomIcon") ) ) + + @classmethod + def create_new_geojson_layer(cls, url: str) -> dl.GeoJSON: + """ + Creates a new Dash Leaflet GeoJSON layer with data fetched from a URL. If the data is not in GeoJSON format, it is converted. + + Args: + url (str): The URL to fetch the data from. + + Returns: + dl.GeoJSON: A Dash Leaflet GeoJSON component. + """ + data = fetch_json_data(url) + + # Check if the data is already in GeoJSON format + if not ('type' in data and 'features' in data): + data = convert_to_geojson(data) + + return dl.GeoJSON( + data=data, + id=str(uuid.uuid4()), + cluster=True, + zoomToBoundsOnClick=True, + superClusterOptions={ + 'radius': 160, + 'maxClusterRadius': 40, + 'minZoom': 3, + }, + options=dict( + pointToLayer=Namespace("myNamespace", "mySubNamespace")("drawCrimeIcon") + ) + ) + # Create a class to hold all of the Dash components for the Lease page class LeaseComponents(BaseClass): @@ -939,7 +953,7 @@ def create_map(self): """ # Create additional layers oil_well_layer = self.create_oil_well_geojson_layer() - crime_layer = create_new_geojson_layer('https://data.lacity.org/resource/2nrs-mtv8.json') + crime_layer = self.create_new_geojson_layer('https://data.lacity.org/resource/2nrs-mtv8.json') # Create the main map with the lease layer map = dl.Map( From 17d912dda467bb317094279955efce45350d85ab Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:45:55 -0800 Subject: [PATCH 08/11] Rename additional layer JS file --- assets/{oil_popup.js => additional_layer_popups.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/{oil_popup.js => additional_layer_popups.js} (100%) diff --git a/assets/oil_popup.js b/assets/additional_layer_popups.js similarity index 100% rename from assets/oil_popup.js rename to assets/additional_layer_popups.js From a1c71c037f4e2cee08ecb557495a4c11c2a269ec Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:46:32 -0800 Subject: [PATCH 09/11] Update drawCustomIcon to drawOilIcon --- assets/additional_layer_popups.js | 2 +- pages/components.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/additional_layer_popups.js b/assets/additional_layer_popups.js index 08ca4250..90a408e5 100644 --- a/assets/additional_layer_popups.js +++ b/assets/additional_layer_popups.js @@ -1,6 +1,6 @@ window.myNamespace = Object.assign({}, window.myNamespace, { mySubNamespace: { - drawCustomIcon: function(feature, latlng) { + drawOilIcon: function(feature, latlng) { const customIcon = L.icon({ iconUrl: '/assets/oil_derrick_icon.png', iconSize: [20, 20] // Adjust the size as needed diff --git a/pages/components.py b/pages/components.py index 0a93b31d..96b69835 100644 --- a/pages/components.py +++ b/pages/components.py @@ -59,7 +59,7 @@ def create_oil_well_geojson_layer(cls) -> dl.GeoJSON: 'minZoom': 3, }, options=dict( - pointToLayer=ns("drawCustomIcon") + pointToLayer=ns("drawOilIcon") ) ) From 38d5d2d1fe2050af10cdd8d25fb88208ab21ec94 Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:53:58 -0800 Subject: [PATCH 10/11] Refactor marker icons and add crime popup --- assets/additional_layer_popups.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/assets/additional_layer_popups.js b/assets/additional_layer_popups.js index 90a408e5..427102e7 100644 --- a/assets/additional_layer_popups.js +++ b/assets/additional_layer_popups.js @@ -1,11 +1,11 @@ window.myNamespace = Object.assign({}, window.myNamespace, { mySubNamespace: { drawOilIcon: function(feature, latlng) { - const customIcon = L.icon({ + const OilIcon = L.icon({ iconUrl: '/assets/oil_derrick_icon.png', iconSize: [20, 20] // Adjust the size as needed }); - var marker = L.marker(latlng, {icon: customIcon}); + var marker = L.marker(latlng, {icon: OilIcon}); // Check if the required properties exist and create the popup content if (feature.properties) { @@ -32,6 +32,31 @@ window.myNamespace = Object.assign({}, window.myNamespace, { marker.bindPopup(popupContent); } + return marker; + }, + drawCrimeIcon: function(feature, latlng) { + const CrimeIcon = L.icon({ + iconUrl: '/assets/crime_icon.png', + iconSize: [20, 20] // Adjust the size as needed + }); + var marker = L.marker(latlng, {icon: CrimeIcon}); + + // Check if the required properties exist and create the popup content + if (feature.properties) { + var popupContent = '

Crime Info

'; + popupContent += 'DR No: ' + (feature.properties.dr_no || 'N/A') + '
'; + popupContent += 'Date Occurred: ' + (feature.properties.date_occ || 'N/A') + '
'; + popupContent += 'Time Occurred: ' + (feature.properties.time_occ || 'N/A') + '
'; + popupContent += 'Crime Code Description: ' + (feature.properties.crm_cd_desc || 'N/A') + '
'; + popupContent += 'Victim Age: ' + (feature.properties.vict_age || 'N/A') + '
'; + popupContent += 'Victim Sex: ' + (feature.properties.vict_sex || 'N/A') + '
'; + popupContent += 'Premise Description: ' + (feature.properties.premis_desc || 'N/A') + '
'; + popupContent += 'Weapon Description: ' + (feature.properties.weapon_desc || 'N/A') + '
'; + popupContent += 'Status Description: ' + (feature.properties.status_desc || 'N/A') + '
'; + + marker.bindPopup(popupContent); + } + return marker; } } From 47ce7c037bec5a0457042e0afa3881a27f7d3fd4 Mon Sep 17 00:00:00 2001 From: Sahib Bhai Date: Sun, 21 Jan 2024 22:57:38 -0800 Subject: [PATCH 11/11] Update oil well labels and layer name --- assets/additional_layer_popups.js | 2 +- pages/components.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/additional_layer_popups.js b/assets/additional_layer_popups.js index 427102e7..a7933ef8 100644 --- a/assets/additional_layer_popups.js +++ b/assets/additional_layer_popups.js @@ -9,7 +9,7 @@ window.myNamespace = Object.assign({}, window.myNamespace, { // Check if the required properties exist and create the popup content if (feature.properties) { - var popupContent = '

Oil Well Info

'; + var popupContent = '

Oil/Gas Well Info

'; popupContent += 'API Number: ' + (feature.properties.API || 'N/A') + '
'; popupContent += 'Lease Name: ' + (feature.properties.LeaseName || 'N/A') + '
'; popupContent += 'Start Date: ' + (feature.properties.SpudDate || 'N/A') + '
'; diff --git a/pages/components.py b/pages/components.py index 96b69835..950ff7cb 100644 --- a/pages/components.py +++ b/pages/components.py @@ -973,7 +973,7 @@ def create_map(self): # Add a layer control for the additional layers layers_control = dl.LayersControl( [ # Create a list of layers to add to the control - dl.Overlay(oil_well_layer, name="Oil Wells", checked=False), + dl.Overlay(oil_well_layer, name="Oil & Gas Wells", checked=False), dl.Overlay(crime_layer, name="Crime", checked=False), ], collapsed=True,