@@ -296,91 +296,108 @@ function convertCoordinates(x, y) {
296296 }
297297}
298298
299- // Load and parse CSV data
300- function loadData ( ) {
301- showLoading ( 'Loading crash data (190,000+ records)...' ) ;
302-
303- // Load crash data first
304- Papa . parse ( 'data/2012-2024_DATA_SA_Crash.csv' , {
305- download : true ,
306- header : true ,
307- skipEmptyLines : true ,
308- complete : function ( results ) {
309- console . log ( 'Crash CSV loaded. Total rows:' , results . data . length ) ;
310-
311- crashData = results . data . filter ( row => {
312- return row . ACCLOC_X && row . ACCLOC_Y &&
313- row . ACCLOC_X . trim ( ) !== '' &&
314- row . ACCLOC_Y . trim ( ) !== '' ;
315- } ) ;
299+ // Load and decompress JSON data
300+ async function loadData ( ) {
301+ showLoading ( 'Loading crash data...' ) ;
316302
317- console . log ( 'Filtered crash data:' , crashData . length , 'records with coordinates' ) ;
303+ try {
304+ // Fetch gzipped data
305+ const response = await fetch ( 'data/2012-2024_DATA_SA_Crash.json.gz' ) ;
318306
319- // Load casualty data
320- loadCasualtyData ( ) ;
321- } ,
322- error : function ( error ) {
323- console . error ( 'Error loading crash data:' , error ) ;
324- hideLoading ( ) ;
325- alert ( 'Error loading crash data. Please ensure the CSV file is in the correct location.' ) ;
307+ if ( ! response . ok ) {
308+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
326309 }
327- } ) ;
310+
311+ // Get compressed bytes
312+ const compressedData = await response . arrayBuffer ( ) ;
313+
314+ // Decompress with pako.js
315+ const decompressed = pako . inflate ( new Uint8Array ( compressedData ) , { to : 'string' } ) ;
316+
317+ // Parse JSON
318+ const allCrashData = JSON . parse ( decompressed ) ;
319+ console . log ( 'Crash data loaded:' , allCrashData . length , 'total records' ) ;
320+
321+ // Filter crashes with valid coordinates
322+ crashData = allCrashData . filter ( row => {
323+ return row . ACCLOC_X && row . ACCLOC_Y &&
324+ row . ACCLOC_X !== '' && row . ACCLOC_Y !== '' ;
325+ } ) ;
326+
327+ console . log ( 'Filtered crash data:' , crashData . length , 'records with coordinates' ) ;
328+
329+ // Load casualty data
330+ await loadCasualtyData ( ) ;
331+
332+ } catch ( error ) {
333+ console . error ( 'Error loading crash data:' , error ) ;
334+ hideLoading ( ) ;
335+ alert ( 'Error loading crash data. Please check your connection and try again.' ) ;
336+ }
328337}
329338
330339// Load casualty data
331- function loadCasualtyData ( ) {
332- showLoading ( 'Loading casualty data (77,000+ records)...' ) ;
333-
334- Papa . parse ( 'data/2012-2024_DATA_SA_Casualty.csv' , {
335- download : true ,
336- header : true ,
337- skipEmptyLines : true ,
338- complete : function ( results ) {
339- casualtyData = results . data ;
340- console . log ( 'Casualty data loaded:' , casualtyData . length , 'records' ) ;
341-
342- // Load units data
343- loadUnitsData ( ) ;
344- } ,
345- error : function ( error ) {
346- console . error ( 'Error loading casualty data:' , error ) ;
347- hideLoading ( ) ;
348- alert ( 'Error loading casualty data. Please ensure the CSV file is in the correct location.' ) ;
340+ async function loadCasualtyData ( ) {
341+ showLoading ( 'Loading casualty data...' ) ;
342+
343+ try {
344+ const response = await fetch ( 'data/2012-2024_DATA_SA_Casualty.json.gz' ) ;
345+
346+ if ( ! response . ok ) {
347+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
349348 }
350- } ) ;
349+
350+ const compressedData = await response . arrayBuffer ( ) ;
351+ const decompressed = pako . inflate ( new Uint8Array ( compressedData ) , { to : 'string' } ) ;
352+ casualtyData = JSON . parse ( decompressed ) ;
353+
354+ console . log ( 'Casualty data loaded:' , casualtyData . length , 'records' ) ;
355+
356+ // Load units data
357+ await loadUnitsData ( ) ;
358+
359+ } catch ( error ) {
360+ console . error ( 'Error loading casualty data:' , error ) ;
361+ hideLoading ( ) ;
362+ alert ( 'Error loading casualty data. Please check your connection and try again.' ) ;
363+ }
351364}
352365
353366// Load units data
354- function loadUnitsData ( ) {
355- showLoading ( 'Loading units data (407,000+ records) ...' ) ;
367+ async function loadUnitsData ( ) {
368+ showLoading ( 'Loading units data...' ) ;
356369
357- Papa . parse ( 'data/2012-2024_DATA_SA_Units.csv' , {
358- download : true ,
359- header : true ,
360- skipEmptyLines : true ,
361- complete : function ( results ) {
362- unitsData = results . data ;
363- console . log ( 'Units data loaded:' , unitsData . length , 'records' ) ;
370+ try {
371+ const response = await fetch ( 'data/2012-2024_DATA_SA_Units.json.gz' ) ;
364372
365- // Link data together
366- linkCrashData ( ) ;
373+ if ( ! response . ok ) {
374+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
375+ }
367376
368- // Populate filter dropdowns
369- populateFilterOptions ( ) ;
377+ const compressedData = await response . arrayBuffer ( ) ;
378+ const decompressed = pako . inflate ( new Uint8Array ( compressedData ) , { to : 'string' } ) ;
379+ unitsData = JSON . parse ( decompressed ) ;
370380
371- // Initialise marker colour legend with the default (severity) mode
372- updateMarkerColorLegend ( ) ;
381+ console . log ( 'Units data loaded:' , unitsData . length , 'records' ) ;
373382
374- // Load LGA boundaries first, then apply filters
375- // This ensures LGA assignments are complete before map is displayed
376- loadLGABoundaries ( ) ;
377- } ,
378- error : function ( error ) {
379- console . error ( 'Error loading units data:' , error ) ;
380- hideLoading ( ) ;
381- alert ( 'Error loading units data. Please ensure the CSV file is in the correct location.' ) ;
382- }
383- } ) ;
383+ // Link data together
384+ linkCrashData ( ) ;
385+
386+ // Populate filter dropdowns
387+ populateFilterOptions ( ) ;
388+
389+ // Initialise marker colour legend with the default (severity) mode
390+ updateMarkerColorLegend ( ) ;
391+
392+ // Load LGA boundaries first, then apply filters
393+ // This ensures LGA assignments are complete before map is displayed
394+ loadLGABoundaries ( ) ;
395+
396+ } catch ( error ) {
397+ console . error ( 'Error loading units data:' , error ) ;
398+ hideLoading ( ) ;
399+ alert ( 'Error loading units data. Please check your connection and try again.' ) ;
400+ }
384401}
385402
386403// Link casualty and units data to crashes by REPORT_ID
@@ -593,10 +610,8 @@ function loadSuburbBoundaries(filePath = 'data/sa_suburbs.geojson') {
593610}
594611
595612// Pre-compute LGA assignments for crashes with missing/N/A LGA names
596- // Note: LGA assignments are now pre-computed in the CSV file (see scripts/add_lga_column.py)
597- // This function now just applies filters immediately without client-side computation
598613function precomputeLGAAssignments ( ) {
599- console . log ( 'Using pre-computed LGA assignments from CSV ' ) ;
614+ console . log ( 'Using pre-computed LGA assignments' ) ;
600615
601616 // Count how many crashes have LGA assignments
602617 const withLGA = crashData . filter ( row => row [ 'LGA' ] && row [ 'LGA' ] . trim ( ) ) . length ;
@@ -787,7 +802,12 @@ function getFullLGAName(abbreviatedName) {
787802// Returns unique, alphabetically-sorted, non-empty values for a column
788803function uniqueValues ( data , column ) {
789804 return [ ...new Set ( data . map ( row => row [ column ] ) . filter ( v => v ) ) ]
790- . sort ( ( a , b ) => a . localeCompare ( b ) ) ;
805+ . sort ( ( a , b ) => {
806+ // Handle both strings and numbers
807+ const aStr = String ( a ) ;
808+ const bStr = String ( b ) ;
809+ return aStr . localeCompare ( bStr ) ;
810+ } ) ;
791811}
792812
793813// Appends <option> elements to a <select> element
@@ -1847,7 +1867,7 @@ function getMarkerIcon(row) {
18471867function addMarkers ( callback ) {
18481868 markersLayer . clearLayers ( ) ;
18491869
1850- const chunkSize = 2000 ; // Process 2000 markers per chunk
1870+ const chunkSize = 20000 ;
18511871 const totalMarkers = filteredData . length ;
18521872 let processedCount = 0 ;
18531873
@@ -2034,7 +2054,7 @@ function addChoropleth() {
20342054 const lgaCountsNormalized = { } ;
20352055
20362056 filteredData . forEach ( row => {
2037- // Use pre-computed LGA from CSV
2057+ // Use pre-computed LGA
20382058 const lga = row [ 'LGA' ] ;
20392059
20402060 if ( lga && lga . trim ( ) ) {
0 commit comments