thematic-earth
Version:
HTML-based, whole-Earth thematic maps using locally hosted data layers
2 lines • 5.84 kB
JavaScript
/* Copyright (c) 2023 Read Write Tools. Legal use subject to the Thematic Earth Software License Agreement. */
import RS from'../enum/rendering-state.enum.js';import*as Color from'../graphics/color.js';import Layer from'../layers/layer.class.js';import expect from'../dev/expect.js';import terminal from'../dev/terminal.js';class OrderedPair{constructor(e,a){this.zOrder=e,this.layerId=a}}export default class Catalog{constructor(e){this.thematicEarthElement=e,this.spatialFiles=new Map,this.layers=new Map,this.paintSequence=[],this.distanceSpatialFile=null,this.distanceLayer=null,Object.seal(this)}addSpatialData(e){return expect(e,['Space','Sphere','Night','Crosshairs','Crosshairs','Graticule','NamedMeridians','NamedParallels','GreatCircles','PlaceOfInterest','TopojsonSpatialFile','GcsSpatialFile']),this.spatialFiles.set(e.spatialId,e),e.spatialId}addLayer(e){return expect(e,'Layer'),this.layers.set(e.layerId,e),expect(e.zOrder,'Number'),this.paintSequence.push(new OrderedPair(e.zOrder,e.layerId)),this.paintSequence.sort(((e,a)=>e.zOrder<a.zOrder?-1:e.zOrder>a.zOrder?1:0)),e.layerNeedsRestyling=!0,this.thematicEarthElement.signal.broadcast('catalog/layerAdded',{layerId:e.layerId,spatialId:e.spatialId,zOrder:e.zOrder,layerName:e.layerName,identifiable:e.identifiable,selectable:e.selectable,wantsLabels:e.wantsLabels}),e.layerId}getSpatialFile(e){return expect(e,'Number'),this.spatialFiles.has(e)?this.spatialFiles.get(e):null}getLayer(e){return expect(e,'Number'),this.layers.has(e)?this.layers.get(e):null}async getDistanceSpatialFile(){if(null==this.distanceSpatialFile){var e=await import('../catalog/great-circles.class.js');this.distanceSpatialFile=new e.default(this.thematicEarthElement,[]);var a=this.addSpatialData(this.distanceSpatialFile);this.distanceLayer=new Layer(this.thematicEarthElement,a,1e3,'Distances','distances','great-circles','id','yes',null,'yes','yes'),this.addLayer(this.distanceLayer)}return this.distanceSpatialFile}async getDistanceLayer(){return await this.getDistanceSpatialFile(),this.distanceLayer}renderAllInOne(e,a){expect(e,'Earth'),expect(a,'RenderClock'),a.renderingState==RS.PAINTING&&this.thematicEarthElement.signal.broadcast('catalog/beginRender',null),this.cleanSlate(e);for(let l=0;l<this.paintSequence.length;l++){var t=this.paintSequence[l].layerId,r=this.layers.get(t);if(expect(r,'Layer'),r.isVisible()&&a.isRenderTimeAvailable()){var i=this.spatialFiles.get(r.spatialId);i.rotation(a,e.coords),i.projection(a,e.ortho),i.transformation(a,e.carte),i.placement(a,e.viewport),i.recomputeStyles(a,e.visual,r,t),i.drawLayer(a,e,r)}}a.renderingState==RS.PAINTING&&this.thematicEarthElement.signal.broadcast('catalog/endRender',null)}cleanSlate(e){for(let e=0;e<this.paintSequence.length;e++){var a=this.paintSequence[e].layerId,t=this.layers.get(a);if(expect(t,'Layer'),'Space'==this.spatialFiles.get(t.spatialId).constructor.name)if(1==t.isVisible())return}var r,i=this.thematicEarthElement.earth.visual.tessManager.theAnyMapScaleRule(),l=null;i.selectorExists('.space')&&((r=i.getDeclarationsBySelector('.space')).has('deep-space-color')&&(l=r.get('deep-space-color')));null==l&&(i.selectorExists('space')&&(r=i.getDeclarationsBySelector('space')).has('deep-space-color')&&(l=r.get('deep-space-color')));if(null!=l)return(s=e.canvas.getContext('2d')).globalAlpha=1,s.fillStyle=l.value,void s.fillRect(0,0,e.canvas.width,e.canvas.height);var s,n=window.getComputedStyle(this.thematicEarthElement).getPropertyValue('background-color'),c=Color.rgbaHexFromCSS(n);c=`${c.substr(0,7)}ff`,(s=e.canvas.getContext('2d')).globalAlpha=1,s.fillStyle=c,s.fillRect(0,0,e.canvas.width,e.canvas.height)}runCourtesyValidator(e){expect(e,'Visualizer');for(let[t,r]of this.layers)if(r.isVisible()){var a=this.spatialFiles.get(r.spatialId);expect(a,['Space','Sphere','Night','Crosshairs','Graticule','NamedMeridians','NamedParallels','GreatCircles','PlaceOfInterest','TopojsonSpatialFile','GcsSpatialFile']),a.runCourtesyValidator(e,r,t)}}discoverFeatures(e,a){var t=[];for(let d=this.paintSequence.length-1;d>=0;d--){var r=this.paintSequence[d].layerId,i=this.layers.get(r);if(1==i.visible&&i.isIdentifiable()){var l=this.spatialFiles.get(i.spatialId).discoverFeatures(e,a,r);if(null!=l){var s=i.featureKey,n=l.kvPairs.hasOwnProperty(s)?l.kvPairs[s]:'';if(i.identifyCallback)c=i.identifyCallback(l.kvPairs);else var c=`<tr><td>${i.layerName}</td><td>${n}</td></tr>`;t.push({layerName:i.layerName,featureId:l.featureId,featureType:l.featureType,featureName:l.featureName,featureKey:s,featureValue:n,featureData:Object.assign(l.kvPairs),identifyHTML:c})}}}return t}selectFeatures(e,a){var t=[];for(let o=this.paintSequence.length-1;o>=0;o--){var r=this.paintSequence[o].layerId,i=this.layers.get(r);if(1==i.visible&&i.isSelectable()){var l=this.spatialFiles.get(i.spatialId).discoverFeatures(e,a,r);if(null!=l){l.toggleSelectedState(),i.layerNeedsRestyling=!0,this.thematicEarthElement.invalidateCanvas();var s=i.featureKey,n=l.kvPairs.hasOwnProperty(s)?l.kvPairs[s]:'';if(i.identifyCallback)c=i.identifyCallback(l.kvPairs);else var c=`<tr><td>${i.layerName}</td><td>${n}</td></tr>`;var d=l.roughAndReadyPoint();t.push({layerName:i.layerName,layerId:i.layerId,spatialId:i.spatialId,featureId:l.featureId,featureType:l.featureType,featureName:l.featureName,featureKey:s,featureValue:n,featureData:Object.assign(l.kvPairs),identifyHTML:c,isSelected:l.isSelected,latitude:d.latitude,longitude:d.longitude})}}}return t}chooseFeature(e,a){for(let l=this.paintSequence.length-1;l>=0;l--){var t=this.paintSequence[l].layerId,r=this.layers.get(t);if(1==r.visible){var i=this.spatialFiles.get(r.spatialId).discoverFeatures(e,a,t);if(null!=i)return{feature:i,layer:r}}}return null}}function monitorPerformance(e){var a=performance.now();e();var t=performance.now()-a;terminal.trace(`${e} ${t.toFixed(2)} ms`)}