thematic-earth
Version:
HTML-based, whole-Earth thematic maps using locally hosted data layers
2 lines • 8.01 kB
JavaScript
/* Copyright (c) 2023 Read Write Tools. Legal use subject to the Thematic Earth Software License Agreement. */
import CanvasParams from'../tess/canvas-params.class.js';import LegendConsts from'../legend/legend-consts.js';import*as LegendSymbols from'../legend/legend-symbols.js';import*as PointGraphics from'../graphics/point-graphics.js';import*as LineGraphics from'../graphics/line-graphics.js';import*as PolygonGraphics from'../graphics/polygon-graphics.js';import*as LabelGraphics from'../graphics/label-graphics.js';import FT from'../enum/feature-type.enum.js';import LS from'../enum/legend-symbol.enum.js';import expect from'../dev/expect.js';import terminal from'../dev/terminal.js';export default class LegendSlice{constructor(e,s,a,t,i,n,r,o,l,h){this.layerId=e,this.zOrder=s,this.legendSymbol=a,this.tessClassname=t,this.tessIdentifier=i,this.tessPropertyName=n,this.tessPropertyValue=r,this.legendText=o,this.tessBackgroundIdentifier=l,this.tessLabelIdentifier=h,this.backgroundCanvasParams=new CanvasParams,this.featureCanvasParams=new CanvasParams,this.labelCanvasParams=new CanvasParams,this.backgroundPoints=[],this.featurePoints=[],this.displaySlice=!0,this.initializeLegendFeaturePoints(),Object.seal(this)}showSlice(){return this.displaySlice}initializeLegendFeaturePoints(){switch(this.backgroundPoints=LegendSymbols.SymbolBox(),this.legendSymbol){case LS.PLACE:this.featurePoints=LegendSymbols.Place();break;case LS.HORIZONTAL_LINE:this.featurePoints=LegendSymbols.HorizontalLine();break;case LS.VERTICAL_LINE:this.featurePoints=LegendSymbols.VerticalLine();break;case LS.ARC:this.featurePoints=LegendSymbols.Arc();break;case LS.RIVER:this.featurePoints=LegendSymbols.River();break;case LS.ROUTE:this.featurePoints=LegendSymbols.Route();break;case LS.RECTANGLE:this.featurePoints=LegendSymbols.Rectangle();break;case LS.SPACE:this.featurePoints=LegendSymbols.Space();break;case LS.CIRCLE:this.featurePoints=LegendSymbols.Circle();break;case LS.LAKE:this.featurePoints=LegendSymbols.Lake();break;case LS.TERRITORY:this.featurePoints=LegendSymbols.Territory();break;default:terminal.logic(`Unhandled legendSymbol ${this.legendSymbol}`)}}recomputeStyles(e){expect(e,'Visualizer');var s=!1,a='',t={};''!=this.tessPropertyName&&(t[this.tessPropertyName]=this.tessPropertyValue);if(null!=this.layerId){if(0==e.thematicEarthElement.earth.catalog.getLayer(this.layerId).isVisible())return void(this.displaySlice=!1);this.displaySlice=!0}switch(this.legendSymbol){case LS.PLACE:this.featureCanvasParams=e.computeStyle(FT.POINT,this.tessClassname,this.tessIdentifier,s,a,t,0),this.displaySlice=this.featureCanvasParams.displaySymbols();break;case LS.HORIZONTAL_LINE:case LS.VERTICAL_LINE:case LS.ARC:case LS.RIVER:case LS.ROUTE:this.featureCanvasParams=e.computeStyle(FT.LINE,this.tessClassname,this.tessIdentifier,s,a,t,0),this.displaySlice=this.featureCanvasParams.displayStrokes();break;case LS.RECTANGLE:case LS.CIRCLE:case LS.LAKE:case LS.TERRITORY:this.featureCanvasParams=e.computeStyle(FT.POLYGON,this.tessClassname,this.tessIdentifier,s,a,t,0);break;case LS.SPACE:this.featureCanvasParams=e.computeStyle(FT.SPACE,this.tessClassname,this.tessIdentifier,s,a,t,0);break;default:terminal.logic(`Unhandled legendSymbol ${this.legendSymbol}`)}this.backgroundCanvasParams=e.computeStyle(FT.POLYGON,'legend-background',this.tessBackgroundIdentifier,s,a,t,0),this.labelCanvasParams=e.computeStyle(FT.LABEL,'legend-label','',s,a,t,0),e.overlayCanvasParams(this.labelCanvasParams,this.tessClassname,this.tessIdentifier),e.overlayCanvasParams(this.labelCanvasParams,'',this.tessLabelIdentifier),this.limitLabelFontSize(this.labelCanvasParams)}limitLabelFontSize(e){var s=e['label-font-size'],a=e.safeNumber('scale-labels-coefficient');s*a<7?e['label-font-size']=7/a:s*a>28&&(e['label-font-size']=28/a)}runCourtesyValidator(e){expect(e,'Visualizer');var s='',a=[];switch(this.legendSymbol){case LS.PLACE:e.runCourtesyValidator(FT.POINT,this.tessClassname,this.tessIdentifier,s,a,0);break;case LS.HORIZONTAL_LINE:case LS.VERTICAL_LINE:case LS.ARC:case LS.RIVER:case LS.ROUTE:e.runCourtesyValidator(FT.LINE,this.tessClassname,this.tessIdentifier,s,a,0);break;case LS.RECTANGLE:case LS.CIRCLE:case LS.LAKE:case LS.TERRITORY:e.runCourtesyValidator(FT.POLYGON,this.tessClassname,this.tessIdentifier,s,a,0);break;case LS.SPACE:e.runCourtesyValidator(FT.SPACE,this.tessClassname,this.tessIdentifier,s,a,0);break;default:terminal.logic(`Unhandled legendSymbol ${this.legendSymbol}`)}e.runCourtesyValidator(FT.POLYGON,'legend-background',this.tessBackgroundIdentifier,s,a,0),e.runCourtesyValidator(FT.LABEL,'legend-label',this.tessLabelIdentifier,s,a,0)}determineSliceXY(){if(0!=this.featurePoints.length){var e=this.featurePoints[0],s={minX:e.symbolX,minY:e.symbolY,maxX:e.symbolX,maxY:e.symbolY};for(let e=1;e<this.featurePoints.length;e++){var a=this.featurePoints[e];s.minX=Math.min(s.minX,a.symbolX),s.minY=Math.min(s.minY,a.symbolY),s.maxX=Math.max(s.maxX,a.symbolX),s.maxY=Math.max(s.maxY,a.symbolY)}var t=s.maxX-s.minX,i=s.maxY-s.minY,n=0==t?1:(LegendConsts.symbolBoxWidth-2*LegendConsts.symbolPadding)/t,r=0==i?1:(LegendConsts.symbolBoxHeight-2*LegendConsts.symbolPadding)/i,o=t*n,l=i*r,h=Math.min(n,r),d=t*h,c=i*h,m=0==t?0:s.minX*h-LegendConsts.symbolPadding-(o-d)/2,L=0==i?0:s.minY*h-LegendConsts.symbolPadding-(l-c)/2;for(let e=0;e<this.featurePoints.length;e++)this.featurePoints[e].determineSliceXY(LegendConsts.symbolLeftMargin,LegendConsts.symbolTopMargin,m,L,h,h);for(let e=0;e<this.backgroundPoints.length;e++)this.backgroundPoints[e].determineSliceXY(0,0,0,0,1,1)}}determineLegendXY(e){expect(e,'Number');for(let s=0;s<this.featurePoints.length;s++)this.featurePoints[s].determineLegendXY(e);for(let s=0;s<this.backgroundPoints.length;s++)this.backgroundPoints[s].determineLegendXY(e)}draw(e,s,a){if(expect(e,'HTMLCanvasElement'),expect(s,'PatternCache'),expect(a,'Number'),0!=this.displaySlice){var t=e.getContext('2d');switch(t.save(),this.drawSymbolBox(t,s),this.clipToSymbolBox(t),this.legendSymbol){case LS.PLACE:this.drawPointLegend(t);break;case LS.HORIZONTAL_LINE:case LS.VERTICAL_LINE:case LS.ARC:case LS.RIVER:case LS.ROUTE:this.drawLineLegend(t,s);break;case LS.RECTANGLE:case LS.CIRCLE:case LS.LAKE:case LS.TERRITORY:this.drawPolygonLegend(t,s);break;case LS.SPACE:this.drawDeepSpace(t);break;default:terminal.logic(`Unhandled legendSymbol ${this.legendSymbol}`)}t.restore();var i=a+LegendConsts.getVerticalBaseline();LabelGraphics.draw(e,this.labelCanvasParams,LegendConsts.getTextLeft(),i,this.legendText,'left','middle')}}drawPointLegend(e){PointGraphics.draw(e,'',this.featureCanvasParams,this.featurePoints[0])}drawLineLegend(e,s){LineGraphics.draw(e,s,this.featureCanvasParams,this.featurePoints)}drawPolygonLegend(e,s){PolygonGraphics.draw(e,s,this.featureCanvasParams,1,0,0,this.featurePoints,[],!1)}drawDeepSpace(e){e.beginPath(),e.moveTo(this.backgroundPoints[0].canvasX,this.backgroundPoints[0].canvasY),e.lineTo(this.backgroundPoints[1].canvasX,this.backgroundPoints[1].canvasY),e.lineTo(this.backgroundPoints[2].canvasX,this.backgroundPoints[2].canvasY),e.lineTo(this.backgroundPoints[3].canvasX,this.backgroundPoints[3].canvasY),e.fillStyle=this.featureCanvasParams.safeString('deep-space-color'),e.closePath(),e.fill(),e.fillStyle=this.featureCanvasParams.safeString('deep-space-star-color');for(var s=this.featureCanvasParams.safeNumber('deep-space-star-count')/50,a=this.backgroundPoints[0].canvasX,t=this.backgroundPoints[0].canvasY,i=this.backgroundPoints[2].canvasX-a,n=this.backgroundPoints[2].canvasY-t,r=0;r<s;r++){var o=a+Math.random()*i,l=t+Math.random()*n;e.beginPath(),e.arc(o,l,1,0,2*Math.PI,!1),e.closePath(),e.fill()}}drawSymbolBox(e,s){PolygonGraphics.draw(e,s,this.backgroundCanvasParams,1,0,0,this.backgroundPoints,[],!1)}clipToSymbolBox(e){e.beginPath();var s=this.backgroundPoints[0];e.moveTo(s.canvasX,s.canvasY);for(let s=0;s<this.backgroundPoints.length;s++){let a=this.backgroundPoints[s];e.lineTo(a.canvasX,a.canvasY)}e.closePath(),e.clip()}}