我使用 google places API 编写了一个 .kmz 文件生成器。该程序在我的本地机器上运行良好,但一旦我在 Azure 上启动它,用户在谷歌地球上打开时就不会收到自定义图标。它只显示中心带有红色 x 的白色框作为图标。我已经通过让远程用户将 .kmz 更改为 .zip 并解压缩文件以查看内容来验证图标正在与 kml 文件一起下载到 .kmz 文件中。他们在那里找到了 kml 文件和自定义图标 png 文件,所以它一定与我放置它的位置有关,或者 google earth 如何引用 kmz 中的图标......?我迷路了我已经尝试了一切。这是我的应用程序的主要部分:
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
只是想更新这个,因为我最终自己找到了答案。问题是 Bank Icon.png 需要位于名为“files”的目录中,我必须更新 kml_generator 以引用新位置。这是更新后的代码:
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 pathlib
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('files', icon_filename)
# Create the 'files' directory if it doesn't exist
files_dir = os.path.join(script_dir, 'files')
pathlib.Path(files_dir).mkdir(parents=True, exist_ok=True)
# Copy the 'Bank Icon.png' to the 'files' directory if it doesn't exist
icon_src_path = os.path.join(script_dir, icon_filename)
icon_dest_path = os.path.join(files_dir, icon_filename)
if not os.path.exists(icon_dest_path):
shutil.copy(icon_src_path, icon_dest_path)
# Google Maps API key
api_key = "My_Google_Place_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:
icon_filename = 'Bank Icon.png'
icon_path = os.path.join('files', 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')
zf.write(os.path.join(script_dir, icon_filename), arcname=os.path.join('files', icon_filename))
# Remove the temporary KML file
os.remove(kml_file_path)
return kmz_file_path