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 密钥
如需向响应中的网址发出请求,请将 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。
如需向响应中的网址发出请求,请传入结算项目名称和 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"
TypeScript
如需向响应中的网址发出请求,请在请求中包含您的 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 中的"type"。在此示例中,我们定义一个自定义类型,用于存储响应中的相关字段(例如像素值和纬度/经度边界框)。您可以根据需要添加更多字段。
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=6d654a0300e454f4c6db7fff24d7ab98-f51261151c9d4c7e055dd21ce57fa3b5", "rgbUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=7c71f407a36c1cd051f5ada9c17a6cb8-4b1a9e2b489656febfb7676f205aea1d", "maskUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=814470096c53cb221b524119e1e2700c-ac51cf76452dd6c2e843e6b11922ccc0", "annualFluxUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=e044991d7f376dc23f9abe8d4efc909b-982983cd98d0572b9d62ca0a2db38eb3", "monthlyFluxUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=9b4638db10d2d58560b9f1e9fb013551-dff565175a1e6861a7afb62ece41e218", "hourlyShadeUrls": [ "https://solar.googleapis.com/v1/geoTiff:get?id=9aa96f4568d2561ad8b6db495b8f8582-da043a2c74541668b3d668e556451e31", "https://solar.googleapis.com/v1/geoTiff:get?id=125e26c35e4eb07d385a6868253fb1e3-54fa27bd2c5cd72b79e9f14cf0fa9899", ... ], "imageryQuality": "HIGH" }
访问响应数据
通过响应网址访问数据需要额外的身份验证。如果您使用身份验证密钥,则必须将 API 密钥附加到网址。如果您使用 OAuth 身份验证,则必须添加 OAuth 标头。
API 密钥
如需向响应中的网址发出请求,请将 API 密钥附加到该网址:
curl -X GET "https://solar.googleapis.com/v1/solar/geoTiff:get?id=fbde33e9cd16d5fd10d19a19dc580bc1-8614f599c5c264553f821cd034d5cf32&key=YOUR_API_KEY"
您还可以将 c网址 请求中的网址粘贴到浏览器的网址栏中,以发出 HTTP 请求。传递 API 密钥可为您提供更好的使用和分析功能,以及更好的响应数据访问权限控制。
OAuth 令牌
如需向响应中的网址发出请求,请传入结算项目名称和 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"
TypeScript
以下示例展示了如何获取像素数据值(存储在数字图片各个像素中的信息,包括颜色值和其他属性),根据 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)。
如需了解此请求和响应的完整规范,请参阅参考文档。