Bladeren bron

⚡️ 🐛 fix display of pop-ups

this change also improves performace by pre-caching values
instead of a search in 6.5k long array
jmacura 4 jaren geleden
bovenliggende
commit
81f089ca3c
3 gewijzigde bestanden met toevoegingen van 80 en 50 verwijderingen
  1. 56 41
      src/adjuster/adjuster.service.ts
  2. 17 8
      src/app.config.ts
  3. 7 1
      src/app.service.ts

+ 56 - 41
src/adjuster/adjuster.service.ts

@@ -175,10 +175,15 @@ export class AdjusterService {
       .toPromise()
       .then((data: any) => {
         console.log('data received', data);
-        let logs = 0;
+        //let logs = 0;
         let errs = 0;
         const clusterData = data.response;
-        console.log(obceIndexLayer);
+        // Store relation between region and its data in a hash-table-like structure
+        // more memory consuming, but much faster then find()
+        const codeRecordRelations = {};
+        clusterData.forEach((c) => {
+          codeRecordRelations[c.lau2] = c;
+        });
         /*let sublayers = [];
           const oldSublayers = obceLayer.get('Layer');
           if (oldSublayers !== undefined && Array.isArray(oldSublayers)) {
@@ -202,39 +207,52 @@ export class AdjusterService {
             i++;
           }*/
         console.time('forEach-Cluster');
-        obce.forEachFeature((feature) => {
-          // Pair each feature with its clustering data
-          const featureData = clusterData.find(
-            // NOTE: Do NOT add triple equal sign!
-            (item) => item['lau2'] == feature.get('nationalCode')
-          );
-          if (!featureData) {
-            if (errs < 20) {
-              errs++;
-              console.warn(
-                `No data for feature ${feature.get('nationalCode')}`
-              );
-              console.log(feature);
-            }
-            return;
-          }
-          logs++;
-          if (logs % 100 == 0) {
-            console.log(`processed ${logs} items`);
-          }
-          Object.keys(featureData).forEach(function (key, index) {
-            if (key !== 'lau2') {
-              feature.set(key, featureData[key], true);
+        for (const method of this.methods) {
+          method.layer.getSource().forEachFeature((feature) => {
+            // Pair each feature with its clustering data
+            const featureData =
+              codeRecordRelations[feature.get('nationalCode')];
+            /*const featureData = clusterData.find(
+              // NOTE: Do NOT add triple equal sign!
+              (item) => item['lau2'] == feature.get('nationalCode')
+            );*/
+            if (!featureData) {
+              if (errs < 20) {
+                errs++;
+                console.warn(
+                  `No data for feature ${feature.get('nationalCode')}`
+                );
+                console.log(feature);
+              }
+              return;
             }
+            /*logs++;
+            if (logs % 100 == 0) {
+              console.log(`processed ${logs} items`);
+            }*/
+            feature.set(method.codename, featureData[method.codename], true);
+            /*Object.keys(featureData).forEach(function (key, index) {
+              if (key !== 'lau2') {
+                feature.set(key, featureData[key], true);
+              }
+            });*/
           });
-        });
+          // Since we are updating the features silently, we now have to refresh manually
+          method.layer.getSource().getFeatures()[0].dispatchEvent('change');
+        }
         //const clusters = [];
         //const obceFeatures: Array<any> = obce.getFeatures();
-        /*for (const region of clusterData) {
-            if (!clusters.includes(region[this.method])) {
-              clusters.push(region[this.method]);
-            }
-            const feature = obceFeatures.find(
+        // Array of arrays
+        /*const methodsFeatures = this.methods.map((m) =>
+          m.layer.getSource().getFeatures()
+        );
+        for (const region of clusterData) {
+          //if (!clusters.includes(region[this.method])) {
+          //  clusters.push(region[this.method]);
+          //}
+          for (const features of methodsFeatures) {
+
+            const feature = features.find(
               // NOTE: Do NOT add triple equal sign!
               (f) => f.get('nationalCode') == region['lau2']
             );
@@ -246,24 +264,21 @@ export class AdjusterService {
               }
               continue;
             }
-            logs++;
-            if (logs % 100 == 0) {
-              console.log(`processed ${logs} items`);
-            }
             Object.keys(region).forEach(function (key, index) {
               if (key !== 'lau2') {
                 feature.set(key, region[key], true);
               }
             });
-            if (logs % 100 == 0) {
-              //sublayers[0].getSource().addFeature(feature);
-            }
-            //sublayers[region[this.method] - 1].getSource().addFeature(feature);
-          }*/
+          }
+          logs++;
+          if (logs % 100 == 0) {
+            console.log(`processed ${logs} items`);
+          }
+          //sublayers[region[this.method] - 1].getSource().addFeature(feature);
+        }*/
         //obceLayer.set('Layer', sublayers);
         //this.hsLayerMetadataService.fillMetadata(obceLayer);
         //console.log(sublayers[0].getSource().getFeatures());
-        obce.getFeatures()[0].dispatchEvent('change');
         console.timeEnd('forEach-Cluster');
         console.log('clustering done!');
         //this.clusters = clusters;

+ 17 - 8
src/app.config.ts

@@ -58,7 +58,11 @@ function perc2color(perc) {
   return `rgba(${r}, ${g}, ${b}, 0.7)`;
 }
 
-const indexStyle = function (feature) {
+const decimal2prettyPerc = (x) => {
+  return `${(x * 100).toFixed(2)}&nbsp;%`;
+};
+
+const indexStyle = (feature) => {
   if (isNaN(feature.get('aggregate'))) {
     return [
       new Style({
@@ -96,19 +100,24 @@ export const obceIndexLayer = new VectorLayer({
 });
 obceIndexLayer.set('popUp', {
   attributes: [
-    {attribute: 'text', label: 'Název'},
     {
       attribute: 'aggregate',
       label: 'index',
-      displayFunction: (x) => {
-        return `${(x * 100).toFixed(2)}&nbsp;%`;
-      },
+      displayFunction: decimal2prettyPerc,
+    },
+    {
+      attribute: 'Konec chudoby',
+      displayFunction: decimal2prettyPerc,
     },
-    'Social & Human', //TODO: factors?
+    'Zdraví a kvalitní život',
+    'Kvalitní vzdělání',
+    'Důstojná práce a ekonomický růst',
+    'Udržitelná města a obce',
+    'Ostatní',
   ],
 });
 obceIndexLayer.set('editable', false);
-obceIndexLayer.set('queryable', false);
+//obceIndexLayer.set('queryable', false);
 
 const okresyStyle = new Style({
   stroke: new Stroke({
@@ -177,7 +186,7 @@ export const AppConfig = {
   panelsEnabled: {
     composition_browser: false,
     feature_crossfilter: false,
-    info: false,
+    info: true,
     saveMap: false,
     sensors: false,
     tracking: false,

+ 7 - 1
src/app.service.ts

@@ -2,7 +2,9 @@ import hsv2rgb from 'hsv2rgb';
 import {Feature} from 'ol';
 import {Fill, Stroke, Style} from 'ol/style';
 import {Injectable} from '@angular/core';
+import {TopoJSON} from 'ol/format';
 import {Vector as VectorLayer} from 'ol/layer';
+import {Vector as VectorSource} from 'ol/source';
 
 import {HsConfig} from 'hslayers-ng/config.service';
 import {HsEventBusService} from 'hslayers-ng/components/core/event-bus.service';
@@ -80,7 +82,11 @@ export class AppService {
   prepareLayers(): void {
     for (const method of this.adjusterService.methods) {
       method.layer = new VectorLayer({
-        source: obce,
+        source: new VectorSource({
+          format: new TopoJSON({dataProjection: 'EPSG:5514'}),
+          url: require('./data/obce_cr_20210310_5p_5514.topojson').default,
+          overlaps: false,
+        }),
         editor: {editable: false},
         visible: true,
         style: this.generateStyle(method.codename),