GeoScene Maps 完整入门指南:从安装到实战

发布于:2025-08-31 ⋅ 阅读:(19) ⋅ 点赞:(0)

什么是GeoScene Maps

GeoScene Maps是一套功能强大的Web地图开发平台,它基于现代Web技术构建,为开发者提供了丰富的地图服务和开发工具。与其他地图API相比,GeoScene Maps具有以下特点:

核心优势

  • 全面的地图服务:支持2D/3D地图、多种底图类型
  • 高性能渲染:基于WebGL的高效渲染引擎
  • 丰富的API:完整的地图操作、空间分析功能
  • 跨平台支持:支持桌面端和移动端
  • 灵活的样式:可自定义地图样式和符号

适用场景

  • 位置服务应用
  • 物流追踪系统
  • 智慧城市平台
  • 地理信息系统(GIS)
  • 实时监控系统

环境准备与安装

1. 前置要求

在开始之前,确保您的开发环境满足以下要求:

# Node.js版本要求
Node.js >= 14.0.0
npm >= 6.0.0

# 或者使用yarn
yarn >= 1.22.0

2. 创建Vue项目

# 使用Vue CLI创建项目
npm install -g @vue/cli
vue create geoscene-map-demo

# 或使用Vite创建项目(推荐)
npm create vue@latest geoscene-map-demo
cd geoscene-map-demo
npm install

3. 安装GeoScene Maps SDK

# 安装GeoScene Maps核心包
npm install @geoscene/core

# 如果需要额外的功能模块
npm install @geoscene/map-components
npm install @geoscene/calcite-components

创建第一个地图

1. 基础地图组件

首先,让我们创建一个基础的地图组件:

<!-- src/components/MapContainer.vue -->
<template>
  <div class="map-container">
    <div 
      ref="mapDiv" 
      class="map-view"
      id="map-view"
    ></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import Map from '@geoscene/core/Map.js'
import MapView from '@geoscene/core/views/MapView.js'
import TileLayer from '@geoscene/core/layers/TileLayer.js'

// 模板引用
const mapDiv = ref(null)

// 地图实例
let map = null
let view = null

// 初始化地图
const initializeMap = async () => {
  try {
    // 创建地图实例
    map = new Map({
      basemap: 'streets-navigation-vector' // 使用内置底图
    })

    // 创建地图视图
    view = new MapView({
      container: mapDiv.value,
      map: map,
      center: [116.397, 39.909], // 北京天安门坐标
      zoom: 13
    })

    // 等待视图加载完成
    await view.when()
    console.log('地图初始化完成')

  } catch (error) {
    console.error('地图初始化失败:', error)
  }
}

// 组件挂载时初始化地图
onMounted(() => {
  initializeMap()
})

// 组件卸载时清理资源
onUnmounted(() => {
  if (view) {
    view.destroy()
    view = null
  }
  map = null
})

// 暴露地图实例供父组件使用
defineExpose({
  getMap: () => map,
  getView: () => view
})
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.map-view {
  width: 100%;
  height: 100%;
}
</style>

2. 使用自定义底图

如果需要使用天地图等国内地图服务

// src/utils/mapConfig.js
export const TIANDITU_CONFIG = {
  key: '您的天地图API密钥', // 需要到天地图官网申请
  baseUrl: 'https://t{subDomain}.tianditu.gov.cn'
}

export const MAP_TYPES = {
  SATELLITE: 'satellite',    // 卫星图
  VECTOR: 'vector',         // 矢量图
  TERRAIN: 'terrain'        // 地形图
}
// 创建天地图底图的函数
import WebTileLayer from '@geoscene/core/layers/WebTileLayer.js'
import Basemap from '@geoscene/core/Basemap.js'
import { TIANDITU_CONFIG } from '@/utils/mapConfig.js'

const createTiandituBasemap = (mapType = 'vector') => {
  let layerType = ''
  let annotationType = ''
  
  switch (mapType) {
    case 'satellite':
      layerType = 'img_w'
      annotationType = 'cia_w'
      break
    case 'terrain':
      layerType = 'ter_w'
      annotationType = 'cta_w'
      break
    default: // vector
      layerType = 'vec_w'
      annotationType = 'cva_w'
  }

  return new Basemap({
    baseLayers: [
      // 底图层
      new WebTileLayer({
        urlTemplate: `${TIANDITU_CONFIG.baseUrl}/${layerType}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${layerType.split('_')[0]}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=${TIANDITU_CONFIG.key}`,
        subDomains: ['0', '1', '2', '3'],
        copyright: '© 天地图'
      }),
      // 标注层
      new WebTileLayer({
        urlTemplate: `${TIANDITU_CONFIG.baseUrl}/${annotationType}/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${annotationType.split('_')[0]}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=${TIANDITU_CONFIG.key}`,
        subDomains: ['0', '1', '2', '3'],
        copyright: '© 天地图'
      })
    ]
  })
}

地图基础操作

1. 地图导航控制

// 添加地图导航控件
import Home from '@geoscene/core/widgets/Home.js'
import Zoom from '@geoscene/core/widgets/Zoom.js'
import Compass from '@geoscene/core/widgets/Compass.js'

const addMapControls = (view) => {
  // 添加缩放控件
  const zoomWidget = new Zoom({
    view: view
  })
  view.ui.add(zoomWidget, 'top-left')

  // 添加指南针控件
  const compassWidget = new Compass({
    view: view
  })
  view.ui.add(compassWidget, 'top-left')

  // 添加主页按钮
  const homeWidget = new Home({
    view: view
  })
  view.ui.add(homeWidget, 'top-left')
}

2. 地图视图操作

// 地图操作工具函数
export const mapOperations = {
  // 跳转到指定位置
  goTo: async (view, target, options = {}) => {
    try {
      await view.goTo(target, {
        duration: options.duration || 1000,
        easing: options.easing || 'ease-in-out'
      })
    } catch (error) {
      console.error('地图跳转失败:', error)
    }
  },

  // 设置地图中心点
  setCenter: (view, longitude, latitude, zoom = null) => {
    view.center = [longitude, latitude]
    if (zoom !== null) {
      view.zoom = zoom
    }
  },

  // 获取当前地图范围
  getExtent: (view) => {
    return view.extent
  },

  // 设置地图范围
  setExtent: async (view, extent) => {
    try {
      await view.goTo(extent)
    } catch (error) {
      console.error('设置地图范围失败:', error)
    }
  }
}

3. 地图事件处理

// 地图事件监听
const setupMapEvents = (view) => {
  // 点击事件
  view.on('click', (event) => {
    console.log('地图被点击:', event.mapPoint)
    const { longitude, latitude } = event.mapPoint
    console.log(`坐标: ${longitude}, ${latitude}`)
  })

  // 双击事件
  view.on('double-click', (event) => {
    console.log('地图被双击:', event.mapPoint)
    // 阻止默认的缩放行为
    event.stopPropagation()
  })

  // 鼠标移动事件
  view.on('pointer-move', (event) => {
    // 获取鼠标位置的地理坐标
    const point = view.toMap(event)
    if (point) {
      // 可以在这里更新坐标显示
      updateCoordinateDisplay(point.longitude, point.latitude)
    }
  })

  // 地图范围变化事件
  view.watch('extent', (newExtent) => {
    console.log('地图范围发生变化:', newExtent)
  })

  // 缩放级别变化事件
  view.watch('zoom', (newZoom) => {
    console.log('缩放级别变化:', newZoom)
  })
}

添加图层和数据

1. 添加图形图层

import GraphicsLayer from '@geoscene/core/layers/GraphicsLayer.js'
import Graphic from '@geoscene/core/Graphic.js'
import Point from '@geoscene/core/geometry/Point.js'
import SimpleMarkerSymbol from '@geoscene/core/symbols/SimpleMarkerSymbol.js'

// 创建图形图层
const createGraphicsLayer = () => {
  return new GraphicsLayer({
    id: 'graphics-layer',
    title: '标记图层'
  })
}

// 添加点标记
const addPointMarker = (layer, longitude, latitude, attributes = {}) => {
  // 创建点几何
  const point = new Point({
    longitude: longitude,
    latitude: latitude
  })

  // 创建点符号
  const symbol = new SimpleMarkerSymbol({
    color: [226, 119, 40], // 橙色
    outline: {
      color: [255, 255, 255], // 白色边框
      width: 2
    },
    size: 12
  })

  // 创建图形
  const graphic = new Graphic({
    geometry: point,
    symbol: symbol,
    attributes: attributes
  })

  // 添加到图层
  layer.add(graphic)
  
  return graphic
}

2. 添加自定义图标

import PictureMarkerSymbol from '@geoscene/core/symbols/PictureMarkerSymbol.js'

// 创建自定义图标标记
const addCustomIconMarker = (layer, longitude, latitude, iconUrl, attributes = {}) => {
  const point = new Point({
    longitude: longitude,
    latitude: latitude
  })

  // 使用图片符号
  const symbol = new PictureMarkerSymbol({
    url: iconUrl,
    width: 32,
    height: 32
  })

  const graphic = new Graphic({
    geometry: point,
    symbol: symbol,
    attributes: attributes
  })

  layer.add(graphic)
  return graphic
}

// 批量添加标记点
const addMultipleMarkers = (layer, markersData) => {
  const graphics = markersData.map(marker => {
    return addCustomIconMarker(
      layer,
      marker.longitude,
      marker.latitude,
      marker.iconUrl,
      marker.attributes
    )
  })
  
  return graphics
}

3. 添加线和面

import Polyline from '@geoscene/core/geometry/Polyline.js'
import Polygon from '@geoscene/core/geometry/Polygon.js'
import SimpleLineSymbol from '@geoscene/core/symbols/SimpleLineSymbol.js'
import SimpleFillSymbol from '@geoscene/core/symbols/SimpleFillSymbol.js'

// 添加线要素
const addPolyline = (layer, paths, attributes = {}) => {
  const polyline = new Polyline({
    paths: paths
  })

  const symbol = new SimpleLineSymbol({
    color: [226, 119, 40],
    width: 4
  })

  const graphic = new Graphic({
    geometry: polyline,
    symbol: symbol,
    attributes: attributes
  })

  layer.add(graphic)
  return graphic
}

// 添加面要素
const addPolygon = (layer, rings, attributes = {}) => {
  const polygon = new Polygon({
    rings: rings
  })

  const symbol = new SimpleFillSymbol({
    color: [227, 139, 79, 0.8], // 半透明填充
    outline: {
      color: [255, 255, 255],
      width: 1
    }
  })

  const graphic = new Graphic({
    geometry: polygon,
    symbol: symbol,
    attributes: attributes
  })

  layer.add(graphic)
  return graphic
}

交互功能实现

1. 弹窗功能

import PopupTemplate from '@geoscene/core/PopupTemplate.js'

// 创建弹窗模板
const createPopupTemplate = (title, content) => {
  return new PopupTemplate({
    title: title,
    content: content,
    // 自定义弹窗操作
    actions: [
      {
        title: '详细信息',
        id: 'show-details',
        className: 'geoscene-icon-description'
      },
      {
        title: '导航到此',
        id: 'navigate-to',
        className: 'geoscene-icon-navigation'
      }
    ]
  })
}

// 为图形添加弹窗
const addPopupToGraphic = (graphic, popupTemplate) => {
  graphic.popupTemplate = popupTemplate
}

// 处理弹窗操作
const handlePopupActions = (view) => {
  view.popup.on('trigger-action', (event) => {
    const action = event.action
    
    switch (action.id) {
      case 'show-details':
        console.log('显示详细信息')
        // 实现详细信息逻辑
        break
      case 'navigate-to':
        console.log('导航到此位置')
        // 实现导航逻辑
        break
    }
  })
}

2. 绘制工具

import SketchViewModel from '@geoscene/core/widgets/Sketch/SketchViewModel.js'

// 创建绘制工具
const createSketchViewModel = (view, layer) => {
  return new SketchViewModel({
    view: view,
    layer: layer,
    // 绘制符号样式
    pointSymbol: new SimpleMarkerSymbol({
      color: [255, 0, 0],
      size: 10
    }),
    polylineSymbol: new SimpleLineSymbol({
      color: [0, 255, 0],
      width: 3
    }),
    polygonSymbol: new SimpleFillSymbol({
      color: [0, 0, 255, 0.3],
      outline: {
        color: [0, 0, 255],
        width: 2
      }
    })
  })
}

// 绘制操作
const drawingOperations = {
  // 开始绘制点
  drawPoint: (sketchViewModel) => {
    sketchViewModel.create('point')
  },

  // 开始绘制线
  drawPolyline: (sketchViewModel) => {
    sketchViewModel.create('polyline')
  },

  // 开始绘制面
  drawPolygon: (sketchViewModel) => {
    sketchViewModel.create('polygon')
  },

  // 取消绘制
  cancel: (sketchViewModel) => {
    sketchViewModel.cancel()
  }
}

// 监听绘制事件
const setupDrawingEvents = (sketchViewModel) => {
  // 绘制完成事件
  sketchViewModel.on('create', (event) => {
    if (event.state === 'complete') {
      console.log('绘制完成:', event.graphic)
      // 处理绘制完成的图形
      handleDrawingComplete(event.graphic)
    }
  })

  // 更新事件
  sketchViewModel.on('update', (event) => {
    if (event.state === 'complete') {
      console.log('更新完成:', event.graphics)
    }
  })

  // 删除事件
  sketchViewModel.on('delete', (event) => {
    console.log('删除图形:', event.graphics)
  })
}

3. 测量工具

import DistanceMeasurement2D from '@geoscene/core/widgets/DistanceMeasurement2D.js'
import AreaMeasurement2D from '@geoscene/core/widgets/AreaMeasurement2D.js'

// 创建距离测量工具
const createDistanceMeasurement = (view) => {
  const distanceMeasurement = new DistanceMeasurement2D({
    view: view
  })
  
  return distanceMeasurement
}

// 创建面积测量工具
const createAreaMeasurement = (view) => {
  const areaMeasurement = new AreaMeasurement2D({
    view: view
  })
  
  return areaMeasurement
}

// 测量工具管理
const measurementTools = {
  distanceTool: null,
  areaTool: null,

  // 开始距离测量
  startDistanceMeasurement: (view) => {
    // 清除其他测量工具
    measurementTools.clearAll()
    
    measurementTools.distanceTool = createDistanceMeasurement(view)
    view.ui.add(measurementTools.distanceTool, 'top-right')
  },

  // 开始面积测量
  startAreaMeasurement: (view) => {
    // 清除其他测量工具
    measurementTools.clearAll()
    
    measurementTools.areaTool = createAreaMeasurement(view)
    view.ui.add(measurementTools.areaTool, 'top-right')
  },

  // 清除所有测量工具
  clearAll: () => {
    if (measurementTools.distanceTool) {
      measurementTools.distanceTool.destroy()
      measurementTools.distanceTool = null
    }
    if (measurementTools.areaTool) {
      measurementTools.areaTool.destroy()
      measurementTools.areaTool = null
    }
  }
}

高级功能应用

1. 聚合显示

import FeatureLayer from '@geoscene/core/layers/FeatureLayer.js'

// 创建聚合图层
const createClusterLayer = (data) => {
  // 创建要素图层
  const featureLayer = new FeatureLayer({
    source: data.map(item => ({
      geometry: {
        type: 'point',
        longitude: item.longitude,
        latitude: item.latitude
      },
      attributes: item.attributes
    })),
    objectIdField: 'ObjectID',
    geometryType: 'point',
    spatialReference: { wkid: 4326 },
    fields: [
      {
        name: 'ObjectID',
        alias: 'ObjectID',
        type: 'oid'
      },
      {
        name: 'name',
        alias: '名称',
        type: 'string'
      }
    ],
    // 启用聚合
    featureReduction: {
      type: 'cluster',
      clusterRadius: '100px',
      popupTemplate: {
        title: '聚合点',
        content: '此处有 {cluster_count} 个点'
      },
      symbol: {
        type: 'simple-marker',
        color: '#69dcff',
        outline: {
          color: 'rgba(0, 139, 174, 0.5)',
          width: 15
        },
        size: 15
      },
      labelingInfo: [{
        deconflictionStrategy: 'none',
        labelExpressionInfo: {
          expression: '$feature.cluster_count_label'
        },
        symbol: {
          type: 'text',
          color: '#004a5d',
          font: {
            weight: 'bold',
            family: 'Noto Sans',
            size: 10
          }
        },
        labelPlacement: 'center-center'
      }]
    }
  })

  return featureLayer
}

2. 热力图

// 创建热力图图层
const createHeatmapLayer = (data) => {
  const featureLayer = new FeatureLayer({
    source: data,
    objectIdField: 'ObjectID',
    fields: [
      {
        name: 'ObjectID',
        alias: 'ObjectID',
        type: 'oid'
      },
      {
        name: 'intensity',
        alias: '强度',
        type: 'double'
      }
    ],
    // 使用热力图渲染器
    renderer: {
      type: 'heatmap',
      field: 'intensity',
      colorStops: [
        { color: 'rgba(63, 40, 102, 0)', ratio: 0 },
        { color: '#472d7b', ratio: 0.083 },
        { color: '#4e2d87', ratio: 0.166 },
        { color: '#563086', ratio: 0.249 },
        { color: '#5d3280', ratio: 0.332 },
        { color: '#65337c', ratio: 0.415 },
        { color: '#6e3375', ratio: 0.498 },
        { color: '#76336e', ratio: 0.581 },
        { color: '#7f3465', ratio: 0.664 },
        { color: '#88355f', ratio: 0.747 },
        { color: '#903658', ratio: 0.83 },
        { color: '#99374f', ratio: 0.913 },
        { color: '#a23847', ratio: 1 }
      ],
      maxPixelIntensity: 25,
      minPixelIntensity: 1
    }
  })

  return featureLayer
}

网站公告

今日签到

点亮在社区的每一天
去签到