【问题标题】:How do you implement Google Maps in Uno WASM你如何在 Uno WASM 中实现谷歌地图
【发布时间】:2021-07-12 11:16:53
【问题描述】:

我是 Uno Platform 的新手,需要帮助我将 Google 地图添加到我的应用中。由于 MapControl 不提供 WASM 支持,看来我需要嵌入一个 javascript 组件。根据https://platform.uno/blog/how-to-embed-javascript-components-in-c-built-uno-webassembly-web-applications/,这应该是可能的。但我似乎无法让它工作。

我有一个包含以下内容的 javascript 文件,该文件直接取自谷歌地图官方网站。也不确定将地图 API 密钥放在哪里。

// Initialize and add the map
function initMap() {
    // The location of Uluru
    const uluru = { lat: -25.344, lng: 131.036 };
    // The map, centered at Uluru
    const map = new google.maps.Map(document.getElementById("map"), {
        zoom: 4,
        center: uluru,
    });
    // The marker, positioned at Uluru
    const marker = new google.maps.Marker({
        position: uluru,
        map: map,
    });
}

我也有这个类,尝试过类似于官方 Uno Platform Embedd Javascript Components 指南中的part 3

    public class GoogleMapsController : FrameworkElement
    {
        public GoogleMapsController()
        {
            LoadJavaScript();
        }

        private async void LoadJavaScript()
        {
            await this.ExecuteJavascriptAsync("initMap()");
        }

    }

在 xaml 页面中显示地图:

<local:GoogleMapsController x:Name="googlemaps" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" />

当我运行应用程序时,地图不显示。有谁知道我做错了什么?

Web 控制台中显示以下内容

fail: Windows.UI.Core.CoreDispatcher[0]
dotnet.js:1       Dispatcher unhandled exception
dotnet.js:1 System.ApplicationException
dotnet.js:1   at TestMaps.GoogleMapsController.LoadJavaScript () <0x2f90540 + 0x000e6> in <filename unknown>:0 
dotnet.js:1   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) <0x2f9ba10 + 0x00010> in <filename unknown>:0 
dotnet.js:1   at Windows.UI.Core.CoreDispatcherSynchronizationContext+<>c__DisplayClass3_0.<Post>b__0 () <0x2f9b9d0 + 0x00014> in <filename unknown>:0 
dotnet.js:1   at Windows.UI.Core.CoreDispatcher.DispatchItems () <0x2a8a0a0 + 0x001e6> in <filename unknown>:0 

如果我在 GoogleMapsController 中将 LoadJavaScript() 更改为同步,则 Web 控制台中会显示以下内容。

dotnet.js:1 Error #1 "ReferenceError: google is not defined" executing javascript: "
put_char @ dotnet.js:1
dotnet.js:1 (function(element) {
put_char @ dotnet.js:1
dotnet.js:1 initMap()
put_char @ dotnet.js:1
dotnet.js:1 })(Uno.UI.WindowManager.current.getView(38002));
put_char @ dotnet.js:1
dotnet.js:1 "

【问题讨论】:

标签: google-maps webassembly uno-platform


【解决方案1】:

搞定了,以后我可能会写一篇关于它的博文。

获取 Google Maps API 密钥

您可以按照网络上的任何教程了解如何通过 Google 开发者控制台获取 API 密钥。它涉及创建项目、添加所需的计费信息、创建 API 密钥,然后为其启用 Google Maps API。 当您计划公开时,请务必限制 API 密钥,以免有人滥用您的密钥并以这种方式耗尽您的账单。

将自定义 index.html 添加到您的 WASM 项目中

由于 Google 地图需要加载外部 JavaScript 库,因此在您的应用首次加载时提前加载它会很有用。为此,请将 index.html 文件添加到您的 WASM 项目的根目录,其中包含以下内容:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

    <script type="text/javascript" src="./require.js"></script>
    <script type="text/javascript" src="./mono-config.js"></script>
    <script type="text/javascript" src="./uno-config.js"></script>
    <script type="text/javascript" src="./uno-bootstrap.js"></script>
    <script async type="text/javascript" src="./dotnet.js"></script>
    <!-- Google Maps libs here: -->
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&libraries=&v=weekly"></script>

    $(ADDITIONAL_CSS)
    $(ADDITIONAL_HEAD)
</head>
<body>
    <div id="uno-body" class="container-fluid uno-body">
        <div class="uno-loader"
             loading-position="bottom"
             loading-alert="none">

            <!-- Logo: change src to customize the logo -->
            <img class="logo"
                 src=""
                 title="Uno is loading your application" />

            <progress></progress>
            <span class="alert"></span>
        </div>
    </div>
    <noscript>
        <p>This application requires Javascript and WebAssembly to be enabled.</p>
    </noscript>
</body>
</html>

请注意,大部分代码都是样板代码,是 Uno WASM 项目中的默认代码(请参阅 here)。将 MYAPIKEY 替换为开发者控制台中的 API 密钥。

现在您需要指示 WASM 引导程序使用此自定义 index.html。在解决方案资源管理器中双击 .csproj 并添加以下内容:

<PropertyGroup>
   <WasmShellIndexHtmlPath>index.html</WasmShellIndexHtmlPath>
</PropertyGroup>

创建自定义地图元素

与文档中的教程类似,我创建了以下元素:

#if __WASM__
using System;
using Uno.UI.Runtime.WebAssembly;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;

namespace UnoWasmGoogleMaps
{
    [HtmlElement("div")]
    public class GoogleMapView : FrameworkElement
    {
        private readonly string _mapObjectName = "map_" + Guid.NewGuid().ToString().Replace("-", "");

        public GoogleMapView()
        {            
            Background = new SolidColorBrush(Colors.Transparent);
            LoadMap();
        }

        private void LoadMap()
        {
            var javascript = $@"var {_mapObjectName} = new google.maps.Map(element, {{ center: {{lat: -34.397, lng: 150.644}}, zoom: 8 }});";

            this.ExecuteJavascript(javascript);
        }
    }
}
#endif

注意我使用自定义唯一变量名来存储由 Google Maps API 创建的地图对象。您可以使用此变量名来操作地图并在其上调用一些函数。

使用元素

最后,您可以像这样在应用中使用该元素:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <local:GoogleMapView />
</Grid>

结果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2016-06-20
    • 2016-11-11
    相关资源
    最近更新 更多