uniapp+arcgis系列(四): 获取wgs84坐标、获取火星坐标GCJ-02以及当前位置信息的省市街道地址名称、poi兴趣点,点击地图画点和轨迹
github地址:点击此处跳转
uniapp-arcgis系列目录:
一、目标
本文所完成的功能是:
(一)设置两个定时器:
定时器1,通过uniapp获取火星坐标系GCJ-02的位置信息,并从中获取到poiName、以及具体的省市街道地址名称。
定时器2,通过uniapp获取wgs84坐标系的位置信息,并从中获取到wgs84坐标点,在地图上实时定位并可视化出来。
(二)地图的点击事件,点击地图,画出所点击的点和轨迹。
效果图1:
看到中间那个可爱的猫猫头了嘛。
效果图2:
二、疑问和几个坑
1.为什么要分别获取火星坐标系和wgs84坐标系的位置信息?
因为获取wgs84坐标返回的数据中可能没有"xx省市xx街道xx号"这样的信息,也没有poi信息,需要特殊配置第三方SDK才会有。
但获取火星坐标系的数据,一定会带上位置解析出来的地址信息,包括兴趣点poi。
兴趣点poi: POI是“Point of Interest”的缩写,中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。百度百科
uniapp官网对这两种获取位置信息类型的介绍:点击跳转
2. 后台运行程序,获取不到位置信息了
高版本的安卓,是要对这一项进行授权的。
在授权位置信息的时候,有两个选项:
- 仅在使用中允许
- 始终允许
选第一个,就不能在后台获取位置信息;选第二个,可以。
3. 获取位置信息的方法只能写在逻辑层中,不能写在视图层RenderJS中
所以需要在逻辑层里获取坐标,再把坐标传参到视图层中,视图层来对这个坐标进行定位、高亮可视化。
**4. wgs84坐标系和火星坐标系GCJ-02可以互转,并且一般来说坐标系相同才能正确定位可视化。如果定位出错,请检查点、面、地图的坐标系是否一致。
5.为什么感觉符号pictureMarkerSymbol的url没有写错,却无法在地图上展示?
这里的url推荐使用base64编码(图片转base64网站),或者使用完整的url路径
例如:https://www.baidu.com/img/flexible/logo/pc/result.png
写相对路径我从来没写对过 = = ,它好像会去手机内存的appData里面去找。
6.为什么wgs84坐标点也可以在webMercator坐标系地图中显示?
嘿嘿嘿确实是可以的。
arcgis的动态投影机制,默认第一个加载的数据的坐标系为当前坐标系,如果后面传来的数据坐标系不同,会自动把数据转换成当前坐标系进行展示。
大概是这个意思吧,如果有误,请观众老爷留言更正。
三、具体实现
1. 定位获取wgs84坐标
uni.getLocation({
type: 'wgs84',
geocode: true,
success: function(res) {
// 获取到经纬度
var lon = res.longitude;
var lat = res.latitude;
this_.locationPoint = lon+","+lat;
this_.valueChangeSign = [new Date().getTime(), [lon,lat]];
},
fail(e) {
if (e.errMsg.includes("geolocation:14")) {
console.log("gps定位信号弱 ")
} else if (e.errMsg.includes("geolocation:12")) {
console.log("无法定位!请开启gps定位权限。")
}
}
});
这里稍微处理了一下两种获取不到定位的情况。
2.定位获取火星坐标和poi
uni.getLocation({
type: 'gcj02',
geocode: true,
success: function(res) {
if (res && res.address) {
res.address.street = res.address.street ? res.address.street :
"";
res.address.poiName = res.address.poiName ? res.address
.poiName : "";
console.log("兴趣点是:"+ res.address.poiName;);
}
},
});
地址信息都是在返回结果的res.address里面的,所有的字段信息如表:
3.地图可视化
简单介绍下arcgis是怎么对一个点进行可视化展示的:
- 首先在地图上创建一个图形图层(GraphicsLayer),并将这个图层添加到地图中
// 创建图形图层
var graphicsLayer = new GraphicsLayer();
map.grahicsLayer = graphicsLayer;
// 把这个图层添加到地图中
map.add(map.graphicsLayer);
- 其次根据获取到的wgs84坐标创建一个点(Point),参数需要传入坐标系
// 创建一个wgs84坐标系
var sr = new SpatialReference(4326);
// 创建一个点
var point = new Point(lon,lat,sr);
- 然后创建一个符号(Symbol),这个符号就是定位坐标点要在地图上展示出来的样子,它可以是一个文本、一张图片、一个形状......
// 创建一个符号
var symbol = {
type: "picture-marker",
url:this_.pictureMarkerUrl,
width: "30px",
height: "30px"
};
重要提示:这里的url推荐使用base64编码(图片转base64网站),或者使用完整的绝对url路径
例如:https://www.baidu.com/img/flexible/logo/pc/result.png
写相对路径我从来没写对过 = = ,它好像会去手机内存的appData里面去找。
- 接着创建一个图形Graphic,把刚刚创建的点Point和Symbol作为参数传进去
// 创建一个graphic
var graphic = new Graphic({
geometry: point,
symbol: symbol
})
- 将这个Graphic添加到第一步创建的图形图层GraphicsLayer中
// 将这个graphic添加至图形图层
map.grahicsLayer.add(graphic);
这样,就展示出来了。但是,还有一点需要注意:
每次进行定位坐标可视化的时候,要把之前图层GraphicsLayer中的图形Graphic清空!
不然做的就不是实时定位效果了,是实时轨迹。
// 每次定位 都清空图形图层上之前的元素
map.grahicsLayer.removeAll();
引入需要的类
在上面,需要用到图形图层、点、图形、坐标系这几个类,把它们引进来。
引用的顺序一定要写对噢。
"esri/layers/GraphicsLayer",
"esri/geometry/Point",
"esri/Graphic",
"esri/geometry/SpatialReference",
"esri/geometry/support/webMercatorUtils"
GraphicsLayer,Point,Graphic,SpatialReference,webMercatorUtils
关于符号Symbol,文档说可以写成json的形式,自动cast为一个具体的符号类。
四、点击地图,在地图上画点和轨迹
本来这个打算单独开一篇的,但因为比较简单,就一起写在这里了。
1. 首先捕捉地图的点击事件
view.on("click", function(event) {
console.log(event.mapPoint);
});
说一下这个mapPoint.
代码:
// 地图点击事件
view.on("click", function(event) {
// mapPoint的longitude和latitude是84坐标的经纬度
// x,y是地图坐标系的经纬度,这里是webMercator坐标系
console.log(event.mapPoint);
// 创建84坐标系
var sr84 = new SpatialReference({
wkid: 4326
});
// 转换成84坐标系点
console.log(webMercatorUtils);
var point84 = webMercatorUtils.webMercatorToGeographic(event.mapPoint);
// 创建webMercator坐标系
var srWm = new SpatialReference({
wkid: 102100
});
// 获取webMercator坐标系的点
var pointWm = event.mapPoint;
var circleymbol = {
type: "simple-marker",
style: "circle",
color: [255, 102, 102, 1],
size: "15px",
outline: {
color: [102, 253, 204, 0.8],
width: 1
}
};
// 创建一个graphic 传入坐标点
var graphic = new Graphic({
geometry: point84,
symbol: circleymbol
})
// 添加到点击图层
this_.myMapObject.map.clickLayer.add(graphic);
})
uniapp+arcgis系列就写到这里啦!
五、源代码
当前位置:{{locationText}}
wgs84坐标:{{locationPoint}}