我的 kmz 生成器应用程序未在远程用户的机器上显示自定义图标

问题描述 投票:0回答:1

我使用 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
python azure kml google-earth kmz
1个回答
0
投票

只是想更新这个,因为我最终自己找到了答案。问题是 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
© www.soinside.com 2019 - 2024. All rights reserved.