Browse Source

✨ use new CZ API calls

+bug fixes
+decreased topojson file size
jmacura 4 years ago
parent
commit
861acc3030

+ 3 - 3
src/adjuster/adjuster.directive.html

@@ -1,5 +1,5 @@
 <div [hidden]="!isVisible()" class="card mainpanel">
-    <hs-panel-header name="adjuster" [title]="'Adjust factors'"></hs-panel-header>
+    <hs-panel-header name="adjuster" [title]="'Vyladit faktory'"></hs-panel-header>
     <style>
         .weather-table>tbody>tr>td,
         .table-condensed>tbody>tr>th,
@@ -15,9 +15,9 @@
                 <div *ngFor="let factor of adjusterService.factors">
                     <div class="d-flex flex-row">
                         <div class="p-2 flex-grow-1">
-                            <label>{{factor.factor}}</label>
+                            <label>{{factor.name}}</label>
                         </div>
-                        <div class="p-2">{{(factor.weight * 100).toFixed(0)}}%</div>
+                        <div class="p-2">{{(factor.weight * 100).toFixed(0)}}&nbsp;%</div>
                     </div>
                     <input type="range" class="custom-range" (change)="adjusterService.apply()" [(ngModel)]="factor.weight" min="0" max="1.0" step="0.05">
                 </div>

+ 124 - 100
src/adjuster/adjuster.service.ts

@@ -8,53 +8,135 @@ import {obce} from '../app.config';
 
 @Injectable({providedIn: 'root'})
 export class AdjusterService {
+  serviceBaseUrl: string;
   nutsCodeRecordRelations = {};
-  attractivity;
-  factors: any = [
-    {
-      name: 'Natural',
-      column: 'N_index',
-      weight: 1,
-    },
-    {
-      name: 'Social & Human',
-      column: 'S_index',
-      weight: 1,
-    },
-    {
-      name: 'Anthropic',
-      column: 'A_index',
-      weight: 1,
-    },
-    {
-      name: 'Economical',
-      column: 'E_index',
-      weight: 1,
-    },
-    {
-      name: 'Cultural',
-      column: 'C_index',
-      weight: 1,
-    },
-    {
-      name: 'Institutional',
-      column: 'I_index',
-      weight: 1,
-    },
-  ];
+  //attractivity;
+  factors: any = [];
 
-  constructor(public HsUtilsService: HsUtilsService, public $http: HttpClient) {
+  constructor(public hsUtilsService: HsUtilsService, public $http: HttpClient) {
+    this.serviceBaseUrl =
+      window.location.hostname === 'localhost'
+        ? 'http://localhost:3000/' // 'https://jmacura.ml/ws/'
+        : 'https://publish.lesprojekt.cz/nodejs/';
+    this.init();
+  }
+
+  /**
+   * Sends a request to polirural-attractiveness-service
+   * and applies the returned values
+   */
+  apply(): void {
+    const f = () => {
+      this.$http
+        .post(this.serviceBaseUrl + 'scores/cz', {
+          factors: this.factors.map((f) => {
+            return {
+              factor: f.name,
+              weight: f.weight,
+              datasets: f.datasets
+                .filter((ds) => ds.included)
+                .map((ds) => ds.name),
+            };
+          }),
+        })
+        .toPromise()
+        .then((attractivenessData: any) => {
+          console.log(attractivenessData);
+          //this.attractivity = attractivenessData;
+          /*let max = 0;
+          attractivenessData.forEach((a) => {
+            if (a.aggregate > max) {
+              max = a.aggregate;
+            }
+          });*/
+          const max = Math.max(
+            ...attractivenessData.map((a) => a.aggregate),
+            0
+          );
+          const normalizer = 1 / max;
+          attractivenessData.forEach((a) => {
+            a.aggregate *= normalizer;
+          });
+          const codeRecordRelations = {};
+          attractivenessData.forEach((a) => {
+            codeRecordRelations[a.code] = a;
+          });
+          let errs = 0;
+          let logs = 0;
+          console.time('forEachObce');
+          obce.forEachFeature((feature) => {
+            // Pair each feature with its attractivity data
+            const featureData =
+              codeRecordRelations[feature.get('nationalCode')];
+            /*const featureData = attractivenessData.find(
+              // NOTE: Do NOT add triple equal sign!
+              (item) => item['code'] == feature.get('nationalCode')
+            );*/
+            if (!featureData && 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((key, index) => {
+              if (key !== 'lau2') {
+                feature.set(key, featureData[key]);
+              }
+            });
+            /*feature.set(
+              'total',
+              this.nutsCodeRecordRelations[feature.get('nationalCode')]
+                .aggregate
+            );*/
+            /*feature.set(
+              'totalForHumans',
+              (
+                this.nutsCodeRecordRelations[feature.get('nationalCode')]
+                  .aggregate * 100
+              ).toFixed(2)
+            );*/
+            /*this.factors.forEach((factor) => {
+              feature.set(
+                factor.name,
+                (
+                  this.nutsCodeRecordRelations[feature.get('nationalCode')][
+                    factor.name
+                  ] * 100
+                ).toFixed(2)
+              );
+            });*/
+          });
+          console.timeEnd('forEachObce');
+        })
+        .catch((error) => {
+          console.warn(`Error obtaining data from ${this.serviceBaseUrl}.`);
+          console.log(error);
+        });
+    };
+    this.hsUtilsService.debounce(f, 300, false, this)();
+  }
+
+  init(): void {
     this.$http
-      .get('https://publish.lesprojekt.cz/nodejs/datasets')
+      .get(this.serviceBaseUrl + 'datasets/cz')
       .toPromise()
       .then((data: any) => {
         this.factors = data.map((dataset) => {
-          return {factor: dataset.Factor, weight: 1, datasets: []};
+          return {name: dataset.Factor, weight: 1, datasets: []};
         });
-        this.factors = HsUtilsService.removeDuplicates(this.factors, 'factor');
+        this.factors = this.hsUtilsService.removeDuplicates(
+          this.factors,
+          'name'
+        );
         this.factors.forEach((factor) => {
           factor.datasets = data
-            .filter((ds) => ds.Factor === factor.factor)
+            .filter((ds) => ds.Factor === factor.name)
             .map((ds) => {
               return {
                 name: ds.Name,
@@ -63,68 +145,10 @@ export class AdjusterService {
             });
         });
         this.apply();
+      })
+      .catch((error) => {
+        console.warn(`Web service at ${this.serviceBaseUrl} unavailable!`);
+        console.log(error);
       });
   }
-
-  apply() {
-    this.HsUtilsService.debounce(
-      function () {
-        this.$http
-          .post('https://publish.lesprojekt.cz/nodejs/scores', {
-            factors: this.factors.map((f) => {
-              return {
-                factor: f.factor,
-                weight: f.weight,
-                datasets: f.datasets
-                  .filter((ds) => ds.included)
-                  .map((ds) => ds.name),
-              };
-            }),
-          })
-          .toPromise()
-          .then((data: any) => {
-            this.attractivity = data;
-            let max = 0;
-            this.attractivity.forEach((a) => {
-              if (a.aggregate > max) {
-                max = a.aggregate;
-              }
-            });
-            const normalizer = 1 / max;
-            this.attractivity.forEach((a) => {
-              a.aggregate *= normalizer;
-            });
-            this.attractivity.forEach((a) => {
-              this.nutsCodeRecordRelations[a.code] = a;
-            });
-            obce.forEachFeature((feature) => {
-              feature.set(
-                'total',
-                this.nutsCodeRecordRelations[feature.get('NUTS_ID')].aggregate
-              );
-              feature.set(
-                'totalForHumans',
-                (
-                  this.nutsCodeRecordRelations[feature.get('NUTS_ID')]
-                    .aggregate * 100
-                ).toFixed(2)
-              );
-              this.factors.forEach((factor) => {
-                feature.set(
-                  factor.factor,
-                  (
-                    this.nutsCodeRecordRelations[feature.get('NUTS_ID')][
-                      factor.factor
-                    ] * 100
-                  ).toFixed(2)
-                );
-              });
-            });
-          });
-      },
-      300,
-      false,
-      this
-    )();
-  }
 }

+ 34 - 24
src/app.config.ts

@@ -49,7 +49,7 @@ function perc2color(perc) {
 }
 
 const styles = function (feature) {
-  if (isNaN(feature.get('total'))) {
+  if (isNaN(feature.get('aggregate'))) {
     return [
       new Style({
         fill: new Fill({
@@ -62,7 +62,7 @@ const styles = function (feature) {
     return [
       new Style({
         fill: new Fill({
-          color: perc2color(feature.get('total')),
+          color: perc2color(feature.get('aggregate')),
         }),
         stroke: stroke,
       }),
@@ -72,33 +72,37 @@ const styles = function (feature) {
 
 export const obce = new VectorSource({
   format: new TopoJSON({dataProjection: 'EPSG:5514'}),
-  url: require('./data/obce_cr_20210310_15p_5514.topojson').default,
+  url: require('./data/obce_cr_20210310_5p_5514.topojson').default,
   overlaps: false,
 });
 
 const obceLayer = new VectorLayer({
   source: obce,
+  editor: {editable: false},
   visible: true,
   style: styles,
   title: 'Obce ČR',
+  attributions: ['CC-BY ČÚZK, 2021'],
 });
-obceLayer.set('hoveredKeys', [
-  'NUTS_NAME',
-  'totalForHumans',
-  'Social & Human',
-  'Anthropic',
-  'Institutional',
-  'Economical',
-  'Natural',
-  'Cultural',
-]);
-obceLayer.set('hoveredKeysTranslations', {
-  NUTS_NAME: 'Name',
-  totalForHumans: 'Calculated score',
+obceLayer.set('popUp', {
+  attributes: [
+    {attribute: 'text', label: 'Název'},
+    {attribute: 'nationalCode', label: 'LAU2 code'},
+    {
+      attribute: 'aggregate',
+      label: 'RAI',
+      displayFunction: (x) => {
+        return `${(x * 100).toFixed(2)}&nbsp;%`;
+      },
+    },
+    'Social & Human', //TODO: factors?
+  ],
 });
+obceLayer.set('editable', false);
+//obceLayer.set('queryable', false);
 
 export const AppConfig = {
-  proxyPrefix: '../8085/',
+  //proxyPrefix: '../8085/',
   default_layers: [
     new Tile({
       source: new OSM(),
@@ -109,11 +113,12 @@ export const AppConfig = {
     }),
     obceLayer,
   ],
+  popUpDisplay: 'hover',
   project_name: 'erra/map',
   default_view: new View({
     projection: sjtskProjection,
     center: transform([15.628, 49.864249], 'EPSG:4326', 'EPSG:5514'),
-    zoom: 7,
+    zoom: 7.6,
     units: 'm',
   }),
   advanced_form: true,
@@ -128,15 +133,20 @@ export const AppConfig = {
   },
   panelWidths: {},
   panelsEnabled: {
-    language: false,
     composition_browser: false,
-    legend: false,
-    ows: false,
+    feature_crossfilter: false,
     info: false,
     saveMap: false,
+    sensors: false,
+    tracking: false,
+    routing: false,
+    permalink: false,
+    language: false,
+    legend: false,
+    feature_table: false,
     draw: false,
   },
-  searchProvider: (q) => {
-    return `/app/jupyter-test/8085/search/?q=${q}`;
-  },
+  sizeMode: 'fullscreen',
 };
+
+export default AppConfig;

File diff suppressed because it is too large
+ 0 - 0
src/data/obce_cr_20210310_15p_5514.topojson


File diff suppressed because it is too large
+ 0 - 0
src/data/obce_cr_20210310_5p_5514.topojson


Some files were not shown because too many files changed in this diff