Maui Blazor 中文社区 QQ群:645660665

Blazor组件自做六 : 使用JS隔离封装Baidu地图

1. 运行截图

演示地址

2. 在文件夹wwwroot/lib,添加baidu子文件夹,添加baidumap.js文件

2.1 跟上一篇类似,用代码方式异步加载API,脚本生成新的 body > script 元素添加到页面文档,使用异步加载回调 initMapsG 方法初始化地图.

var map = null;
var containerid = null;
export function addScript(key, elementId, dotnetRef, backgroundColor, controlSize) {
    if (!key || !elementId) {
        return;
    }

    containerid = elementId;
    let url = "https://api.map.baidu.com/api?v=3.0&ak=";
    let scriptsIncluded = false;

    let scriptTags = document.querySelectorAll('body > script');
    scriptTags.forEach(scriptTag => {
        if (scriptTag) {
            let srcAttribute = scriptTag.getAttribute('src');
            if (srcAttribute && srcAttribute.startsWith(url)) {
                scriptsIncluded = true;
                return true;
            }
        }
    });

    if (scriptsIncluded) {
        initMapsG();
        return true;
    }

    url = url + key + "&callback=initMapsG";
    let script = document.createElement('script');
    script.src = url;
    document.body.appendChild(script);
    return false;
}

2.2 初始化地图方法.

export function resetMaps(elementId) {
    initMaps(elementId);
}
function initMapsG() {
    initMaps(containerid);
}
function initMaps(elementId) {
    // 创建地图实例
    map = new BMap.Map(elementId, {
        coordsType: 5 // coordsType指定输入输出的坐标类型,3为gcj02坐标,5为bd0ll坐标,默认为5。指定完成后API将以指定的坐标类型处理您传入的坐标
    });
    // 创建点坐标
    var point = new BMap.Point(116.47496, 39.77856);
    // 初始化地图,设置中心点坐标和地图级别
    map.centerAndZoom(point, 15);
    //开启鼠标滚轮缩放
    map.enableScrollWheelZoom(true);
    map.addControl(new BMap.NavigationControl());
    map.addControl(new BMap.ScaleControl());
    map.addControl(new BMap.OverviewMapControl());
    map.addControl(new BMap.MapTypeControl());
    // 仅当设置城市信息时,MapTypeControl的切换功能才能可用
    map.setCurrentCity("北京");
}

2.3 百度地定位图API,并开启SDK辅助定位.

export function geolocation(wrapper) {
    var geolocation = new BMap.Geolocation();
    // 开启SDK辅助定位
    geolocation.enableSDKLocation();
    geolocation.getCurrentPosition(function (r) {
        let geolocationitem;
        if (this.getStatus() == BMAP_STATUS_SUCCESS) {
            var mk = new BMap.Marker(r.point);
            map.addOverlay(mk);
            map.panTo(r.point);
            console.log('您的位置:' + r.point.lng + ',' + r.point.lat);
            let lng = r.point.lng;
            let lat = r.point.lat;
            geolocationitem= {
                "Longitude":lng,
                "Latitude" : lat,
                "Status": '您的位置:' + r.point.lng + ',' + r.point.lat
            };
        }
        else {
            geolocationitem= {
                "Longitude": 0,
                "Latitude": 0,
                "Status": 'failed' + this.getStatus()
            };
        }
        wrapper.invokeMethodAsync('GetResult', geolocationitem);
        return geolocationitem;
    });
}

3. 打开Components文件夹 , 新建baidu文件夹, 新建BaiduMap.razor文件

razor代码
@implements IAsyncDisposable
@inject IJSRuntime JS
@namespace Blazor100.Components
@inject IConfiguration config 

<div id="@ID" style="@Style"></div>
<button class="btn btn-primary" type="button" onclick="@(async()=>await GetLocation())">Location</button>
<button class="btn btn-primary" type="button" onclick="@(async()=>await ResetMaps())">Reset</button>

@code{

    /// <summary>
    /// 获得/设置 错误回调方法
    /// </summary>
    [Parameter]
    public Func<string, Task>? OnError { get; set; }

    /// <summary>
    /// 获得/设置 BaiduKey<para></para>
    /// 为空则在 IConfiguration 服务获取 "BaiduKey" , 默认在 appsettings.json 文件配置
    /// </summary>
    [Parameter]
    public string? Key { get; set; }

    /// <summary>
    /// 获得/设置 style
    /// </summary>
    [Parameter]
    public string Style { get; set; } = "height:700px;width:100%;";

    /// <summary>
    /// 获得/设置 ID
    /// </summary>
    [Parameter]
    public string ID { get; set; } = "container";

    /// <summary>
    /// 获得/设置 定位结果回调方法
    /// </summary>
    [Parameter]
    public Func<BaiduItem, Task>? OnResult { get; set; }

    private IJSObjectReference? module;
    private DotNetObjectReference<BaiduMap>? InstanceGeo { get; set; }

    private string key = String.Empty;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            key = Key ?? config["BaiduKey"];
            module = await JS.InvokeAsync<IJSObjectReference>("import", "./lib/baidu/baidumap.js");
            InstanceGeo = DotNetObjectReference.Create(this);
            while (!(await Init()))
            {
                await Task.Delay(500);
            }
            //await module!.InvokeVoidAsync("initMaps");
        }
    }

    public async Task<bool> Init() => await module!.InvokeAsync<bool>("addScript", new object?[] { key, ID, null, null, null });

    public async Task OnOptionsChanged(ViewerOptions options) => await module!.InvokeVoidAsync("init", options);
    public async Task ResetMaps() => await module!.InvokeVoidAsync("resetMaps", ID);

    public async Task OnBtnClick(string btn) => await module!.InvokeVoidAsync(btn);

    /// <summary>
    /// 获取定位
    /// </summary>
    public virtual async Task GetLocation()
    {
        try
        {
            await module!.InvokeVoidAsync("geolocation", InstanceGeo);
        }
        catch (Exception e)
        {
            if (OnError != null) await OnError.Invoke(e.Message);
        }
    }


    /// <summary>
    /// 定位完成回调方法
    /// </summary>
    /// <param name="geolocations"></param>
    /// <returns></returns>
    [JSInvokable]
    public async Task GetResult(BaiduItem geolocations)
    {
        try
        {
            if (OnResult != null) await OnResult.Invoke(geolocations);
        }
        catch (Exception e)
        {
            if (OnError != null) await OnError.Invoke(e.Message);
        }
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            //await module.InvokeVoidAsync("destroy", Options);
            await module.DisposeAsync();
        }
    }
}


4. Components/baidu文件夹 , 新建文件夹, 新建BaiduItem.cs文件

Baidu定位数据类

using System;
using System.ComponentModel;

namespace Blazor100.Components
{

    /// <summary>
    /// Baidu定位数据类
    /// </summary>
    public class BaiduItem
    {
        /// <summary>
        /// 状态
        /// </summary>
        /// <returns></returns>
        [DisplayName("状态")]
        public string? Status { get; set; }

        /// <summary>
        /// 纬度
        /// </summary>
        /// <returns></returns>
        [DisplayName("纬度")]
        public decimal Latitude { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        /// <returns></returns>
        [DisplayName("经度")]
        public decimal Longitude { get; set; }


    }
}

5. Pages文件夹添加BaiduMapPage.razor文件,用于演示组件调用.

BaiduMapPage.razor

@page "/baidumap"

<h3>百度地图 Baidu Map</h3>

<p>@message</p>

<BaiduMap OnError="@OnError" OnResult="@OnResult" />

BaiduMapPage.razor.cs

using Blazor100.Components;

namespace Blazor100.Pages;

/// <summary>
/// 百度地图 BaiduMap
/// </summary>
public sealed partial class BaiduMapPage
{

    private string message;
    private BaiduItem baiduItem;

    private Task OnResult(BaiduItem geolocations)
    {
        baiduItem = geolocations;
        this.message = baiduItem.Status;
        StateHasChanged();
        return Task.CompletedTask;
    }

    private Task OnError(string message)
    {
        this.message = message;
        StateHasChanged();
        return Task.CompletedTask;
    }
      
}

6. _Imports.razor加入一行引用组件的命名空间.

@using Blazor100.Components

7. 首页引用组件演示页 <BaiduMapPage /> 或者 Shared/NavMenu.razor 添加导航

<div class="nav-item px-3">
    <NavLink class="nav-link" href="baidumap">
        百度地图
    </NavLink>
</div>

8. F5运行程序

至此,使用JS隔离封装Baidu地图大功告成! Happy coding!

Blazor组件自做系列

Blazor组件自做一 : 使用JS隔离封装viewerjs库
Blazor组件自做二 : 使用JS隔离制作手写签名组件
Blazor组件自做三 : 使用JS隔离封装ZXing扫码
Blazor组件自做四: 使用JS隔离封装signature_pad签名组件
Blazor组件自做五: 使用JS隔离封装Google地图<03-24>
Blazor组件自做六: 使用JS隔离封装Baidu地图<03-25>
Blazor组件自做七: 使用JS隔离制作定位/持续定位组件<03-26>
Blazor组件自做八: 使用JS隔离封装屏幕键盘kioskboard.js组件<03-27>

项目源码 Github | Gitee

posted @ 2022-03-25 10:08  AlexChow  阅读(473)  评论(0编辑  收藏  举报