基于OpenLayers实现地理围栏 谷歌百度高德地图都可以

2020-03-18 21:30:57

参考地址 基于OpenLayers实现地理围栏 谷歌百度高德地图都可以

前言.因为项目有点特殊,需要接入谷歌地图实现地理围栏,因为谷歌地图的地理围栏接口相关接口并不完善,于是就换了一个思路,利用OpenLayers来实现地理围栏  openlayers 中文地址 http://weilin.me/ol3-primer/ch02/index.html

`X9(1OM@MU089}IGC$C4$FA.png


这是效果实现图,以下是思路
1.第一步肯定是用户在地图上随意画一个圈,然后我们能获取这个圈在地图上的坐标,否则这一切并没有意义。
参考文章 http://weilin.me/ol3-primer/ch09/09-07.html
不过我这里对文章的代码略作改动


 var lineDraw = new ol.interaction.Draw({
        type: 'Polygon',
        source: lineLayer.getSource(),    // 注意设置source,这样绘制好的线,就会添加到这个source里
         freehand: true,
    });

注意这里的   type: 'Polygon', 和文章不一样  其他的设置样式什么的自行参考;
改动完毕,运行一下 在 获取位置,得到效果图如下


image.png

好了, 到这能正确正常的获取用户在地图上随意画的圆圈的坐标了

2.我们要如何在地图上显示用户随意画的地理围栏
第一步,加载地图和geojson文件。geojson文件是地图格式文件,用户加载用户之前画的地理围栏。
http://geojson.io/#map 网站生成一个 geojson文件即可,随后把我们在第一步获取到的位置进行替换

"geometry": {
            "type": "Polygon",
            "coordinates": 
            [[[ ]]] //你之前获取的坐标数据
        }

image.png


没什么特殊需求不要改geojson文件里面的其他内容, 只修改coordinates里面的数据就好


image.png


起一个ajax获取数据 然后加载到地图上


image.png


image.png


到这个步骤 基本上已经能正常的获取用户在地图上画的地理围栏了
接下来 加载谷歌地图

image.png

var googleMapLayer = new ol.layer.Tile({
                source: new ol.source.XYZ({
                    url: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0'

                })
            });

加载谷歌地图 ,也可以加载其他地图,我是因为项目需要才加载谷歌地图

map.once('postrender', function(event) {
                    var t = this;
                    console.log(layer2.getSource().getFeatures()[0].getGeometry().intersectsCoordinate([11578910.355723355, 3502000.669399493]));

                });

监听地图加载完成,然后随意检测一个点是否在地理围栏里面

map.on('singleclick', function(evt) {
                    var coordinate = evt.coordinate;
                    var hdms = ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326');
                    
                    var coordinate = evt.coordinate;
                    var userDogColler = userindex.getClosestPoint(coordinate);
                    var t = ol.proj.transform(userDogColler, 'EPSG:3857', 'EPSG:4326');
                     console.log('点击的地方距离围栏多少+',jwdjs(hdms[0],hdms[1],t[0],t[1]),'+M')  
                    //console.log(userindex.getClosestPoint(coordinate))

                    console.log(userindex.intersectsCoordinate(coordinate))

                });

给地图添加点击事件,然后获取点击的坐标,判断到地理围栏的距离 ,这里我采用的算法是经纬度算法 jwdjs()

function jwdjs(lat1, lng1, lat2, lng2) {
                var EARTH_RADIUS = 6378137.0; //单位M 地球的周长
                var PI = Math.PI;

                function getRad(d) {
                    return d * PI / 180.0;
                }

                function getGreatCircleDistance(lat1, lng1, lat2, lng2) {
                    var radLat1 = getRad(lat1);
                    var radLat2 = getRad(lat2);

                    var a = radLat1 - radLat2;
                    var b = getRad(lng1) - getRad(lng2);

                    var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
                    s = s * EARTH_RADIUS;
                    s = Math.round(s * 10000) / 10000.0;

                    return s;
                }
                return getGreatCircleDistance(lat1, lng1, lat2, lng2)

            }

到这基本上就能实现效果图所示的效果了 ,其他无效代码都删了



  • 2019-06-06 16:14:50

    intent-filter的action,category,data匹配规则

    我们知道有两种方式来启动Activity,显示调用和隐式调用。当使用隐式调用时,又会涉及到IntentFilter的匹配规则。我确信大多数开发者很少关注隐式调用,因为平时开发中用到大多数是显示调用。例如:用Intent直接打开一个Activity,或者用Intent通过包名等其他信息打开另外一个应用等。而隐式调用则使用的比较少,当然也不是完全不使用。例如:当我们需要打开浏览器访问某个链接时,手机上可能存在多个浏览器,我们也无法拿到某一个浏览器的包名,那么一般情况下我们会写如下代码:

  • 2019-06-06 17:57:57

    input【type="checkbox"】标签与字体对齐

    今天分享一个比较实用的技巧,在实际项目中我们会经常遇到表单的input标签多选和单选的问题,但是往往由于标签自身的样式和我们项目的风格很不搭调,就不能实现了,今天就来告诉大家怎么去实现吧。

  • 2019-06-10 11:54:52

    html.div禁用点击事件

    今天做项目中偶然误把元素加上了pointer-events属性,结果导致后来在js中给该元素加点击事件不能用,检查了半天才发现是这个属性的问题。之前没有好好研究,于是决定仔细研究一下。

  • 2019-06-12 22:34:16

    PHP身份证号打星号

    一个很简单的问题,想把身份证的号生日的4位隐藏,一开始查函数居然没有看到,然后用了好几个函数处理,觉得太麻烦就上网搜,后来发现有一个函数就能直接处理,我居然没看到~~初学者~~

  • 2019-06-13 10:09:51

    java(Android)跨Module调用对应类方法需求解决方案

    在开发组件化项目中,遇到一个这样的问题,两个不同的Module相互之间没有任何直接依赖关系,现在需求是需要在Module_A中调用Module_B中的某个类的方法,以下为解决此问题的方法;

  • 2019-06-13 11:31:32

    Android Studio接入ARouter以及简单使用

    你可能会说如果我的A module依赖了 B module,那么只要在B里面配置是不是就可以了?绝对不行!无论module之间关系如何,必须要同样配置!包括主项目和library项目!