dataLayers 端点可提供指定地点周围区域的详细太阳能信息。该端点会返回 17 个可下载的 TIFF 文件,包括:
- 数字地表模型 (DSM)
- RGB 复合图层(航空影像)
- 用于标识分析边界的掩码图层
- 年太阳辐射量,或给定表面的年产量
- 每月太阳辐射量,或给定表面的每月产量
- 每小时遮阳度(24 小时)
如需详细了解 Solar API 如何定义通量,请参阅 Solar API 概念。
数据层请求简介
以下示例展示了向 dataLayers
方法发出的 REST 请求的网址:
https://solar.googleapis.com/v1/dataLayers:get?parameters
添加请求网址参数,用于指定以下内容:
- 相应位置的经纬度坐标
- 相应地理位置周围区域的半径
- 要返回的数据子集(DSM、RGB、掩码、年光合量或月光合量)
- 结果中允许的最低质量
- 要返回的数据的最小比例(以每像素米为单位)
数据层请求示例
以下示例请求纬度为 37.4450、经度为 -122.1390 的坐标位置方圆 100 米范围内的所有建筑数据分析信息:
如需向响应中的网址发出请求,请将您的 API 密钥附加到该网址:
curl -X GET "https://solar.googleapis.com/v1/dataLayers:get?location.latitude=37.4450 &location.longitude=-122.1390 &radiusMeters=100 &view=FULL_LAYERS&requiredQuality=HIGH&exactQualityRequired=true&pixelSizeMeters=0.5&key= YOUR_API_KEY "
您还可以将 c网址 请求中的网址粘贴到浏览器的网址栏中,以发出 HTTP 请求。传递 API 密钥可让您更好地使用和分析数据,并更好地控制对响应数据的访问。
注意:此格式仅适用于测试环境。如需了解详情,请参阅使用 OAuth。
如需向响应中的网址发出请求,请传入您的结算项目名称和 OAuth 令牌:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "X-Goog-User-Project:PROJECT_NUMBER_OR_ID " \ "https://solar.googleapis.com/v1/dataLayers:get?location.latitude=37.4450&location.longitude=-122.1390&radius_meters=100&required_quality=HIGH&exactQualityRequired=true"
如需向响应中的网址发出请求,请在请求中添加您的 API 密钥或 OAuth 令牌。以下示例使用了 API 密钥:
/**
* Fetches the data layers information from the Solar API.
* https://developers.google.com/maps/documentation/solar/data-layers
*
* @param {LatLng} location Point of interest as latitude longitude.
* @param {number} radiusMeters Radius of the data layer size in meters.
* @param {string} apiKey Google Cloud API key.
* @return {Promise<DataLayersResponse>} Data Layers response.
*/
export async function getDataLayerUrls(
location: LatLng,
radiusMeters: number,
apiKey: string,
): Promise<DataLayersResponse> {
const args = {
'location.latitude': location.latitude.toFixed(5),
'location.longitude': location.longitude.toFixed(5),
radius_meters: radiusMeters.toString(),
// The Solar API always returns the highest quality imagery available.
// By default the API asks for HIGH quality, which means that HIGH quality isn't available,
// but there is an existing MEDIUM or LOW quality, it won't return anything.
// Here we ask for *at least* LOW quality, but if there's a higher quality available,
// the Solar API will return us the highest quality available.
required_quality: 'LOW',
};
console.log('GET dataLayers\n', args);
const params = new URLSearchParams({ ...args, key: apiKey });
// https://developers.google.com/maps/documentation/solar/reference/rest/v1/dataLayers/get
return fetch(`https://solar.googleapis.com/v1/dataLayers:get?${params}`).then(
async (response) => {
const content = await response.json();
if (response.status != 200) {
console.error('getDataLayerUrls\n', content);
throw content;
}
console.log('dataLayersResponse', content);
return content;
},
);
}
字段和数据类型在 TypeScript 中是“类型”。在此示例中,我们定义了一个自定义类型,用于在响应中存储感兴趣的字段,例如像素值和经纬度边界框。您可以根据需要添加更多字段。
export interface GeoTiff {
width: number;
height: number;
rasters: Array<number>[];
bounds: Bounds;
}
数据类型定义
支持以下数据类型:
export interface DataLayersResponse {
imageryDate: Date;
imageryProcessedDate: Date;
dsmUrl: string;
rgbUrl: string;
maskUrl: string;
annualFluxUrl: string;
monthlyFluxUrl: string;
hourlyShadeUrls: string[];
imageryQuality: 'HIGH' | 'MEDIUM' | 'LOW';
}
export interface Bounds {
north: number;
south: number;
east: number;
west: number;
}
// https://developers.google.com/maps/documentation/solar/reference/rest/v1/buildingInsights/findClosest
export interface BuildingInsightsResponse {
name: string;
center: LatLng;
boundingBox: LatLngBox;
imageryDate: Date;
imageryProcessedDate: Date;
postalCode: string;
administrativeArea: string;
statisticalArea: string;
regionCode: string;
solarPotential: SolarPotential;
imageryQuality: 'HIGH' | 'MEDIUM' | 'LOW';
}
export interface SolarPotential {
maxArrayPanelsCount: number;
panelCapacityWatts: number;
panelHeightMeters: number;
panelWidthMeters: number;
panelLifetimeYears: number;
maxArrayAreaMeters2: number;
maxSunshineHoursPerYear: number;
carbonOffsetFactorKgPerMwh: number;
wholeRoofStats: SizeAndSunshineStats;
buildingStats: SizeAndSunshineStats;
roofSegmentStats: RoofSegmentSizeAndSunshineStats[];
solarPanels: SolarPanel[];
solarPanelConfigs: SolarPanelConfig[];
financialAnalyses: object;
}
export interface SizeAndSunshineStats {
areaMeters2: number;
sunshineQuantiles: number[];
groundAreaMeters2: number;
}
export interface RoofSegmentSizeAndSunshineStats {
pitchDegrees: number;
azimuthDegrees: number;
stats: SizeAndSunshineStats;
center: LatLng;
boundingBox: LatLngBox;
planeHeightAtCenterMeters: number;
}
export interface SolarPanel {
center: LatLng;
orientation: 'LANDSCAPE' | 'PORTRAIT';
segmentIndex: number;
yearlyEnergyDcKwh: number;
}
export interface SolarPanelConfig {
panelsCount: number;
yearlyEnergyDcKwh: number;
roofSegmentSummaries: RoofSegmentSummary[];
}
export interface RoofSegmentSummary {
pitchDegrees: number;
azimuthDegrees: number;
panelsCount: number;
yearlyEnergyDcKwh: number;
segmentIndex: number;
}
export interface LatLng {
latitude: number;
longitude: number;
}
export interface LatLngBox {
sw: LatLng;
ne: LatLng;
}
export interface Date {
year: number;
month: number;
day: number;
}
export interface RequestError {
error: {
code: number;
message: string;
status: string;
};
}
该 API 会返回以下格式的网址:
https://solar.googleapis.com/v1/solar/geoTiff:get?id=HASHED_ID
您可以使用这些网址访问包含请求数据的 GeoTIFF 文件。
示例响应
该请求会生成以下格式的 JSON 响应:
{
"imageryDate": {
"year": 2022,
"month": 4,
"day": 6
},
"imageryProcessedDate": {
"year": 2023,
"month": 8,
"day": 4
},
"dsmUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=MmQyMzI0NTMyZDc3YjBjNmQ3OTgyM2ZhNzMyNzk5NjItN2ZjODJlOThkNmQ5ZDdmZDFlNWU3MDY4YWFlMWU0ZGQ6UkdCOkhJR0g=",
"rgbUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=NzQwNGQ0NmUyMzAzYWRiNmMxNzMwZTJhN2IxMTc4NDctOTI5YTNkZTlkM2MzYjRiNjE4MGNkODVmNjNiNDhkMzE6UkdCOkhJR0g=",
"maskUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=ZTk1YTBlZmY5Y2FhMThlNWYzMWEzZGZhYzEzMGQzOTAtM2Q4NmUyMmM5ZThjZmE0YjhhZWMwN2UzYzdmYmQ3ZjI6TUFTSzpISUdI",
"annualFluxUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=OTE0OWIxZDM3NmNlYjkzMWY2YjQyYjY5Y2RkYzNiOTAtZjU5YTVjZGQ3MzE3ZTQ4NTNmN2M4ZmY2MWZlZGZkMzg6QU5OVUFMX0ZMVVg6SElHSA==",
"monthlyFluxUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=Y2NhOGRhOWI2MjVmYmNiZTY3Njk4Yjk0MGJhNTk1NDUtY2MyYTI4NDJmN2Q5YTI0MmY2NDQyZGUwZWJkMWQ0ZDg6TU9OVEhMWV9GTFVYOkhJR0g=",
"hourlyShadeUrls": [
"https://solar.googleapis.com/v1/geoTiff:get?id=OWFhOTZmNDU2OGQyNTYxYWQ4YjZkYjQ5NWI4Zjg1ODItZGEwNDNhMmM3NDU0MTY2OGIzZDY2OGU1NTY0NTFlMzE6TU9OVEhMWV9GTFVYOkhJR0g=",
"https://solar.googleapis.com/v1/geoTiff:get?id=MTI1ZTI2YzM1ZTRlYjA3ZDM4NWE2ODY4MjUzZmIxZTMtNTRmYTI3YmQyYzVjZDcyYjc5ZTlmMTRjZjBmYTk4OTk6TU9OVEhMWV9GTFVYOkhJR0g=",
...
],
"imageryQuality": "HIGH"
}
访问响应数据
如需通过响应网址访问数据,需要进行额外的身份验证。如果您使用身份验证密钥,则必须将 API 密钥附加到网址。如果您使用 OAuth 身份验证,则必须添加 OAuth 标头。
如需向响应中的网址发出请求,请将您的 API 密钥附加到该网址:
curl -X GET "https://solar.googleapis.com/v1/solar/geoTiff:get?id=fbde33e9cd16d5fd10d19a19dc580bc1-8614f599c5c264553f821cd034d5cf32&key=YOUR_API_KEY "
您还可以将 c网址 请求中的网址粘贴到浏览器的网址栏中,以发出 HTTP 请求。传递 API 密钥可让您更好地使用和分析数据,并更好地控制对响应数据的访问。
如需向响应中的网址发出请求,请传入您的结算项目名称和 OAuth 令牌:
curl -X GET \ -H 'X-Goog-User-Project:PROJECT_NUMBER_OR_ID ' \ -H "Authorization: Bearer $TOKEN" \ "https://solar.googleapis.com/v1/solar/geoTiff:get?id=fbde33e9cd16d5fd10d19a19dc580bc1-8614f599c5c264553f821cd034d5cf32"
以下示例展示了如何获取像素数据值(存储在数字图片的各个像素中的信息,包括颜色值和其他属性)、从 GeoTIFF 计算纬度和经度,并将其存储在 TypeScript 对象中。
对于这个具体示例,我们选择允许进行类型检查,这有助于减少类型错误,提高代码可靠性,并简化代码维护。
// npm install geotiff geotiff-geokeys-to-proj4 proj4
import * as geotiff from 'geotiff';
import * as geokeysToProj4 from 'geotiff-geokeys-to-proj4';
import proj4 from 'proj4';
/**
* Downloads the pixel values for a Data Layer URL from the Solar API.
*
* @param {string} url URL from the Data Layers response.
* @param {string} apiKey Google Cloud API key.
* @return {Promise<GeoTiff>} Pixel values with shape and lat/lon bounds.
*/
export async function downloadGeoTIFF(url: string, apiKey: string): Promise<GeoTiff> {
console.log(`Downloading data layer: ${url}`);
// Include your Google Cloud API key in the Data Layers URL.
const solarUrl = url.includes('solar.googleapis.com') ? url + `&key=${apiKey}` : url;
const response = await fetch(solarUrl);
if (response.status != 200) {
const error = await response.json();
console.error(`downloadGeoTIFF failed: ${url}\n`, error);
throw error;
}
// Get the GeoTIFF rasters, which are the pixel values for each band.
const arrayBuffer = await response.arrayBuffer();
const tiff = await geotiff.fromArrayBuffer(arrayBuffer);
const image = await tiff.getImage();
const rasters = await image.readRasters();
// Reproject the bounding box into lat/lon coordinates.
const geoKeys = image.getGeoKeys();
const projObj = geokeysToProj4.toProj4(geoKeys);
const projection = proj4(projObj.proj4, 'WGS84');
const box = image.getBoundingBox();
const sw = projection.forward({
x: box[0] * projObj.coordinatesConversionParameters.x,
y: box[1] * projObj.coordinatesConversionParameters.y,
});
const ne = projection.forward({
x: box[2] * projObj.coordinatesConversionParameters.x,
y: box[3] * projObj.coordinatesConversionParameters.y,
});
return {
// Width and height of the data layer image in pixels.
// Used to know the row and column since Javascript
// stores the values as flat arrays.
width: rasters.width,
height: rasters.height,
// Each raster reprents the pixel values of each band.
// We convert them from `geotiff.TypedArray`s into plain
// Javascript arrays to make them easier to process.
rasters: [...Array(rasters.length).keys()].map((i) =>
Array.from(rasters[i] as geotiff.TypedArray),
),
// The bounding box as a lat/lon rectangle.
bounds: {
north: ne.y,
south: sw.y,
east: ne.x,
west: sw.x,
},
};
}
除了 RGB 图层外,所有 TIFF 文件都将在图片查看器应用中显示为空白图片。如需查看下载的 TIFF 文件,请将其导入地图应用软件(例如 QGIS)。
如需查看此请求和响应的完整规范,请参阅参考文档。