用Geolocation获位置信息

地理位置

如果设备支持Geolocation,并且所使用的浏览器支持,就可以使用Geolocation获取设备的当前地理位置。可以打开网页http://caniuse.com/#search=geolocation查看有哪些浏览器版本支持Geolocation。显示Supported表示支持。

1

​ Geolocation返回的GeolocationInfo,包含以下信息:

  • latitude —— 纬度(度)。
  • longitude —— 经度(度)。
  • altitude —— 相对于海平面的海拔高度(米)。如果设备不提供海拔数据,altitude 的值为null。
  • accuracy —— 返回经纬度的精度,以米为单位。
  • altitudeAccuracy —— 返回海拔的精度,以米为单位。altitudeAccuracy 可能为null
  • heading —— 返回设备的移动方向(角度),指示距离北方的角度。0度表示指向正北方,方向以顺时针旋转(这表示东方是90度,西方是270度)。如果speed是0,heading会是NaN。如果设备无法提供heading信息,值为null
  • speed —— 返回设备每秒的移动速度(米)。speed可能为null
  • timestamp —— 获取得到设备当前位置的时间。

​ Geolocation静态属性值包含以下通用设置:

  • enableHighAccuracy —— 布尔值,如果设为true并且设备能够提供更精确地位置,则应用尽可能获取最佳结果。注意着可能导致更长的响应时间和更大的电量消耗(如开启了移动设备的GPS)。如果设置为false,将会得到更快速的响应和更少的电量消耗。默认值为false。
  • timeout —— 代表返回位置的最大时间(毫秒)限制。默认值是Infinity,意味着getCurrentPosition()直到位置可用时才会返回。
  • maximumAge —— 代表可返回的可用缓存位置的最大时限。如果设置为0,意味着设备不使用缓存位置,始终尝试获取实时位置。如果设置为Infinity,设备必须返回缓存位置无论其寿命。默认值:0。

1、获取当前定位

使用静态方法Geolocation.getCurrentPosition()获取当前的位置,getCurrentPosition()只触发一次。

    /**
     * 获取设备当前位置。
     * @param    onSuccess    带有唯一<code>Position</code>参数的回调处理器。
     * @param    onError        可选的。带有错误信息的回调处理器。错误代码为Geolocation.PERMISSION_DENIED、Geolocation.POSITION_UNAVAILABLE和Geolocation.TIMEOUT之一。
     */
    static getCurrentPosition(onSuccess: Handler, onError: Handler = null): void {
        Geolocation.navigator.geolocation.getCurrentPosition(function (pos: any): void {
            Geolocation.position.setPosition(pos);
            onSuccess.runWith(Geolocation.position);
        },
            function (error: any): void {
                onError.runWith(error);
            },
            {
                enableHighAccuracy: Geolocation.enableHighAccuracy,
                timeout: Geolocation.timeout,
                maximumAge: Geolocation.maximumAge
            });
    }

在LayaAir IDE中,给Scene2D添加一个自定义的组件脚本,添加如下代码,实现鼠标点击后,获取地理位置。

const { regClass, property } = Laya;

@regClass()
export class NewScript extends Laya.Script {

    constructor() {
        super();
    }

    onMouseClick(evt: Laya.Event): void {
        // 尝试获取当前位置
        Laya.Geolocation.getCurrentPosition(
            Laya.Handler.create(this, this.onSuccess),
            Laya.Handler.create(this, this.onError)
        );
        console.log("click");
    }

    // 成功获取位置后触发
    onSuccess(info: Laya.GeolocationInfo): void {
        console.log('经纬度: (' + info.longitude + '°, ' + info.latitude + '°),精确度:' + info.accuracy + 'm');

        if (info.altitude != null)
            console.log('海拔:' + info.altitude + 'm' + (info.altitudeAccuracy != null ? (',精确度:' + info.altitudeAccuracy + 'm') : ''));

        if (info.heading != null && !isNaN(info.heading))
            console.log('方向:' + info.heading + "°");

        if (info.speed != null && !isNaN(info.speed))
            console.log('速度:' + info.speed + "m/s");
    }

    // 获取位置失败后触发
    onError(err: any): void {
        var errType: String;
        if (err.code == Laya.Geolocation.PERMISSION_DENIED)
            errType = "Permission Denied";
        else if (err.code == Laya.Geolocation.POSITION_UNAVAILABLE)
            errType = "Position Unavailable";
        else if (err.code == Laya.Geolocation.TIMEOUT)
            errType = "Time Out";
        console.log('ERROR(' + errType + '): ' + err.message);
    }
}

以上示例代码演示使用getCurrentPosition()获取当前的位置信息,成功时打印地理位置信息,失败时打印错误信息和错误原因。

开发者如果点击IDE内的浏览器预览,上述示例则会打印Permission Denied(没有权限)的错误信息,原因是getCurrentPosition()获取位置信息时,Geolocation中navigator.geolocation的使用,只能使用https协议,普通的http协议是无法执行的,而IDE默认打开的谷歌浏览器里使用的是http协议。

这里提供一种测试办法,开发者可以先Web发布,然后用anywhere命令启动https进行测试。这里要注意,示例中将获取地理位置的方法放在了鼠标点击事件中,原因是navigator.geolocation只有响应用户的手势操作时,才会返回地理信息。所以如果直接放在onStart()等全局方法里面是不行的,得是像onMouseClick()这样的手势事件的响应函数才可以。

获取位置信息需要开启代理。

2、监视位置改变

除了获取当前位置之外,还可以监视位置的改变。使用Geolocation.watchPosition()监视位置改变,该函数返回一个监视器ID值,可以使用Geolocation.clearWatch()并传入该ID值来取消由watchPosition()注册的位置监听器。

    /**
     * 监视设备当前位置。回调处理器在设备位置改变时被执行。
     * @param    onSuccess    带有唯一<code>Position</code>参数的回调处理器。
     * @param    onError        可选的。带有错误信息的回调处理器。错误代码为Geolocation.PERMISSION_DENIED、Geolocation.POSITION_UNAVAILABLE和Geolocation.TIMEOUT之一。
     */
    static watchPosition(onSuccess: Handler, onError: Handler): number {
        return Geolocation.navigator.geolocation.watchPosition(function (pos: any): void {
            Geolocation.position.setPosition(pos);
            onSuccess.runWith(Geolocation.position);
        },
            function (error: any): void {
                onError.runWith(error);
            },
            {
                enableHighAccuracy: Geolocation.enableHighAccuracy,
                timeout: Geolocation.timeout,
                maximumAge: Geolocation.maximumAge
            });
    }

    /**
     * 移除<code>watchPosition</code>安装的指定处理器。
     * @param    id
     */
    static clearWatch(id: number): void {
        Geolocation.navigator.geolocation.clearWatch(id);
    }

以下示例同第1节示例的测试方法相同,需要发布后进行测试。

const { regClass, property } = Laya;

@regClass()
export class NewScript extends Laya.Script {

    constructor() {
        super();
    }

    onKeyDown(): void {
        // Geolocation.watchPosition函数签名
        Laya.Geolocation.watchPosition(
            Laya.Handler.create(this, this.updatePosition),
            Laya.Handler.create(this, this.onError));
        console.log("keydown");
    }

    updatePosition(info: Laya.GeolocationInfo): void {
        console.log('经纬度: (' + info.longitude + '°, ' + info.latitude + '°),精确度:' + info.accuracy + 'm');
    }

    onError(err: any): void {
        var errType: String;
        if (err.code == Laya.Geolocation.PERMISSION_DENIED)
            errType = "Permission Denied";
        else if (err.code == Laya.Geolocation.POSITION_UNAVAILABLE)
            errType = "Position Unavailable";
        else if (err.code == Laya.Geolocation.TIMEOUT)
            errType = "Time Out";
        console.log('ERROR(' + errType + '): ' + err.message);
    }
}

watchPosition()具有和getCurrentPosition()一样的函数签名。更多关于watchPosition()的应用,可以查看文档《使用百度地图》

Copyright ©Layabox 2022 all right reserved,powered by LayaAir Engine更新时间: 2023-07-25 15:14:06

results matching ""

    No results matching ""