데이터 영역 요청

dataLayers 엔드포인트는 특정 위치를 둘러싼 지역의 자세한 태양광 정보를 제공합니다. 엔드포인트는 다음과 같이 다운로드 가능한 TIFF 파일 17개를 반환합니다.

  • 디지털 표면 모델 (DSM)
  • RGB 합성 레이어 (항공 이미지)
  • 분석의 경계를 식별하는 마스크 레이어
  • 연간 태양광 흐름 또는 특정 표면의 연간 생산량
  • 월간 태양광 플럭스 또는 특정 표면의 월간 수익률
  • 시간별 명암 (24시간)

Solar API가 자속을 정의하는 방법에 관한 자세한 내용은 Solar API 개념을 참고하세요.

데이터 영역 요청에 대한 정보

다음 예시는 dataLayers 메서드에 대한 REST 요청의 URL을 보여줍니다.

https://solar.googleapis.com/v1/dataLayers:get?parameters

다음을 지정하는 요청 URL 매개변수를 포함합니다.

  • 위치의 위도 및 경도 좌표
  • 위치 주변 지역의 반경입니다.
  • 반환할 데이터의 하위 집합 (DSM, RGB, 마스크, 연간 자속 또는 월간 자속)
  • 검색결과에 허용되는 최소 품질
  • 반환할 데이터의 최소 크기(픽셀당 미터)입니다.

데이터 영역 요청 예

다음 예에서는 위도 = 37.4450, 경도 = -122.1390인 좌표 위치의 반경 100미터 이내의 모든 건물 통계 정보를 요청합니다.

API 키

응답의 URL에 요청을 하려면 API 키를 URL에 추가합니다.

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&pixelSizeMeters=0.5&key=YOUR_API_KEY"

cURL 요청의 URL을 브라우저의 URL 입력란에 붙여넣어 HTTP 요청을 수행할 수도 있습니다. API 키를 전달하면 사용 및 분석 기능이 향상되고 응답 데이터에 대한 액세스를 더 효과적으로 제어할 수 있습니다.

OAuth 토큰

참고: 이 형식은 테스트 환경 전용입니다. 자세한 내용은 OAuth 사용을 참고하세요.

응답의 URL에 요청을 하려면 결제 프로젝트 이름과 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"
        

TypeScript

응답의 URL에 대한 요청을 하려면 요청에 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는 다음 형식으로 URL을 반환합니다.

https://solar.googleapis.com/v1/solar/geoTiff:get?id=HASHED_ID

이러한 URL은 요청된 데이터가 포함된 GeoTIFF 파일에 액세스하는 데 사용할 수 있습니다.

응답 예

이 요청은 다음 형식의 JSON 응답을 생성합니다.

{
  "imageryDate": {
    "year": 2019,
    "month": 7,
    "day": 9
  },
  "imageryProcessedDate": {
    "year": 2022,
    "month": 3,
    "day": 21
  },
  "dsmUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=14f82e6931a8c33fc31ab8378e51804a-852f4ca7f056addda5b8fcb93e02c2fd",
  "rgbUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=bf769c43d72eb85493b20df583bc0c95-d13126638efaa89e44951abc8664d6a3",
  "maskUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=ed089240efc78e417c96a945460830ef-e666758b7cc183f82d1c7b7a891f858b",
  "annualFluxUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=aaa2637073d62cc7331d067eb7080bbe-f94eab79915f66759f5265b2ff8b1ad4",
  "monthlyFluxUrl": "https://solar.googleapis.com/v1/geoTiff:get?id=d1608d342a3d0393b5decd063d330271-2a2e27504a2009cad1f1f3d2b471bcd3",
  "hourlyShadeUrls": [
    "https://solar.googleapis.com/v1/geoTiff:get?id=541c2f32b936f190f7562309ea1d60fc-432bf94bcd0dc918f0c828d07aa00e7c",
    "https://solar.googleapis.com/v1/geoTiff:get?id=4eb7a0b9c0f34e0e746816d0f3085274-4794b9eb35ab18ad4fbe2c3ee59f151d",
    ...
  ],
  "imageryQuality": "HIGH"
}

응답 데이터에 액세스

응답 URL을 통해 데이터에 액세스하려면 추가 인증이 필요합니다. 인증 키를 사용하는 경우 API 키를 URL에 추가해야 합니다. OAuth 인증을 사용하는 경우 OAuth 헤더를 추가해야 합니다.

API 키

응답의 URL에 요청을 하려면 API 키를 URL에 추가합니다.

curl -X GET "https://solar.googleapis.com/v1/solar/geoTiff:get?id=fbde33e9cd16d5fd10d19a19dc580bc1-8614f599c5c264553f821cd034d5cf32&key=YOUR_API_KEY"

cURL 요청의 URL을 브라우저의 URL 입력란에 붙여넣어 HTTP 요청을 수행할 수도 있습니다. API 키를 전달하면 사용 및 분석 기능이 향상되고 응답 데이터에 대한 액세스를 더 효과적으로 제어할 수 있습니다.

OAuth 토큰

응답의 URL에 요청을 하려면 결제 프로젝트 이름과 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와 같은 매핑 애플리케이션 소프트웨어로 가져옵니다.

이 요청 및 응답의 전체 사양은 참조 문서에서 확인할 수 있습니다.