@@ -4,18 +4,67 @@ import {hcat} from "./codes";
44import VectorTile from "ol/layer/VectorTile" ;
55import { PMTilesVectorSource } from "ol-pmtiles" ;
66const cropExtension = "https://fiboa.github.io/hcat-extension/v0.1.0/schema.yaml" ;
7+ import debounce from "lodash.debounce" ;
8+ import TileState from 'ol/TileState' ;
9+ import { intersects } from "ol/extent" ;
10+ import { toGeometry } from "ol/render/Feature" ;
11+ import { CropLegendControl } from "./CropLegendControl" ;
712
13+ const CROP_ATTRIBUTE = "ec:hcat_code" ;
814const fieldStyle = {
915 "stroke-color" : 'rgb(88, 88, 88, 88)' ,
1016 "stroke-width" : 0.5 ,
1117 "fill-color" : [ 'get' , 'color' ]
1218}
1319const mapping = Object . fromEntries ( hcat . map ( c => [ c . code , c . color ] ) ) ;
1420
21+ function forFeaturesInExtent ( vt , extent , callback ) {
22+ const renderer = vt . getRenderer ( ) ;
23+ const tileCache = renderer . getTileCache ( ) ;
24+ if ( tileCache . getCount ( ) === 0 ) return ;
25+
26+ const tileGrid = renderer . getLayer ( ) . getSource ( ) . tileGrid ;
27+ const z = tileGrid . getZForResolution ( renderer . renderedResolution ) ;
28+ tileCache . forEach ( ( tile ) => {
29+ if ( tile . tileCoord [ 0 ] !== z || tile . getState ( ) !== TileState . LOADED ) return ;
30+ for ( const sourceTile of tile . getSourceTiles ( ) ) {
31+ const tileCoord = sourceTile . tileCoord ;
32+ if ( intersects ( extent , tileGrid . getTileCoordExtent ( tileCoord ) ) ) {
33+ for ( const candidate of sourceTile . getFeatures ( ) ) {
34+ if ( intersects ( extent , candidate . getExtent ( ) ) ) callback ( candidate ) ;
35+ }
36+ }
37+ }
38+ } ) ;
39+ }
40+
1541class CropMap extends FiboaMap {
1642 constructor ( ) {
1743 super ( ) ;
1844 this . fieldStyle = fieldStyle ;
45+ this . vectortiles = [ ] ;
46+ this . updateFeatureCount = debounce ( this . updateFeatureCount , 1000 ) . bind ( this ) ;
47+ this . map . on ( "moveend" , this . updateFeatureCount )
48+ this . map . addControl ( new CropLegendControl ( ) ) ;
49+ }
50+ updateFeatureCount ( e ) {
51+ // const extent = this.map.getView().calculateExtent();
52+ const extent = this . map . getView ( ) . calculateExtentInternal ( ) ;
53+ const result = {
54+ area : 0 ,
55+ count : 0 ,
56+ perCrop : { }
57+ }
58+ for ( const vt of this . vectortiles ) {
59+ forFeaturesInExtent ( vt , extent , ( feature ) => {
60+ const area = feature . properties_ [ "area" ] || toGeometry ( feature ) . getArea ( ) ;
61+ const crop = feature . properties_ [ CROP_ATTRIBUTE ] ;
62+ result . count ++ ;
63+ result . area += area ;
64+ result [ crop ] = ( result [ crop ] || 0 ) + area ;
65+ } ) ;
66+ }
67+ console . log ( extent , result ) ;
1968 }
2069 addPMTilesLayer ( c , options ) {
2170 const source = new PMTilesVectorSource ( options ) ;
@@ -29,18 +78,12 @@ class CropMap extends FiboaMap {
2978 } ) ;
3079 // TODO, Count the features in view and display a legend explaining the top 5 crops
3180 // TODO, Add a filter based on crops. This will not be perfect on high zoom levels (lossy vector tiles)
32- // source.on('tileloadend', e => {
33- // const features = e.tile.getFeatures();
34- // console.log(e, features.length, features[0].getProperties());
35- // for (const feature of features) {
36- // feature.getProperties().color = "##ff0000";
37- // }
38- // })
81+ this . vectortiles . push ( fields ) ;
3982 source . on ( 'tileloadend' , e => {
4083 const features = e . tile . getFeatures ( ) ;
4184 for ( const feature of features ) {
4285 const p = feature . getProperties ( ) ;
43- p . color = mapping [ p [ "ec:hcat_code" ] ] || "#99bbccaa" ;
86+ p . color = mapping [ p [ CROP_ATTRIBUTE ] ] || "#99bbccaa" ;
4487 }
4588 this . updateFeatureCount ( e )
4689 } )
0 commit comments