微信小程序地图画区域 和计算区域面积

微信小程序地图画区域 和计算区域面积

  1. 画小程序地图
<map id="myMap" scale="20" :polygons="polygons3" :markers="markers2" :longitude="longitude" :latitude="latitude" class="map" @regionchange="regionchange">
export default {
		computed: {
			...mapGetters(['region', 'username'])
		},
		data() {
			return {
				num: 10,
				numb: 10,
				longitude: 0,
				latitude: 0,
				qqmapsdk: null,
				mapCtx: "",
				polygons: [],
				angle: 0,
				markers2: [],
				polygons2: [],
				polygons3: [],
				center: "",
				area: [],
				name: '',
				xinshow: false,
				xinchen: false,
				urlimgs: '',
				type: '',
				pointList: []
			}
		},
		onLoad() {
			that = this;
			setTimeout(() => {
				this.qqmapsdk = new QQMapWX({
					key: qqmapkey
				});
			}, 100);
			this.getdata();
			// this.addtx()
			this.currentLocation();
		},
		onShow() {

		},
		onReady() {
			this.mapCtx = wx.createMapContext('myMap')
		},
		methods: {
			choose(str) {
				this.angle = 0;
				this.type = str;
				this.addtx();
				this.xinchen = false
			},
			// 画区域
			getdata() {
				this.polygons2 = []
				this.markers2 = []
				getRegionDetail({
					region_id: 19
				}).then(res => {
					var list = res.data
					if (list.length > 0) {
						list.map((item, index) => {
							if (Number(item.type) == 1) {
								that.pointList = []
								var data = JSON.parse(item.json).path
								var server = {
									points: [],
									fillColor: "#883d3e00", //填充颜色
									strokeColor: "#0092FF", //描边颜色
									strokeWidth: 2, //描边宽度
									zIndex: 100, //层级
								}
								for (var j = 0; j < data.length; j++) {
									server.points.push({
										"longitude": data[j][0],
										"latitude": data[j][1]
									})
									that.pointList.push({
										"longitude": data[j][0],
										"latitude": data[j][1]
									})
								}
								that.polygons2.push(server)
							} else if (Number(item.type) == 2) { //禁停区
								var data = JSON.parse(item.json).path
								var server = {
									points: [],
									fillColor: "#FB818950", //填充颜色
									strokeColor: "#FB8189", //描边颜色
									strokeWidth: 2, //描边宽度
									zIndex: 1000, //层级
								}
								for (var j = 0; j < data.length; j++) {
									server.points.push({
										"longitude": data[j][0],
										"latitude": data[j][1]
									})
								}
								var server2 = {
									latitude: JSON.parse(item.center).la,
									longitude: JSON.parse(item.center).ln,
									id: index,
									width: 20,
									height: 30,
									iconPath: 'http://lxxybucket.oss-cn-hangzhou.aliyuncs.com/electric/noparking.png',
								}

								that.polygons2.push(server)
								that.markers2.push(server2)
							} else if (Number(item.type) == 3) { // 停车区
								var data = JSON.parse(item.json).path
								if (data) {
									var server = {
										points: [],
										fillColor: "#56E87850", //填充颜色
										strokeColor: "#56E878", //描边颜色
										strokeWidth: 2, //描边宽度
										zIndex: 100, //层级
									}
									for (var j = 0; j < data.length; j++) {
										server.points.push({
											"longitude": data[j][0],
											"latitude": data[j][1]
										})
									}
									var server2 = {
										latitude: JSON.parse(item.center).la,
										longitude: JSON.parse(item.center).ln,
										id: index,
										width: 20,
										height: 30,
										iconPath: 'http://lxxybucket.oss-cn-hangzhou.aliyuncs.com/electric/parkPng.png',
									}
									that.polygons2.push(server)
									that.markers2.push(server2)
								}

							} else if (Number(item.type) == 4) {
								var data = JSON.parse(item.json).path
								var server = {
									points: [],
									fillColor: "#EFD72250", //填充颜色
									strokeColor: "#EFD722", //描边颜色
									strokeWidth: 2, //描边宽度
									zIndex: 100, //层级
								}
								for (var j = 0; j < data.length; j++) {
									server.points.push({
										"longitude": data[j][0],
										"latitude": data[j][1]
									})
								}
								// var server2 = {
								// 	latitude: JSON.parse(item.center).la,
								// 	longitude: JSON.parse(item.center).ln,
								// 	id: index,
								// 	width: 20,
								// 	height: 30,
								// 	iconPath: 'http://lxxybucket.oss-cn-hangzhou.aliyuncs.com/electric/parkPng.png',
								// }
								that.polygons2.push(server)
								// that.markers2.push(server2)
							}
						})
						that.polygons3 = [...that.polygons2]
					}
				})
			},
			regionchange(e) {
				if (e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag')) {
					that.add()
				}
			},
			currentLocation() {
				let that = this;
				uni.getLocation({
					type: 'gcj02',
					success: function(res) {
						that.longitude = res.longitude;
						that.latitude = res.latitude;
					},
				})
			},

			shang() {
				let num = parseInt(this.angle) + 30;
				if (num > 180) {
					this.angle = 0
				} else {
					this.angle = num

				}
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			shangxia() {
				let num = parseInt(this.angle) - 30;
				if (num < -180) {
					this.angle = 0
				} else {
					this.angle = num

				}
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			add() {
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			addw() {
				this.numb += 1
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			jiaw() {
				let num = this.numb - 1
				if (num == 0) {
					this.numb = 1
				} else {
					this.numb = num

				}
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			jiac() {
				let num = this.num - 1;
				if (num == 0) {
					this.num = 1
				} else {
					this.num = num
				}
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			addc() {
				this.num += 1
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			addnum() {
				if (this.num < 1) {
					this.num = 1;
				}
				if (this.numb < 1) {
					this.numb = 1;
				}
				if (this.polygons.length > 0) {
					this.addtx()
				}
			},
			// 结算角度
			getAngle(x, y) {
				var radian = Math.atan(y / x); //弧度
				var angle = Math.floor(180 / (Math.PI / radian)); //弧度转角度
				if (x < 0) { //x小于0的时候加上180°,即实际角度
					angle = angle + 180;
				}
				return angle;
			},
			addtx() {
				let that = this;
				this.area = []
				let mapObjs = uni.createMapContext('myMap', this);
				let mySqrtnum = parseFloat(this.num / 2) * parseFloat(this.num / 2) + parseFloat(this.numb / 2) * parseFloat(this.numb / 2);
				let angle = that.getAngle(parseFloat(this.num / 2), parseFloat(this.numb / 2));
				mapObjs.getCenterLocation({
					success: res => {
						var polygonArr01 = [];
						var lng = res.longitude
						var lat = res.latitude
						let arr1 = that.getLonAndLat(lng, lat, angle, that.mySqrt(mySqrtnum))
						let angle1 = 180 - parseInt(angle)
						let arr2 = that.getLonAndLat(lng, lat, angle1, that.mySqrt(mySqrtnum))
						let angle2 = parseInt(angle) + 180
						let arr3 = that.getLonAndLat(lng, lat, angle2, that.mySqrt(mySqrtnum))
						let angle3 = 360 - parseInt(angle)
						let arr4 = that.getLonAndLat(lng, lat, angle3, that.mySqrt(mySqrtnum))
						let ptRotationCenter = {
							x: lat,
							y: lng
						}
						that.center = {
							la: lat,
							ln: lng
						}
						let num = this.rotatePoint({
							y: arr1.lng,
							x: arr1.lat
						}, ptRotationCenter, that.angle)
						that.area.push({
							lng: arr1.lng,
							lat: arr1.lat
						})
						polygonArr01.push([num.y, num.x]);

						let num1 = this.rotatePoint({
							y: arr2.lng,
							x: arr2.lat
						}, ptRotationCenter, that.angle)
						that.area.push({
							lng: arr2.lng,
							lat: arr2.lat
						})
						polygonArr01.push([num1.y, num1.x]);

						let num2 = this.rotatePoint({
							y: arr3.lng,
							x: arr3.lat
						}, ptRotationCenter, that.angle)
						that.area.push({
							lng: arr3.lng,
							lat: arr3.lat
						})
						polygonArr01.push([num2.y, num2.x]);

						let num3 = this.rotatePoint({
							y: arr4.lng,
							x: arr4.lat
						}, ptRotationCenter, that.angle);
						that.area.push({
							lng: arr4.lng,
							lat: arr4.lat
						})
						polygonArr01.push([num3.y, num3.x]);

						var server = {
							points: [],
							fillColor: "#55ff7f50", //填充颜色
							strokeColor: "#55ff7f", //描边颜色
							strokeWidth: 2, //描边宽度
							zIndex: 100, //层级
						}
						for (var j = 0; j < polygonArr01.length; j++) {
							server.points.push({
								"longitude": polygonArr01[j][0],
								"latitude": polygonArr01[j][1]
							})
						}
						that.polygons = [server];
						that.polygons3 = [...that.polygons2, ...that.polygons]
						// let area = that.computeSignedArea(that.area);
						// console.log(area);
					},
				})
			},
			// 结算平分差
			mySqrt(x) {
				if (isNaN(x)) return NaN;
				if (x === 0 || x === 1) return x;

				let low = 0,
					high = x,
					pivot = (low + high) / 2,
					lastPivot;
				do {
					if (Math.pow(pivot, 2) > x) {
						high = pivot;
					} else if (Math.pow(pivot, 2) < x) {
						low = pivot
					} else {
						return pivot
					}
					lastPivot = pivot;
					pivot = (low + high) / 2;
				}
				// 使用Number.EPSILON表示能够接受的最小误差范围
				while (Math.abs(pivot - lastPivot) >= Number.EPSILON);
				return pivot
			},
			// 结算经纬度
			getLonAndLat(lng, lat, brng, dist) {
				var a = 6378137;
				var b = 6356752.3142;
				var f = 1 / 298.257223563;
				var lon1 = lng * 1;
				var lat1 = lat * 1;
				var s = dist;
				var alpha1 = brng * (Math.PI / 180)
				var sinAlpha1 = Math.sin(alpha1);
				var cosAlpha1 = Math.cos(alpha1);
				var tanU1 = (1 - f) * Math.tan(lat1 * (Math.PI / 180));
				var cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)),
					sinU1 = tanU1 * cosU1;
				var sigma1 = Math.atan2(tanU1, cosAlpha1);
				var sinAlpha = cosU1 * sinAlpha1;
				var cosSqAlpha = 1 - sinAlpha * sinAlpha;
				var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
				var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
				var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));

				var sigma = s / (b * A),
					sigmaP = 2 * Math.PI;
				while (Math.abs(sigma - sigmaP) > 1e-12) {
					var cos2SigmaM = Math.cos(2 * sigma1 + sigma);
					var sinSigma = Math.sin(sigma);
					var cosSigma = Math.cos(sigma);
					var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
						B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
					sigmaP = sigma;
					sigma = s / (b * A) + deltaSigma;
				}

				var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
				var lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
					(1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
				var lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
				var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
				var L = lambda - (1 - C) * f * sinAlpha *
					(sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));

				var revAz = Math.atan2(sinAlpha, -tmp); // final bearing

				var lngLatObj = {
					lng: lon1 + L * (180 / Math.PI),
					lat: lat2 * (180 / Math.PI)
				}
				return lngLatObj;
			},
			// 计算偏移的角度
			rotatePoint(ptSrc, ptRotationCenter, angle) {
				var a = ptRotationCenter.x
				var b = ptRotationCenter.y
				var x0 = ptSrc.x
				var y0 = ptSrc.y
				var rx = a + (x0 - a) * Math.cos(angle * Math.PI / 180) - (y0 - b) * Math.sin(angle * Math.PI / 180);
				var ry = b + (x0 - a) * Math.sin(angle * Math.PI / 180) + (y0 - b) * Math.cos(angle * Math.PI / 180);
				var json = {
					x: rx,
					y: ry
				}
				return json;
			},
			addNoPar() {
				let that = this
				if (!this.type) {
					return uni.showToast({
						icon: 'none',
						title: '请选择创建的类型'
					})
				}
				if (!that.urlimgs) {
					return uni.showToast({
						icon: 'none',
						title: '请上传图片'
					})
				}
				let img = that.$tui.globelurl() + that.urlimgs
				if (this.name) {
					let data = that.polygons[0];
					let path = []
					if (data.points.length > 0) {
						data.points.map(item => {
							path.push([item.longitude, item.latitude])
						});
					}
					let pathnum = 0
					path.filter(item => {
						if (item.length > 0) {
							let is = that.IsPtInPoly(item[1], item[0], that.pointList);
							if (is == true) {
								pathnum += 1;
							}
						}
					});
					if (Number(pathnum) != 4) {
						return uni.showToast({
							icon: 'none',
							title: '请在服务区范围内添加'
						})
					};
					let position = {
						fillColor: data.fillColor,
						strokeColor: data.strokeColor,
						strokeWidth: data.strokeWidth,
						zIndex: data.zIndex,
						path: path
					}
					// let area = this.computeSignedArea(this.area);
					let area = parseFloat(this.num) * parseFloat(this.numb)
					let type = this.type == '停车区' ? 3 : this.type == '禁停区' ? 2 : 4
					addNoParking({
						agent_id: '',
						region_id: this.region.id,
						type: type,
						name: this.name,
						position: position,
						center: that.center,
						image: img,
						admin_id: this.username.id,
						area: area
					}).then(res => {
						if (res.code == 200) {
							if (res.status == 'success') {
								that.name = ''
								that.type = ''
								that.polygons = []
								that.polygons2 = []
								that.polygons3 = []
								that.center = ''
								that.area = []
								that.getdata();
							}
							return uni.showToast({
								icon: 'none',
								title: res.data
							})
						}
					})
				} else {
					return uni.showToast({
						icon: 'none',
						title: '请填写区域的名称'
					})
				}

			},
			// 计算区域面积
			computeSignedArea(path) {
				if (path.length > 0) {
					let _this = this;
					let radius = 6371009
					let len = path.length;
					if (len < 3) return 0;
					let total = 0;
					let prev = path[len - 1];
					if (prev.lat && prev.lng) {
						let prevTanlant = Math.tan((Math.PI / 2 - parseFloat(prev.lat) / 180 * Math.PI) / 2);
						let prevTanLat = Math.tan((Math.PI / 2 - prev.lat / 180 * Math.PI) / 2);
						let prevLng = (prev.lng) / 180 * Math.PI;
						for (let i in path) {
							let tanLat = Math.tan((Math.PI / 2 - (path[i].lat) / 180 * Math.PI) / 2);
							let lng = (path[i].lng) / 180 * Math.PI;
							total += this.polarTriangleArea(tanLat, lng, prevTanLat, prevLng);
							prevTanLat = tanLat;
							prevLng = lng;
						}
						let area = Math.abs(total * (radius * radius));
						return area;
					}
				}
			},
			polarTriangleArea(tan1, lng1, tan2, lng2) {
				let deltaLng = lng1 - lng2;
				let t = tan1 * tan2;
				return 2 * Math.atan2(t * Math.sin(deltaLng), 1 + t * Math.cos(deltaLng));
			},
			chooseAvatar(str) {
				let that = this;
				if (str == 'album') {
					uni.getSetting({
						success: (res) => {
							if (!res.authSetting["scope.writePhotosAlbum"]) {
								uni.authorize({
									scope: 'scope.writePhotosAlbum',
									success() {
										that.getroute(str);
									},
								})
							} else {
								that.getroute(str);
							}
						}
					})
				} else {
					uni.getSetting({
						success: (res) => {
							if (!res.authSetting["scope.camera"]) {
								uni.authorize({
									scope: 'scope.camera',
									success() {
										that.getroute(str);
									}
								})
							} else {
								that.getroute(str);
							}
						}
					})
				}

			},
			getroute(str) {
				let that = this;
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'],
					sourceType: [str],
					success: function(res) {
						var tempFilePaths = res.tempFilePaths[0];
						that.$api.uploadFile(tempFilePaths).then(res => {
							that.urlimgs = res.data.path;
							that.xinshow = false;
						})
					}
				})

			},
			// 判断在不在服务区
			IsPtInPoly(aLat, aLon, pointList) {
				var iSum = 0;
				var iCount = pointList.length;

				if (iCount < 3) {
					return false;
				}
				var y = aLat;
				var x = aLon;
				for (var i = 0; i < iCount; i++) {
					var y1 = pointList[i].latitude;
					var x1 = pointList[i].longitude;
					if (i == iCount - 1) {
						var y2 = pointList[0].latitude;
						var x2 = pointList[0].longitude;
					} else {
						var y2 = pointList[i + 1].latitude;
						var x2 = pointList[i + 1].longitude;
					}
					if (((y >= y1) && (y < y2)) || ((y >= y2) && (y < y1))) {
						if (Math.abs(y1 - y2) > 0) {
							var x_intersect = x1 - ((x1 - x2) * (y1 - y)) / (y1 - y2);
							if (x_intersect < x) {
								iSum += 1;
							}
						}
					}
				}
				if (iSum % 2 != 0) {
					return true;
				} else {
					return false;
				}
			}
		}
	}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值