mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-12-05 13:39:39 +08:00
!2396 feat(#I4SQKN): add GeolocationService
* Merge branch 'main' into dev-alex-geo * doc: 更新地理位置信息服务示例 * chore: 更新打包文件 * doc: 格式化文档 * chore: 删除资源文件 * chore: 增加地理位置服务 * feat: 删除地理位置组件改用服务形式 * feat: 增加地理位置脚本调用方法 * doc: 更新示例文档 * chore: 调整位置 * revert: 删除图片 * chore: 更新菜单位置 * chore: 删除 nuevo_libs 组件库 * chore: 恢复配置 * chore: 更新配置 * chore: 移除 GenlocationItem 资源文件 * refactor: 恢复配置 * scripts: 打包脚本 * refactor: 继承 IDispose 接口 * refactor: 重命名符合命名规范 * refactor: 重命名 GeolocationItem * refactor: 格式化代码 * refactor: 移除标签 * Merge branch 'main' into dev-alex-geo * 提交地理定位/移动距离追踪组件[Desktop/Mobile 通用] * Merge branch 'main' into dev-alex-geo * Re-build bootstrap.blazor.bundle.min.js * 合并 dev * Merge branch 'dev' into dev-alex-geo * 加入[停止追踪]功能, 正确放置 Geolocation.js ,移除host调试引用的js * Geolocation 国际化 * 国际化
This commit is contained in:
parent
e9c26d3ac8
commit
14e8926602
@ -417,7 +417,8 @@
|
||||
"ChartPieText": "Pie",
|
||||
"ChartDoughnutText": "Doughnut",
|
||||
"ChartBubbleText": "Bubble",
|
||||
"DispatchText": "Dispatch"
|
||||
"DispatchText": "Dispatch",
|
||||
"GeolocationText": "Geolocation"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.GlobalException": {
|
||||
"Title": "Global exception",
|
||||
@ -2675,7 +2676,8 @@
|
||||
"ChartPie": "Pie",
|
||||
"ChartDoughnut": "Doughnut",
|
||||
"ChartBubble": "Bubble",
|
||||
"Transition": "Transition"
|
||||
"Transition": "Transition",
|
||||
"Geolocation": "Geolocation"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.Table.TablesFooter": {
|
||||
"Left": "Left",
|
||||
@ -2744,5 +2746,27 @@
|
||||
"ClearButtonTextDefaultValue": "Clear",
|
||||
"Result": "Handwritten signature imgBase64 string",
|
||||
"HandwrittenBase64": "Handwritten result callback method"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.Geolocations": {
|
||||
"Title": "Geolocation",
|
||||
"BaseUsageText": "Basic usage",
|
||||
"IntroText1": "Obtain location information through browser API.",
|
||||
"IntroText2": "Click the button to get your coordinates.",
|
||||
"IntroText3": "Note: For security reasons, when a web page tries to access location information, the user is notified and asked to grant permission. Be aware that each browser has its own policies and methods for requesting this permission.",
|
||||
"GetLocationButtonText": "Get Location",
|
||||
"WatchPositionButtonText": "Watch Position",
|
||||
"ClearWatchPositionButtonText": "Stop Watch Position",
|
||||
"GetLocationResultSuccess": "Call GetLocaltion success",
|
||||
"GetLocationResultFailed": "Call GetLocaltion failed",
|
||||
"Longitude": "Longitude",
|
||||
"Latitude": "Latitude",
|
||||
"Accuracy": "Accuracy",
|
||||
"Altitude": "Altitude",
|
||||
"AltitudeAccuracy": "AltitudeAccuracy",
|
||||
"Heading": "Heading",
|
||||
"Speed": "Speed",
|
||||
"LastUpdateTime": "UpdateTime",
|
||||
"CurrentDistance": "CurrentDistance",
|
||||
"TotalDistance": "TotalDistance"
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +417,8 @@
|
||||
"ChartPieText": "饼图",
|
||||
"ChartDoughnutText": "圆环图",
|
||||
"ChartBubbleText": "气泡图",
|
||||
"DispatchText": "消息分发 Dispatch"
|
||||
"DispatchText": "消息分发 Dispatch",
|
||||
"GeolocationText": "地理定位组件 Geolocation"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.GlobalException": {
|
||||
"Title": "全局异常",
|
||||
@ -2680,7 +2681,8 @@
|
||||
"ChartPie": "饼图",
|
||||
"ChartDoughnut": "圆环图",
|
||||
"ChartBubble": "气泡图",
|
||||
"Transition": "过渡效果 Transition"
|
||||
"Transition": "过渡效果 Transition",
|
||||
"Geolocation": "地理定位组件 Geolocation"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.Table.TablesFooter": {
|
||||
"Left": "左对齐",
|
||||
@ -2749,5 +2751,27 @@
|
||||
"ClearButtonTextDefaultValue": "清除",
|
||||
"Result": "手写签名imgBase64字符串",
|
||||
"HandwrittenBase64": "手写结果回调方法"
|
||||
},
|
||||
"BootstrapBlazor.Shared.Samples.Geolocations": {
|
||||
"Title": "地理定位/移动距离追踪",
|
||||
"BaseUsageText": "基础用法",
|
||||
"IntroText1": "通过浏览器API获取定位信息。",
|
||||
"IntroText2": "单击按钮以获取地理位置坐标。",
|
||||
"IntroText3": "注意: 出于安全考虑,当网页请求获取用户位置信息时,用户会被提示进行授权。注意不同浏览器在请求权限时有不同的策略和方式。Windows10 在未开启定位的情况下无法获取位置。",
|
||||
"GetLocationButtonText": "获取位置",
|
||||
"WatchPositionButtonText": "移动距离追踪",
|
||||
"ClearWatchPositionButtonText": "停止追踪",
|
||||
"GetLocationResultSuccess": "调用 GetLocaltion 成功",
|
||||
"GetLocationResultFailed": "调用 GetLocaltion 失败",
|
||||
"Longitude": "经度",
|
||||
"Latitude": "纬度",
|
||||
"Accuracy": "位置精度",
|
||||
"Altitude": "海拔",
|
||||
"AltitudeAccuracy": "海拔精度",
|
||||
"Heading": "方向",
|
||||
"Speed": "速度",
|
||||
"LastUpdateTime": "时间戳",
|
||||
"CurrentDistance": "移动距离",
|
||||
"TotalDistance": "总移动距离"
|
||||
}
|
||||
}
|
||||
|
@ -83,8 +83,10 @@
|
||||
<ComponentCard Text="@Localizer["CircleText"]" Image="Circle.png" Url="circles"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["CollapseText"]" Image="Collapse.svg" Url="collapses"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["DisplayText"]" Image="Display.jpg" Url="displays"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["DownloadText"]" Image="Download.png" Url="downloads"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["DropdownWidgetText"]" Image="DropdownWidget.png" Url="dropdownwidgets"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["EmptyText"]" Image="Empty.jpg" Url="empties"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["GeolocationText"]" Image="Geolocation.jpg" Url="geolocations"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["GroupBoxText"]" Image="GroupBox.png" Url="groupboxs"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["HandwrittenPageText"]" Image="Handwritten.jpg" Url="handwrittenpage"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["LinkButtonText"]" Image="LinkButton.png" Url="linkbuttons"></ComponentCard>
|
||||
@ -98,10 +100,9 @@
|
||||
<ComponentCard Text="@Localizer["TagText"]" Image="Tag.svg" Url="tags"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["TimelineText"]" Image="Timeline.svg" Url="timelines"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["TitleText"]" Image="Title.jpg" Url="titles"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["DownloadText"]" Image="Download.png" Url="downloads"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["TreeText"]" Image="Tree.svg" Url="trees"></ComponentCard>
|
||||
<ComponentCard Text="@Localizer["TransitionText"]" Image="Transition.jpg" Url="transitions"></ComponentCard>
|
||||
</ComponentCategory>
|
||||
</ComponentCategory>
|
||||
|
||||
<ComponentCategory Text="@Localizer["Text6"]">
|
||||
<ComponentCard Text="@Localizer["ChartSummaryText"]" Image="Chart.png" Url="charts/index"></ComponentCard>
|
||||
|
@ -32,56 +32,56 @@ public partial class FloatingLabels
|
||||
|
||||
private IEnumerable<AttributeItem> GetAttributes() => new[]
|
||||
{
|
||||
new AttributeItem() {
|
||||
Name = "ChildContent",
|
||||
Description = Localizer["Att1"].Value,
|
||||
Type = "RenderFragment",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "ShowLabel",
|
||||
Description = Localizer["Att2"].Value,
|
||||
Type = "bool",
|
||||
ValueList = "true|false",
|
||||
DefaultValue = "false"
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "DisplayText",
|
||||
Description = Localizer["Att3"].Value,
|
||||
Type = "string",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "FormatString",
|
||||
Description = Localizer["Att4"].Value,
|
||||
Type = "string",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "Formatter",
|
||||
Description = Localizer["Att5"].Value,
|
||||
Type = "RenderFragment<TItem>",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem()
|
||||
{
|
||||
Name = "type",
|
||||
Description = Localizer["Att6"].Value,
|
||||
Type = "string",
|
||||
ValueList = "text / number / email / url / password",
|
||||
DefaultValue = "text"
|
||||
},
|
||||
new AttributeItem()
|
||||
{
|
||||
Name = "IsDisabled",
|
||||
Description = Localizer["Att7"].Value,
|
||||
Type = "bool",
|
||||
ValueList = "true|false",
|
||||
DefaultValue = "false"
|
||||
}
|
||||
};
|
||||
new AttributeItem() {
|
||||
Name = "ChildContent",
|
||||
Description = Localizer["Att1"].Value,
|
||||
Type = "RenderFragment",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "ShowLabel",
|
||||
Description = Localizer["Att2"].Value,
|
||||
Type = "bool",
|
||||
ValueList = "true|false",
|
||||
DefaultValue = "false"
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "DisplayText",
|
||||
Description = Localizer["Att3"].Value,
|
||||
Type = "string",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "FormatString",
|
||||
Description = Localizer["Att4"].Value,
|
||||
Type = "string",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem() {
|
||||
Name = "Formatter",
|
||||
Description = Localizer["Att5"].Value,
|
||||
Type = "RenderFragment<TItem>",
|
||||
ValueList = " — ",
|
||||
DefaultValue = " — "
|
||||
},
|
||||
new AttributeItem()
|
||||
{
|
||||
Name = "type",
|
||||
Description = Localizer["Att6"].Value,
|
||||
Type = "string",
|
||||
ValueList = "text / number / email / url / password",
|
||||
DefaultValue = "text"
|
||||
},
|
||||
new AttributeItem()
|
||||
{
|
||||
Name = "IsDisabled",
|
||||
Description = Localizer["Att7"].Value,
|
||||
Type = "bool",
|
||||
ValueList = "true|false",
|
||||
DefaultValue = "false"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
51
src/BootstrapBlazor.Shared/Samples/Geolocations.razor
Normal file
51
src/BootstrapBlazor.Shared/Samples/Geolocations.razor
Normal file
@ -0,0 +1,51 @@
|
||||
@page "/geolocations"
|
||||
|
||||
<h3>@Localizer["Title"]</h3>
|
||||
|
||||
<DemoBlock Title="@Localizer["BaseUsageText"]" Introduction="@Localizer["IntroText1"]" Name="Normal">
|
||||
<p>@Localizer["IntroText2"]</p>
|
||||
<Tips>
|
||||
<p>@Localizer["IntroText3"]</p>
|
||||
</Tips>
|
||||
<Button Text="@Localizer["GetLocationButtonText"]" OnClick="GetLocation"></Button>
|
||||
@if (Model != null)
|
||||
{
|
||||
<div class="form-inline row mt-3">
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.Longitude" ShowLabel="true" DisplayText="@Localizer["Longitude"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.Latitude" ShowLabel="true" DisplayText="@Localizer["Latitude"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.Accuracy" ShowLabel="true" DisplayText="@Localizer["Accuracy"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.Altitude" ShowLabel="true" DisplayText="@Localizer["Altitude"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.AltitudeAccuracy" ShowLabel="true" DisplayText="@Localizer["AltitudeAccuracy"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.Heading" ShowLabel="true" DisplayText="@Localizer["Heading"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.Speed" ShowLabel="true" DisplayText="@Localizer["Speed"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.CurrentDistance" ShowLabel="true" DisplayText="@Localizer["CurrentDistance"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.TotalDistance" ShowLabel="true" DisplayText="@Localizer["TotalDistance"]" />
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<Display Value="@Model.LastUpdateTime" ShowLabel="true" DisplayText="@Localizer["LastUpdateTime"]" />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<BlockLogger @ref="Trace" class="mt-3" />
|
||||
</DemoBlock>
|
80
src/BootstrapBlazor.Shared/Samples/Geolocations.razor.cs
Normal file
80
src/BootstrapBlazor.Shared/Samples/Geolocations.razor.cs
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
using BootstrapBlazor.Shared.Common;
|
||||
using BootstrapBlazor.Shared.Components;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace BootstrapBlazor.Shared.Samples;
|
||||
|
||||
/// <summary>
|
||||
/// Geolocation 地理定位/移动距离追踪
|
||||
/// </summary>
|
||||
public partial class Geolocations : IDisposable
|
||||
{
|
||||
private JSInterop<Geolocations>? Interop { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private BlockLogger? Trace { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<Geolocations>? Localizer { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IJSRuntime? JSRuntime { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private GeolocationService? GeolocationService { get; set; }
|
||||
|
||||
private GeolocationItem? Model { get; set; }
|
||||
|
||||
private async Task GetLocation()
|
||||
{
|
||||
Interop ??= new JSInterop<Geolocations>(JSRuntime);
|
||||
var ret = await GeolocationService.GetLocaltion(Interop, this, nameof(GetLocationCallback));
|
||||
Trace.Log(ret ? Localizer["GetLocationResultSuccess"] : Localizer["GetLocationResultFailed"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
[JSInvokable]
|
||||
public void GetLocationCallback(GeolocationItem item)
|
||||
{
|
||||
Model = item;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (Interop != null)
|
||||
{
|
||||
Interop.Dispose();
|
||||
Interop = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -445,6 +445,12 @@ public sealed partial class NavMenu
|
||||
Url = "empties"
|
||||
},
|
||||
new()
|
||||
{
|
||||
IsNew= true,
|
||||
Text = Localizer["Geolocation"],
|
||||
Url = "geolocations"
|
||||
},
|
||||
new()
|
||||
{
|
||||
Text = Localizer["GroupBox"],
|
||||
Url = "groupboxs"
|
||||
|
BIN
src/BootstrapBlazor.Shared/wwwroot/images/Geolocation.jpg
Normal file
BIN
src/BootstrapBlazor.Shared/wwwroot/images/Geolocation.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
139
src/BootstrapBlazor/Components/Geolocation/Geolocation.js
Normal file
139
src/BootstrapBlazor/Components/Geolocation/Geolocation.js
Normal file
@ -0,0 +1,139 @@
|
||||
(function ($) {
|
||||
Number.prototype.toRadians = function () {
|
||||
return this * Math.PI / 180;
|
||||
}
|
||||
|
||||
$.extend({
|
||||
bb_geo_distance: function (latitude1, longitude1, latitude2, longitude2) {
|
||||
// R is the radius of the earth in kilometers
|
||||
var R = 6371;
|
||||
|
||||
var deltaLatitude = (latitude2 - latitude1).toRadians();
|
||||
var deltaLongitude = (longitude2 - longitude1).toRadians();
|
||||
latitude1 = latitude1.toRadians(), latitude2 = latitude2.toRadians();
|
||||
|
||||
var a = Math.sin(deltaLatitude / 2) *
|
||||
Math.sin(deltaLatitude / 2) +
|
||||
Math.cos(latitude1) *
|
||||
Math.cos(latitude2) *
|
||||
Math.sin(deltaLongitude / 2) *
|
||||
Math.sin(deltaLongitude / 2);
|
||||
|
||||
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
var d = R * c;
|
||||
return d;
|
||||
},
|
||||
bb_geo_updateLocaltion: function (position) {
|
||||
// 纬度
|
||||
var latitude = position.coords.latitude;
|
||||
// 经度
|
||||
var longitude = position.coords.longitude;
|
||||
// 位置精度
|
||||
var accuracy = position.coords.accuracy;
|
||||
// 海拔高度
|
||||
var altitude = position.coords.altitude;
|
||||
// 位置的海拔精度
|
||||
var altitudeAccuracy = position.coords.altitudeAccuracy;
|
||||
// 方向,从正北开始以度计
|
||||
var heading = position.coords.heading;
|
||||
// 速度
|
||||
var speed = position.coords.speed;
|
||||
// 响应的日期/时间
|
||||
var timestamp = position.timestamp;
|
||||
|
||||
// sanity test... don't calculate distance if accuracy
|
||||
// value too large
|
||||
if (accuracy >= 500) {
|
||||
console.warn("Need more accurate values to calculate distance.");
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate distance
|
||||
var currentDistance = 0.0;
|
||||
var totalDistance = 0.0;
|
||||
if (lastLat != null && lastLong != null) {
|
||||
currentDistance = $.bb_geo_distance(latitude, longitude, lastLat, lastLong);
|
||||
totalDistance += currentDistance;
|
||||
}
|
||||
|
||||
var lastLat = latitude;
|
||||
var lastLong = longitude;
|
||||
|
||||
if (altitude == null) {
|
||||
altitude = 0;
|
||||
}
|
||||
if (altitudeAccuracy == null) {
|
||||
altitudeAccuracy = 0;
|
||||
}
|
||||
if (heading == null) {
|
||||
heading = 0;
|
||||
}
|
||||
if (speed == null) {
|
||||
speed = 0;
|
||||
}
|
||||
return {
|
||||
latitude,
|
||||
longitude,
|
||||
accuracy,
|
||||
altitude,
|
||||
altitudeAccuracy,
|
||||
heading,
|
||||
speed,
|
||||
timestamp,
|
||||
currentDistance,
|
||||
totalDistance,
|
||||
lastLat,
|
||||
lastLong,
|
||||
};
|
||||
},
|
||||
bb_geo_handleLocationError: function (error) {
|
||||
switch (error.code) {
|
||||
case 0:
|
||||
console.error("There was an error while retrieving your location: " + error.message);
|
||||
break;
|
||||
case 1:
|
||||
console.error("The user prevented this page from retrieving a location.");
|
||||
break;
|
||||
case 2:
|
||||
console.error("The browser was unable to determine your location: " + error.message);
|
||||
break;
|
||||
case 3:
|
||||
console.error("The browser timed out before retrieving the location.");
|
||||
break;
|
||||
}
|
||||
},
|
||||
bb_geo_getCurrnetPosition: function (obj, method) {
|
||||
var ret = false;
|
||||
if (navigator.geolocation) {
|
||||
ret = true;
|
||||
navigator.geolocation.getCurrentPosition(position => {
|
||||
var info = $.bb_geo_updateLocaltion(position);
|
||||
obj.invokeMethodAsync(method, info);
|
||||
}, $.bb_geo_handleLocationError);
|
||||
}
|
||||
else {
|
||||
console.warn("HTML5 Geolocation is not supported in your browser");
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
bb_geo_watchPosition: function (obj) {
|
||||
var id = 0;
|
||||
if (navigator.geolocation) {
|
||||
id = navigator.geolocation.watchPosition(position => {
|
||||
$.bb_geo_updateLocaltion(position);
|
||||
}, $.bb_geo_handleLocationError, {
|
||||
maximumAge: 20000
|
||||
});
|
||||
}
|
||||
else {
|
||||
console.warn("HTML5 Geolocation is not supported in your browser");
|
||||
}
|
||||
return id;
|
||||
},
|
||||
bb_geo_clearWatchLocation: function (id) {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.clearWatch(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
@ -0,0 +1,91 @@
|
||||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
namespace BootstrapBlazor.Components;
|
||||
|
||||
/// <summary>
|
||||
/// 定位数据类
|
||||
/// </summary>
|
||||
public class GeolocationItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 纬度
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public decimal Latitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 经度
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public decimal Longitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 位置精度
|
||||
/// </summary>
|
||||
public decimal Accuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 海拔高度单位米
|
||||
/// </summary>
|
||||
public decimal Altitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 海拔精度
|
||||
/// </summary>
|
||||
public decimal AltitudeAccuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 方向 从正北开始以度计
|
||||
/// </summary>
|
||||
public decimal Heading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 速度 以米/每秒计
|
||||
/// </summary>
|
||||
public decimal Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 时间戳
|
||||
/// </summary>
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 时间
|
||||
/// </summary>
|
||||
public DateTime LastUpdateTime { get => UnixTimeStampToDateTime(Timestamp); }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 移动距离
|
||||
/// </summary>
|
||||
public decimal CurrentDistance { get; set; } = 0.0M;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 总移动距离
|
||||
/// </summary>
|
||||
public decimal TotalDistance { get; set; } = 0.0M;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 最后一次获取到的纬度
|
||||
/// </summary>
|
||||
public decimal LastLat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 最后一次获取到的经度
|
||||
/// </summary>
|
||||
public decimal LastLong { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="unixTimeStamp"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime UnixTimeStampToDateTime(long unixTimeStamp)
|
||||
{
|
||||
// Unix timestamp is seconds past epoch
|
||||
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
|
||||
dtDateTime = dtDateTime.AddMilliseconds(unixTimeStamp).ToLocalTime();
|
||||
return dtDateTime;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
namespace BootstrapBlazor.Components;
|
||||
|
||||
/// <summary>
|
||||
/// 地理位置坐标服务
|
||||
/// </summary>
|
||||
public class GeolocationService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前地理位置坐标信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> GetLocaltion<TComponent>(JSInterop<TComponent> interop, TComponent component, string callbackMethodName) where TComponent : class
|
||||
{
|
||||
var ret = await interop.GetGeolocationItemAsync(component, callbackMethodName);
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -53,6 +53,7 @@ public static class BootstrapBlazorServiceCollectionExtensions
|
||||
services.TryAddSingleton<IConfigureOptions<BootstrapBlazorOptions>, ConfigureOptions<BootstrapBlazorOptions>>();
|
||||
services.ConfigureBootstrapBlazorOption(configureOptions);
|
||||
|
||||
services.TryAddSingleton<GeolocationService>();
|
||||
services.TryAddSingleton<IIPLocatorProvider, DefaultIPLocatorProvider>();
|
||||
services.TryAddSingleton<IConfigureOptions<IPLocatorOption>, ConfigureOptions<IPLocatorOption>>();
|
||||
return services;
|
||||
|
@ -53,13 +53,23 @@ public class JSInterop<TValue> : IDisposable where TValue : class
|
||||
{
|
||||
_objRef = DotNetObjectReference.Create(value);
|
||||
var paras = new List<object>()
|
||||
{
|
||||
_objRef
|
||||
};
|
||||
{
|
||||
_objRef
|
||||
};
|
||||
paras.AddRange(args);
|
||||
return await _jsRuntime.InvokeAsync<TReturn>(el, func, paras.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal ValueTask<bool> GetGeolocationItemAsync(TValue value, string callbackMethodName)
|
||||
{
|
||||
_objRef = DotNetObjectReference.Create(value);
|
||||
return _jsRuntime.InvokeAsync<bool>("$.bb_geo_getCurrnetPosition", _objRef, callbackMethodName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose 方法
|
||||
/// </summary>
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user