Toamnă 🍂

3 min read

#30DayMapChallenge Ziua 2. Linii

Toamnă – colorarea râurilor după ordinea de curgere în QGIS 🍂

linii

Iată una dintre hărțile pe care le-am făcut pentru #30DayMapChallenge de pe Twitter în 2021. Puteți afla mai multe despre provocare și celelalte hărți ale mele în această postare.

Scop: O hartă cu linii.

Live: https://maptheclouds.com/playground/30-day-map-challenge/lines/

Tweet: https://twitter.com/maptheclouds/status/1455593450720595984

Cod: https://github.com/alexaac/map-challenges/tree/master/lines

Descriere:

Vizualizarea arată rețeaua și zona de captare de râuri din Yosemite Valley, și este creată prin colorarea râurilor după ordinaea de curgere folosind QGIS.

Date: OpenTopography

Tag-uri: #D3js #QGIS #mapshaper #canvas #LiDAR #hidrology #river #channels

Inspirație:

https://observablehq.com/@jipexu/chinese-rivers
https://www.youtube.com/watch?v=xwiHQlmEEjw
https://angrytools.com/gradient/

Provocări: Pentru această hartă aveam deja modelul digital de elevație pentru Yosemite, derivat din fișiere LiDAR descărcate de pe OpenTopography.

Am avut ocazia să fac niște analiză GIS în QGIS, să mă joc cu stilurile și gradientele în JavaScript și CSS, și să vizualizez rezultatele în browser.

Am folosit QGIS pentru a extrage rețeaua de râuri (puteți urmări un tutorial care explică cum se face asta, ‘Deriving River Network & Catchments from a DEM using QGIS’), și le-am afișat pe hartă în browser folosind D3.js și Canvas.

Ce este interesant la această hartă este obținerea efectului de frunze, pornind de la setarea unui fillStyle pentru liniile ce reprezintă râurile, și gradient-ul ce simbolizează cerul. Am colorat frunzele după ordinul râurilor, cu excepția râului principal.

// Color scale
colorScale = d3
  .scaleQuantile()
  .domain([0, 1, 2, 3, 4, 5, 6, 7])
  .range([
    '#1b251d',
    '#403310',
    '#8e6035',
    '#99700a',
    '#ad8a38',
    '#be903b',
    '#feef8b',
  ]);

[...]

    if (river.properties.ORDER > 1) {
      context.fillStyle = colorScale(river.properties.ORDER);
      context.fill();
    }

Am creat gradientele pentru trei elemente din pagină, în titlu, pentru legendă și ca un background pentru hartă.

Iată cum am obținut gradientul din titlu, ca background pentru simbolul de tip unicode, folosind CSS:

.sky {
  padding: 0.5rem;

  /* ff 3.6+ */
  background: -moz-radial-gradient(
    ellipse at 91% 15%,
    #67afee 0%,
    #158fc2 25%,
    #288ce2 50%,
    #096cc4 75%,
    #1262ad 100%
  );

  /* safari 5.1+,chrome 10+ */
  background: -webkit-radial-gradient(
    ellipse at 91% 15%,
    #67afee 0%,
    #158fc2 25%,
    #288ce2 50%,
    #096cc4 75%,
    #1262ad 100%
  );

  /* opera 11.10+ */
  background: -o-radial-gradient(
    ellipse at 91% 15%,
    #67afee 0%,
    #158fc2 25%,
    #288ce2 50%,
    #096cc4 75%,
    #1262ad 100%
  );

  /* ie 10+ */
  background: -ms-radial-gradient(
    ellipse at 91% 15%,
    #67afee 0%,
    #158fc2 25%,
    #288ce2 50%,
    #096cc4 75%,
    #1262ad 100%
  );

  /* global 92%+ browsers support */
  background: radial-gradient(
    ellipse at 91% 15%,
    #67afee 0%,
    #158fc2 25%,
    #288ce2 50%,
    #096cc4 75%,
    #1262ad 100%
  );
}

Aici este codul pentru crearea gradientului pentru legendă, folosind D3.js:

// Add sky gradient
  const defs = svg.append('defs');

  const gradient = defs
    .append('radialGradient')
    .attr('id', 'svgGradient')
    .attr('cx', '50%')
    .attr('cy', '50%')
    .attr('r', '50%')
    .attr('y1', '0%');

  gradient
    .append('stop')
    .attr('offset', '0%')
    .attr('style', 'stop-color:rgb(21,143,194);stop-opacity:1.00');
  gradient
    .append('stop')
    .attr('offset', '50%')
    .attr('style', 'stop-color:rgb(40,140,226);stop-opacity:1.00');

  mapLegend
    .append('rect')
    .attr('x', 0)
    .attr('y', -20)
    .attr('width', 150)
    .attr('height', 300)
    .style('fill', 'url(#svgGradient)')
    .style('stroke', '#dddddd');

Iar aici este codul pentru crearea fundalului hărții:

  // Background
  const grad = context.createRadialGradient(408, 216, 0, 408, 216, 427.8);

  grad.addColorStop(0, 'rgba(103, 175, 238, 1)');
  grad.addColorStop(0.25, 'rgba(21, 143, 194, 1)');
  grad.addColorStop(0.5, 'rgba(40, 140, 226, 1)');
  grad.addColorStop(0.75, 'rgba(9, 108, 196, 1)');
  grad.addColorStop(1, 'rgba(18, 98, 173, 1)');

  context.fillStyle = grad;
  context.fillRect(0, 0, width, height);

Inițial se putea da zoom și pan, dar pentru că imaginea era prea mare, se încărca greu, și nu am vrut să tratez acest aspect, am adăugat o imagine de rezervă pe pagină. Dacă aveți răbdare, poate veți vedea și harta interactivă pe pagină, după un timp. 🙂

TODO: să creez tile-uri și să afișez detalii în funcție de nivelul de zoom, să repar pan-ul.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *