使用高德地图实现地理围栏

使用高德地图实现地理围栏

什么是地理围栏(Geo-fencing)?

地理围栏(Geo-fencing)是LBS的一种新应用,就是用一个虚拟的栅栏围出一个虚拟地理边界。当手机进入、离开某个特定地理区域,或在该区域内活动时,手机可以接收自动通知和警告。有了地理围栏技术,位置社交网站就可以帮助用户在进入某一地区时自动登记。

地理坐标系

我们通常用经纬度来表示一个地理位置,但是由于一些原因,我们从不同渠道得到的经纬度信息可能并不是在同一个坐标系下。

  • 高德地图、腾讯地图以及谷歌中国区地图使用的是GCJ-02坐标系
  • 百度地图使用的是BD-09坐标系
  • 底层接口(HTML5 Geolocation或ios、安卓API)通过GPS设备获取的坐标使用的是WGS-84坐标系

不同的坐标系之间可能有几十到几百米的偏移,所以在开发基于地图的产品,或者做地理数据可视化时,我们需要修正不同坐标系之间的偏差。

WGS-84 - 世界大地测量系统

WGS-84(World Geodetic System, WGS)是使用最广泛的坐标系,也是世界通用的坐标系,GPS设备得到的经纬度就是在WGS84坐标系下的经纬度。通常通过底层接口得到的定位信息都是WGS84坐标系。

GCJ-02 - 国测局坐标

GCJ-02(G-Guojia国家,C-Cehui测绘,J-Ju局),又被称为火星坐标系,是一种基于WGS-84制定的大地测量系统,由中国国测局制定。此坐标系所采用的混淆算法会在经纬度中加入随机的偏移。

国家规定,中国大陆所有公开地理数据都需要至少用GCJ-02进行加密,也就是说我们从国内公司的产品中得到的数据,一定是经过了加密的。绝大部分国内互联网地图提供商都是使用GCJ-02坐标系,包括高德地图,谷歌地图中国区等。

BD-09 - 百度坐标系

BD-09(Baidu, BD)是百度地图使用的地理坐标系,其在GCJ-02上多增加了一次变换,用来保护用户隐私。从百度产品中得到的坐标都是BD-09坐标系。

请添加图片描述

地理坐标系列表

坐标系坐标格式说明
WGS84[lng,lat]WGS-84坐标系,GPS设备获取的经纬度坐标
GCJ02[lng,lat]GCJ-02坐标系,google中国地图、SoSo地图、AliYun地图、MapAbc地图和高德地图所用的经纬度坐标
BD09[lng,lat]BD-09坐标系,百度地图采用的经纬度坐标
BD09LL[lng,lat]同BD09
BD09MC[x,y]BD-09米制坐标,百度地图采用的米制坐标,单位:米
BD09Meter[x,y]同BD09MC
Baidu[lng,lat]百度坐标系,BD-09坐标系别名,同BD-09
BMap[lng,lat]百度地图,BD-09坐标系别名,同BD-09
AMap[lng,lat]高德地图,同GCJ-02
WebMercator[x,y]Web Mercator投影,墨卡托投影,同EPSG3857,单位:米
WGS1984[lng,lat]WGS-84坐标系别名,同WGS-84
EPSG4326[lng,lat]WGS-84坐标系别名,同WGS-84
EPSG3857[x,y]Web Mercator投影,同WebMercator,单位:米
EPSG900913[x,y]Web Mercator投影,同WebMercator,单位:米

地理围栏 GeoJSON 数据

地理围栏或地理围栏集的数据由 rfc7946 中定义的、采用 GeoJSON 格式的 Feature 对象和 FeatureCollection 对象表示。 除此之外:

  • GeoJSON 对象类型可以是 Feature 对象或 FeatureCollection 对象。
  • 几何对象类型可以是 PointMultiPointLineStringMultiLineStringPolygonMultiPolygonGeometryCollection
  • 所有特征属性应该包含用于标识地理围栏的 geometryId
  • 具有 PointMultiPointLineStringMultiLineString 的特征必须在属性中包含 radiusradius 值的计量单位为米,radius 值的范围为 1 到 10000。
  • 具有 polygonmultipolygon 几何类型的特征没有半径属性。
  • validityTime 是可选属性,可让用户为地理围栏数据设置过期时间和有效时间。 如果未指定该属性,则数据永不过期,而是一直有效。
  • expiredTime 是地理围栏数据的过期日期和时间。 如果请求中 userTime 的值晚于此值,则将相应的地理围栏数据视为过期的数据,且不会查询这些数据。 基于这一点,此地理围栏数据的 geometryId 将包含在地理围栏响应中的 expiredGeofenceGeometryId 数组内。
  • validityPeriod 是地理围栏有效时段的列表。 如果请求中 userTime 的值超出有效时段,则将相应的地理围栏数据视为无效,且不会查询这些数据。 此地理围栏数据的 geometryId 包含在地理围栏响应中的 invalidPeriodGeofenceGeometryId 数组内。 下表显示了 validityPeriod 元素的属性。
名称类型必需说明
startTimedatetime有效时段的开始日期时间。
endTimedatetime有效时段的结束日期时间。
recurrenceType字符串false时段的重复类型。 值可为 DailyWeeklyMonthlyYearly。 默认值为 Daily
businessDayOnlyBooleanfalse指示数据是否仅在工作日有效。 默认值为 false
  • 所有坐标值都表示为中定义的 “经度,纬度” WGS84
  • 对于包含 MultiPointMultiLineStringMultiPolygonGeometryCollection 的每个特征,属性将应用到所有元素。 例如:中的所有点 MultiPoint 都将使用相同的半径形成多个圆形地域隔离区内。

标准GeoJSON

GeoJSON 规范仅支持以下几何图形:

  • 点 (Point)
  • 线 (LineString)
  • 多边形 (Polygon)
  • 点集合 (MultiPoint)
  • 线集合 (MultiLineString)
  • 多边形集合 (MultiPolygon)
  • 空间数据集合 (GeometryCollection)
点 (Point)
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}
线 (LineString)
{
    "type": "LineString", 
    "coordinates": [
        [30.0, 10.0], [10.0, 30.0], [40.0, 40.0]
    ]
}
多边形 (Polygon)
{
    "type": "Polygon", 
    "coordinates": [
        [[30.0, 10.0], [40.0, 40.0], [20.0, 40.0], [10.0, 20.0], [30.0, 10.0]]
    ]
}
{
    "type": "Polygon", 
    "coordinates": [
        [[35.0, 10.0], [45.0, 45.0], [15.0, 40.0], [10.0, 20.0], [35.0, 10.0]], 
        [[20.0, 30.0], [35.0, 35.0], [30.0, 20.0], [20.0, 30.0]]
    ]
}
点集合 (MultiPoint)
{
    "type": "MultiPoint", 
    "coordinates": [
        [10.0, 40.0], [40.0, 30.0], [20.0, 20.0], [30.0, 10.0]
    ]
}
线集合 (MultiLineString)
{
    "type": "MultiLineString", 
    "coordinates": [
        [[10.0, 10.0], [20.0, 20.0], [10.0, 40.0]], 
        [[40.0, 40.0], [30.0, 30.0], [40.0, 20.0], [30.0, 10.0]]
    ]
}
多边形集合 (MultiPolygon)
{
    "type": "MultiPolygon", 
    "coordinates": [
        [
            [[30.0, 20.0], [45.0, 40.0], [10.0, 40.0], [30.0, 20.0]]
        ], 
        [
            [[15.0, 5.0], [40.0, 10.0], [10.0, 20.0], [5.0, 10.0], [15.0, 5.0]]
        ]
    ]
}
{
    "type": "MultiPolygon", 
    "coordinates": [
        [
            [[40.0, 40.0], [20.0, 45.0], [45.0, 30.0], [40.0, 40.0]]
        ], 
        [
            [[20.0, 35.0], [10.0, 30.0], [10.0, 10.0], [30.0, 5.0], [45.0, 20.0], [20.0, 35.0]], 
            [[30.0, 20.0], [20.0, 15.0], [20.0, 25.0], [30.0, 20.0]]
        ]
    ]
}
空间数据集合 (GeometryCollection)
{
    "type": "GeometryCollection",
    "geometries": [
        {
            "type": "Point",
            "coordinates": [40.0, 10.0]
        },
        {
            "type": "LineString",
            "coordinates": [
                [10.0, 10.0], [20.0, 20.0], [10.0, 40.0]
            ]
        },
        {
            "type": "Polygon",
            "coordinates": [
                [[40.0, 40.0], [20.0, 45.0], [45.0, 30.0], [40.0, 40.0]]
            ]
        }
    ]
}

扩展GeoJSON

圆形 (Circle)

Circle GeoJSON 规范不支持该几何图形。我们使用 GeoJSON Point Feature 对象来表示圆。

Circle使用对象表示的几何图形 GeoJSON Feature 必须 包含以下坐标和属性:

  • 圆心 (Center)

    圆心使用 GeoJSON Point 对象表示。

  • 半径 (Radius)

    圆形的半径 radius 使用 GeoJSON Feature 的属性表示。 半径值以米为单位,并且其类型必须为 double

  • 子类型 (subType)

    圆形几何图形还必须包含 subType 属性。 此属性必须是的属性的一部分 GeoJSON Feature ,并且其值应为 Circle

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-122.126986, 47.639754]
    },
    "properties": {
        "subType": "Circle",
        "radius": 500
    }
}
矩形 (Rectangle)

Rectangle GeoJSON 规范不支持该几何图形。我们使用 GeoJSON Polygon Feature 对象来表示矩形。 矩形扩展主要由 Web SDK 的 “绘图工具” 模块使用。

Rectangle使用对象表示的几何图形 GeoJSON Polygon Feature 必须 包含以下坐标和属性:

  • 内角

    使用对象的坐标表示矩形的角 GeoJSON Polygon 。 应该有五个坐标,每个角一个。 与第五个坐标相同,用于关闭多边形环。 假定这些坐标对齐,开发人员可以根据需要对其进行旋转。

  • 子类型

    矩形几何图形还必须包含 subType 属性。 此属性必须是的属性的一部分 GeoJSON Feature ,并且其值应为 Rectangle

{
  "type": "Feature",
  "geometry": {
    "type": "Polygon",
    "coordinates": [[[5,25],[14,25],[14,29],[5,29],[5,25]]]
  },
  "properties": {
    "subType": "Rectangle"
  }
}

高德地图

高德地图提供了以下几组API可用于地理围栏:

  1. GeoJSON工具类 AMap.GeoJSON
  2. 编辑器工具类 AMap.PolyEditor AMap.PolygonEditor AMap.CircleEditor AMap.RectangleEditor AMap.EllipseEditor AMap.BezierCurveEditor
  3. 鼠标工具插件 AMap.MouseTool

1. GeoJSON工具类

它可以用来解析标准的GeoJSON,但是需要注意的是:它只支持FeatureCollection形式的数据.

    const geoJson = new AMap.GeoJSON({
      geoJSON: geoJsonObject,
      getMarker: function (geoJson, lngLats) {
        console.log('点', lngLats);
      },
      getPolyline: function (geoJson, lngLats) {
        console.log('线', lngLats);
      },
      getPolygon: function (geoJson, lngLats) {
        console.log('面', lngLats);
      },
    });

2. 矢量图形类

  function createPolygon(path: any, addToMap: boolean, fitView: boolean) {
    const polygon = new AMap.Polygon({
      path: path,
      strokeColor: '#FF33FF',
      strokeWeight: 6,
      strokeOpacity: 0.2,
      fillOpacity: 0.4,
      fillColor: '#1791fc',
      zIndex: 50,
    });

    polygon.on('mouseover', () => {
      polygon.setOptions({
        fillOpacity: 0.7,
        fillColor: '#7bccc4',
      });
    });

    polygon.on('mouseout', () => {
      polygon.setOptions({
        fillOpacity: 0.5,
        fillColor: '#ccebc5',
      });
    });

    if (addToMap) {
      map.add(polygon);
    }
    if (fitView) {
      setFitView();
    }
    currentGeofence = polygon;
    return polygon;
  }

3. 编辑器工具类

它支持:圆形,折线,多边形,贝瑟尔曲线,椭圆,矩形.

虽然说,圆形,矩形绘制简单.但是,真正实用的只有:多边形.

  // 编辑多边形
  function editPolygon(path: any, open: boolean) {
    closePolygonEditor();

    // 创建编辑器
    polygonEditor = new AMap.PolyEditor(map);

    if (path.length > 0) {
      const polygon = createPolygon(path, true, false);

      // 吸附功能
      polygonEditor.addAdsorbPolygons(polygon);
      // 设置编辑目标
      polygonEditor.setTarget(polygon);

      polygon.on('dblclick', () => {
        polygonEditor.setTarget(polygon);
        polygonEditor.open();
      });
    } else {
      polygonEditor.setTarget();
    }

    polygonEditor.on('add', function (event) {
      console.log(event);
      const polygon = event.target;
      polygonEditor.addAdsorbPolygons(polygon);
      polygon.on('dblclick', () => {
        polygonEditor.setTarget(polygon);
        polygonEditor.open();
      });
    });

    polygonEditor.on('end', function (event) {
        const paths = event.target.getPath();
        console.log('结束多边形编辑', event.target, paths);
    });

    // 打开编辑
    if (open) polygonEditor.open();
  }

需要注意的是:

  1. 绘制出来的路径需要倒序读取,因为标准GeoJson使用的是右手法则.
  2. 绘制出来的路径并没有封口,即起始点和结束点必须是同一个点.
  3. 如果需要被AMap.GeoJSON所解析,GeoJson的数据必须封装成FeatureCollection.

3. 鼠标工具插件

并不实用,弃用.

参考资料

虽然所给引用中未直接提及使用高德地图API实现地理围栏拆分的具体方法,但引用[3]提到JavaScript API GL为支持物流行业实现了几何图形编辑器,用户可通过编辑器接口进行点、线、面、圆的绘制和编辑,且在物流行业对已有区域进行拆分或者合并的场景下,编辑器也提供了相应功能,同时介绍了基于Turf实现多边形的拆分及合并。可以推测,要使用高德地图API实现地理围栏拆分,可能需要借助其JavaScript API GL的几何图形编辑器接口。 通常步骤可能如下: 1. 引入高德地图JavaScript API GL,并进行必要的初始化设置。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>高德地图地理围栏拆分</title> <style> html, body, #container { width: 100%; height: 100%; margin: 0; } </style> <!-- 引入高德地图JavaScript API GL --> <script src="https://webapi.amap.com/maps?v=2.0&key=YOUR_API_KEY"></script> </head> <body> <div id="container"></div> <script> // 初始化地图 var map = new AMap.Map('container', { zoom: 10, center: [116.397428, 39.90923] }); </script> </body> </html> ``` 2. 调用几何图形编辑器接口,创建地理围栏(多边形)。 ```javascript // 创建一个多边形作为地理围栏 var polygon = new AMap.Polygon({ path: [ [116.397428, 39.90923], [116.407428, 39.90923], [116.407428, 39.91923], [116.397428, 39.91923] ], strokeColor: "#FF33FF", strokeWeight: 2, fillColor: "#1791fc", fillOpacity: 0.3 }); polygon.setMap(map); // 开启几何图形编辑器 var editor = new AMap.PolyEditor(map, polygon); editor.open(); ``` 3. 利用编辑器提供的拆分功能对地理围栏进行拆分操作。不过这部分具体的代码可能需要参考高德地图JavaScript API GL的详细文档,因为文档中应该会有关于如何调用拆分功能的说明。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值