园图简易实现


前言

最近在调研一种地图的快速生成技术->园图,这里贴上简单的使用方法。

API文档:https://www.ooomap.com/main/doc/SpriteMarkerNode.html#flash
体验文档:https://www.ooomap.com/main/repl/index.html#view-zoom

地图绘制

地图绘制使用官网的编辑器画,然后将标注与体块的tag中设置同一个bind_id即可。

直接上代码

这里实现了加载地图后,对地图初始化自己的数据,对地图进行修改,搜索展示。

<template>
	<view style="height: 100%">
		<!-- 模拟输入值 -->
		<input v-model="info" type="text" /> 
		<!-- 搜素地址 -->
		<view style="display: flex;">
			<input v-model="keyword" type="text" />
			<button style="width: 100px;" @click="search()">搜索</button>
		</view>
		<!-- 绘制3D地图所用的canvas -->
		<canvas type="webgl" id="ooomap" style="width: 100%; height: 100%" disable-scroll @touchstart="touchStart"
			@touchmove="touchMove" @touchend="touchEnd"></canvas>

		<!-- 创建2d平面图像画布 -->
		<canvas type="2d" id="canvas2d" style="pointer-events: none; position: absolute; left: -1000px"></canvas>

		<!-- 楼层控件 -->
		<floors-control v-if="mapLoaded" id="floors-control" showBtnCount="4" @ready="floorsControlReady" />

		<!-- 2d、3d控件 -->
		<viewmode-control v-if="mapLoaded" id="view-mode" :is3D="true" @ready="viewModeReady" />
	</view>
</template>

<script setup>
	import {
		ref,
		reactive,
		onMounted,
		onBeforeUnmount,
		getCurrentInstance,
		watch
	} from "vue"

	// 在uni-app中需要这样引入ooomap SDK
	var om = require("../../static/ooomap.xcx.min.js")

	// ooomap map 实例
	var map = ref('')
	var canvas2d, canvas3d
	var fc, vm

	var mapLoaded = ref(false)

	// page instance
	var self

	var inputValue = ''

	var building = null

	var info = ref('')
	var op_time = ref('')
	var bind_id = ref('')
	var keyword = ref('')
	var map_id = 'sLO530PHJFS5OLLLP'
	<!-- 在map的事件中,直接使用keywordsFind会有BUG,所以使用监听 -->
	watch(
		op_time,
		(new_val) => {
			test()
		}, {
			deep: true
		}
	)

	// 封装在微信小程序中得到domElement的方法
	function getElement(id, callback) {
		uni.createSelectorQuery().select(`#${id}`).fields({
			node: true,
			size: true
		}).exec(res => {
			if (res[0]) {
				var node = res[0].node

				if (callback) {
					callback(node)
				}
			}
		})
	}

	// 初始化楼层组件
	function floorsControlReady() {
		fc = self.ctx.selectComponent('#floors-control')
		fc.bind(map)
	}

	// 初始化2d/3d切换组件
	function viewModeReady() {
		vm = self.ctx.selectComponent('#view-mode')
		vm.bind(map)
	}
	
	function search(){
		//在建筑中找元素
		building.keywordsFind(keyword.value).then(res => {
			res[0].map((f_v, f_i) => {
				if (f_v.type == 'label') {
					building.getNodeByID(f_v.id).then(node => {
						//找到之后弹一下
						node.node.flash()
					})
				}
			})
		})
	}

	onMounted(() => {

		// 得到当前的页面实例
		// 用于获取 使用到的微信组件
		// self.ctx.selectComponent('#id')
		self = getCurrentInstance()
		// console.log('self', self)

		getElement('ooomap', node => {
			canvas3d = node
			getElement('canvas2d', node => {
				canvas2d = node

				// 得到2个必需的 canvas 后, 创建 ooomap 对象
				createOMMap(canvas3d, canvas2d)

			})
		})
	})

	// 在离开页面时销毁地图对象
	onBeforeUnmount(() => {
		if (map) {
			map.dispose()
		}
	})

	//
	// 创建 ooomap 地图实例
	//
	function createOMMap(canvas3d, canvas2d) {

		// 创建 ooomap 地图对象
		map = new om.Map({
			container: canvas3d, // canvas type: webgl
			canvas2d: canvas2d, // canvas type: 2d

			appID: 'd978475cd14d249615a56a6e51f8c10f',
			verifyUrl: 'https://www.ooomap.com/ooomap-verify/check/a51440b70ae174349b02ae9a824ea92e',

			viewMode: '2d',
			viewAngle: 0,

			frameRate: 20,
		})

		// ooomap 已经创建
		// 可以初始化楼层组件了
		mapLoaded.value = true

		map.on('picked', res => {
			if (!res.node) {
				return
			}
			// console.log(res.node)
			if (res.node.type === 'SpriteMarkerNode') {
				// console.log(map.view.zoomLevel)
				// map.view.zoomLevel = map.view.zoomLevel+1
				let data = res.node.data
				uni.showModal({
					title: '输入框示例',
					content: '修改店铺信息为:' + info.value,
					showCancel: true,
					confirmText: '确定',
					cancelText: '取消',
					success: function(res) {
						if (res.confirm) {
							op_time.value = new Date().toISOString()
							bind_id.value = JSON.parse(data.tag).bind_id
						}
					}
				});
			}

			if (res.node.type === 'OMBlock') {
				// console.log(map.view.zoomLevel)
				// map.view.zoomLevel = map.view.zoomLevel-1
				let data = res.node.data
				uni.showModal({
					title: '输入框示例',
					content: '模拟输入店铺信息' + info.value,
					showCancel: true,
					confirmText: '确定',
					cancelText: '取消',
					success: function(res) {
						if (res.confirm) {
							op_time.value = new Date().toISOString()
							bind_id.value = JSON.parse(data.tag).bind_id
						}
					}
				});
			}

		})

		map.on('sceneLoaded', s => {
			// init(map, s)
		})

		map.on('buildingLoaded', b => {
			initData()
		})

		map.on('floorLoaded', f => {
			// initData(map, f)
		})
	}

	function big() {
		map.view.zoomLevel = map.view.zoomLevel + 1;
	}

	function small() {
		map.view.zoomLevel = map.view.zoomLevel - 1;
	}

	function test() {
		// console.log(bind_id.value)
		building.keywordsFind(bind_id.value).then(res => {
			res[0].map((f_v, f_i) => {
				if (f_v.type == 'label') {
					building.getNodeByID(f_v.id).then(node => {
						let d = node.node.data
						// console.log(d)
						d.content.texts = []
						d.content.texts.push(info.value)
						node.node.setData(d)
						let data = {
							"content": JSON.stringify(d.content),
							"id": d.id,
							"tag": d.tag,
							"map_id": map_id,
						}
						// console.log(data)
						uni.request({
							url: "http://www.xiaozhu.com/index.php/test/update_marker",
							data: data,
							method: 'POST',
							header: {
								'content-type': 'application/x-www-form-urlencoded',
							},
							success: (res) => {
								// console.log(res)
							}
						})
					})
				}
			})
		})
	}

	function initData() {
		map.omScene.getBuildingByIndex(0).then(build => {
			building = build
			uni.request({
				url: "http://www.xiaozhu.com/index.php/test/get_marker",
				data: {
					"map_id": map_id
				},
				method: 'POST',
				header: {
					'content-type': 'application/x-www-form-urlencoded',
				},
				success: (res) => {
					res.data.data.map((m_v, m_i) => {
						// console.log(m_v)
						m_v.content = JSON.parse(m_v.content)
						m_v.tag = JSON.parse(m_v.tag)
						building.keywordsFind(m_v.tag.bind_id).then(res => {
							res[0].map((f_v, f_i) => {
								if (f_v.type == 'label') {
									f_v.content = m_v.content
								}
							})
						})
					})

				}
			})
		})
	}

	function init(map, scene) {
		var planeMarker = new om.PlaneMarkerNode(map, {
			url: '../../static/logo.png',
			size: [20, 20],
			fixedSize: true,
			position: [19, -23, 2.1]
		})

		scene.markerNode.add(planeMarker)

		planeMarker.moveTo({
			position: [0, 0, 2.1],
			duration: 3000,
			callback: () => {
				console.log("move success")
			}
		})
	}

	// 必要的几个canvas3d事件
	function touchStart(e) {
		canvas3d.dispatchTouchEvent({
			...e,
			type: 'touchstart'
		})
	}

	function touchMove(e) {
		canvas3d.dispatchTouchEvent({
			...e,
			type: 'touchmove'
		})
	}

	function touchEnd(e) {
		canvas3d.dispatchTouchEvent({
			...e,
			type: 'touchend'
		})
	}
</script>

<style>
	.floors-control {
		float: left;
		width: 100px;
	}

	.viewmode-control {
		float: left;
		width: 100px;
	}
</style>

总结

上面就是简单的用法,但是可以实现修改地图,搜索地址了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值