Created
December 11, 2023 08:12
-
-
Save zainaali/2c0617d96c55d2fad94029abedf56adc to your computer and use it in GitHub Desktop.
Google Solar API JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Google Maps Autocomplete</title> | |
<style> | |
body{ | |
background: #1a202c; | |
color:white; | |
} | |
#map { | |
height: 500px; | |
width: 100%; | |
margin-top:20px; | |
} | |
.slider_con { | |
width: 40%; | |
margin-top: 30px; | |
/*display:none;*/ | |
} | |
.slider_con input{ | |
width: 100%; | |
} | |
#location-input { | |
width: 300px; | |
padding: 8px; | |
font-size: 16px; | |
} | |
#panelMarker{ | |
display:none; | |
} | |
.slider-container { | |
padding: 8px 24px; | |
background: white; | |
display: flex; | |
align-items: center; | |
color: rgb(60, 64, 67); | |
font-weight: 400; | |
border-radius: 40px; | |
} | |
.panel-count-label { | |
padding: 2px 0px; | |
white-space: nowrap; | |
} | |
div#yourParentContainerId { | |
display: flex; | |
width: 100%; | |
} | |
.panel_c { | |
width: 10%; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="mian_co"> | |
<div class="item_con"> | |
<h1>Google Maps Autocomplete</h1> | |
<label for="location-input">Enter Location:</label> | |
<input type="text" id="location-input" placeholder="Enter a location"> | |
<button id="panelMarker" onclick="findSolar('panel')">Find Solar Panels</button> | |
<div class="slider_con"> | |
</div> | |
<div id="solar_data"></div> | |
<div id="yourParentContainerId"></div> | |
</div> | |
<div class="map_con"> | |
<div id="map"></div> | |
</div> | |
</div> | |
<script> | |
let map; | |
let roofSegmentMarkers = []; | |
let panelMarkers = []; | |
let mainLocationMarker; | |
function initMap() { | |
map = new google.maps.Map(document.getElementById('map'), { | |
center: { | |
lat: -34.397, | |
lng: 150.644 | |
}, // Set default map location | |
zoom: 5, // Set default map zoom | |
streetViewControl: false, | |
mapTypeControl: false, | |
rotateControl: false, | |
tilt: 0, | |
styles: [{ | |
featureType: "all", | |
elementType: "labels", | |
stylers: [{ | |
visibility: "off" | |
}] | |
}], | |
mapTypeId: 'satellite' // Set default map type to satellite | |
}); | |
var input = document.getElementById('location-input'); | |
var autocomplete = new google.maps.places.Autocomplete(input); | |
autocomplete.addListener('place_changed', function() { | |
var place = autocomplete.getPlace(); | |
if (!place.geometry) { | |
window.alert("Sorry, there's no coverage available for this address!: '" + place.name + "'"); | |
return; | |
} | |
// can call function to fetch solar data based on the location | |
// Display roof segments and main location marker | |
fetchSolarData(place.geometry.location.lat(), place.geometry.location.lng(), 'roof'); | |
map.setZoom(25); | |
map.setCenter(place.geometry.location); | |
}); | |
} | |
function findSolar(type) { | |
// Clear existing markers | |
clearMarkers(); | |
const addressInput = document.getElementById("location-input").value; | |
// Geocode the address to get the latitude and longitude | |
const geocoder = new google.maps.Geocoder(); | |
geocoder.geocode({ | |
address: addressInput | |
}, (results, status) => { | |
if (status === "OK" && results[0]) { | |
const location = results[0].geometry.location; | |
// Now you can use the location (latitude and longitude) to make the Solar API request | |
// Example: Call another function to fetch solar data based on the location and type | |
fetchSolarData(location.lat(), location.lng(), type); | |
} else { | |
alert("Geocode was not successful for the following reason: " + status); | |
} | |
}); | |
} | |
function fetchSolarData(latitude, longitude, type) { | |
const apiUrl = `https://solar.googleapis.com/v1/buildingInsights:findClosest?location.latitude=${latitude}&location.longitude=${longitude}&requiredQuality=HIGH&key={KEY}`; | |
fetch(apiUrl) | |
.then(response => response.json()) | |
.then(data => { | |
console.log(data); // Log the data to the console for inspection | |
// Process the data and update the map as needed | |
// Example: Parse the response and update the map markers or polygons | |
displayResultsOnMap(map, data, type); | |
}) | |
.catch(error => console.error("Error fetching solar data:", error)); | |
} | |
function displayResultsOnMap(map, data, type) { | |
this.solarPanelPolygonReferences = new Map(); | |
this.solarPanelPolygons = []; | |
let panelsCount = 0; | |
let configIndex = 0; | |
// Check if roofSegmentStats array exists in the data | |
if (data && data.solarPotential.roofSegmentStats && Array.isArray(data.solarPotential.roofSegmentStats)) { | |
console.log(data.solarPotential.roofSegmentStats); | |
if (type === 'roof') { | |
let slider = document.querySelector('.slider_con'); | |
slider.innerHTML = ""; | |
// Loop through roofSegmentStats and add markers to the map for roof segments | |
data.solarPotential.roofSegmentStats.forEach(segment => { | |
const segmentMarker = new google.maps.Marker({ | |
position: { | |
lat: segment.center.latitude, | |
lng: segment.center.longitude | |
}, | |
map: map, | |
title: 'Roof Segment', | |
}); | |
map.setCenter({ | |
lat: segment.center.latitude, | |
lng: segment.center.longitude | |
}); | |
const solarDataDiv_chat = document.getElementById('yourParentContainerId'); | |
solarDataDiv_chat.innerHTML = ''; | |
// Attach a click event listener to the marker | |
google.maps.event.addListener(segmentMarker, 'click', function() { | |
const solarDataDiv = document.getElementById('solar_data'); | |
// Clear previous content | |
solarDataDiv.innerHTML = ''; | |
// Create elements to display the data | |
const areaMeters2Element = document.createElement('p'); | |
areaMeters2Element.textContent = 'Area meters2: ' + Math.floor(segment.stats.areaMeters2); | |
const pitchDegreesElement = document.createElement('p'); | |
pitchDegreesElement.textContent = 'Pitch Degrees: ' + Math.floor(segment.pitchDegrees); | |
const azimuthDegreesElement = document.createElement('p'); | |
azimuthDegreesElement.textContent = 'Azimuth Degrees: ' + Math.floor(segment.azimuthDegrees); | |
// Append elements to the div | |
solarDataDiv.appendChild(areaMeters2Element); | |
solarDataDiv.appendChild(pitchDegreesElement); | |
solarDataDiv.appendChild(azimuthDegreesElement); | |
}); | |
roofSegmentMarkers.push(segmentMarker); | |
}); | |
// Add a marker for the main location of the address | |
mainLocationMarker = new google.maps.Marker({ | |
position: { | |
lat: data.center.latitude, | |
lng: data.center.longitude | |
}, | |
map: map, | |
title: 'Main Location', | |
}); | |
google.maps.event.addListener(mainLocationMarker, 'click', function() { | |
const solarDataDiv = document.getElementById('solar_data'); | |
solarDataDiv.innerHTML = ''; | |
// Create elements to display the main location data | |
const sunshineHoursElement = document.createElement('p'); | |
sunshineHoursElement.textContent = 'Sunshine hours/year: ' + Math.floor(data.solarPotential.maxSunshineHoursPerYear); | |
const areaMeters2Element = document.createElement('p'); | |
areaMeters2Element.textContent = 'Area meters2: ' + Math.floor(data.solarPotential.maxArrayAreaMeters2); | |
const maxPanelsCountElement = document.createElement('p'); | |
maxPanelsCountElement.textContent = 'Max panels count: ' + Math.floor(data.solarPotential.maxArrayPanelsCount); | |
// Append elements to the div | |
solarDataDiv.appendChild(sunshineHoursElement); | |
solarDataDiv.appendChild(areaMeters2Element); | |
solarDataDiv.appendChild(maxPanelsCountElement); | |
}); | |
const myElement = document.getElementById('panelMarker'); | |
myElement.style.display = 'inline'; | |
} else if (type === 'panel') { | |
// Remove the main location marker | |
mainLocationMarker.setMap(null); | |
const myElement = document.getElementById('panelMarker'); | |
myElement.style.display = 'none'; | |
const solarDataDiv = document.getElementById('solar_data'); | |
solarDataDiv.innerHTML = ''; | |
// Find the existing div with the class "slider_con" | |
const sliderContainer = document.querySelector('.slider_con'); | |
clearSolarPanels(); | |
// Create a parent div for all elements | |
const sliderParentDiv = document.createElement("div"); | |
sliderParentDiv.className = "slider-container"; | |
sliderContainer.appendChild(sliderParentDiv); | |
// Create and append the panel-count-label div | |
const panelCountLabelElement = document.createElement("div"); | |
panelCountLabelElement.className = "panel-count-label"; | |
panelCountLabelElement.textContent = "Panels Count"; | |
sliderParentDiv.appendChild(panelCountLabelElement); | |
// Create a slider input and append it to the parent div | |
this.panelSliderElement = document.createElement("input"); | |
this.panelSliderElement.className = "solar-panels-panel-slider"; | |
this.panelSliderElement.type = "range"; | |
this.panelSliderElement.min = "0"; | |
this.panelSliderElement.max = (data.solarPotential.solarPanelConfigs.length) - 1; | |
this.panelSliderElement.value = "0"; | |
this.panelSliderElement.step = "1"; | |
sliderParentDiv.appendChild(this.panelSliderElement); | |
// Add an event listener to the slider input | |
this.panelSliderElement.addEventListener("input", () => { | |
// Clear existing solar panels on the map | |
clearSolarPanels(); | |
solarpanlespl(data, parseInt(this.panelSliderElement.value)); | |
}); | |
// Create and append the slider-value div | |
const sliderValueElement = document.createElement("div"); | |
sliderValueElement.className = "slider-value"; | |
sliderValueElement.textContent = "0"; | |
sliderParentDiv.appendChild(sliderValueElement); | |
// Reference to the parent container | |
const parentContainer = document.getElementById('yourParentContainerId'); | |
// Create the first div with the "panel_c" class and an h3 element | |
const divOne = document.createElement('div'); | |
divOne.className = 'panel_c'; | |
const h3One = document.createElement('h3'); | |
h3One.className = 'solar-panels-panel-title'; | |
h3One.textContent = 'Panels count'; | |
// Create a div with class "panel_co_val" and append it after h3 | |
const panelValueDivOne = document.createElement('div'); | |
panelValueDivOne.className = 'panel_co_val'; | |
// Append the h3 and the div to the first div | |
divOne.appendChild(h3One); | |
divOne.appendChild(panelValueDivOne); | |
// Create the second div with the "energy_c" class and an h3 element | |
const divTwo = document.createElement('div'); | |
divTwo.className = 'energy_c'; | |
const h3Two = document.createElement('h3'); | |
h3Two.className = 'solar-panels-panel-title'; | |
h3Two.textContent = 'Energy'; | |
// Create a div with class "energy_co_val" and append it after h3 | |
const energyValueDivTwo = document.createElement('div'); | |
energyValueDivTwo.className = 'energy_co_val'; | |
// Append the h3 and the div to the second div | |
divTwo.appendChild(h3Two); | |
divTwo.appendChild(energyValueDivTwo); | |
// Append the divs to the parent container | |
parentContainer.appendChild(divOne); | |
parentContainer.appendChild(divTwo); | |
const solarPanelConfig = data.solarPotential.solarPanelConfigs[configIndex]; | |
solarpanlespl(data, configIndex); | |
} | |
map.setZoom(25); | |
} else { | |
console.error('Invalid data format or missing roofSegmentStats.'); | |
} | |
} | |
function solarpanlespl(data, configIndex) { | |
this.solarPanelPolygonReferences = new Map(); | |
this.solarPanelPolygons = []; | |
let panelsCount = 0; | |
let energy = 0; | |
// let configIndex = 0; | |
const solarPanelConfig = data.solarPotential.solarPanelConfigs[configIndex]; | |
solarPanelConfig.roofSegmentSummaries.forEach((roofSegmentSummary) => { | |
data.solarPotential.solarPanels.filter((solarPanel) => solarPanel.segmentIndex === roofSegmentSummary.segmentIndex).slice(0, Math.min(solarPanelConfig.panelsCount - panelsCount, roofSegmentSummary.panelsCount)).forEach((solarPanel) => { | |
let height = data.solarPotential.panelHeightMeters / 2; | |
let width = data.solarPotential.panelWidthMeters / 2; | |
if (solarPanel.orientation === "LANDSCAPE") { | |
const previousHeight = height; | |
height = width; | |
width = previousHeight; | |
} | |
const angle = roofSegmentSummary.azimuthDegrees; | |
if (!this.solarPanelPolygonReferences.has(solarPanel)) { | |
const center = { | |
lat: solarPanel.center.latitude, | |
lng: solarPanel.center.longitude | |
}; | |
const top = google.maps.geometry.spherical.computeOffset(center, height, angle + 0); | |
const right = google.maps.geometry.spherical.computeOffset(center, width, angle + 90); | |
const left = google.maps.geometry.spherical.computeOffset(center, width, angle + 270); | |
const topRight = google.maps.geometry.spherical.computeOffset(top, width, angle + 90); | |
const bottomRight = google.maps.geometry.spherical.computeOffset(right, height, angle + 180); | |
const bottomLeft = google.maps.geometry.spherical.computeOffset(left, height, angle + 180); | |
const topLeft = google.maps.geometry.spherical.computeOffset(left, height, angle + 0); | |
solarPanelPolygonReferences.set(solarPanel, new google.maps.Polygon({ | |
map: map, | |
fillColor: "#2B2478", | |
fillOpacity: 0.8, | |
strokeWeight: 1, | |
strokeColor: "#AAAFCA", | |
strokeOpacity: 1, | |
geodesic: false, | |
paths: [ | |
topRight, | |
bottomRight, | |
bottomLeft, | |
topLeft | |
] | |
})); | |
} | |
const polygon = solarPanelPolygonReferences.get(solarPanel); | |
polygon.setMap(map); | |
solarPanelPolygons.push(polygon); | |
}); | |
panelsCount += roofSegmentSummary.panelsCount; | |
energy += roofSegmentSummary.yearlyEnergyDcKwh; | |
const slider_count_solar = document.querySelector('.slider-value'); | |
slider_count_solar.innerHTML = panelsCount; | |
console.log("Current Panel Count:", panelsCount); | |
// Assuming panelsCount and solarPotential.maxArrayPanelsCount are defined variables | |
// Get the slider_chart_val element | |
const slider_chart_val = document.querySelector('.panel_co_val'); | |
// Set the innerHTML dynamically with concatenated values | |
slider_chart_val.innerHTML = panelsCount + ' / ' + data.solarPotential.maxArrayPanelsCount; | |
// // Get the slider_chart_val element | |
const slider_chart_val_en = document.querySelector('.energy_co_val'); | |
// Set the innerHTML dynamically with concatenated values | |
slider_chart_val_en.innerHTML = Math.round(energy).toString() + " kwh"; | |
}); | |
} | |
function clearSolarPanels() { | |
// Clear existing solar panels from the map | |
solarPanelPolygons.forEach(polygon => polygon.setMap(null)); | |
solarPanelPolygons = []; | |
panelsCount = 0; | |
solarPanelPolygonReferences.clear(); | |
} | |
function clearMarkers() { | |
// Clear roof segment markers | |
roofSegmentMarkers.forEach(marker => marker.setMap(null)); | |
roofSegmentMarkers = []; | |
// Clear solar panel markers | |
panelMarkers.forEach(marker => marker.setMap(null)); | |
panelMarkers = []; | |
} | |
</script> | |
<script async defer | |
src="https://maps.googleapis.com/maps/api/js?{KEY}&libraries=places,geometry&callback=initMap"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment