gpw-data-viewer.html 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <!doctype html>
  2. <html>
  3. <meta charset="utf-8">
  4. <head>
  5. <title>gpw data viewer</title>
  6. <style>
  7. canvas {
  8. max-width: calc(100vw - 16px);
  9. }
  10. </style>
  11. </head>
  12. <body>
  13. <canvas></canvas>
  14. </body>
  15. <script>
  16. 'use strict';
  17. async function loadFile(url) {
  18. const req = await fetch(url);
  19. return req.text();
  20. }
  21. function parseData(text) {
  22. const data = [];
  23. const settings = {data};
  24. let max;
  25. let min;
  26. // split into lines
  27. text.split('\n').forEach((line) => {
  28. // split the line by whitespace
  29. const parts = line.trim().split(/\s+/);
  30. if (parts.length === 2) {
  31. // only 2 parts, must be a key/value pair
  32. settings[parts[0]] = parseFloat(parts[1]);
  33. } else if (parts.length > 2) {
  34. // more than 2 parts, must be data
  35. const values = parts.map((v) => {
  36. const value = parseFloat(v);
  37. if (value === settings.NODATA_value) {
  38. return undefined;
  39. }
  40. max = Math.max(max === undefined ? value : max, value);
  41. min = Math.min(min === undefined ? value : min, value);
  42. return value;
  43. });
  44. data.push(values);
  45. }
  46. });
  47. return Object.assign(settings, {min, max});
  48. }
  49. function drawData(file) {
  50. const {min, max, ncols, nrows, data} = file;
  51. const range = max - min;
  52. const ctx = document.querySelector('canvas').getContext('2d');
  53. // make the canvas the same size as the data
  54. ctx.canvas.width = ncols;
  55. ctx.canvas.height = nrows;
  56. // but display it double size so it's not too small
  57. ctx.canvas.style.width = px(ncols * 2);
  58. // fill the canvas to dark gray
  59. ctx.fillStyle = '#444';
  60. ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  61. // draw each data point
  62. data.forEach((row, latNdx) => {
  63. row.forEach((value, lonNdx) => {
  64. if (value === undefined) {
  65. return;
  66. }
  67. const amount = (value - min) / range;
  68. const hue = 1;
  69. const saturation = 1;
  70. const lightness = amount;
  71. ctx.fillStyle = hsl(hue, saturation, lightness);
  72. ctx.fillRect(lonNdx, latNdx, 1, 1);
  73. });
  74. });
  75. }
  76. function px(v) {
  77. return `${v | 0}px`;
  78. }
  79. function hsl(h, s, l) {
  80. return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
  81. }
  82. loadFile('resources/data/gpw/gpw-v4-basic-demographic-characteristics-rev10_a000_014_2010_1_deg_asc/gpw_v4_basic_demographic_characteristics_rev10_a000_014mt_2010_cntm_1_deg.asc')
  83. .then(parseData)
  84. .then(drawData);
  85. </script>
  86. </html>