UNPKG

@giro3d/giro3d

Version:

A JS/WebGL framework for 3D geospatial data visualization

212 lines 8.55 kB
import type { BufferAttribute } from 'three'; import { Box3, EventDispatcher, Sphere, type Object3D } from 'three'; import type Disposable from '../core/Disposable'; import type Instance from '../core/Instance'; import type Progress from '../core/Progress'; import type Entity3D from '../entities/Entity3D'; import ColorMap from '../core/ColorMap'; import Extent from '../core/geographic/Extent'; import PointCloud from '../entities/PointCloud'; /** * The names of the computed variables. * - `meanIrradiance` (in Watts/square meter) is the mean irradiance received by the surface over the * time period. * - `irradiation` (in Watt-hours/square meter) is the cumulated energy received by the surface over * the time period * - `hoursOfSunlight` is the total number of hours that the surface was exposed to direct sunlight. */ export type VariableName = 'meanIrradiance' | 'irradiation' | 'hoursOfSunlight'; /** * The solar constant, in Watts / m². * Taken from https://en.wikipedia.org/wiki/Solar_constant */ export declare const SOLAR_CONSTANT = 1361; /** * The amount of solar energy that is absorbed by the atmosphere. * 25% is typical for a clear sky. */ export declare const ATMOSPHERIC_ABSORPTION = 0.25; /** * The result of the computation. */ export interface ComputationResult { /** * The generated point cloud. This is the same entity * as seen in the preview during computation. This point * cloud contains one attribute per solar variable. */ entity: PointCloud; /** * The computed variables. Note that those variables are already * set up in the {@link entity}. However if for some reason you * want to use them for other purposes, you can access them directly here. */ variables: Record<VariableName, SolarVariable>; } /** * Describes a single measured value for all probes. */ export interface SolarVariable { /** The variable values for all probes. Can directly be used * as a buffer attribute for a geometry. */ buffer: BufferAttribute; /** The average value of the variable across all probes */ mean: number; /** The minimum value of the variable across all probes */ min: number; /** The maximum value of the variable across all probes */ max: number; } export interface SunExposureOptions { /** * The Giro3D instance to use. This must be the same instance * as the one that will host the resulting point cloud. */ instance: Instance; /** * The objects to include in the computation. */ objects: Array<Entity3D | Object3D>; /** * The area of interest to limit the simulation. * The smaller the area of interest, the faster the simulation will be. */ limits: Extent | Box3 | Sphere; /** * The date at the start of the simulation time range. */ start: Date; /** * The date at the end of the simulation time range. * If unspecified, then the time range will be [start, start] * and only one simulation step will be performed. */ end?: Date; /** * The color map to use on the point cloud preview to display irradiation. * Note that once the computation is finished, you * can modify the colormaps on the resulting point cloud. * @defaultValue a rainbow colormap */ colorMap?: ColorMap; /** * The spatial resolution, in scene units. This is the * average space between simulation probes. If unspecified, * a default value is computed from the dimensions of {@link limits}. */ spatialResolution?: number; /** * If true, show helpers to help visualize the computation steps. * Helpers will remain visible until the dispose() method is called. * @defaultValue false */ showHelpers?: boolean; /** * The temporal resolution, in seconds. This is the interval * between simulation steps. If {@link end} was not set, * then this parameter has no effect. * @defaultValue 3600 */ temporalResolution?: number; } export interface SunExposureEventMap { /** Raised when the simulation progress changes */ progress: { progress: number; }; } /** * Simulates sun exposure on meshes and produces various sun-related measures (see {@link VariableName}). * * The output is a point cloud that covers the area of interest. * Each point represents a _sun probe_ that samples sun exposure at this location. * * Computation can occurs on a single point in time or within a time range. In that case, * the time range is discretized into snapshots that are one `temporalResolution` apart. * * ### Irradiance and irradiation * * Irradiance (in Watts / square meter) represents the amount of solar power that reaches a surface at a given time. * * We first compute the cosine between the probe's normal and the sun direction. If the cosine * is zero or less, it means the surface is not exposed to sunlight at all. It thus receives * zero watts of solar power. * * If the cosine is greater than zero, it is used to compute the solar power with a simple formula: * * irradiance = cos(angle) * SolarConstant * AtmosphereAbsorption * * where SolarConstant is the {@link SOLAR_CONSTANT} and AtmosphereAbsorption is the {@link * ATMOSPHERIC_ABSORPTION} constant. * * Thus, at noon UTC during summer solstice and at the northern tropic (23.43° N, 0° E), * the irradiance of an horizontal surface will be at its maximum value, which is * (SolarConstant * AtmosphereAbsorption), since the cosine of the angle will be 1. * * Irradiation (in Watt-hours / square meter) is then computed as the integral of the * irradiance over the time period (in hours). * * ### Hours of sunlight * * This variable is computed by counting the number of time increments that a given probe * receives sunlight (i.e is not in the shadow of another object). Those increments do not * need to be consecutive. Thus, if a probe receives 0.5 hours of sunlight in the morning, * then is in the shade until 16:00, then receives another 2 hours of sunlight in the afternoon, * then is occluded by shadow again, then receives 1.5 hours until sunset, its hours of sunlight * will be 4 hours (0.5 + 2 + 1.5). * * ### Remarks and caveats * * - Be careful when passing `Date` parameters. By default, dates are using the local * time zone. It is advised to pass UTC dates to avoid ambiguity. * * - Only mesh-like objects (3D models, maps, 3D tiles, etc) are supported. * Point clouds are not supported, as they don't expose surfaces and normals required * for solar exposure computation. * * - You must include "ground" like meshes so that other meshes (like buildings) are properly * shaded (especially in morning/evening periods) when the sun is low. A simple flat plane * is enough if you don't have anything else. Otherwise you can use a Map with terrain. * * - Be _very_ careful with the `spatialResolution` parameter. It must be reasonable * and consistent with the dimensions of the area of interest. For example, if the area * of interest is 1000m long, and the spatial resolution is 0.1, then this will create * millions of sun probes, making computation much longer than expected, and using a lot * of memory. It is recommended to start with a high value and then reduce it afterwards. */ export declare class SunExposure extends EventDispatcher<SunExposureEventMap> implements Progress, Disposable { private readonly _opCounter; private readonly _start; private readonly _end; private readonly _temporalResolution; private readonly _limits; private readonly _instance; private readonly _root; private readonly _showHelpers; private readonly _objects; private readonly _spatialResolution; private readonly _colorMap; private readonly _toDispose; get loading(): boolean; get progress(): number; constructor(params: SunExposureOptions); private createShadowMapCamera; private createDepthMapHelper; private processStep; private computeTightBounds; private createBoundsHelper; private createOutputPointCloud; private computeVariableStatistics; private runSimulationStep; /** * Starts the computation. */ compute(options?: { /** An optional signal to abort the computation */ signal?: AbortSignal; }): Promise<ComputationResult>; dispose(): void; } export default SunExposure; //# sourceMappingURL=SunExposure.d.ts.map