场景:在项目开发中会遇到在map上绘制图层,一般想到的方法会是通过接口获取图层边界的所有点,由点生成polygons多边形面。polygons 多边形示例 数据过多地图会存在卡顿的问题。

目的:创建自定义图片图层,可以解决数据过多地图卡顿的问题并优化提高了性能。

目录

1、uniapp - map地图组件addGroundOverlay 创建实时更新自定义图片图层方法

2、高德地图web API  自定义图层 CustomLayer 自定义图层-图层- JS API v2.0 | 高德地图API

3、腾讯地图 API  

4、百度地图 地面叠加层覆盖

1、uniapp - map地图组件addGroundOverlay 创建实时更新自定义图片图层方法

  • 配置 "requiredPrivateInfos" : [ "startLocationUpdate", "startLocationUpdateBackground", "getLocation",  "onLocationChange"  ],如图
  • uni.createMapContext(mapId,this);例:this.mapContext = uni.createMapContext("map",this)。
  • @regiοnchange="onRegionChange",视野发生变化时触发。
  • 通过this.mapContext.getRegion({success: res=>{}})获取当前地图的视野范围,接口调用成功的回调函数,res = {southwest, northeast},西南角与东北角的经纬度。
  • this.mapContext.addGroundOverlay(),创建自定义图片图层,图片会随着地图缩放而缩放。
  • this.mapContext.removeGroundOverlay(),移除上一个自定义图片图层。

效果图如下:

代码示例如下: 

<template>
	<view class="map-wrap">
		<map
			id="map"
            ref="map"
			style="height: 100vh; width:100%;"
			:latitude="map.latitude"
			:longitude="map.longitude"
			:polyline="polyline"
			:scale="scale"
			:show-location="true"
			:enable-building="true"
			:enable-3D="true"
			@regionchange="onRegionChange"
		></map>
	</view>
</template>

<script>
export default {
	name: '',
	components: {},
	props: {
		optionInfo:{
			type: Object,
			default: () => {
				return {}
			}
		},
		Iconstyle:{
			type: Boolean,
			default:false
		}
	},
	data() {
		return {
			map: { //地图初始中心点
				latitude: "",
				longitude: ""
			},
			mapContext:null,
			gdtbLayerId: 0 // 耕地图斑图层ID
		};
	},
	created() {
		this.mapContext = uni.createMapContext("map",this);
	},
	mounted() {
		this.onRegionChange();
	},
	methods: {
		//监听移动 获取当前地图的视野范围
		onRegionChange(e){
			if (!e || e.type === "end") {
				this.mapContext.getRegion({
					success: res=>{
						this.loadGdtbLayerByRegion(res)
					}
				})
			}
		},
		// 根据经纬度加载当前屏幕范围内的耕地 
		loadGdtbLayerByRegion (region) {
			let northeast = region.northeast
			let southwest = region.southwest
			//获取的图片坐标是wgs84,则需要将地图坐标gcj02转成wgs84的
			let wgs84Northeast = this.gcj02towgs84(northeast.longitude, northeast.latitude)
			let wgs84Southwest = this.gcj02towgs84(southwest.longitude, southwest.latitude)
			let bboxs = [wgs84Southwest[0],wgs84Southwest[1],wgs84Northeast[0],wgs84Northeast[1]];
			let hkb = ((bboxs[2] - bboxs [0]) / (bboxs[3] - bboxs[1])).toFixed(8)
			let size = [ 1200, Math.ceil(1200 / hkb) ]
			let oldGdtbLayerId = this.gdtbLayerId
			this.gdtbLayerId = this.gdtbLayerId + 1

			let layerParma = {
				id: this.gdtbLayerId, //图片图层 id
				//图片路径,支持网络图片、临时路径、代码包路径
				src: "",
                下面src地址是gis服务提供的,可通过 &bbox=" + bboxs.join(",") 动态获取图片地址,
                //src: config.arcgisurl + "/GDDLTB/MapServer/export?dpi=96&transparent=true&format=png8&bbox=" + bboxs.join(",") + "&bboxSR=4490&size=" + size.join(",") + "&imageSR=4490&f=image",
				visible: true,//是否可见
				zindex: 1,//图层绘制顺序
				opacity: 0.6, //图层透明度
				bounds: {//图片覆盖的经纬度范围
					northeast: northeast,//东北角经纬度
					southwest: southwest//西南角经纬度
				},
				success: res => {
					if (oldGdtbLayerId) {
                        //移除上一个自定义图片图层
						this.mapContext.removeGroundOverlay({ id: oldGdtbLayerId })
					}
				},
				fail: err => {
					console.log("失败:", err)
				},
			}
			this.mapContext.addGroundOverlay(layerParma)
		},
		//经纬度坐标转换:gcj02转wgs84
		gcj02towgs84(lng, lat) {
			lat = parseFloat(lat)
			lng = parseFloat(lng)
			// 定义一些常量
			var PI = 3.1415926535897932384626
			var a = 6378245.0
			var ee = 0.00669342162296594323
			function transformlat(lng, lat) {
				var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
				ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
				ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
				ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
				return ret
			}
			function transformlng(lng, lat) {
				var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
				ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
				ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
				ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
				return ret
			}
			// 判断是否在国内,不在国内则不做偏移
			function out_of_china(lng, lat) {
				return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false)
			}
			if(out_of_china(lng, lat)) {
				return [lng, lat]
			} else {
				var dlat = transformlat(lng - 105.0, lat - 35.0)
				var dlng = transformlng(lng - 105.0, lat - 35.0)
				var radlat = lat / 180.0 * PI
				var magic = Math.sin(radlat)
				magic = 1 - ee * magic * magic
				var sqrtmagic = Math.sqrt(magic)
				dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
				dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
				var mglat = lat + dlat
				var mglng = lng + dlng
				return [lng * 2 - mglng, lat * 2 - mglat]
			}
		}
	}
};
</script>

uniapp - map地图组件addGroundOverlay创建自定义图片图层方法:代码如上

  • uni.createMapContext(mapId,this);例:this.mapContext = uni.createMapContext("map",this)。
  • 去掉视野发生变化时触发,@regiοnchange="onRegionChange",在mounted中调用onRegionChange方法
  • 通过this.mapContext.getRegion({success: res=>{}})获取当前地图的视野范围,接口调用成功的回调函数,res = {southwest, northeast},西南角与东北角的经纬度。
  • this.mapContext.addGroundOverlay(),创建自定义图片图层,图片会随着地图缩放而缩放。
  • this.mapContext.removeGroundOverlay(),移除上一个自定义图片图层。

2、高德地图web API  自定义图层 CustomLayer 自定义图层-图层- JS API v2.0 | 高德地图API

示例代码:高德地图自定义图层-Canvas-示例中心-JS API 2.0 示例
var cLayer = new AMap.CustomLayer(canvas, {
     zooms: [2, 18],
     zIndex: 120,
     render() {
         // 对 canvas 进行绘制
     }
})

3、腾讯地图 API  

用于创建自定义图片图层,图片会随着地图缩放而缩放。

 静态图贴地图层 | 代码示例

4、百度地图 地面叠加层覆盖物

SAPI GL提供的GroundOverlay类支持在地图底面上叠加覆盖物,覆盖物可以是图片、自定义Canvas、视频。
GroundOverlay类继承Overlay类,基于Bounds确定在地面上的显示范围和大小,通过options来配置覆盖物的类型、源、透明度等。

 图片类型示例

  • 创建地图参照展示地图
  • 创建地面叠加层实例,并添加到地图上

    创建地面叠加层使用BMapGL.GroundOverlay类,其继承自Overlay,通过map.addoverlay()方法将创建的叠加层添加到地图上。

     // 创建叠加物显示的范围Bounds
     var pStart = new BMapGL.Point(117.19635, 36.24093);
     var pEnd = new BMapGL.Point(117.20350, 36.24764);
     var bounds = new BMapGL.Bounds(new BMapGL.Point(pStart.lng, pEnd.lat), 
                                       new BMapGL.Point(pEnd.lng, pStart.lat));
     // 创建地面叠加层实例
     var imgOverlay = new BMapGL.GroundOverlay(bounds, {
            type: 'image',
            url: '/jsdemo/img/shouhuimap.png',
            opacity: 1
     });
     // 叠加层添加到地图
     map.addOverlay(imgOverlay);

示例:地图JS API示例

其它几种api没有实践,仅供参考...​

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐