UNPKG

@openpv/simshady

Version:

Simulating Shadows for PV Potential Analysis on 3D Data on the GPU.

283 lines (276 loc) 11.3 kB
import * as THREE from 'three'; import { BufferGeometry } from 'three'; /** * Solar irradiance data. `metadata` json holds the coordinates * where the irradiance data can be used. valid_timesteps_for_aggregation * is the number of hours of daylight in the considered timeframe. If * the skydome represents a whole year, this is about 8760. * * `data` holds a list of * sky segments, where altitude_deg and azimuth_deg define the position * and average_radiance_W_m2_sr defines the averaged incoming irradinace in W per m2 per sr. * Read more about it in the "How does simshady work" section of the docs page. * * Definition of the coordiante system in `simshady`: * Angles are expected in degree. * Azimuth = 0 is North, Azimuth = 90° is East. * Altitude = 0 is the horizon, Altitude = 90° is upwards / Zenith. * * Example Data: * ```json * { "data": [ { "altitude_deg": 78.28, "azimuth_deg": 45.0, "average_radiance_W_m2_sr": 17.034986301369866 }, { "altitude_deg": 78.28, "azimuth_deg": 315.0, "average_radiance_W_m2_sr": 17.034986301369866 }, ... ], "metadata": { "latitude": 49.8, "longitude": 8.6, "valid_timesteps_for_aggregation": 8760, } } ``` */ type SolarIrradianceData = { metadata: { latitude: number; longitude: number; valid_timesteps_for_aggregation: number; }; data: Array<{ altitude_deg: number; azimuth_deg: number; average_radiance_W_m2_sr: number; }>; }; /** * Cartesian Coordinate of a point. * * Positive X-axis is east. * Positive Y-axis is north. * Positive z-axis is upwards. */ type CartesianPoint = { x: number; y: number; z: number; }; /** * RGB values of a color, where all values are in intervall [0,1] */ type Color = [number, number, number]; /** * A color Map maps a value t in [0,1] to a color */ type ColorMap = (t: number) => Color; /** * Interface for the parameter object for {@link index.ShadingScene.calculate} */ interface CalculateParams { /** * Efficiency of the conversion from solar energy to electricity. This includes the * pv cell efficiency (about 20%) as well as the coverage density of PV panels per area * (about 70%). * Value in [0,1]. * @defaultValue 0.15 */ solarToElectricityConversionEfficiency?: number; /** * Upper boundary of annual yield in kWh/m2/year. This value is used to normalize * the color of the returned three.js mesh. * In Germany this is something like 1400 kWh/m2/year multiplied with the given * solarToElectricityConversionEfficiency. * @defaultValue 1400*0.15 */ maxYieldPerSquareMeter?: number; /** * Callback function to indicate the progress of the simulation * @param progress number indicating the current progress * @param total number indicating the final number that progress needs to reach * @returns */ progressCallback?: (progress: number, total: number) => void; } /** * The viridis color Map, as defined in https://observablehq.com/@flimsyhat/webgl-color-maps * @param t parameter in [0,1] to go through viridis color map * @returns */ declare function viridis(t: number): Color; /** * Creates a color map function that interpolates between two colors. * @param {Object} colors - The input colors. * @param {Color} colors.c0 - The starting color. * @param {Color} colors.c1 - The ending color. * @returns {ColorMap} A function that takes a value t (0 to 1) and returns an interpolated color. */ declare function interpolateTwoColors(colors: { c0: Color; c1: Color; }): ColorMap; /** * Creates a color map function that interpolates between three colors using quadratic interpolation. * @param {Object} colors - The input colors. * @param {Color} colors.c0 - The first color. * @param {Color} colors.c1 - The second color. * @param {Color} colors.c2 - The third color. * @returns {ColorMap} A function that takes a value t (0 to 1) and returns an interpolated color. */ declare function interpolateThreeColors(colors: { c0: Color; c1: Color; c2: Color; }): ColorMap; declare const colormaps_interpolateThreeColors: typeof interpolateThreeColors; declare const colormaps_interpolateTwoColors: typeof interpolateTwoColors; declare const colormaps_viridis: typeof viridis; declare namespace colormaps { export { colormaps_interpolateThreeColors as interpolateThreeColors, colormaps_interpolateTwoColors as interpolateTwoColors, colormaps_viridis as viridis }; } /** * This class holds all information about the scene that is simulated. * A ShadingScene is typically equipped with the following attributes: * * Simulation geometry, where the PV potential is calculated * * Shading geometry, where no PV potential is calculated but which are * responsible for shading * * Solar Irradiance Data that contains information about incoming irradiance * in the format of sky domes * The Usage of this class and its methods is explained in the "Getting Started" Section * of this site. */ declare class ShadingScene { /** * A Three.js geometry holding the main object of the scene, * see {@link ShadingScene.addShadingGeometry} */ simulationGeometry: BufferGeometry | undefined; /** * A Three.js geometry holding the objects that cause shading, * see {@link ShadingScene.addShadingGeometry} */ shadingGeometry: BufferGeometry | undefined; /** * A Raster (2D Matrix) holding rasterized data of the terrain, * see {@link ShadingScene.addElevationRaster} */ elevationRaster: Array<CartesianPoint>; /** * The midpoint of the elevationRaster, where the main object of * the scene is located. * See {@link ShadingScene.addElevationRaster} */ private elevationRasterMidpoint; /** * A timeseries of Skydomes holding averaged direct and diffuse * irradiance data. * See {@link ShadingScene.addSolarIrradiance} */ solarIrradiance: SolarIrradianceData[] | null; private colorMap; constructor(); /** * Adds a geometry as a target for the shading simulation. * For these geometries, the PV potential will be simulated. * This geometry will also be used as a shading geometry, hence * it is not needed to additionally add it by using `addShadingGeometry`. * * @param geometry Flat Buffer Array of a Three.js geometry, where three * consecutive numbers of the array represent one 3D point and nine consecutive * numbers represent one triangle. */ addSimulationGeometry(geometry: BufferGeometry): void; /** * Adds a geometry as an outer geometry for the shading simulation. * These geometries are responsible for shading. * * @param geometry Flat Buffer Array of a Three.js geometry, where three * consecutive numbers of the array represent one 3D point and nine consecutive * numbers represent one triangle. */ addShadingGeometry(geometry: BufferGeometry): void; /** * Add a elevation model to the simulation scene. * @param raster List of Points with x,y,z coordinates, representing a digital elevation model (DEM). It is * important that all values of x,y and z are given with same units. If x and y are given in lat / lon and * z is given in meters, this will result in wrong simulation Results. * @param midpoint The point of the observer, ie the center of the building * angle will be [0, ..., 2Pi] where the list has a lenght of azimuthDivisions */ addElevationRaster(raster: CartesianPoint[], midpoint: CartesianPoint): void; /** * Add data of solar irradiance to the scene. If it comes as a List of SolarIrradianceData, * this is interpreted as a time series of skydomes. * * **Important Note:** The first skydome of the list is used for the coloring of the final mesh! * Check out the type definition of {@link utils.SolarIrradianceData} for more information. * @param irradiance */ addSolarIrradiance(irradiance: SolarIrradianceData[] | SolarIrradianceData): void; /** * Fetches a SolarIrradiance Object from a url and adds it to the * ShadingScene. * @param url */ addSolarIrradianceFromURL(url: string): Promise<void>; /** * Change the Color Map that is used for the colors of the simulated Three.js mesh. This is * optional, the default colorMap is viridis (blue to green to yellow). Other options are * {@link colormaps.interpolateTwoColors} or {@link colormaps.interpolateThreeColors} * @param colorMap */ addColorMap(colorMap: ColorMap): void; /** @ignore * Gets a BufferGeometry representing a mesh. Refines the triangles until all triangles * have sites smaller maxLength. */ refineMesh(mesh: BufferGeometry, maxLength: number): BufferGeometry; /** * This function is called as a last step, after the scene is fully build. * It runs the shading simulation and returns a THREE.js colored mesh. * The colors are chosen from the defined colorMap. * @param params The input object containing information about the simulation. * @returns A three.js colored mesh of the simulationGeometry. Each triangle gets an * attribute called intensity, that holds the annual electricity in kwh/m2 that a PV * system can generate. If {@link ShadingScene.solarIrradiance} is a timeseries of sky * domes, the resulting intensities attribute is a flattened Float32Array of length T*N. */ calculate(params?: CalculateParams): Promise<THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>>; private validateClassParams; private computeMidpoints; /** * @ignore * This function does two things: * - it assigns a color to the given simulationGeometry. The color is assigned * using the FIRST value of the intensities time series and the maxYieldPerSquareMeter * as upper boundary. * - it flattens the time series of intensities and sets them as attribute to the simulationGeometry * * @param simulationGeometry Nx9 Array with the edge points of N triangles * @param intensities T x N intensities, one for every triangle and every time step * @param maxYieldPerSquareMeter number defining the upper boundary of the color map * @returns Mesh with color and new attribute "intensities" that has length T*N */ private createMesh; /** @ignore * This function returns a time series of intensities of shape T x N, with N the number of midpoints. * It includes the shading of geometries, the dot product of normal vector and sky segment vector, * and the radiation values from diffuse and direct irradiance. * * @param midpoints midpoints of triangles for which to calculate intensities * @param normals normals for each midpoint * @param meshArray array of vertices for the shading mesh * @param irradiance Time Series of sky domes * @return */ private rayTrace; } export { ShadingScene, colormaps };