123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>分层聚合可视域</title>
- <script src="../assets/vue@2.7.14.js"></script>
- <script src="../../dist/index.js"></script>
- <style>
- body {
- margin: 0
- }
- #map {
- height: 100vh;
- }
- .control {
- position: absolute;
- top: 20px;
- left: 40px;
- padding: 10px 10px 0;
- background: #fff;
- }
- </style>
- </head>
- <body>
- <div id="app">
- <div id="map"></div>
- <div class="control">
- <button @click="toggleViewShedVisible">展示/隐藏可视域</button>
- <button @click="toggleCluster">{{disableCluster ? '已禁用' : '已启用'}}聚合</button>
- <button @click="setPointsData">设置第三层点位数据</button>
- <button @click="locationById">根据Id定位</button>
- <button @click="deSelect">取消选中</button>
- <button @click="getPointsInView">获取屏幕内非聚合点</button>
- <button @click="setSelectedCameraState">(单可视域)更改选中摄像头状态</button>
- <button @click="setCameraStateById">(单可视域)根据Id更改摄像头状态</button>
- <button @click="zoomToViewShed">缩放地图到点位可视域</button>
- <br>
- <button @click="addViewShedVisibleById">(多可视域)根据Id新增/修改可视域</button>
- <button @click="removeViewShedVisibleById">(多可视域)根据Id移除可视域</button>
- <button @click="clearViewShedVisibleById">根据Id清空可视域</button>
- <p>此工具兼容EPSG:3857和EPSG:4326投影,只需要传入View投影对应坐标即可</p>
- <p>注意:Vue项目中<b>不要</b>将地图相关实例对象赋值给响应式变量,单/多可视域方法不要混用</p>
- </div>
- </div>
- </body>
- <script>
- function makeRandomData(count) {
- return Array(count).fill('').map((item, index) => {
- return {
- id: `id${index}`, // id0,id1,id2... id属性名可自定义,locationById 方法中使用
- longitude: Math.random() / 2 + 116.15,
- latitude: Math.random() / 2 + 39.61,
- distance: Math.random() * 30 + 100, // 半径,单位 米
- heading: Math.random() * 360, // 朝向,顺时针旋转
- angle: Math.random() * 20 + 80, // 角度范围
- isWarning: Math.random() > 0.5 // 是否报警状态
- }
- })
- }
- // 将经纬度坐标转换为墨卡托投影坐标
- function transformProj(data) {
- data.forEach(item => {
- const coords = CTMapOl.proj.fromLonLat([item.longitude, item.latitude])
- item.longitude = coords[0]
- item.latitude = coords[1]
- })
- return data
- }
- const data1 = [
- { longitude: 116.05, latitude: 39.7, count: 50 },
- { longitude: 116.39, latitude: 39.8, count: 113 },
- { longitude: 116.53, latitude: 39.99, count: 88 },
- ]
- const data2 = [
- { longitude: 116.01, latitude: 39.5, count: 12 },
- { longitude: 116.12, latitude: 39.95, count: 16 },
- { longitude: 116.23, latitude: 39.6, count: 6 },
- { longitude: 116.34, latitude: 39.85, count: 6 },
- { longitude: 116.45, latitude: 39.7, count: 3 },
- { longitude: 116.56, latitude: 39.75, count: 12 },
- { longitude: 116.67, latitude: 39.98, count: 3 },
- { longitude: 116.78, latitude: 39.89, count: 12 }
- ]
- let data3 = makeRandomData(3000)
- // 由于 InitMap 的地图投影已改为EPSG:3857,需要将经纬度坐标转换为墨卡托投影坐标
- const layers = [
- { data: transformProj(data1), maxZoom: 10, onClick: data => { console.log(data) } },
- { data: transformProj(data2), minZoom: 10, maxZoom: 12, onClick: data => { console.log(data) } },
- { data: transformProj(data3), minZoom: 12, onClick: data => { console.log(data) } }
- ]
- new Vue({
- el: '#app',
- data() {
- return {
- guid:88,
- viewShedVisible: true,
- disableCluster: false
- }
- },
- mounted() {
- this.map = new CTMapOl.extend.InitMap({
- domId: 'map',
- zoom: 9
- })
- this.initLayers()
- },
- methods: {
- initLayers() {
- // 不要在 data 中定义 lcvs 变量,无需响应式
- // LayeredClusterViewShed 兼容EPSG:3857和EPSG:4326投影,只需要传入View投影对应坐标即可
- this.lcvs = new CTMapOl.extend.LayeredClusterViewShed(this.map.map, layers, {
- minViewShed: 12
- })
- },
- toggleViewShedVisible() {
- this.viewShedVisible = !this.viewShedVisible
- this.lcvs.setViewShedVisible(this.viewShedVisible)
- },
- toggleCluster() {
- this.disableCluster = !this.disableCluster
- this.lcvs.disableCluster(this.disableCluster)
- },
- locationById() {
- const feature = this.lcvs.locationById('id', 'id0')
- console.log('点位数据:', feature.get('data'))
- },
- deSelect() {
- this.lcvs.deSelectCamera()
- },
- getPointsInView() {
- const cameras = this.lcvs.getUnClusteredItems()
- console.log(cameras)
- },
- setPointsData() {
- data3 = transformProj(makeRandomData(3000))
- // 上面重新赋值data3只是为了demo 根据Id更改摄像头状态 时移动地图中心点
- this.lcvs.setLayerData(2, data3)
- },
- setSelectedCameraState() {
- this.lcvs.setSelectedCameraState({
- distance: Math.random() * 200 + 100,
- heading: Math.random() * 360,
- angle: Math.random() * 120,
- isWarning: Math.random() > 0.5
- })
- },
- setCameraStateById() {
- const index = Math.floor(Math.random() * 100)
- // 移动地图到目标摄像头
- this.map.map.getView().animate({
- center: [data3[index].longitude, data3[index].latitude],
- zoom: 17.1,
- duration: 200
- }, _ => {
- setTimeout(_ => {
- // 更新状态
- this.lcvs.setCameraStateById('id', `id${index}`, {
- heading: Math.random() * 360,
- angle: Math.random() * 120,
- isWarning: Math.random() > 0.5
- })
- }, 600)
- })
- },
- zoomToViewShed () {
- this.lcvs.zoomToViewShed('id', 'id88')
- },
- // 以下3个方法为多可视域模式方法
- // 请勿与 setSelectedCameraState、setCameraStateById 两个方法同时混用
- addViewShedVisibleById() {
- const index = 88
- // 移动地图到目标点位
- this.map.map.getView().animate({
- center: [data3[index].longitude, data3[index].latitude],
- zoom: 17.1,
- duration: 200
- }, _ => {
- setTimeout(_ => {
- // 新增/更新可视域
- this.lcvs.addViewShedVisibleById('id', `id${index}`, {
- guid: this.guid,
- distance: 200,
- heading: Math.random() * 360,
- angle: Math.random() * 120,
- // isWarning: Math.random() > 0.5,
- ishalf: Math.random() > 0.8,
- viewDistanceColor: 'rgba(255, 0, 6, 0.2)',
- viewAngleColor: 'rgba(0, 236, 6, 0.8)'
- })
- this.guid++
- }, 400)
- })
- },
- removeViewShedVisibleById(){
- this.lcvs.removeViewShedVisibleById('id', `id${index}`, {
- guid: --this.guid,
- })
- },
- clearViewShedVisibleById() {
- const index = 88
- this.lcvs.clearViewShedVisibleById('id', `id${index}`)
- }
- }
- })
- </script>
- </html>
|