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
要使用 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
没错,tsx 是正确的扩展名,你正在使用 TypeScript 和 jsx,所以应该使用 tsx。
将 API 密钥存储在环境变量文件中
我们将使用 HERE Technologies 提供的地图和服务。他们提供不错的免费套餐,对于想要尝试位置服务的开发者来说非常实用。要使用地图和服务,您需要访问开发者门户,注册账号,创建一个免费增值套餐的新项目,并创建一个新的 API 密钥。创建新项目的网址是:https://developer.here.com/projects。
获取 API 密钥后,即可创建.env.local文件并创建一个新参数:
REACT_APP_HERE_APIKEY="your-here-API Key"
请记住将“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;
直接复制粘贴之前的代码会很方便,但让我来解释一下代码(请查看注释):
- 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;
}
包含 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>
加载地图组件
在 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;
运行项目
返回到新项目目录下的控制台,执行以下命令:
npm run start
就这些!
欢迎在评论区留下您的反馈意见。

