You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Maps Animations TypeScript重构报错及API使用问题求助

Azure Maps Animations TypeScript重构问题排查

控制台错误

运行时Chrome控制台抛出两个错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'EventEmitter')
    at azure-maps-animations.js:1101:23
    at azure-maps-animations.js:3424:2

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'moveAlongRoute')
    at main.ts:96:41

环境配置

tsconfig.json

{
  "compilerOptions": {
    "module": "AMD",
    "target": "ES6",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "declaration": false,
    "lib": ["ES6", "DOM"],
    "resolveJsonModule": true,
    "downlevelIteration": true,
    "outDir": "./js",
    "rootDir": "./ts",
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "typeRoots": [
      "./node_modules/@types",
      "./types"
    ],
    "baseUrl": "./",
    "paths": {
      "azure-maps-control": ["node_modules/azure-maps-control/dist/atlas.min"]
    }
  }
}

RequireJS config.js

require.config({
  baseUrl: './js',
  paths: {
    'azure-maps-control': 'https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas',
    'azure-maps-animations': '../lib/azure-maps/azure-maps-animations'
  }
});

require(['main'], function(main) {
});

HTML页面

<head>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>
    <script src="./node_modules/requirejs/require.js" defer></script>
    <script src="./config.js" defer></script>
    <link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css" rel="stylesheet" />
</head>
<body>
    <div id="myMap"></div>
</body>

main.ts代码

import * as azmaps from 'azure-maps-control'
import * as atlas from 'azure-maps-animations'

var anim: atlas.RoutePathAnimation;
var map: azmaps.Map;

function main() {
    try {
        map = new azmaps.Map("myMap", {
            center: [-122.345, 47.615],
            zoom: 14,
            view: 'Auto',
            authOptions: {...}
        });

        map.events.add('click', function () {
            //anim.play();
        });

        map.events.add('ready', function () {
            map.imageSprite.createFromTemplate('arrow-icon', 'marker-arrow', 'teal', '#fff').then(function () {
                var lineSource = new azmaps.source.DataSource();
                var pinSource = new azmaps.source.DataSource();
                map.sources.add([lineSource, pinSource]);

                map.layers.add(new azmaps.layer.LineLayer(lineSource, undefined, {
                    strokeColor: 'DodgerBlue',
                    strokeWidth: 3
                }));

                var path: azmaps.data.Position[] = [];
                var routePoints = [
                    new azmaps.data.Feature(new azmaps.data.Point([-122.34758, 47.62155]), { _timestamp: new Date('Tue, 18 Aug 2020 00:53:53 GMT').getTime() }),
                    new azmaps.data.Feature(new azmaps.data.Point([-122.34764, 47.61859]), { _timestamp: new Date('Tue, 18 Aug 2020 00:54:53 GMT').getTime() }),
                    new azmaps.data.Feature(new azmaps.data.Point([-122.33787, 47.61295]), { _timestamp: new Date('Tue, 18 Aug 2020 00:56:53 GMT').getTime() }),
                    new azmaps.data.Feature(new azmaps.data.Point([-122.34217, 47.60964]), { _timestamp: new Date('Tue, 18 Aug 2020 00:59:53 GMT').getTime() })
                ];

                routePoints.forEach(f => {
                    path.push(f.geometry.coordinates);
                });

                lineSource.add(new azmaps.data.LineString(path));

                map.layers.add(new azmaps.layer.SymbolLayer(pinSource, undefined, {
                    iconOptions: {
                        image: 'arrow-icon',
                        anchor: 'center',
                        rotation: ['+', 180, ['get', 'heading']],
                        rotationAlignment: 'map',
                        ignorePlacement: true,
                        allowOverlap: true
                    },
                    textOptions: {
                        ignorePlacement: true,
                        allowOverlap: true
                    }
                }));

                var pin = new azmaps.Shape(routePoints[0]);
                pinSource.add(pin);

                anim = atlas.animations.moveAlongRoute(routePoints, pin, { 
                    //timestampProperty: 'timestamp',
                    captureMetadata: true,
                    loop: false,
                    reverse: false,
                    rotationOffset: 0,
                    speedMultiplier: 60,
                    map: undefined,
                    zoom: 15,
                    pitch: 45,
                    rotate: true
                });
            });
        });
    } catch (error) {
        console.error('Error initializing game:', error);
    }
}

function ready(fn: () => void) {
    if (document.readyState !== 'loading') {
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

ready(() => {
    console.log("addEventListener");
    main();
});

额外类型错误

  1. 取消注释//anim.play();时,提示:Property 'play' does not exist on type 'RoutePathAnimation'
  2. 取消注释//timestampProperty: 'timestamp',时,提示:'timestampProperty' does not exist in type 'RoutePathAnimationOptions'

问题背景

原示例中control和animations均使用atlas命名空间,但当前代码分开导入导致冲突。使用的animations库和类型定义文件来自Azure官方示例仓库,希望启用timestampProperty功能。


修复方案

1. 解决命名空间与依赖加载问题

animations库依赖control库的EventEmitter,且原设计是挂载到全局atlas命名空间,分开导入会导致依赖缺失。调整RequireJS配置添加依赖声明:

require.config({
  baseUrl: './js',
  paths: {
    'azure-maps-control': 'https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas',
    'azure-maps-animations': '../lib/azure-maps/azure-maps-animations'
  },
  shim: {
    'azure-maps-animations': {
      deps: ['azure-maps-control'],
      exports: 'atlas'
    }
  }
});

同时统一TypeScript中的命名空间使用,修改main.ts导入方式:

// 移除分开的导入,直接使用全局atlas
declare var atlas: typeof import('azure-maps-control') & typeof import('./types/azure-maps-animations');

var anim: atlas.RoutePathAnimation;
var map: atlas.Map;

// 后续代码中所有azmaps替换为atlas

2. 补充缺失的类型定义

下载的类型定义文件未包含play()方法和timestampProperty属性,手动修改./types/azure-maps-animations.d.ts:

// 在RoutePathAnimationOptions接口中添加
timestampProperty?: string;

// 在RoutePathAnimation接口中添加
play(): void;
pause(): void;
stop(): void;

3. 修正动画初始化参数

创建动画时,map参数需传入实际地图实例,且timestampProperty要匹配数据中的字段(当前数据用的是_timestamp):

anim = atlas.animations.moveAlongRoute(routePoints, pin, { 
  timestampProperty: '_timestamp',
  captureMetadata: true,
  loop: false,
  reverse: false,
  rotationOffset: 0,
  speedMultiplier: 60,
  map: map,
  zoom: 15,
  pitch: 45,
  rotate: true
});

内容的提问来源于stack exchange,提问作者ClaudeVernier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:33:11