vue+arcgis api for js实现地图经纬网格显示

vue代码调用:

javascript 复制代码
import { gridLineLatLng } from './js/mapGrids.js'

export default {
	mounted(){
		// 显示经纬网格
        gridLineLatLng.currentMap = this.mapAndView
        // gridLineLatLng.isGetMapPageXmax = false
        gridLineLatLng.init()
	},
	beforeDestroy() {
		// 删除经纬网格
        gridLineLatLng.destory()
    },

}

详细实现代码 mapGrids.js:

javascript 复制代码
/** 
 * 地图网格工具js
 * 
 */

import Graphic from '@arcgis/core/Graphic.js'
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer.js'

/** 地图经纬网格 */
let gridLineLatLng = {
    currentMap: null, // view
    currentFeatureLayer: null, // 网格图层layer
    stationaryHandler: null,
    color: 'blue', // 网格颜色 '#6666ff'
    degree: 1, // 间隔度数,
    xmax: 0,
    isGetMapPageXmax: true, // 是否获取地图页面最右边的地图可见范围(最大经度)
    timer: null,
    init: function() {
        let gridLineLayer = gridLineLatLng.currentMap.map.findLayerById('gridLineLayer')
        if (!gridLineLayer) {
            gridLineLayer = new GraphicsLayer({
                id: 'gridLineLayer',
                graphics: [],
                spatialReference: gridLineLatLng.currentMap.spatialReference
            })
            gridLineLatLng.currentMap.map.add(gridLineLayer)
        } else {
            // 清理图层
            gridLineLayer.graphics.removeAll()
        }
        gridLineLatLng.currentFeatureLayer = gridLineLayer
       
        let zoom = gridLineLatLng.currentMap.zoom // 获取当前地图缩放级别
        gridLineLatLng.degree = gridLineLatLng.getDegree(zoom)// 经纬度间隔
        let degree = gridLineLatLng.degree  // 数值越小,计算事件越长

        const decimalPart = degree.toString().split('.')[1]// 经纬度小数部分
        const fixedNum = decimalPart ? decimalPart.length : 0// 经纬度小数点后保留位数
        console.log('zoom:', zoom, ', increase degree:', degree)
        // 获取地图页面最右边的地图可见范围(最大经度)
        gridLineLatLng.xmax = 0
        if (gridLineLatLng.isGetMapPageXmax) {
            // 获取地图页面右上角的经纬度
            const html = document.getElementById('map-container')
            const screenPoint = {
                x: html.clientWidth,
                y: 0,
                spatialReference: gridLineLatLng.currentMap.spatialReference
            }
            const point = gridLineLatLng.currentMap.toMap(screenPoint)
            gridLineLatLng.xmax = point.x
        }

        if (zoom > 0 || zoom < 20) {
            let extent = gridLineLatLng.currentMap.extent
            let ymax = extent.ymax // 当前视口最北点纬度
            let xmax = gridLineLatLng.xmax || extent.xmax // 当前视口最东点经度
            let ymin = extent.ymin
            let xmin = extent.xmin

            let lineSymbol = {
                type: 'simple-fill', 
                outline: { 
                    color: gridLineLatLng.color,
                    width: 1,
                    style: 'dash'
                }
            }
            let textSymbol = {
                type: 'text',  
                color: 'white',
                haloColor: 'red',
                haloSize: '1px',
                text: '',
                xoffset: 0,
                yoffset: -10,
                font: {  
                    size: 11,
                    weight: 'bold'
                }
            }
            // 经线网格
            // for (let index = -180; index <= 180; index += degree) {
            for (let index = xmin + degree / 3; index <= xmax; index += degree) {
                let polyline = {
                    type: 'polyline', 
                    paths: [[index, 90], [index, -90]],
                    spatialReference: gridLineLatLng.currentMap.spatialReference
                }
                let lonLineGraphic = new Graphic({
                    geometry: polyline,
                    symbol: lineSymbol
                })
                // 添加到图层组中
                gridLineLatLng.currentFeatureLayer.graphics.add(lonLineGraphic)

                textSymbol.text = index.toFixed(fixedNum) + '°'
                const textGraphic = new Graphic({
                    geometry: {
                        type: 'point', 
                        longitude: index,
                        latitude: ymax,
                        spatialReference: gridLineLatLng.currentMap.spatialReference
                    }, 
                    symbol: textSymbol
                })
                gridLineLatLng.currentFeatureLayer.graphics.add(textGraphic)
            }

            // 纬线网格
            // for (let index = -90; index <= 90; index += degree) {
            for (let index = ymin + degree / 3; index <= ymax; index += degree) {
                let polyline = {
                    type: 'polyline', 
                    paths: [[-180, index], [180, index]],
                    spatialReference: gridLineLatLng.currentMap.spatialReference
                }
                let lonLineGraphic = new Graphic({
                    geometry: polyline,
                    symbol: lineSymbol
                })
                // 添加到图层组中
                gridLineLatLng.currentFeatureLayer.graphics.add(lonLineGraphic)

                textSymbol.text = index.toFixed(fixedNum) + '°'
                textSymbol.yoffset = 4
                textSymbol.xoffset = -22
                const textGraphic = new Graphic({
                    geometry: {
                        type: 'point', 
                        longitude: xmax,
                        latitude: index,
                        spatialReference: gridLineLatLng.currentMap.spatialReference
                    }, 
                    symbol: textSymbol
                })
                gridLineLatLng.currentFeatureLayer.graphics.add(textGraphic)
            }
        }
       
        // 添加范围变动监听,,动态生成网格
        gridLineLatLng.stationaryHandler = gridLineLatLng.currentMap.watch('stationary', status => {
            if (status) {
                if (gridLineLatLng.timer) {
                    clearTimeout(gridLineLatLng.timer)
                }
                gridLineLatLng.timer = setTimeout(() => {
                    if (gridLineLatLng.stationaryHandler) {
                        gridLineLatLng.stationaryHandler.remove()
                    }
                    gridLineLatLng.init()
                }, 1000)
            }
        })
    },
    getDegree: function(zoom) {
        let degree = 0.01
        switch (zoom) {
            case 0:
                degree = 0.7
                break
            case 1:
                degree = 0.3
                break
            case 2:
                degree = 0.1
                break
            case 3:
                degree = 0.06
                break
            case 4:
                degree = 0.04
                break
            case 5:
                degree = 0.02
                break
            case 6:
                degree = 0.009
                break
            case 7:
                degree = 0.006
                break
            case 8:
                degree = 0.003
                break
            default:
                degree = 0.01
                break
        }
        return degree
    },
    
    destory: function() {
        // 移除地图事件
        if (gridLineLatLng.stationaryHandler) {
            gridLineLatLng.stationaryHandler.remove()
        }
        // 移除图层
        gridLineLatLng.currentMap.map.remove(gridLineLatLng.currentFeatureLayer)
    }
}

export {
    gridLineLatLng
}

实现思路可参考:
vue+leaflet实现地图网格(https://blog.csdn.net/qq_41441896/article/details/131470559)

相关推荐
用户83134859306982 小时前
Cesium自定义可调节星空夜景+星星闪烁
vue.js·cesium
WindfallSheng3 小时前
从Vibe Coding到Spec Coding:一套可落地的AI-SDD企业级研发实战工程
javascript·vue.js
我有满天星辰4 小时前
Vue 指令完全指南:从 Vue 2 到 Vue 3 的演进与实战
前端·javascript·vue.js
我有满天星辰7 小时前
Vue 3 响应式双雄:ref 与 reactive 完全指南
前端·javascript·vue.js
leoZ23118 小时前
Claude 驱动的全栈开发:Spring Boot + Vue 的 BS 架构实践
vue.js·spring boot·架构
荒诞英雄21 小时前
从 17MB Vendor 大包到按需加载:Vite 多入口 Vue 组件库首屏优化实践
vue.js·vite
jsonbro21 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
Cobyte1 天前
23.Vue Vapor 组件 attrs 的实现
前端·javascript·vue.js
斯特凡今天也很帅1 天前
xml页面可以打开,不报错,但是显示数据的地方也不显示,我是怎么解决的
xml·vue.js
柯克七七1 天前
给老项目加了 TypeScript,本来只想自己爽,结果全公司代码审查标准被我抬高了
前端·vue.js·typescript