diff --git a/sample_data/boston_floods/data.json b/sample_data/boston_floods/data.json index c128d4eb..ef84223b 100644 --- a/sample_data/boston_floods/data.json +++ b/sample_data/boston_floods/data.json @@ -1,357 +1,357 @@ [ - { - "type": "Project", - "name": "Boston Transportation", - "default_map_center": [ - 42.4, - -71.1 - ], - "default_map_zoom": 11, - "datasets": [ - "MBTA Rapid Transit", - "MBTA Commuter Rail", - "Massachusetts Elevation Data", - "Boston Orthoimagery", - "Boston Neighborhoods", - "Boston Census 2020 Block Groups", - "Boston Zip Codes", - "Boston Rivers Boundary", - "Massachusetts Amenities" - ] - }, - { - "type": "Dataset", - "name": "MBTA Rapid Transit", - "description": "Boston Subway System Lines and Stops", - "category": "transportation", - "tags": [ - "boston", - "public transit", - "network" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64b95be1cf6a0eaef6c141f6/download", - "hash": "1a8d1a602e7880d091a156b3b97a47d453260ba41c7c4e6e872ca4543453985d", - "path": "boston/mbta_rapid_transit.zip", - "metadata": { - "combine_contents": "true" - } - } - ], - "conversion_script": "./ingest_mbta.py", - "network_options": { - "connection_column": "ROUTE", - "connection_column_delimiter": "/", - "node_id_column": "STATION" + { + "type": "Project", + "name": "Boston Transportation", + "default_map_center": [ + -71.1, + 42.4 + ], + "default_map_zoom": 11, + "datasets": [ + "MBTA Rapid Transit", + "MBTA Commuter Rail", + "Massachusetts Elevation Data", + "Boston Orthoimagery", + "Boston Neighborhoods", + "Boston Census 2020 Block Groups", + "Boston Zip Codes", + "Boston Rivers Boundary", + "Massachusetts Amenities" + ] + }, + { + "type": "Dataset", + "name": "MBTA Rapid Transit", + "description": "Boston Subway System Lines and Stops", + "category": "transportation", + "tags": [ + "boston", + "public transit", + "network" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64b95be1cf6a0eaef6c141f6/download", + "hash": "1a8d1a602e7880d091a156b3b97a47d453260ba41c7c4e6e872ca4543453985d", + "path": "boston/mbta_rapid_transit.zip", + "metadata": { + "combine_contents": "true" } - }, - { - "type": "Dataset", - "name": "MBTA Commuter Rail", - "description": "Rail linework and station points for passenger, freight, and Amtrak and MBTA Commuter Rail trains.", - "category": "transportation", - "tags": [ - "boston", - "public transit", - "network" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64907c77f04fb368544295ed/download", - "hash": "57158adcedb10e6e8db680d2b031556ad7ff31b2e936ac29679b5e68746aa2e0", - "path": "boston/commuter_rail.zip", - "metadata": { - "combine_contents": "true" - } - } - ] - }, - { - "type": "Dataset", - "name": "Massachusetts Elevation Data", - "description": "Low resolution sampling of land elevation in meters above sea level", - "category": "elevation", - "tags": [ - "boston", - "terrain" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64907e4df04fb368544295f0/download", - "hash": "fceb76454c786d4e5ad6e05220073a0009e8deb008f5fd9195ff21c432fb8682", - "path": "boston/easternmass.tif" - } - ], - "layers": [ - { - "name": "Elevation", - "frames": [ - { - "name": "Band 1", - "data": "easternmass.tif" - } - ] - } + } + ], + "conversion_script": "./ingest_mbta.py", + "network_options": { + "connection_column": "ROUTE", + "connection_column_delimiter": "/", + "node_id_column": "STATION" + } + }, + { + "type": "Dataset", + "name": "MBTA Commuter Rail", + "description": "Rail linework and station points for passenger, freight, and Amtrak and MBTA Commuter Rail trains.", + "category": "transportation", + "tags": [ + "boston", + "public transit", + "network" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64907c77f04fb368544295ed/download", + "hash": "57158adcedb10e6e8db680d2b031556ad7ff31b2e936ac29679b5e68746aa2e0", + "path": "boston/commuter_rail.zip", + "metadata": { + "combine_contents": "true" + } + } + ] + }, + { + "type": "Dataset", + "name": "Massachusetts Elevation Data", + "description": "Low resolution sampling of land elevation in meters above sea level", + "category": "elevation", + "tags": [ + "boston", + "terrain" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64907e4df04fb368544295f0/download", + "hash": "fceb76454c786d4e5ad6e05220073a0009e8deb008f5fd9195ff21c432fb8682", + "path": "boston/easternmass.tif" + } + ], + "layers": [ + { + "name": "Elevation", + "frames": [ + { + "name": "Band 1", + "data": "easternmass.tif" + } ] - }, - { - "type": "Dataset", - "name": "Boston Orthoimagery", - "description": "Sourced from https://gis.data.mass.gov/maps/6c7009c789354573a42af7251fb768a4/about", - "category": "imagery", - "tags": [ - "boston", - "aerial imagery" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/6744df3c22f196cb5d931161/download", - "hash": "ea35f2e3d2c5dc0b2d3621ea66c1faf23632a2e1de6438cd2303e1896f75f4d4", - "path": "boston/boston_orthoimagery.tiff" - } - ], - "layers": [ - { - "name": "Orthoimagery from a single precomposited image", - "frames": [ - { - "name": "2023", - "index": 0, - "data": "boston_orthoimagery.tiff" - } - ] - } + } + ] + }, + { + "type": "Dataset", + "name": "Boston Orthoimagery", + "description": "Sourced from https://gis.data.mass.gov/maps/6c7009c789354573a42af7251fb768a4/about", + "category": "imagery", + "tags": [ + "boston", + "aerial imagery" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/6744df3c22f196cb5d931161/download", + "hash": "ea35f2e3d2c5dc0b2d3621ea66c1faf23632a2e1de6438cd2303e1896f75f4d4", + "path": "boston/boston_orthoimagery.tiff" + } + ], + "layers": [ + { + "name": "Orthoimagery from a single precomposited image", + "frames": [ + { + "name": "2023", + "index": 0, + "data": "boston_orthoimagery.tiff" + } ] + } + ] + }, + { + "type": "Dataset", + "name": "Boston Neighborhoods", + "description": "The Neighborhood boundaries data layer is a combination of zoning neighborhood boundaries, zip code boundaries and 2010 Census tract boundaries", + "category": "region", + "tags": [ + "boston", + "region boundaries", + "census", + "neighborhoods" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64caa3da77edef4e1ea8ef57/download", + "hash": "9917afa67c77b3f7a4e13637b21af60ec348cee0cd18bca92a0c87adf9d7134f", + "path": "boston/neighborhoods2020.json" + } + ], + "region_options": { + "name_property": "BlockGr202" + } + }, + { + "type": "Dataset", + "name": "Boston Census 2020 Block Groups", + "description": "Block groups (between 600 and 3,000 people per block) for Boston from the 2020 census", + "category": "region", + "tags": [ + "boston", + "region boundaries", + "census" + ], + "files": [ + { + "url": "https://data.boston.gov/dataset/c478b600-3e3e-46fd-9f57-da89459e9928/resource/11282722-9386-4272-8a82-2fcec89e6d55/download/census2020_blockgroups.zip", + "hash": "98d6346c117ea2bf6e7da3a382f88e75e3a028fd395fe4419a46022e76c2cf50", + "path": "mass/blockgroups.zip" + } + ], + "region_options": { + "name_property": "GEOID20" + } + }, + { + "type": "Dataset", + "name": "Boston Zip Codes", + "description": "Zip codes 01001-02791", + "category": "region", + "tags": [ + "boston", + "region boundaries" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64fbb4c6e99e9e6006f00114/download", + "hash": "44ea42d43c6699118e6e9b4d4939ecc1fde95f1150b9d288842efbd9900eaa3f", + "path": "boston/zipcodes.zip" + } + ], + "region_options": { + "name_property": "GEOID20" + } + }, + { + "type": "Dataset", + "name": "Boston Rivers Boundary", + "description": "Area including Charles River, Mystic River, Boston Harbor, and other small streams", + "category": "region", + "tags": [ + "boston", + "region boundaries", + "water" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/690a354103d1a144cbcf4244/download", + "hash": "708e4988c943db421a67b84926aee834e8dac5eb0a3b4331451ba2b401ac764a", + "path": "boston/water_boundary.geojson" + } + ] + }, + { + "type": "Dataset", + "name": "Massachusetts Amenities", + "description": "Various amenity locations, sourced from https://maps.massgis.digital.mass.gov/MassMapper/MassMapper.html", + "category": "amenities", + "tags": [ + "massachusetts", + "infrastructure" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/698a39825389b41db2e728a9/download", + "hash": "2a251bbd270341e9648f2bcbf488fa769b04995e3a9e93bf3ccaa0f36af327f9", + "path": "mass/amenities.zip" + } + ] + }, + { + "type": "Chart", + "name": "Boston Harbor Daily Tide Levels", + "description": "Raw data was obtained using the NOAA CO-OPS API for Data Retrieval and reformatted in tabular form", + "project": "Boston Transportation", + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64beb508b4d956782eee8cb1/download", + "hash": "299afb2e6726024cc943c0267507cae7b635282db358fea688be81b569f0b9db", + "path": "boston/tide_level_data.csv" + } + ], + "editable": false, + "metadata": { + "columns": { + "Date": "YYYY-MM-DD", + "H": "High water", + "HH": "Higher High water", + "L": "Low water", + "LL": "Lower Low Water" + }, + "contents": "Daily high-low tide levels", + "date_range": { + "from": "01-Jan-1980", + "to": "30-Jun-2023" + }, + "location": { + "latitude": 42.3539, + "longitude": -71.0503 + }, + "rows": 15857, + "source": "https://api.tidesandcurrents.noaa.gov/api/prod/", + "station": { + "datum": "Station Datum (STND)", + "id": 8443970 + } }, - { - "type": "Dataset", - "name": "Boston Neighborhoods", - "description": "The Neighborhood boundaries data layer is a combination of zoning neighborhood boundaries, zip code boundaries and 2010 Census tract boundaries", - "category": "region", - "tags": [ - "boston", - "region boundaries", - "census", - "neighborhoods" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64caa3da77edef4e1ea8ef57/download", - "hash": "9917afa67c77b3f7a4e13637b21af60ec348cee0cd18bca92a0c87adf9d7134f", - "path": "boston/neighborhoods2020.json" - } - ], - "region_options": { - "name_property": "BlockGr202" - } - }, - { - "type": "Dataset", - "name": "Boston Census 2020 Block Groups", - "description": "Block groups (between 600 and 3,000 people per block) for Boston from the 2020 census", - "category": "region", - "tags": [ - "boston", - "region boundaries", - "census" - ], - "files": [ - { - "url": "https://data.boston.gov/dataset/c478b600-3e3e-46fd-9f57-da89459e9928/resource/11282722-9386-4272-8a82-2fcec89e6d55/download/census2020_blockgroups.zip", - "hash": "98d6346c117ea2bf6e7da3a382f88e75e3a028fd395fe4419a46022e76c2cf50", - "path": "mass/blockgroups.zip" - } - ], - "region_options": { - "name_property": "GEOID20" - } - }, - { - "type": "Dataset", - "name": "Boston Zip Codes", - "description": "Zip codes 01001-02791", - "category": "region", - "tags": [ - "boston", - "region boundaries" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64fbb4c6e99e9e6006f00114/download", - "hash": "44ea42d43c6699118e6e9b4d4939ecc1fde95f1150b9d288842efbd9900eaa3f", - "path": "boston/zipcodes.zip" - } - ], - "region_options": { - "name_property": "GEOID20" - } + "chart_options": { + "chart_title": "Daily Tide Levels", + "x_title": "Date Recorded", + "y_title": "Distance from Sensor (m)" }, - { - "type": "Dataset", - "name": "Boston Rivers Boundary", - "description": "Area including Charles River, Mystic River, Boston Harbor, and other small streams", - "category": "region", - "tags": [ - "boston", - "region boundaries", - "water" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/690a354103d1a144cbcf4244/download", - "hash": "708e4988c943db421a67b84926aee834e8dac5eb0a3b4331451ba2b401ac764a", - "path": "boston/water_boundary.geojson" - } - ] + "conversion_options": { + "labels": "Date", + "datasets": [ + "HH", + "H", + "L", + "LL" + ], + "palette": { + "HH": "red", + "H": "pink", + "L": "lightblue", + "LL": "blue" + } + } + }, + { + "type": "Chart", + "name": "Charles River Hydrograph (Long Flow Length)", + "description": "Hourly hydrograph for Charles River, using a longer flow length measurement coming from Chester Brook. Uses the following units. Timestep is one hour. Values are volume without units - volume is a proportion of total flood volume. Since these are hourly timesteps, each value can also be thought of as a per-hour rate (volume/hour = discharge).", + "project": "Boston Transportation", + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/68d950f73ba8f1c07a875e68/download", + "hash": "c2c7164b0b9ad8272c225c496e2f17a40a84d0712b00fe6e5aa3f677910cef1f", + "path": "boston/hydrograph_charles_long.csv" + } + ], + "metadata": { + "method": "NRCS lag equation", + "watershed_slope_percent": 3, + "curve_number": 85, + "flow_length_ft": 124080, + "time_of_concentration_hours": 12.3, + "peak_rate_factor": 484, + "time_to_peak_hours": 7.2, + "attribution": "Calculated by August Posch, September 2025, Northeastern University." }, - { - "type": "Dataset", - "name": "Massachusetts Amenities", - "description": "Various amenity locations, sourced from https://maps.massgis.digital.mass.gov/MassMapper/MassMapper.html", - "category": "amenities", - "tags": [ - "massachusetts", - "infrastructure" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/698a39825389b41db2e728a9/download", - "hash": "2a251bbd270341e9648f2bcbf488fa769b04995e3a9e93bf3ccaa0f36af327f9", - "path": "mass/amenities.zip" - } - ] + "chart_options": { + "chart_title": "Proportional Discharge over 24 hours", + "x_title": "Hour", + "y_title": "Proportional discharge rate (volume/hour)" }, - { - "type": "Chart", - "name": "Boston Harbor Daily Tide Levels", - "description": "Raw data was obtained using the NOAA CO-OPS API for Data Retrieval and reformatted in tabular form", - "project": "Boston Transportation", - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64beb508b4d956782eee8cb1/download", - "hash": "299afb2e6726024cc943c0267507cae7b635282db358fea688be81b569f0b9db", - "path": "boston/tide_level_data.csv" - } - ], - "editable": false, - "metadata": { - "columns": { - "Date": "YYYY-MM-DD", - "H": "High water", - "HH": "Higher High water", - "L": "Low water", - "LL": "Lower Low Water" - }, - "contents": "Daily high-low tide levels", - "date_range": { - "from": "01-Jan-1980", - "to": "30-Jun-2023" - }, - "location": { - "latitude": 42.3539, - "longitude": -71.0503 - }, - "rows": 15857, - "source": "https://api.tidesandcurrents.noaa.gov/api/prod/", - "station": { - "datum": "Station Datum (STND)", - "id": 8443970 - } - }, - "chart_options": { - "chart_title": "Daily Tide Levels", - "x_title": "Date Recorded", - "y_title": "Distance from Sensor (m)" - }, - "conversion_options": { - "labels": "Date", - "datasets": [ - "HH", - "H", - "L", - "LL" - ], - "palette": { - "HH": "red", - "H": "pink", - "L": "lightblue", - "LL": "blue" - } - } + "conversion_options": { + "labels": "hour", + "datasets": [ + "discharge" + ], + "palette": { + "discharge": "blue" + } + } + }, + { + "type": "Chart", + "name": "Charles River Hydrograph (Short Flow Length)", + "description": "Hourly hydrograph for Charles River, using a shorter flow length measurement directly from Waltham gage to mouth. Uses the following units. Timestep is one hour. Values are volume without units - volume is a proportion of total flood volume. Since these are hourly timesteps, each value can also be thought of as a per-hour rate (volume/hour = discharge).", + "project": "Boston Transportation", + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/68d950f63ba8f1c07a875e65/download", + "hash": "d0ce5335c53bc2ee80b8762b5c458d06f0cdce8e03cfce935964d365da118c4d", + "path": "boston/hydrograph_charles_short.csv" + } + ], + "metadata": { + "method": "NRCS lag equation", + "watershed_slope_percent": 3, + "curve_number": 85, + "flow_length_ft": 81840, + "time_of_concentration_hours": 8.8, + "peak_rate_factor": 484, + "time_to_peak_hours": 5.2, + "attribution": "Calculated by August Posch, September 2025, Northeastern University." }, - { - "type": "Chart", - "name": "Charles River Hydrograph (Long Flow Length)", - "description": "Hourly hydrograph for Charles River, using a longer flow length measurement coming from Chester Brook. Uses the following units. Timestep is one hour. Values are volume without units - volume is a proportion of total flood volume. Since these are hourly timesteps, each value can also be thought of as a per-hour rate (volume/hour = discharge).", - "project": "Boston Transportation", - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/68d950f73ba8f1c07a875e68/download", - "hash": "c2c7164b0b9ad8272c225c496e2f17a40a84d0712b00fe6e5aa3f677910cef1f", - "path": "boston/hydrograph_charles_long.csv" - } - ], - "metadata": { - "method": "NRCS lag equation", - "watershed_slope_percent": 3, - "curve_number": 85, - "flow_length_ft": 124080, - "time_of_concentration_hours": 12.3, - "peak_rate_factor": 484, - "time_to_peak_hours": 7.2, - "attribution": "Calculated by August Posch, September 2025, Northeastern University." - }, - "chart_options": { - "chart_title": "Proportional Discharge over 24 hours", - "x_title": "Hour", - "y_title": "Proportional discharge rate (volume/hour)" - }, - "conversion_options": { - "labels": "hour", - "datasets": [ - "discharge" - ], - "palette": { - "discharge": "blue" - } - } + "chart_options": { + "chart_title": "Proportional Discharge over 24 hours", + "x_title": "Hour", + "y_title": "Proportional discharge rate (volume/hour)" }, - { - "type": "Chart", - "name": "Charles River Hydrograph (Short Flow Length)", - "description": "Hourly hydrograph for Charles River, using a shorter flow length measurement directly from Waltham gage to mouth. Uses the following units. Timestep is one hour. Values are volume without units - volume is a proportion of total flood volume. Since these are hourly timesteps, each value can also be thought of as a per-hour rate (volume/hour = discharge).", - "project": "Boston Transportation", - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/68d950f63ba8f1c07a875e65/download", - "hash": "d0ce5335c53bc2ee80b8762b5c458d06f0cdce8e03cfce935964d365da118c4d", - "path": "boston/hydrograph_charles_short.csv" - } - ], - "metadata": { - "method": "NRCS lag equation", - "watershed_slope_percent": 3, - "curve_number": 85, - "flow_length_ft": 81840, - "time_of_concentration_hours": 8.8, - "peak_rate_factor": 484, - "time_to_peak_hours": 5.2, - "attribution": "Calculated by August Posch, September 2025, Northeastern University." - }, - "chart_options": { - "chart_title": "Proportional Discharge over 24 hours", - "x_title": "Hour", - "y_title": "Proportional discharge rate (volume/hour)" - }, - "conversion_options": { - "labels": "hour", - "datasets": [ - "discharge" - ], - "palette": { - "discharge": "blue" - } - } + "conversion_options": { + "labels": "hour", + "datasets": [ + "discharge" + ], + "palette": { + "discharge": "blue" + } } + } ] diff --git a/sample_data/dc_metro.json b/sample_data/dc_metro.json index cc9242ed..83741efe 100644 --- a/sample_data/dc_metro.json +++ b/sample_data/dc_metro.json @@ -1,39 +1,39 @@ [ - { - "type": "Project", - "name": "DC Transportation", - "default_map_center": [ - 38.9, - -77.1 - ], - "default_map_zoom": 11, - "datasets": [ - "DC Metro" - ] - }, - { - "type": "Dataset", - "name": "DC Metro", - "description": "DC Metro Lines and Stations", - "category": "transportation", - "tags": [ - "public transit", - "network" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64b80188cf6a0eaef6c1416e/download", - "hash": "d0d4c957a7571402ce102d47cb53a3bddee11b0c8f278f509dc5615a9810c83f", - "path": "washington/DC_Metro.zip", - "metadata": { - "combine_contents": "true" - } - } - ], - "network_options": { - "connection_column": "LINE", - "connection_column_delimiter": ", ", - "node_id_column": "NAME" + { + "type": "Project", + "name": "DC Transportation", + "default_map_center": [ + -77.1, + 38.9 + ], + "default_map_zoom": 11, + "datasets": [ + "DC Metro" + ] + }, + { + "type": "Dataset", + "name": "DC Metro", + "description": "DC Metro Lines and Stations", + "category": "transportation", + "tags": [ + "public transit", + "network" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64b80188cf6a0eaef6c1416e/download", + "hash": "d0d4c957a7571402ce102d47cb53a3bddee11b0c8f278f509dc5615a9810c83f", + "path": "washington/DC_Metro.zip", + "metadata": { + "combine_contents": "true" } + } + ], + "network_options": { + "connection_column": "LINE", + "connection_column_delimiter": ", ", + "node_id_column": "NAME" } + } ] diff --git a/sample_data/la_wildfires.json b/sample_data/la_wildfires.json index b5ac5cb4..3e24a78e 100644 --- a/sample_data/la_wildfires.json +++ b/sample_data/la_wildfires.json @@ -1,98 +1,97 @@ [ - { - "type": "Project", - "name": "Los Angeles Wildfires (Jan 2025)", - "default_map_center": [ - 34.27, - -118.47 - ], - "default_map_zoom": 9, - "datasets": [ - "MODIS 1km 48h USA + Hawaii", - "USA Current Wildfire Perimeters", - "USA Current Wildfire Incidents", - "California Fire Perimeters", - "Palisades Satellite Imagery", - "Eaton/Altadena Satellite Imagery" - ] - }, - { - "type": "Dataset", - "name": "MODIS 1km 48h USA + Hawaii", - "description": "MODIS 1km USA (Conterminous) + Hawaii 48h shapefile. From: https://firms.modaps.eosdis.nasa.gov/active_fire/", - "category": "region", - "files": [ - { - "path": "la-fire-2025/modis-1-48.zip", - "url": "https://data.kitware.com/api/v1/item/67aa368b091a514e82eec908/download", - "hash": "5271a47008fdd75b8bd9d3df453ece9eae27d6bbe3050cbf8c00e486edd286e4" - } - ] - }, - { - "type": "Dataset", - "name": "USA Current Wildfire Perimeters", - "description": "NIFC, taken on Feb 4, 2025. From: https://data-nifc.opendata.arcgis.com/", - "category": "region", - "files": [ - { - "path": "la-fire-2025/current_fire_perimeters.geojson", - "url": "https://data.kitware.com/api/v1/item/67aa368c091a514e82eec90b/download", - "hash": "781b75f35db48ac53a917a524809f87108cd183941deaefe2503e128f86e465e" - } - ] - }, - { - "type": "Dataset", - "name": "USA Current Wildfire Incidents", - "description": "IRWIN, taken on Feb 4, 2025. From: https://forestsandrangelands.gov/WFIT/applications/IRWIN/index.shtml", - "category": "region", - "files": [ - { - "path": "la-fire-2025/current_fire_incidents.geojson", - "url": "https://data.kitware.com/api/v1/item/67aa368c091a514e82eec90e/download", - "hash": "649f641ec200ff2bb64f12ba3928e289cc35fcfc942fc16b5890dc3382ce4a79" - } - ] - }, - { - "type": "Dataset", - "name": "California Fire Perimeters", - "description": "NIFC + FIRIS, taken Feb 4, 2025. From: https://www.fire.ca.gov/incidents/2025/1/7/palisades-fire", - "category": "region", - "files": [ - { - "path": "la-fire-2025/ca_perimeters_nifc_firis.geojson", - "url": "https://data.kitware.com/api/v1/item/67aa33ed091a514e82eec8ff/download", - "hash": "53fdb0484bd05725fe1569302ebd7c66404d93e9f8772bf557473f6e59c3a02a" - } - ] - }, - { - "type": "Dataset", - "name": "Palisades Satellite Imagery", - "description": "MAXAR, Jan 14, 2025. From: https://registry.opendata.aws/maxar-open-data/", - "category": "region", - "files": [ - { - "path": "la-fire-2025/palidades-2025-01-14.tif", - "url": "https://data.kitware.com/api/v1/item/67aa368a091a514e82eec905/download", - "hash": "7630707f87a54ae134ec56012911884c5648d55419c8742e264c4d4c4354ea1f" - } - ] - }, - { - "type": "Dataset", - "name": "Eaton/Altadena Satellite Imagery", - "description": "MAXAR, Jan 14-19, 2025. From: https://registry.opendata.aws/maxar-open-data/", - "category": "region", - "files": [ - { - "path": "la-fire-2025/eaton-2025-01-14_to_19.tif", - "url": "https://data.kitware.com/api/v1/item/67aa353a091a514e82eec902/download", - "hash": "163a8b84bf7fb356b66ff2700ec0d2043c25a9a153f7778e84b9b85ca51dcf74" - } - ] - } - -] \ No newline at end of file + { + "type": "Project", + "name": "Los Angeles Wildfires (Jan 2025)", + "default_map_center": [ + -118.47, + 34.27 + ], + "default_map_zoom": 9, + "datasets": [ + "MODIS 1km 48h USA + Hawaii", + "USA Current Wildfire Perimeters", + "USA Current Wildfire Incidents", + "California Fire Perimeters", + "Palisades Satellite Imagery", + "Eaton/Altadena Satellite Imagery" + ] + }, + { + "type": "Dataset", + "name": "MODIS 1km 48h USA + Hawaii", + "description": "MODIS 1km USA (Conterminous) + Hawaii 48h shapefile. From: https://firms.modaps.eosdis.nasa.gov/active_fire/", + "category": "region", + "files": [ + { + "path": "la-fire-2025/modis-1-48.zip", + "url": "https://data.kitware.com/api/v1/item/67aa368b091a514e82eec908/download", + "hash": "5271a47008fdd75b8bd9d3df453ece9eae27d6bbe3050cbf8c00e486edd286e4" + } + ] + }, + { + "type": "Dataset", + "name": "USA Current Wildfire Perimeters", + "description": "NIFC, taken on Feb 4, 2025. From: https://data-nifc.opendata.arcgis.com/", + "category": "region", + "files": [ + { + "path": "la-fire-2025/current_fire_perimeters.geojson", + "url": "https://data.kitware.com/api/v1/item/67aa368c091a514e82eec90b/download", + "hash": "781b75f35db48ac53a917a524809f87108cd183941deaefe2503e128f86e465e" + } + ] + }, + { + "type": "Dataset", + "name": "USA Current Wildfire Incidents", + "description": "IRWIN, taken on Feb 4, 2025. From: https://forestsandrangelands.gov/WFIT/applications/IRWIN/index.shtml", + "category": "region", + "files": [ + { + "path": "la-fire-2025/current_fire_incidents.geojson", + "url": "https://data.kitware.com/api/v1/item/67aa368c091a514e82eec90e/download", + "hash": "649f641ec200ff2bb64f12ba3928e289cc35fcfc942fc16b5890dc3382ce4a79" + } + ] + }, + { + "type": "Dataset", + "name": "California Fire Perimeters", + "description": "NIFC + FIRIS, taken Feb 4, 2025. From: https://www.fire.ca.gov/incidents/2025/1/7/palisades-fire", + "category": "region", + "files": [ + { + "path": "la-fire-2025/ca_perimeters_nifc_firis.geojson", + "url": "https://data.kitware.com/api/v1/item/67aa33ed091a514e82eec8ff/download", + "hash": "53fdb0484bd05725fe1569302ebd7c66404d93e9f8772bf557473f6e59c3a02a" + } + ] + }, + { + "type": "Dataset", + "name": "Palisades Satellite Imagery", + "description": "MAXAR, Jan 14, 2025. From: https://registry.opendata.aws/maxar-open-data/", + "category": "region", + "files": [ + { + "path": "la-fire-2025/palidades-2025-01-14.tif", + "url": "https://data.kitware.com/api/v1/item/67aa368a091a514e82eec905/download", + "hash": "7630707f87a54ae134ec56012911884c5648d55419c8742e264c4d4c4354ea1f" + } + ] + }, + { + "type": "Dataset", + "name": "Eaton/Altadena Satellite Imagery", + "description": "MAXAR, Jan 14-19, 2025. From: https://registry.opendata.aws/maxar-open-data/", + "category": "region", + "files": [ + { + "path": "la-fire-2025/eaton-2025-01-14_to_19.tif", + "url": "https://data.kitware.com/api/v1/item/67aa353a091a514e82eec902/download", + "hash": "163a8b84bf7fb356b66ff2700ec0d2043c25a9a153f7778e84b9b85ca51dcf74" + } + ] + } +] diff --git a/sample_data/multiframe_test.json b/sample_data/multiframe_test.json index bdb1812f..ff969e37 100644 --- a/sample_data/multiframe_test.json +++ b/sample_data/multiframe_test.json @@ -3,8 +3,8 @@ "type": "Project", "name": "Test", "default_map_center": [ - 42.4, - -71.1 + -71.1, + 42.4 ], "default_map_zoom": 11, "datasets": [ diff --git a/sample_data/new_york_energy/data.json b/sample_data/new_york_energy/data.json index 7d76b1f3..f9ffaebb 100644 --- a/sample_data/new_york_energy/data.json +++ b/sample_data/new_york_energy/data.json @@ -1,81 +1,81 @@ [ - { - "type": "Project", - "name": "NY Energy", - "default_map_center": [ - 43.5, - -75.5 - ], - "default_map_zoom": 8, - "datasets": [ - "National Grid CompanyBoundary", - "National Grid County Networks", - "National Grid Substations", - "County Boundaries" - ] - }, - { - "type": "Dataset", - "name": "National Grid CompanyBoundary", - "description": "CompanyBoundary vector data", - "category": "region", - "tags": [ - "new york", - "energy grid", - "region boundaries" - ], - "conversion_script": "./ingest.py" - }, - { - "type": "Dataset", - "name": "County Boundaries", - "description": "From https://gis.ny.gov/civil-boundaries", - "category": "region", - "tags": [ - "new york", - "region boundaries" - ], - "conversion_script": "./ingest.py", - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/66a2a19a5d2551c516b1e502/download", - "hash": "32f44d7d9f3571185ce2c9e1d28fb90987ddbebb13923a887e1733e2f1c84c89", - "path": "nyc/counties.zip" - } - ], - "region_options": { - "name_property": "NAME" - } - }, - { - "type": "Dataset", - "name": "National Grid Substations", - "description": "Substations vector data", - "category": "energy", - "tags": [ - "new york", - "energy grid", - "region boundaries" - ], - "conversion_script": "./ingest.py" - }, - { - "type": "Dataset", - "name": "National Grid County Networks", - "description": "Energy networks for each county in New York", - "category": "energy", - "tags": [ - "new york", - "energy grid", - "region boundaries" - ], - "conversion_script": "./ingest.py", - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/66cdd8a6886c56bdc7e282a4/download", - "hash": "3f7e8c036cf7fbd1f10fd25b34e76d7c4b10ae9b985a148316b4a826336c4ad5", - "path": "nyc/networks.zip" - } - ] + { + "type": "Project", + "name": "NY Energy", + "default_map_center": [ + -75.5, + 43.5 + ], + "default_map_zoom": 8, + "datasets": [ + "National Grid CompanyBoundary", + "National Grid County Networks", + "National Grid Substations", + "County Boundaries" + ] + }, + { + "type": "Dataset", + "name": "National Grid CompanyBoundary", + "description": "CompanyBoundary vector data", + "category": "region", + "tags": [ + "new york", + "energy grid", + "region boundaries" + ], + "conversion_script": "./ingest.py" + }, + { + "type": "Dataset", + "name": "County Boundaries", + "description": "From https://gis.ny.gov/civil-boundaries", + "category": "region", + "tags": [ + "new york", + "region boundaries" + ], + "conversion_script": "./ingest.py", + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/66a2a19a5d2551c516b1e502/download", + "hash": "32f44d7d9f3571185ce2c9e1d28fb90987ddbebb13923a887e1733e2f1c84c89", + "path": "nyc/counties.zip" + } + ], + "region_options": { + "name_property": "NAME" } + }, + { + "type": "Dataset", + "name": "National Grid Substations", + "description": "Substations vector data", + "category": "energy", + "tags": [ + "new york", + "energy grid", + "region boundaries" + ], + "conversion_script": "./ingest.py" + }, + { + "type": "Dataset", + "name": "National Grid County Networks", + "description": "Energy networks for each county in New York", + "category": "energy", + "tags": [ + "new york", + "energy grid", + "region boundaries" + ], + "conversion_script": "./ingest.py", + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/66cdd8a6886c56bdc7e282a4/download", + "hash": "3f7e8c036cf7fbd1f10fd25b34e76d7c4b10ae9b985a148316b4a826336c4ad5", + "path": "nyc/networks.zip" + } + ] + } ] diff --git a/sample_data/testRasters/sample.json b/sample_data/testRasters/sample.json index bbae43a6..8ee74412 100644 --- a/sample_data/testRasters/sample.json +++ b/sample_data/testRasters/sample.json @@ -1,209 +1,209 @@ [ - { - "type": "Project", - "name": "Sentinel-2 Clipped Images", - "datasets": [ - "Sequential Test Rasters" - ], - "default_map_center": [ - 43.135763, - -74.1767949 - ], - "default_map_zoom": 11 - }, - { - "type": "Dataset", - "name": "Sequential Test Rasters", - "description": "Clipped Sentinel-2 images downloaded and clipped around point", - "category": "imagery", - "files": [ - { - "path": "sequentialTestRasters/S2C_T18TWN_20250822T155805_L2A_visual_clip_10km.tif", - "name": "Frame 0" - }, - { - "path": "sequentialTestRasters/S2C_T18TWN_20250812T155109_L2A_visual_clip_10km.tif", - "name": "Frame 1" - }, - { - "path": "sequentialTestRasters/S2C_T18TWN_20250802T155417_L2A_visual_clip_10km.tif", - "name": "Frame 2" - }, - { - "path": "sequentialTestRasters/S2C_T18TWN_20250723T155909_L2A_visual_clip_10km.tif", - "name": "Frame 3" - }, - { - "path": "sequentialTestRasters/S2B_T18TWN_20250608T155508_L2A_visual_clip_10km.tif", - "name": "Frame 4" - }, - { - "path": "sequentialTestRasters/S2C_T18TWN_20250603T155650_L2A_visual_clip_10km.tif", - "name": "Frame 5" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20250526T155707_L2A_visual_clip_10km.tif", - "name": "Frame 6" - }, - { - "path": "sequentialTestRasters/S2C_T18TWN_20250424T155922_L2A_visual_clip_10km.tif", - "name": "Frame 7" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20250327T155839_L2A_visual_clip_10km.tif", - "name": "Frame 8" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20241125T155718_L2A_visual_clip_10km.tif", - "name": "Frame 9" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20241115T160059_L2A_visual_clip_10km.tif", - "name": "Frame 10" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20241105T155941_L2A_visual_clip_10km.tif", - "name": "Frame 11" - }, - { - "path": "sequentialTestRasters/S2B_T18TWN_20241031T155727_L2A_visual_clip_10km.tif", - "name": "Frame 12" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20241026T155709_L2A_visual_clip_10km.tif", - "name": "Frame 13" - }, - { - "path": "sequentialTestRasters/S2B_T18TWN_20241021T155603_L2A_visual_clip_10km.tif", - "name": "Frame 14" - }, - { - "path": "sequentialTestRasters/S2B_T18TWN_20241011T155627_L2A_visual_clip_10km.tif", - "name": "Frame 15" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20241006T160103_L2A_visual_clip_10km.tif", - "name": "Frame 16" - }, - { - "path": "sequentialTestRasters/S2A_T18TWN_20240916T155314_L2A_visual_clip_10km.tif", - "name": "Frame 17" - }, - { - "path": "sequentialTestRasters/S2B_T18TWN_20240911T155232_L2A_visual_clip_10km.tif", - "name": "Frame 18" - }, - { - "path": "sequentialTestRasters/S2B_T18TWN_20240901T155454_L2A_visual_clip_10km.tif", - "name": "Frame 19" - } - ], - "layers": [ - { - "name": "Sequential Test Layers", - "frames": [ - { - "name": "Sequential Layer 0", - "index": 0, - "data": "S2C_T18TWN_20250822T155805_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 1", - "index": 1, - "data": "S2C_T18TWN_20250812T155109_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 2", - "index": 2, - "data": "S2C_T18TWN_20250802T155417_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 3", - "index": 3, - "data": "S2C_T18TWN_20250723T155909_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 4", - "index": 4, - "data": "S2B_T18TWN_20250608T155508_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 5", - "index": 5, - "data": "S2C_T18TWN_20250603T155650_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 6", - "index": 6, - "data": "S2A_T18TWN_20250526T155707_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 7", - "index": 7, - "data": "S2C_T18TWN_20250424T155922_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 8", - "index": 8, - "data": "S2A_T18TWN_20250327T155839_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 9", - "index": 9, - "data": "S2A_T18TWN_20241125T155718_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 10", - "index": 10, - "data": "S2A_T18TWN_20241115T160059_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 11", - "index": 11, - "data": "S2A_T18TWN_20241105T155941_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 12", - "index": 12, - "data": "S2B_T18TWN_20241031T155727_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 13", - "index": 13, - "data": "S2A_T18TWN_20241026T155709_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 14", - "index": 14, - "data": "S2B_T18TWN_20241021T155603_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 15", - "index": 15, - "data": "S2B_T18TWN_20241011T155627_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 16", - "index": 16, - "data": "S2A_T18TWN_20241006T160103_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 17", - "index": 17, - "data": "S2A_T18TWN_20240916T155314_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 18", - "index": 18, - "data": "S2B_T18TWN_20240911T155232_L2A_visual_clip_10km.tif" - }, - { - "name": "Sequential Layer 19", - "index": 19, - "data": "S2B_T18TWN_20240901T155454_L2A_visual_clip_10km.tif" - } - ] - } + { + "type": "Project", + "name": "Sentinel-2 Clipped Images", + "datasets": [ + "Sequential Test Rasters" + ], + "default_map_center": [ + -74.1767949, + 43.135763 + ], + "default_map_zoom": 11 + }, + { + "type": "Dataset", + "name": "Sequential Test Rasters", + "description": "Clipped Sentinel-2 images downloaded and clipped around point", + "category": "imagery", + "files": [ + { + "path": "sequentialTestRasters/S2C_T18TWN_20250822T155805_L2A_visual_clip_10km.tif", + "name": "Frame 0" + }, + { + "path": "sequentialTestRasters/S2C_T18TWN_20250812T155109_L2A_visual_clip_10km.tif", + "name": "Frame 1" + }, + { + "path": "sequentialTestRasters/S2C_T18TWN_20250802T155417_L2A_visual_clip_10km.tif", + "name": "Frame 2" + }, + { + "path": "sequentialTestRasters/S2C_T18TWN_20250723T155909_L2A_visual_clip_10km.tif", + "name": "Frame 3" + }, + { + "path": "sequentialTestRasters/S2B_T18TWN_20250608T155508_L2A_visual_clip_10km.tif", + "name": "Frame 4" + }, + { + "path": "sequentialTestRasters/S2C_T18TWN_20250603T155650_L2A_visual_clip_10km.tif", + "name": "Frame 5" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20250526T155707_L2A_visual_clip_10km.tif", + "name": "Frame 6" + }, + { + "path": "sequentialTestRasters/S2C_T18TWN_20250424T155922_L2A_visual_clip_10km.tif", + "name": "Frame 7" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20250327T155839_L2A_visual_clip_10km.tif", + "name": "Frame 8" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20241125T155718_L2A_visual_clip_10km.tif", + "name": "Frame 9" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20241115T160059_L2A_visual_clip_10km.tif", + "name": "Frame 10" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20241105T155941_L2A_visual_clip_10km.tif", + "name": "Frame 11" + }, + { + "path": "sequentialTestRasters/S2B_T18TWN_20241031T155727_L2A_visual_clip_10km.tif", + "name": "Frame 12" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20241026T155709_L2A_visual_clip_10km.tif", + "name": "Frame 13" + }, + { + "path": "sequentialTestRasters/S2B_T18TWN_20241021T155603_L2A_visual_clip_10km.tif", + "name": "Frame 14" + }, + { + "path": "sequentialTestRasters/S2B_T18TWN_20241011T155627_L2A_visual_clip_10km.tif", + "name": "Frame 15" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20241006T160103_L2A_visual_clip_10km.tif", + "name": "Frame 16" + }, + { + "path": "sequentialTestRasters/S2A_T18TWN_20240916T155314_L2A_visual_clip_10km.tif", + "name": "Frame 17" + }, + { + "path": "sequentialTestRasters/S2B_T18TWN_20240911T155232_L2A_visual_clip_10km.tif", + "name": "Frame 18" + }, + { + "path": "sequentialTestRasters/S2B_T18TWN_20240901T155454_L2A_visual_clip_10km.tif", + "name": "Frame 19" + } + ], + "layers": [ + { + "name": "Sequential Test Layers", + "frames": [ + { + "name": "Sequential Layer 0", + "index": 0, + "data": "S2C_T18TWN_20250822T155805_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 1", + "index": 1, + "data": "S2C_T18TWN_20250812T155109_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 2", + "index": 2, + "data": "S2C_T18TWN_20250802T155417_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 3", + "index": 3, + "data": "S2C_T18TWN_20250723T155909_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 4", + "index": 4, + "data": "S2B_T18TWN_20250608T155508_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 5", + "index": 5, + "data": "S2C_T18TWN_20250603T155650_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 6", + "index": 6, + "data": "S2A_T18TWN_20250526T155707_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 7", + "index": 7, + "data": "S2C_T18TWN_20250424T155922_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 8", + "index": 8, + "data": "S2A_T18TWN_20250327T155839_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 9", + "index": 9, + "data": "S2A_T18TWN_20241125T155718_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 10", + "index": 10, + "data": "S2A_T18TWN_20241115T160059_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 11", + "index": 11, + "data": "S2A_T18TWN_20241105T155941_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 12", + "index": 12, + "data": "S2B_T18TWN_20241031T155727_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 13", + "index": 13, + "data": "S2A_T18TWN_20241026T155709_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 14", + "index": 14, + "data": "S2B_T18TWN_20241021T155603_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 15", + "index": 15, + "data": "S2B_T18TWN_20241011T155627_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 16", + "index": 16, + "data": "S2A_T18TWN_20241006T160103_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 17", + "index": 17, + "data": "S2A_T18TWN_20240916T155314_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 18", + "index": 18, + "data": "S2B_T18TWN_20240911T155232_L2A_visual_clip_10km.tif" + }, + { + "name": "Sequential Layer 19", + "index": 19, + "data": "S2B_T18TWN_20240901T155454_L2A_visual_clip_10km.tif" + } ] - } -] \ No newline at end of file + } + ] + } +] diff --git a/sample_data/tests/analytics.json b/sample_data/tests/analytics.json index 4b3088b2..4ea1a545 100644 --- a/sample_data/tests/analytics.json +++ b/sample_data/tests/analytics.json @@ -1,77 +1,77 @@ [ - { - "type": "Project", - "name": "Boston Transportation", - "default_map_center": [ - 42.4, - -71.1 - ], - "default_map_zoom": 11, - "datasets": [ - "MBTA Rapid Transit" - ] - }, - { - "type": "Dataset", - "name": "MBTA Rapid Transit", - "description": "Boston Subway System Lines and Stops", - "category": "transportation", - "tags": [ - "boston", - "public transit", - "network" - ], - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/64b95be1cf6a0eaef6c141f6/download", - "hash": "1a8d1a602e7880d091a156b3b97a47d453260ba41c7c4e6e872ca4543453985d", - "path": "boston/mbta_rapid_transit.zip", - "metadata": { - "combine_contents": "true" - } - } - ], - "network_options": { - "connection_column": "ROUTE", - "connection_column_delimiter": "/", - "node_id_column": "STATION" - } - }, - { - "type": "Chart", - "name": "Charles River Hydrograph (Short Flow Length)", - "description": "Hourly hydrograph for Charles River, using a shorter flow length measurement directly from Waltham gage to mouth. Uses the following units. Timestep is one hour. Values are volume without units - volume is a proportion of total flood volume. Since these are hourly timesteps, each value can also be thought of as a per-hour rate (volume/hour = discharge).", - "project": "Boston Transportation", - "files": [ - { - "url": "https://data.kitware.com/api/v1/item/68d950f63ba8f1c07a875e65/download", - "hash": "d0ce5335c53bc2ee80b8762b5c458d06f0cdce8e03cfce935964d365da118c4d", - "path": "boston/hydrograph_charles_short.csv" - } - ], + { + "type": "Project", + "name": "Boston Transportation", + "default_map_center": [ + -71.1, + 42.4 + ], + "default_map_zoom": 11, + "datasets": [ + "MBTA Rapid Transit" + ] + }, + { + "type": "Dataset", + "name": "MBTA Rapid Transit", + "description": "Boston Subway System Lines and Stops", + "category": "transportation", + "tags": [ + "boston", + "public transit", + "network" + ], + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/64b95be1cf6a0eaef6c141f6/download", + "hash": "1a8d1a602e7880d091a156b3b97a47d453260ba41c7c4e6e872ca4543453985d", + "path": "boston/mbta_rapid_transit.zip", "metadata": { - "method": "NRCS lag equation", - "watershed_slope_percent": 3, - "curve_number": 85, - "flow_length_ft": 81840, - "time_of_concentration_hours": 8.8, - "peak_rate_factor": 484, - "time_to_peak_hours": 5.2, - "attribution": "Calculated by August Posch, September 2025, Northeastern University." - }, - "chart_options": { - "chart_title": "Proportional Discharge over 24 hours", - "x_title": "Hour", - "y_title": "Proportional discharge rate (volume/hour)" - }, - "conversion_options": { - "labels": "hour", - "datasets": [ - "discharge" - ], - "palette": { - "discharge": "blue" - } + "combine_contents": "true" } + } + ], + "network_options": { + "connection_column": "ROUTE", + "connection_column_delimiter": "/", + "node_id_column": "STATION" + } + }, + { + "type": "Chart", + "name": "Charles River Hydrograph (Short Flow Length)", + "description": "Hourly hydrograph for Charles River, using a shorter flow length measurement directly from Waltham gage to mouth. Uses the following units. Timestep is one hour. Values are volume without units - volume is a proportion of total flood volume. Since these are hourly timesteps, each value can also be thought of as a per-hour rate (volume/hour = discharge).", + "project": "Boston Transportation", + "files": [ + { + "url": "https://data.kitware.com/api/v1/item/68d950f63ba8f1c07a875e65/download", + "hash": "d0ce5335c53bc2ee80b8762b5c458d06f0cdce8e03cfce935964d365da118c4d", + "path": "boston/hydrograph_charles_short.csv" + } + ], + "metadata": { + "method": "NRCS lag equation", + "watershed_slope_percent": 3, + "curve_number": 85, + "flow_length_ft": 81840, + "time_of_concentration_hours": 8.8, + "peak_rate_factor": 484, + "time_to_peak_hours": 5.2, + "attribution": "Calculated by August Posch, September 2025, Northeastern University." + }, + "chart_options": { + "chart_title": "Proportional Discharge over 24 hours", + "x_title": "Hour", + "y_title": "Proportional discharge rate (volume/hour)" + }, + "conversion_options": { + "labels": "hour", + "datasets": [ + "discharge" + ], + "palette": { + "discharge": "blue" + } } + } ] diff --git a/sample_data/tests/ingest.json b/sample_data/tests/ingest.json index 6ed23f71..9810b3d8 100644 --- a/sample_data/tests/ingest.json +++ b/sample_data/tests/ingest.json @@ -3,8 +3,8 @@ "type": "Project", "name": "Boston Transportation", "default_map_center": [ - 42.4, - -71.1 + -71.1, + 42.4 ], "default_map_zoom": 11, "datasets": [ diff --git a/uvdat/core/admin.py b/uvdat/core/admin.py index 2e6b6341..02b1e859 100644 --- a/uvdat/core/admin.py +++ b/uvdat/core/admin.py @@ -25,6 +25,7 @@ TaskResult, VectorData, VectorFeature, + ViewState, ) @@ -140,3 +141,8 @@ class NetworkNodeAdmin(admin.ModelAdmin): @admin.register(TaskResult) class TaskResultAdmin(admin.ModelAdmin): list_display = ["id", "task_type", "inputs"] + + +@admin.register(ViewState) +class ViewStateAdmin(admin.ModelAdmin): + list_display = ["id", "name", "project"] diff --git a/uvdat/core/migrations/0022_view_states.py b/uvdat/core/migrations/0022_view_states.py new file mode 100644 index 00000000..51ec52b9 --- /dev/null +++ b/uvdat/core/migrations/0022_view_states.py @@ -0,0 +1,96 @@ +# Generated by Django 5.2.9 on 2026-03-03 20:50 +from __future__ import annotations + +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion +import s3_file_field.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0021_non_null_text_fields"), + ] + + operations = [ + migrations.CreateModel( + name="ViewState", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("name", models.CharField(max_length=255)), + ("thumbnail", s3_file_field.fields.S3FileField()), + ("theme", models.CharField(default="light", max_length=10)), + ("current_analysis_type", models.CharField(blank=True, max_length=25)), + ("left_sidebar_open", models.BooleanField(default=False)), + ("right_sidebar_open", models.BooleanField(default=False)), + ("map_zoom", models.IntegerField(null=True)), + ( + "map_center", + django.contrib.gis.db.models.fields.PointField(null=True, srid=4326), + ), + ("panel_arrangement", models.JSONField(blank=True, null=True)), + ("selected_layer_current_frames", models.JSONField(blank=True, null=True)), + ("selected_layer_order", models.JSONField(blank=True, null=True)), + ("selected_layer_styles", models.JSONField(blank=True, null=True)), + ( + "current_basemap", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="views", + to="core.basemap", + ), + ), + ( + "current_chart", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="views", + to="core.chart", + ), + ), + ( + "current_network", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="views", + to="core.network", + ), + ), + ( + "current_result", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="views", + to="core.taskresult", + ), + ), + ( + "project", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="views", + to="core.project", + ), + ), + ( + "selected_layers", + models.ManyToManyField(blank=True, related_name="views", to="core.layer"), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint(fields=("project", "name"), name="uniqueviewname") + ], + }, + ), + ] diff --git a/uvdat/core/models/__init__.py b/uvdat/core/models/__init__.py index 782c14b5..83ff7763 100644 --- a/uvdat/core/models/__init__.py +++ b/uvdat/core/models/__init__.py @@ -19,6 +19,7 @@ SizeRangeConfig, ) from .task_result import TaskResult +from .view_state import ViewState __all__ = [ "Basemap", @@ -44,4 +45,5 @@ "TaskResult", "VectorData", "VectorFeature", + "ViewState", ] diff --git a/uvdat/core/models/view_state.py b/uvdat/core/models/view_state.py new file mode 100644 index 00000000..21460322 --- /dev/null +++ b/uvdat/core/models/view_state.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +from django.contrib.gis.db import models as geo_models +from django.db import models +from s3_file_field import S3FileField + +from .basemap import Basemap +from .chart import Chart +from .layer import Layer +from .networks import Network +from .project import Project +from .querysets import ProjectQuerySet +from .task_result import TaskResult + + +class ViewState(models.Model): + name = models.CharField(max_length=255) + project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="views", null=True) + thumbnail = S3FileField() + + theme = models.CharField(max_length=10, default="light") + current_analysis_type = models.CharField( + max_length=25, + blank=True, # max length matches TaskResult.task_type + ) + current_result = models.ForeignKey( + TaskResult, on_delete=models.CASCADE, related_name="views", null=True + ) + current_basemap = models.ForeignKey( + Basemap, on_delete=models.CASCADE, related_name="views", null=True + ) + current_chart = models.ForeignKey( + Chart, on_delete=models.CASCADE, related_name="views", null=True + ) + current_network = models.ForeignKey( + Network, on_delete=models.CASCADE, related_name="views", null=True + ) + left_sidebar_open = models.BooleanField(default=False) + right_sidebar_open = models.BooleanField(default=False) + map_zoom = models.IntegerField(null=True) + map_center = geo_models.PointField(null=True) + panel_arrangement = models.JSONField(blank=True, null=True) + selected_layers = models.ManyToManyField(Layer, related_name="views", blank=True) + selected_layer_current_frames = models.JSONField(blank=True, null=True) + selected_layer_order = models.JSONField(blank=True, null=True) + selected_layer_styles = models.JSONField(blank=True, null=True) + + project_filter_path = "project" + objects = ProjectQuerySet.as_manager() + + class Meta: + constraints = [ + # We enforce name uniqueness across projects + models.UniqueConstraint(name="uniqueviewname", fields=["project", "name"]) + ] + + def __str__(self): + return f"{self.name} ({self.id})" diff --git a/uvdat/core/rest/__init__.py b/uvdat/core/rest/__init__.py index 55621c50..d3c773e7 100644 --- a/uvdat/core/rest/__init__.py +++ b/uvdat/core/rest/__init__.py @@ -12,6 +12,7 @@ from .project import ProjectViewSet from .regions import RegionViewSet from .user import UserViewSet +from .view_state import ViewStateViewSet __all__ = [ "AnalyticsViewSet", @@ -29,4 +30,5 @@ "RegionViewSet", "UserViewSet", "VectorDataViewSet", + "ViewStateViewSet", ] diff --git a/uvdat/core/rest/serializers.py b/uvdat/core/rest/serializers.py index d8be2e5c..6038bb92 100644 --- a/uvdat/core/rest/serializers.py +++ b/uvdat/core/rest/serializers.py @@ -23,6 +23,7 @@ Region, TaskResult, VectorData, + ViewState, ) @@ -66,7 +67,7 @@ class ProjectSerializer(serializers.ModelSerializer): def get_center(self, obj): # Web client expects Lon, Lat if obj.default_map_center: - return [obj.default_map_center.y, obj.default_map_center.x] + return [obj.default_map_center.x, obj.default_map_center.y] return None def get_owner(self, obj: Project): @@ -89,7 +90,7 @@ def to_internal_value(self, data): center = data.get("default_map_center") data = super().to_internal_value(data) if isinstance(center, list): - data["default_map_center"] = Point(center[1], center[0]) + data["default_map_center"] = Point(center[0], center[1]) return data class Meta: @@ -281,3 +282,24 @@ def get_name(self, obj): class Meta: model = TaskResult fields = "__all__" + + +class ViewStateSerializer(serializers.ModelSerializer): + map_center = serializers.SerializerMethodField("get_center") + + def get_center(self, obj): + # Web client expects Lon, Lat + if obj.map_center: + return [obj.map_center.x, obj.map_center.y] + return None + + def to_internal_value(self, data): + center = data.get("map_center") + data = super().to_internal_value(data) + if isinstance(center, list): + data["map_center"] = Point(center[0], center[1]) + return data + + class Meta: + model = ViewState + fields = "__all__" diff --git a/uvdat/core/rest/view_state.py b/uvdat/core/rest/view_state.py new file mode 100644 index 00000000..572001c1 --- /dev/null +++ b/uvdat/core/rest/view_state.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from rest_framework.viewsets import ModelViewSet + +from uvdat.core.models import ViewState +from uvdat.core.rest.serializers import ViewStateSerializer + + +class ViewStateViewSet(ModelViewSet): + queryset = ViewState.objects.all() + serializer_class = ViewStateSerializer diff --git a/uvdat/urls.py b/uvdat/urls.py index f2ffafa7..5ed90c40 100644 --- a/uvdat/urls.py +++ b/uvdat/urls.py @@ -25,6 +25,7 @@ RegionViewSet, UserViewSet, VectorDataViewSet, + ViewStateViewSet, ) router = routers.SimpleRouter() @@ -50,6 +51,7 @@ router.register(r"networks", NetworkViewSet, basename="networks") router.register(r"basemaps", BasemapViewSet, basename="basemaps") router.register(r"analytics", AnalyticsViewSet, basename="analytics") +router.register(r"view-states", ViewStateViewSet, basename="view-states") urlpatterns = [ diff --git a/web/components.d.ts b/web/components.d.ts index 94a019a3..c1ea0bac 100644 --- a/web/components.d.ts +++ b/web/components.d.ts @@ -31,6 +31,8 @@ declare module 'vue' { NodeAnimation: typeof import('./src/components/sidebars/NodeAnimation.vue')['default'] ProjectConfig: typeof import('./src/components/projects/ProjectConfig.vue')['default'] RecursiveTable: typeof import('./src/components/RecursiveTable.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] SideBars: typeof import('./src/components/sidebars/SideBars.vue')['default'] SliderNumericInput: typeof import('./src/components/SliderNumericInput.vue')['default'] ToggleCompareMap: typeof import('./src/components/map/ToggleCompareMap.vue')['default'] diff --git a/web/package-lock.json b/web/package-lock.json index f970b29c..39183f24 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -28,6 +28,7 @@ "vue": "^3.2.13", "vue-chartjs": "^5.2.0", "vue-maplibre-compare": "^1.0.26", + "vue-router": "^5.0.3", "vuedraggable": "^4.1.0", "vuetify": "^3.8.0" }, @@ -51,6 +52,22 @@ "vite-plugin-vuetify": "^2.1.1" } }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -70,12 +87,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -85,9 +102,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -4215,6 +4232,61 @@ "vue": "^3.2.25" } }, + "node_modules/@vue-macros/common": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.1.2.tgz", + "integrity": "sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==", + "license": "MIT", + "dependencies": { + "@vue/compiler-sfc": "^3.5.22", + "ast-kit": "^2.1.2", + "local-pkg": "^1.1.2", + "magic-string-ast": "^1.0.2", + "unplugin-utils": "^0.3.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/vue-macros" + }, + "peerDependencies": { + "vue": "^2.7.0 || ^3.2.25" + }, + "peerDependenciesMeta": { + "vue": { + "optional": true + } + } + }, + "node_modules/@vue-macros/common/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@vue-macros/common/node_modules/unplugin-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/@vue/compiler-core": { "version": "3.5.25", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz", @@ -4519,6 +4591,38 @@ "util": "^0.12.5" } }, + "node_modules/ast-kit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz", + "integrity": "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/ast-walker-scope": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.8.3.tgz", + "integrity": "sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "ast-kit": "^2.1.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5076,7 +5180,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "dev": true, "license": "MIT" }, "node_modules/console-browserify": { @@ -5965,7 +6068,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", - "dev": true, "license": "MIT" }, "node_modules/fast-deep-equal": { @@ -6971,6 +7073,18 @@ "node": ">= 10.16.0" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -7050,6 +7164,18 @@ "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", "license": "MIT" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonpath-plus": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", @@ -7150,7 +7276,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz", "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", - "dev": true, "license": "MIT", "dependencies": { "mlly": "^1.7.4", @@ -7220,6 +7345,21 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/magic-string-ast": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-1.0.3.tgz", + "integrity": "sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==", + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.19" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/maplibre-gl": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.7.1.tgz", @@ -7421,7 +7561,6 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", - "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.15.0", @@ -7434,14 +7573,12 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, "license": "MIT" }, "node_modules/mlly/node_modules/pkg-types": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.1.8", @@ -7456,6 +7593,12 @@ "devOptional": true, "license": "MIT" }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "license": "MIT" + }, "node_modules/murmurhash-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", @@ -7871,7 +8014,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/pbf": { @@ -7989,7 +8131,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", - "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.2.2", @@ -8227,7 +8368,6 @@ "version": "0.2.11", "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", - "dev": true, "funding": [ { "type": "individual", @@ -8604,6 +8744,12 @@ "@parcel/watcher": "^2.4.1" } }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "license": "MIT" + }, "node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -9057,7 +9203,6 @@ "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "devOptional": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -9074,7 +9219,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -9092,7 +9236,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=12" @@ -9297,7 +9440,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true, "license": "MIT" }, "node_modules/unplugin": { @@ -9842,6 +9984,160 @@ "vue": "^3.0.0" } }, + "node_modules/vue-router": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.3.tgz", + "integrity": "sha512-nG1c7aAFac7NYj8Hluo68WyWfc41xkEjaR0ViLHCa3oDvTQ/nIuLJlXJX1NUPw/DXzx/8+OKMng045HHQKQKWw==", + "license": "MIT", + "dependencies": { + "@babel/generator": "^7.28.6", + "@vue-macros/common": "^3.1.1", + "@vue/devtools-api": "^8.0.6", + "ast-walker-scope": "^0.8.3", + "chokidar": "^5.0.0", + "json5": "^2.2.3", + "local-pkg": "^1.1.2", + "magic-string": "^0.30.21", + "mlly": "^1.8.0", + "muggle-string": "^0.4.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "scule": "^1.3.0", + "tinyglobby": "^0.2.15", + "unplugin": "^3.0.0", + "unplugin-utils": "^0.3.1", + "yaml": "^2.8.2" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@pinia/colada": ">=0.21.2", + "@vue/compiler-sfc": "^3.5.17", + "pinia": "^3.0.4", + "vue": "^3.5.0" + }, + "peerDependenciesMeta": { + "@pinia/colada": { + "optional": true + }, + "@vue/compiler-sfc": { + "optional": true + }, + "pinia": { + "optional": true + } + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-api": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.0.6.tgz", + "integrity": "sha512-+lGBI+WTvJmnU2FZqHhEB8J1DXcvNlDeEalz77iYgOdY1jTj1ipSBaKj3sRhYcy+kqA8v/BSuvOz1XJucfQmUA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^8.0.6" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-kit": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.0.6.tgz", + "integrity": "sha512-9zXZPTJW72OteDXeSa5RVML3zWDCRcO5t77aJqSs228mdopYj5AiTpihozbsfFJ0IodfNs7pSgOGO3qfCuxDtw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^8.0.6", + "birpc": "^2.6.1", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^2.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-shared": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.0.6.tgz", + "integrity": "sha512-Pp1JylTqlgMJvxW6MGyfTF8vGvlBSCAvMFaDCYa82Mgw7TT5eE5kkHgDvmOGHWeJE4zIDfCpCxHapsK2LtIAJg==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/vue-router/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/vue-router/node_modules/perfect-debounce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", + "license": "MIT" + }, + "node_modules/vue-router/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vue-router/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/vue-router/node_modules/unplugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz", + "integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vue-router/node_modules/unplugin-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/vuedraggable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz", @@ -9897,7 +10193,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "dev": true, "license": "MIT" }, "node_modules/which": { @@ -9971,6 +10266,21 @@ "node": ">=0.4" } }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/web/package.json b/web/package.json index c073ad1d..ec0199c1 100644 --- a/web/package.json +++ b/web/package.json @@ -29,6 +29,7 @@ "vue": "^3.2.13", "vue-chartjs": "^5.2.0", "vue-maplibre-compare": "^1.0.26", + "vue-router": "^5.0.3", "vuedraggable": "^4.1.0", "vuetify": "^3.8.0" }, diff --git a/web/src/App.vue b/web/src/App.vue index dd8f2d52..f4cb2f4e 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -1,6 +1,8 @@