I wrote a .kmz file generator using a google places API. The program works great on my local machine but once I launched it on Azure, user's are not receiving the custom icon when opened on google earth. It just displays the white box with red x in the center as the icon. I have verified that the icon is downloading inside the .kmz file along with the kml file by having the remote user change .kmz to .zip and unzipping the file to see the contents. There they find the kml file and the custom icon png file so It must be something with where I'm placing it or how google earth references icons in the kmz...? I'm at a lost I've tried everything. Here's the main part of my app:
import requests
from fastkml import kml
from fastkml import styles
from fastkml.geometry import Point
from fastkml.styles import IconStyle
import xml.etree.ElementTree as ET
from pykml.factory import KML_ElementMaker as KML
from pykml.parser import fromstring as kml_fromstring
import os
import zipfile
import tempfile
import shutil
# Get the path of the current script
script_dir = os.path.dirname(os.path.abspath(__file__))
# Construct the path to the icon file
icon_filename = 'Bank Icon.png'
icon_path = os.path.join(script_dir, icon_filename)
# Google Maps API key
api_key = "My_API_key"
def search_institution_locations(institution, location):
search_url = "https://maps.googleapis.com/maps/api/place/textsearch/xml"
query = f"{institution} in {location}"
params = {
"query": query,
"key": api_key,
}
try:
response = requests.get(search_url, params=params)
response.raise_for_status()
except Exception as e:
print(f"An error occurred while searching for {institution} in {location}: {e}")
return None
# Print the response text for debugging purposes
print(response.text)
return response.text
def generate_kml(institution, city=None, state=None, icon_path=None):
print('kml generator initiated')
# Update the icon_path if it's not provided
if icon_path is None:
script_dir = os.path.dirname(os.path.abspath(__file__))
icon_filename = 'Bank Icon.png'
icon_path = os.path.join(script_dir, icon_filename)
# Determine the location based on the search scope
location = f"{city}, {state}"
# Search for institution locations within the location
search_results = search_institution_locations(institution, location)
# Parse the XML search results
root = ET.fromstring(search_results)
# Create a KML document
doc = kml.Document()
# Create the IconStyle with the custom icon
icon_style = styles.IconStyle(icon_href=icon_path, scale=2.0)
# Create the LabelStyle with a scale of 0.0 to hide the text
label_style = styles.LabelStyle(scale=0.0)
# Combine the IconStyle and LabelStyle into a Style
style = styles.Style(id='icon', styles=[icon_style, label_style])
doc.append_style(style)
# Add Placemarks for each search result
for result in root.findall("result"):
name = result.find("name").text
address = result.find("formatted_address").text
lat = float(result.find("geometry/location/lat").text)
lng = float(result.find("geometry/location/lng").text)
placemark = kml.Placemark(
name=name,
description=address,
styleUrl="#icon" # Use the custom icon style
)
placemark.geometry = Point((lng, lat))
doc.append(placemark)
# Save KML file
with tempfile.NamedTemporaryFile(suffix='.kml', delete=False) as temp:
print(doc.to_string(prettyprint=True))
kml_file_path = temp.name
with open(kml_file_path, "w", encoding="utf-8") as f:
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
f.write(doc.to_string(prettyprint=True))
# Create KMZ file
kmz_file_name = f"{institution.replace(' ', '_')}_locations.kmz"
with tempfile.NamedTemporaryFile(suffix='.kmz', delete=False) as temp:
kmz_file_path = temp.name
with zipfile.ZipFile(kmz_file_path, 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write(kml_file_path, arcname=os.path.splitext(kmz_file_name)[0] + '.kml') # Modified line
zf.write(icon_path, arcname=os.path.basename(icon_path))
# Remove the temporary KML file
os.remove(kml_file_path)
return kmz_file_path