Переглянути джерело

✨ allow to select field in the map

jmacura 4 роки тому
батько
коміт
3c503fe055

+ 2 - 2
src/app/app.component.ts

@@ -92,7 +92,7 @@ export class AppComponent {
       ],
       default_view: new View({
         projection: this.sjtskProjection,
-        center: transform([16.944, 49.228], 'EPSG:4326', 'EPSG:5514'),
+        center: transform([16.964, 49.248], 'EPSG:4326', 'EPSG:5514'),
         zoom: 14,
       }),
       /* Use hslayers-server if you need to proxify your requests to other services. See https://www.npmjs.com/package/hslayers-server */
@@ -147,7 +147,7 @@ export class AppComponent {
             sld: fieldSld,
             //path: 'User generated',
           },
-          source: this.fieldService.field,
+          source: this.fieldService.fields,
         }),
       ],
       translationOverrides: i18n,

+ 3 - 0
src/app/calculator/calculator.component.html

@@ -3,6 +3,9 @@
   <div class="card-body">
     <div class="p-2 center-block">
       <!-- FIELD & INDEX SELECTION PART -->
+      <div [hidden]="!noFieldSelected()">
+        <p class="p-1 text-info">{{ 'CALCULATOR.selectField' | translate}}</p>
+      </div>
       <div>
         {{ 'CALCULATOR.selectIndex' | translate}}:&emsp;
         <select class="form-select" [(ngModel)]="data.selectedProduct">

+ 1 - 4
src/app/calculator/calculator.component.ts

@@ -44,14 +44,11 @@ export class CalculatorComponent implements HsPanelComponent {
   }
 
   getDates() {
-    //TODO: temporary hard-coded hack
-    this.fieldService.selectedField = this.fieldService.field;
     this.calcService.getDates({product: this.data.selectedProduct});
   }
 
   getZones() {
-    //TODO: temporary hard-coded hack
-    this.fieldService.selectedField = this.fieldService.field1GeoJSON;
+    console.log(this.fieldService.selectedField);
     this.calcService.getZones({
       product: this.data.selectedProduct,
     });

+ 1 - 1
src/app/calculator/calculator.service.ts

@@ -93,7 +93,7 @@ export class CalculatorService {
             product,
             date: this.selectedDate,
             format: 'geojson',
-            geometry: this.fieldService.selectedField,
+            geometry: this.fieldService.getSelectedFieldGeoJSON(),
           },
           {
             headers: {

+ 95 - 8
src/app/calculator/field.service.ts

@@ -1,14 +1,16 @@
 import {Injectable} from '@angular/core';
 
 import {GeoJSON} from 'ol/format';
-import {Geometry} from 'ol/geom';
+import {Geometry, Polygon} from 'ol/geom';
 import {Vector as VectorSource} from 'ol/source';
 import {getCenter} from 'ol/extent';
 import {transform} from 'ol/proj';
 
+import {HsEventBusService, HsMapService} from 'hslayers-ng';
+
 @Injectable({providedIn: 'root'})
 export class FieldService {
-  field: VectorSource<Geometry>;
+  fields: VectorSource<Geometry>;
   //TODO: temporarry hard-coded hack
   field1GeoJSON = {
     type: 'Polygon',
@@ -25,12 +27,58 @@ export class FieldService {
       ],
     ],
   };
-  //[[[17.01403296191603, 49.24858329768389], [17.014029303734432, 49.24849340104692], [17.01389198448605, 49.2484957958039], [17.013754665219444, 49.24849819039773], [17.013751007554088, 49.248408293744056], [17.013613688518262, 49.24841068816722], [17.013476369464207, 49.24841308242727], [17.013469055184203, 49.248233289084894], [17.01333173660994, 49.24823568316671], [17.01319441801745, 49.24823807708539], [17.013183448228144, 49.24796838701452], [17.013320766073623, 49.24796599311847], [17.01331710926463, 49.247876096432506], [17.013729061944726, 49.24786891378824], [17.01373271950072, 49.24795881045155], [17.0138700372733, 49.24795641590298], [17.013873695096525, 49.24804631255717], [17.014285649051903, 49.24803912791008], [17.014281990481678, 49.247949231278554], [17.014419308181342, 49.247946836077475], [17.014422967000566, 49.24803673270145], [17.015246874309636, 49.24802235802403], [17.015384192130647, 49.24801996167353], [17.01540249521542, 49.24846944450495], [17.01526517614939, 49.248471840893245], [17.01526151574496, 49.24838194432262], [17.015124196909692, 49.24838434054022], [17.015127857065117, 49.248474237118394], [17.01457858054565, 49.248483820387705], [17.014582239723282, 49.248573716994485], [17.01403296191603, 49.24858329768389]]]};
+  //TODO: temporarry hard-coded hack
+  field2GeoJSON = {
+    type: 'Polygon',
+    coordinates: [
+      [
+        [17.002437217427214, 49.25406053771264],
+        [17.007010834533514, 49.25949599987935],
+        [17.00652649276053, 49.26616621617807],
+        [16.994875655608688, 49.25981844649525],
+        [16.995730316423206, 49.257965703041684],
+        [17.002437217427214, 49.25406053771264],
+      ],
+    ],
+  };
+  //TODO: temporarry hard-coded hack
+  field3GeoJSON = {
+    type: 'Polygon',
+    coordinates: [
+      [
+        [16.993895078820575, 49.259216136348286],
+        [16.994671522235812, 49.257860846173166],
+        [17.00155277758227, 49.25349827686348],
+        [16.99702124804218, 49.246825312276215],
+        [16.993862809154038, 49.243797217302074],
+        [16.97947178114977, 49.24513873718192],
+        [16.980782403841776, 49.246567855409126],
+        [16.980234692917616, 49.251993865297734],
+        [16.982332050970445, 49.25428043019449],
+        [16.98326065796653, 49.25618643740068],
+        [16.99037376067523, 49.25783927642802],
+        [16.993895078820575, 49.259216136348286],
+      ],
+    ],
+  };
+  selectableLayers = ['Farma'];
   selectedField;
 
-  constructor() {
+  constructor(
+    private hsEventBus: HsEventBusService,
+    private hsMapService: HsMapService
+  ) {
+    this.hsEventBus.vectorQueryFeatureSelection.subscribe((data) => {
+      if (
+        !this.isValidGeometry(data.feature) ||
+        !this.isValidLayer(data.feature)
+      ) {
+        return;
+      }
+      this.selectedField = data.feature.getGeometry() as Polygon;
+    });
     //TODO: temporary hard-coded hack
-    this.field = new VectorSource({
+    this.fields = new VectorSource({
       features: [
         new GeoJSON().readFeature(this.field1GeoJSON, {
           dataProjection: 'EPSG:4326',
@@ -38,15 +86,25 @@ export class FieldService {
         }),
       ],
     });
-    //TODO: temporary hard-coded hack
-    this.selectedField = this.field;
+    this.fields.addFeatures([
+      new GeoJSON().readFeature(this.field2GeoJSON, {
+        dataProjection: 'EPSG:4326',
+        featureProjection: 'EPSG:5514',
+      }),
+    ]);
+    this.fields.addFeatures([
+      new GeoJSON().readFeature(this.field3GeoJSON, {
+        dataProjection: 'EPSG:4326',
+        featureProjection: 'EPSG:5514',
+      }),
+    ]);
   }
 
   noFieldSelected(): boolean {
     return this.selectedField === undefined;
   }
 
-  getCentroidOfField(field) {
+  getCentroidOfField(field: Geometry) {
     return {
       type: 'Point',
       coordinates: transform(
@@ -60,4 +118,33 @@ export class FieldService {
   getSelectedFieldCentroid() {
     return this.getCentroidOfField(this.selectedField);
   }
+
+  getSelectedFieldGeoJSON() {
+    return {
+      type: 'Polygon',
+      coordinates: this.selectedField
+        .clone()
+        .transform('EPSG:5514', 'EPSG:4326')
+        .getCoordinates(),
+    };
+  }
+
+  /**
+   * Check whether selected feature geometry type is valid
+   * (API expects polygon only)
+   */
+  isValidGeometry(feature) {
+    if (!feature) {
+      return false;
+    }
+    return feature.getGeometry().getType() == 'Polygon';
+  }
+
+  /**
+   * Check whether user clicked into one of selectable layers
+   */
+  isValidLayer(feature) {
+    const layer = this.hsMapService.getLayerForFeature(feature);
+    return this.selectableLayers.includes(layer.get('title'));
+  }
 }

+ 3 - 1
src/app/translations.json

@@ -5,6 +5,7 @@
       "getZones": "ZÍSKAT ZÓNY",
       "panelHeader": "Výpočet indexů pole",
       "selectDate": "Chci datum",
+      "selectField": "Pole vyberte kliknutím do mapy",
       "selectIndex": "Chci vypočítat index"
     }
   },
@@ -14,7 +15,8 @@
       "getZones": "GET ZONES",
       "panelHeader": "Field calculation",
       "selectDate": "I want a datum",
+      "selectField": "Select a field by clicking in the map",
       "selectIndex": "I want to calculate index"
     }
   }
-}
+}