发布于 2026-01-06 6 阅读
0

3D 地图、React.js 和 Typescript

3D 地图、React.js 和 Typescript

我一直在尝试使用 3D 地图、React.js 和 TypeScript,所以我决定将它们结合起来,写一个小项目,并记录下我的实验过程。 目标是向大家展示如何使用 React 和 TypeScript 构建 3D 地图。 我建议使用“Create React App”,这是一个可以帮助你快速上手创建 React 单页应用程序的环境。 步骤如下:
替代文字


  • 使用“Create React App”创建一个启用 TypeScript 的空项目;
  • 为地图创建 React 组件;
  • 存储和使用地图的 API 密钥;
  • 在 HTML 中添加 HERE 地图的 JS 和 CSS;
  • React 组件中正在加载 HERE 地图;

创建一个空项目

当我需要使用 ReactJS 创建一些原型时,我过去常常使用Create React App创建项目

npx create-react-app map-here-ts --template typescript
cd map-here-ts
Enter fullscreen mode Exit fullscreen mode

要使用 TypeScript,您需要使用`--template`选项。
该工具可以帮助您创建包含所有内容的项目。执行该命令后,您将得到一个名为 ` map-here-ts`的目录,其中包含已创建的 `package.json` 文件以及所有已安装的 Node 模块。

创建地图组件

在 src/ 目录下,你需要创建 src/components/Map 目录。
在 src/components/Map 目录下,你需要创建 Map.tsx 和 Map.css 文件。

mkdir -p src/components/Map
touch src/components/Map/Map.tsx
touch src/components/Map/Map.css
Enter fullscreen mode Exit fullscreen mode

没错,tsx 是正确的扩展名,你正在使用 TypeScript 和 jsx,所以应该使用 tsx。

将 API 密钥存储在环境变量文件中

我们将使用 HERE Technologies 提供的地图和服务。他们提供不错的免费套餐,对于想要尝试位置服务的开发者来说非常实用。要使用地图和服务,您需要访问开发者门户,注册账号,创建一个免费增值套餐的新项目,并创建一个新的 API 密钥。创建新项目的网址是:https://developer.here.com/projects

替代文字

获取 API 密钥后,即可创建.env.local文件并创建一个新参数:

REACT_APP_HERE_APIKEY="your-here-API Key"
Enter fullscreen mode Exit fullscreen mode

请记住将“your-here-API Key”替换为您的 API 密钥。

实现地图组件

在之前创建的 src/components/Map/Map.tsx 组件(空文件)中,您可以按照建议填充内容:

import React, { Component } from "react";
// 001 - Importing CSS
import "./Map.css";
// 002 - Adding H declaration in Window
declare global {
  interface Window {
    H: any;
  }
}
// 003 - Defining IProps Interface with debug prop
interface IProps {
  debug?: boolean;
}
// 004 - Defining  IState interface with all attributes we need
interface IState {
  lat: number;
  lng: number;
  zoom: number;
}

// 005 - Defining component with Typescript Generic
class Map extends Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);
    // 006 - Setting some Default (Colosseum - Rome)
    this.state = {
      lat: 41.890251,
      lng: 12.492373,
      zoom: 18
    };
  }

  // 007 - Implementing componentDidMount in order to load map once the component is mounted
  componentDidMount() {
    // 008 - Using H (a Class exported by HERE Map Javascript)
    let H = (window as any).H;
    // 009 - Instancing Map Platform
    var platform = new H.service.Platform({
      // 010 - Using the parameter defined in .env.local
      apikey: process.env.REACT_APP_HERE_APIKEY
    });
    // 011 - Defining default Layers to apply on map
    var defaultLayers = platform.createDefaultLayers();

    // 012 - initialize the map
    var map = new H.Map(
      document.getElementById("map"),
      defaultLayers.vector.normal.map,
      {
        // 013 - using state for lat, lng and zoom
        center: { lat: this.state.lat, lng: this.state.lng },
        zoom: this.state.zoom,
        pixelRatio: window.devicePixelRatio || 1
      }
    );
    // 014 - incline the Map
    map.getViewModel().setLookAtData({ tilt: 45, heading: 0 });
    // 015 - add a resize listener to make sure that the map occupies the whole container
    window.addEventListener("resize", () => map.getViewPort().resize());
    new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
    // 016 - Create the default UI components
    H.ui.UI.createDefault(map, defaultLayers);
  }
  render() {
    // 017 - implement render function
    return (
      <div className="mapWrapper">
        <div className="map" id="map"></div>
      </div>
    );
  }
}
export default Map;

Enter fullscreen mode Exit fullscreen mode

直接复制粘贴之前的代码会很方便,但让我来解释一下代码(请查看注释):

  • 001:导入 CSS 文件,您可以在其中定义样式;
  • 002:为了在 Typescript 中使用 HERE Maps Javascript 导出的 H 类,我们需要为 Window 定义一个包含 H 的接口;
  • 003:由于 TypeScript 的限制,我们需要声明 props 接口,其中包含组件中将要使用的所有 props。在本例中,定义了一个非必需的(问号) debug prop,其类型为布尔值;
  • 004:由于 TypeScript 的限制,我们需要声明一个状态接口,其中包含组件中将要使用的所有属性。在本例中:lat、lng、zoom(以数字形式表示);
  • 005:使用 TypeScript 通用定义组件
  • 006:将默认中心和缩放设置为状态;
  • 007:实现 componentDidMount 函数,以便在组件挂载后加载地图;
  • 008:使用 H(HERE Map Javascript 导出的类);
  • 009:实例地图平台
  • 010:使用之前存储在 .env.local 文件中的 API 密钥;
  • 011:定义要应用于地图的默认图层;
  • 012:初始化映射;
  • 013:通过 this.state 使用状态获取纬度、经度和缩放级别;
  • 014:让我们通过 setLookAtData 方法以及倾斜和航向来旋转地图。
  • 015:添加一个调整大小监听器,确保地图占据整个容器。
  • 016:创建默认 UI 组件

为地图容器定义一些 CSS 样式

在 Map.css CSS 文件(已在 Map.tsx 中导入)中设置地图容器的高度:

.map {
  height: 100vh;
  background: #f0e68c;
}
Enter fullscreen mode Exit fullscreen mode

包含 HERE 地图 Javascript

在 public/index.html 文件中,将 HEAD 部分中的正确 CSS 和 JS 文件添加到 Map JS 文件中:

<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
Enter fullscreen mode Exit fullscreen mode

加载地图组件

在 src/App.tsx 文件中,将“Create React App 创建的示例代码”替换为:

import React from 'react';
import Map from './components/Map/Map'

const App: React.FC = () => {
  return (
    <div className="App">
      <Map></Map>
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

运行项目

返回到新项目目录下的控制台,执行以下命令:

npm run start
Enter fullscreen mode Exit fullscreen mode

替代文字

就这些!
欢迎在评论区留下您的反馈意见。

文章来源:https://dev.to/robertobutti/3d-map-react-js-and-typescript-1hl4