@trapar-waves/react-three-maplibre 1.1.23 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,105 +9,76 @@
9
9
 
10
10
  ---
11
11
 
12
- [English](../README.md) | [中文](/readme/README-CN.md) | [日本語](/readme/README-JP.md)
12
+ [English](../README.md) | [中文](./README-CN.md) | [日本語](./README-JP.md)
13
13
 
14
14
  > Библиотека на базе React, интегрирующая Three.js, MapLibre и AntV для расширенной геопространственной 3D-визуализации.
15
15
 
16
- ## ✨ Особенности
16
+ ![react-three-maplibre hero](../assets/readme/hero.svg)
17
+
18
+ ![Features](../assets/readme/headers/features.svg)
17
19
 
18
20
  - **Геопространственная визуализация:** Комбинирует `@antv/l7` и `maplibre-gl` для мощного рендеринга геопространственных данных с пользовательскими слоями карт.
19
21
  - **3D-рендеринг с React:** Использует `@react-three/fiber` и `@react-three/drei` для интеграции Three.js в рабочий процесс на базе React для декларативного управления 3D-сценами.
20
22
  - **Интеграция настраиваемого UI:** Обеспечивает бесперебойную интеграцию с React (`react`, `react-dom`) для создания интерактивных геопространственных приложений.
21
23
  - **Стилизация с упором на утилиты:** Применяет `tailwindcss` для гибкой и быстрой стилизации компонентов и макетов.
22
- - **Типовая безопасность:** Использует TypeScript для обеспечения типовой безопасности и улучшения опыта разработчика во время разработки.
24
+ - **Типобезопасность:** Использует TypeScript для обеспечения типобезопасности и улучшения опыта разработчика во время разработки.
23
25
  - **Быстрый рабочий процесс разработки:** Использует `rsbuild` для оптимизированных сборок и эффективной производительности сервера разработки.
24
26
  - **Богатая библиотека компонентов:** Интегрируется с `three-stdlib` и `@react-three/drei` для переиспользуемых утилит и компонентов Three.js.
25
27
  - **Интерактивность карт:** Реализует `react-map-gl` для интерактивных элементов управления картами и навигации на клиентской стороне в геопространственных контекстах.
26
28
  - **Дополнения AntV:** Включает `@antv/l7-maps` для дополнительных возможностей слоев карт и инструментов визуализации.
27
29
 
28
- ## 💻 Технологический стек
29
-
30
- - **Фреймворк/Библиотека:** React
31
- - **UI-тулкит/Стилизация:** Tailwind CSS
32
- - **3D-рендеринг:** Three.js (`@react-three/fiber`, `@react-three/drei`)
33
- - **Геопространственные библиотеки:** MapLibre GL, AntV L7
34
- - **Инструмент сборки:** Rsbuild
35
- - **Язык:** TypeScript
36
-
37
- Полный список зависимостей см. в [package.json](package.json).
30
+ ![Tech Stack](../assets/readme/headers/tech-stack.svg)
38
31
 
39
- ## 🚀 Начало работы
32
+ - **Фреймворк/библиотека:** `React`
33
+ - **UI-тулкит/стилизация:** `Tailwind CSS`
34
+ - **3D-рендеринг:** `Three.js` (`@react-three/fiber`, `@react-three/drei`)
35
+ - **Геопространственные библиотеки:** `MapLibre GL`, `AntV L7`
36
+ - **Инструмент сборки:** `Rsbuild`
37
+ - **Язык:** `TypeScript`
40
38
 
41
- Следуйте этим инструкциям, чтобы запустить проект локально.
39
+ Полный список зависимостей смотрите в [package.json](../package.json).
42
40
 
43
- ### Предварительные требования
41
+ ![Getting Started](../assets/readme/headers/getting-started.svg)
44
42
 
45
- Убедитесь, что у вас установлены следующие компоненты:
43
+ ## Предварительные требования
46
44
 
47
- - Node.js (рекомендуется версия >= 18.x)
48
- - Пакетный менеджер (npm, yarn или pnpm)
49
-
50
- ```bash
51
- node -v
52
- npm -v
53
- ```
45
+ - Node.js (рекомендуется >= 18.x)
46
+ - Менеджер пакетов (npm, yarn или pnpm)
54
47
 
55
48
  ### Установка
56
49
 
57
50
  1. Создайте новый проект с помощью шаблона:
58
51
 
59
- ```bash
60
- pnpm create trapar-waves
61
- ```
62
-
63
- 2. Перейдите в каталог вашего проекта и установите зависимости:
52
+ ```bash
53
+ pnpm create trapar-waves
54
+ ```
64
55
 
65
- ```bash
66
- cd your-project-name
67
- pnpm install
68
- # or
69
- npm install
70
- # or
71
- yarn install
72
- ```
56
+ 2. Перейдите в директорию проекта и установите зависимости:
73
57
 
74
- ### Разработка
58
+ ```bash
59
+ pnpm install
60
+ ```
75
61
 
76
- Запустите сервер разработки с горячей перезагрузкой:
77
-
78
- ```bash
79
- pnpm dev
80
- # or
81
- npm run dev
82
- # or
83
- yarn dev
84
- ```
62
+ 3. Запустите сервер разработки:
85
63
 
86
- Приложение будет доступно по адресу `http://localhost:3000` по умолчанию.
64
+ ```bash
65
+ pnpm dev
66
+ ```
87
67
 
88
- ### Сборка для продакшена
68
+ ![Project Structure](../assets/readme/headers/project-structure.svg)
89
69
 
90
- Чтобы создать сборку для продакшена:
91
-
92
- ```bash
93
- pnpm build
94
- # or
95
- npm run build
96
- # or
97
- yarn build
98
70
  ```
99
-
100
- Предварительный просмотр сборки продакшена локально:
101
-
102
- ```bash
103
- pnpm preview
104
- # or
105
- npm run preview
106
- # or
107
- yarn preview
71
+ ├── public/ # Статические ресурсы
72
+ ├── src/ # Исходный код
73
+ │ ├── App.tsx # Основной компонент приложения
74
+ │ └── index.tsx # Точка входа
75
+ ├── rsbuild.config.ts # Конфигурация Rsbuild
76
+ ├── tsconfig.json # Конфигурация TypeScript
77
+ ├── eslint.config.js # Конфигурация ESLint
78
+ └── package.json # Зависимости и скрипты проекта
108
79
  ```
109
80
 
110
- ## 📦 Использование
81
+ ![Usage](../assets/readme/headers/usage.svg)
111
82
 
112
83
  Эта библиотека предназначена для использования в качестве шаблона для создания приложений геопространственной 3D-визуализации. Она предоставляет фундаментальную настройку с React, Three.js, MapLibre GL и AntV L7.
113
84
 
@@ -142,7 +113,8 @@ const latLon = {
142
113
  latitude: 31.215175,
143
114
  longitude: 121.417463,
144
115
  };
145
- const MAPTILER_KEY = import.meta.env.PUBLIC_MAPTILER_KEY;
116
+ const MAP_STYLE_URL
117
+ = "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json";
146
118
 
147
119
  function App() {
148
120
  const ref = useRef<HTMLDivElement>(null!);
@@ -187,7 +159,7 @@ function App() {
187
159
  zoom: 11,
188
160
  pitch: 64.88,
189
161
  }}
190
- mapStyle={`https://api.maptiler.com/maps/streets/style.json?key=${MAPTILER_KEY}`}
162
+ mapStyle={MAP_STYLE_URL}
191
163
  onLoad={initL7}
192
164
  >
193
165
  <Stats className="stats" parent={ref} />
@@ -211,22 +183,17 @@ export default App;
211
183
  ```
212
184
 
213
185
  Этот пример демонстрирует:
186
+
214
187
  - Создание карты MapLibre GL с помощью `react-map-gl`
215
188
  - Интеграция AntV L7 для визуализации геопространственных данных
216
189
  - Использование React Three Fiber и Drei для 3D-рендеринга
217
190
  - Позиционирование 3D-объектов относительно карты с помощью `react-three-map`
218
191
 
219
- ### Переменные окружения
192
+ ### Подложка карты
220
193
 
221
- Для использования сервисов карт, таких как MapTiler, вам нужно настроить переменные окружения. Создайте файл `.env` в корне вашего проекта:
194
+ В шаблоне по умолчанию используется стиль Carto GL без API-ключа (`MAP_STYLE_URL` в `src/App.tsx`). Для другого провайдера (например, MapTiler) задайте `mapStyle` и храните ключи в `.env` / CI.
222
195
 
223
- ```
224
- PUBLIC_MAPTILER_KEY=your_maptiler_api_key_here
225
- ```
226
-
227
- Обязательно добавьте `.env` в ваш `.gitignore`, чтобы ваши ключи оставались в безопасности.
228
-
229
- ## 🤝 Участие в разработке
196
+ ![Contributing](../assets/readme/headers/contributing.svg)
230
197
 
231
198
  Вклад в проект приветствуется и очень ценится! Чтобы внести вклад, следуйте этим шагам:
232
199
 
@@ -236,15 +203,16 @@ PUBLIC_MAPTILER_KEY=your_maptiler_api_key_here
236
203
  4. Отправьте изменения в ветку (`git push origin feature/amazing-feature`)
237
204
  5. Откройте Pull Request
238
205
 
239
- Пожалуйста, убедитесь, что ваш код соответствует существующему стилю и проходит все тесты.
206
+ ![License](../assets/readme/headers/license.svg)
207
+
208
+ MIT License © 2025 Trapar Waves
240
209
 
241
- ## 👤 Author
210
+ ## 👤 Автор
242
211
 
243
- - **Rikka:** (admin@rikka.cc)
244
- - **GitHub Profile:** [Muromi-Rikka](https://github.com/Muromi-Rikka)
212
+ - **Rikka:** [admin@rikka.cc](mailto:admin@rikka.cc)
213
+ - **Профиль GitHub:** [Muromi-Rikka](https://github.com/Muromi-Rikka)
245
214
 
246
- ## 🔗 Links
215
+ ## 🔗 Ссылки
247
216
 
248
217
  - **Репозиторий:** [https://github.com/Trapar-waves/react-three-maplibre](https://github.com/Trapar-waves/react-three-maplibre)
249
- - **Домашняя страница:** [https://github.com/Trapar-waves/react-three-maplibre](https://github.com/Trapar-waves/react-three-maplibre)
250
- - **Проблемы:** [https://github.com/Trapar-waves/react-three-maplibre/issues](https://github.com/Trapar-waves/react-three-maplibre/issues)
218
+ - **Issues:** [https://github.com/Trapar-waves/react-three-maplibre/issues](https://github.com/Trapar-waves/react-three-maplibre/issues)
package/rsbuild.config.ts CHANGED
@@ -1,11 +1,37 @@
1
1
  import { defineConfig, loadEnv } from "@rsbuild/core";
2
+ import { pluginLess } from "@rsbuild/plugin-less";
2
3
  import { pluginReact } from "@rsbuild/plugin-react";
4
+ import { RsdoctorRspackPlugin } from "@rsdoctor/rspack-plugin";
3
5
  import tailwind from "@tailwindcss/postcss";
6
+ import process from "node:process";
7
+ import TurboConsole from "unplugin-turbo-console/rspack";
4
8
 
5
9
  const { publicVars } = loadEnv({ cwd: "./environments" });
6
10
 
11
+ function normalizeBasePath(): string {
12
+ const raw = process.env.BASE_PATH?.trim();
13
+ if (!raw || raw === "/") {
14
+ return "/";
15
+ }
16
+ const prefixed = raw.startsWith("/") ? raw : `/${raw}`;
17
+ return prefixed.endsWith("/") ? prefixed : `${prefixed}/`;
18
+ }
19
+
20
+ const basePath = normalizeBasePath();
21
+ const isUseSubpath = basePath !== "/";
22
+
23
+ const isEnableRsdoctor = Boolean(process.env.RSDOCTOR);
24
+ const isEnableTurboConsole = process.env.NODE_ENV === "development";
25
+
7
26
  export default defineConfig({
8
- plugins: [pluginReact()],
27
+ ...(isUseSubpath && {
28
+ output: { assetPrefix: basePath },
29
+ server: { base: basePath },
30
+ }),
31
+ performance: {
32
+ ...(isEnableRsdoctor && { buildCache: false }),
33
+ },
34
+ plugins: [pluginReact(), pluginLess()],
9
35
  source: {
10
36
  define: publicVars,
11
37
  },
@@ -15,5 +41,24 @@ export default defineConfig({
15
41
  plugins: [tailwind],
16
42
  },
17
43
  },
44
+ rspack: [
45
+ (config) => {
46
+ if (isEnableTurboConsole) {
47
+ config.plugins.push(TurboConsole());
48
+ }
49
+ if (isEnableRsdoctor) {
50
+ config.plugins.push(
51
+ new RsdoctorRspackPlugin({
52
+ output: {
53
+ mode: "brief",
54
+ options: {
55
+ type: ["json"],
56
+ },
57
+ },
58
+ }),
59
+ );
60
+ }
61
+ },
62
+ ],
18
63
  },
19
64
  });
package/src/app.tsx ADDED
@@ -0,0 +1,217 @@
1
+ import type { ReactNode } from "react";
2
+ import type { MapRef } from "react-map-gl/maplibre";
3
+ import { PointLayer, Scene } from "@antv/l7";
4
+ import { MapLibre } from "@antv/l7-maps";
5
+ import { Box, Stats } from "@react-three/drei";
6
+ import { extend } from "@react-three/fiber";
7
+ import { useRef } from "react";
8
+ import Map from "react-map-gl/maplibre";
9
+ import { Canvas } from "react-three-map/maplibre";
10
+ import { LineMaterial, LineSegments2, LineSegmentsGeometry } from "three-stdlib";
11
+
12
+ // eslint-disable-next-line unicorn/no-top-level-side-effects -- R3F extend must run before render
13
+ extend({ LineMaterial, LineSegments2, LineSegmentsGeometry });
14
+
15
+ declare module "@react-three/fiber" {
16
+ interface ThreeElements {
17
+ lineMaterial: Partial<LineMaterial> & ThreeElements["material"];
18
+ lineSegments2: ThreeElements["object3D"] & { children?: ReactNode };
19
+ lineSegmentsGeometry: ThreeElements["bufferGeometry"];
20
+ }
21
+ }
22
+
23
+ const latLon = {
24
+ latitude: 31.215175,
25
+ longitude: 121.417463,
26
+ };
27
+
28
+ /**
29
+ * Carto 托管的 MapLibre GL 矢量底图,无需 API Key(使用请遵守 https://carto.com/basemaps/ 条款)。
30
+ */
31
+ const MAP_STYLE_URL = "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json";
32
+
33
+ function publicAssetUrl(filename: string): string {
34
+ const base = (import.meta.env.BASE_URL ?? "/").replace(/\/$/, "");
35
+ const path = filename.startsWith("/") ? filename : `/${filename}`;
36
+ return `${base || ""}${path}`.replaceAll("//", "/");
37
+ }
38
+
39
+ const HOMEPAGE = "https://github.com/Trapar-waves/react-three-maplibre";
40
+ const LOGOS_SET_URL = "https://icon-sets.iconify.design/logos/";
41
+
42
+ interface TechPill {
43
+ iconClass: string;
44
+ id: string;
45
+ label: string;
46
+ }
47
+
48
+ const techStack: TechPill[] = [
49
+ { iconClass: "icon-[logos--react]", id: "react", label: "React 19" },
50
+ { iconClass: "icon-[logos--typescript-icon]", id: "ts", label: "TypeScript" },
51
+ { iconClass: "icon-[logos--tailwindcss-icon]", id: "tailwind", label: "Tailwind 4" },
52
+ { iconClass: "icon-[material-icon-theme--rstack]", id: "rsbuild", label: "Rsbuild" },
53
+ { iconClass: "icon-[simple-icons--maplibre]", id: "maplibre", label: "MapLibre · react-map-gl" },
54
+ { iconClass: "icon-[logos--markdown]", id: "l7", label: "AntV L7" },
55
+ { iconClass: "icon-[logos--threejs]", id: "r3f", label: "R3F · drei · three-stdlib" },
56
+ { iconClass: "icon-[logos--markdown]", id: "rtmap", label: "react-three-map" },
57
+ { iconClass: "icon-[logos--eslint]", id: "eslint", label: "ESLint" },
58
+ { iconClass: "icon-[logos--pnpm]", id: "pnpm", label: "pnpm" },
59
+ { iconClass: "icon-[logos--github-icon]", id: "github", label: "GitHub Actions" },
60
+ ];
61
+
62
+ const readmeFeatures: string[] = [
63
+ "MapLibre 与 AntV L7 组合,自定义地图与点层渲染。",
64
+ "@react-three/fiber、drei 将 Three.js 以声明式接入 React。",
65
+ "react-three-map 与 MapLibre 视口同步;Canvas 使用 overlay 模式使 Three 叠在 L7 点层之上。",
66
+ "Tailwind CSS 快速布局与面板样式。",
67
+ "TypeScript 覆盖地图与场景相关类型。",
68
+ "Rsbuild 开发与生产构建。",
69
+ "react-map-gl 提供交互与导航体验。",
70
+ "three-stdlib 与 drei 复用常用几何与调试组件。",
71
+ "GitHub Pages 支持 BASE_PATH 与 404.html SPA 部署。",
72
+ "默认 Carto Basemaps GL 样式,本地与 CI 均无需地图 API Key。",
73
+ ];
74
+
75
+ const readmeTechNote = "演示使用 @react-three/drei 的 Stats;生产可按需移除。若需其他底图,可在 App.tsx 中替换 MAP_STYLE_URL 并自行处理鉴权。";
76
+
77
+ function App() {
78
+ const divReference = useRef<HTMLDivElement>(null!);
79
+ const mapReference = useRef<MapRef>(null!);
80
+ function initL7() {
81
+ if (!mapReference.current) {
82
+ return;
83
+ }
84
+
85
+ const scene = new Scene({
86
+ id: "map",
87
+ map: new MapLibre({
88
+ mapInstance: mapReference.current.getMap(),
89
+ }),
90
+ });
91
+ scene.on("loaded", async () => {
92
+ try {
93
+ const response = await fetch(publicAssetUrl("BElVQFEFvpAKzddxFZxJ.txt"));
94
+ if (!response.ok) {
95
+ return;
96
+ }
97
+ const data = await response.text();
98
+ const pointLayer = new PointLayer({
99
+ blend: "additive",
100
+ })
101
+ .source(data, {
102
+ parser: {
103
+ type: "csv",
104
+ x: "lng",
105
+ y: "lat",
106
+ },
107
+ })
108
+ .size(0.5)
109
+ .color("#080298");
110
+
111
+ scene.addLayer(pointLayer);
112
+ }
113
+ catch {}
114
+ });
115
+ }
116
+ return (
117
+ <div className="h-screen w-screen relative overflow-hidden" ref={divReference}>
118
+ <aside
119
+ aria-label="模板说明"
120
+ className="pointer-events-none absolute left-4 top-4 z-10 max-w-sm motion-safe:transition motion-safe:duration-200"
121
+ >
122
+ <div
123
+ className="pointer-events-auto max-h-[min(70vh,560px)] overflow-y-auto overscroll-contain rounded-xl border border-white/15 bg-slate-950/80 p-4 text-sm text-slate-100 shadow-xl backdrop-blur-md"
124
+ >
125
+ <p className="font-semibold text-white">react-three-maplibre</p>
126
+ <p className="mt-2 leading-relaxed text-slate-300">
127
+ MapLibre 与 react-three-map 同屏;L7 点层叠加 CSV,Three 方体经
128
+ {" "}
129
+ <code className="rounded bg-slate-800 px-1">overlay</code>
130
+ {" "}
131
+ 画布叠在 L7 之上。底图为 Carto 公开 GL 样式,无需地图服务 API Key。技术图标见
132
+ {" "}
133
+ <a
134
+ className="font-medium text-sky-300 underline decoration-sky-700 underline-offset-2 hover:text-sky-200"
135
+ href={LOGOS_SET_URL}
136
+ rel="noreferrer"
137
+ target="_blank"
138
+ >
139
+ Iconify logos
140
+ </a>
141
+
142
+ </p>
143
+ <p className="mt-3 text-xs font-medium uppercase tracking-wide text-slate-500">
144
+ 技术栈
145
+ </p>
146
+ <div className="mt-2 flex flex-wrap gap-2">
147
+ {techStack.map(item => (
148
+ <span
149
+ className="inline-flex items-center gap-1.5 rounded-lg border border-white/10 bg-slate-900/80 px-2 py-1 text-xs text-slate-200"
150
+ key={item.id}
151
+ >
152
+ <span aria-hidden className={`${item.iconClass} text-base text-sky-300`} />
153
+ {item.label}
154
+ </span>
155
+ ))}
156
+ </div>
157
+ <p className="mt-4 text-xs font-medium uppercase tracking-wide text-slate-500">
158
+ README 摘要
159
+ </p>
160
+ <ul className="mt-2 list-disc space-y-1 pl-4 text-slate-400">
161
+ {readmeFeatures.map(line => (
162
+ <li key={line}>{line}</li>
163
+ ))}
164
+ </ul>
165
+ <p className="mt-3 text-xs italic leading-relaxed text-slate-500">
166
+ {readmeTechNote}
167
+ </p>
168
+ <p className="mt-3 text-xs leading-relaxed text-slate-500">
169
+ 品牌图标来自
170
+ {" "}
171
+ <a className="text-sky-400 underline hover:text-sky-300" href={LOGOS_SET_URL} rel="noreferrer" target="_blank">SVG Logos</a>
172
+ {" "}
173
+ (CC0)。
174
+ </p>
175
+ <a
176
+ className="mt-3 inline-flex min-h-11 w-full items-center justify-center rounded-lg bg-sky-500 px-4 py-2 text-sm font-semibold text-slate-950 hover:bg-sky-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
177
+ href={HOMEPAGE}
178
+ rel="noreferrer"
179
+ target="_blank"
180
+ >
181
+ 查看仓库
182
+ </a>
183
+ </div>
184
+ </aside>
185
+ <Map
186
+ id="map"
187
+ initialViewState={{
188
+ ...latLon,
189
+ pitch: 64.88,
190
+ zoom: 11,
191
+ }}
192
+ mapStyle={MAP_STYLE_URL}
193
+ onLoad={initL7}
194
+ ref={mapReference}
195
+ >
196
+ <Stats className="stats" parent={divReference} />
197
+
198
+ <Canvas
199
+ id="trapar-r3f-overlay"
200
+ overlay
201
+ {...latLon}
202
+ >
203
+ <hemisphereLight
204
+ args={["#ffffff", "#60666C"]}
205
+ position={[1, 4.5, 3]}
206
+ />
207
+ <object3D scale={500}>
208
+ <Box position={[-1.2, 1, 0]} />
209
+ <Box position={[1.2, 1, 0]} />
210
+ </object3D>
211
+ </Canvas>
212
+ </Map>
213
+ </div>
214
+ );
215
+ }
216
+
217
+ export default App;
package/src/index.tsx CHANGED
@@ -1,10 +1,10 @@
1
1
  import ReactDOM from "react-dom/client";
2
- import App from "./App";
2
+ import App from "./app";
3
3
  import "./global.css";
4
4
 
5
- const rootEl = document.getElementById("root");
6
- if (rootEl) {
7
- const root = ReactDOM.createRoot(rootEl);
5
+ const rootElement = document.querySelector("#root");
6
+ if (rootElement) {
7
+ const root = ReactDOM.createRoot(rootElement);
8
8
  root.render(
9
9
  <App />,
10
10
  );
package/tsconfig.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
4
  "jsx": "react-jsx",
5
- "lib": ["DOM", "ES2020"],
5
+ "lib": ["DOM", "ESNext"],
6
6
  "useDefineForClassFields": true,
7
7
 
8
8
  /* modules */
package/src/App.tsx DELETED
@@ -1,91 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import type { MapRef } from "react-map-gl/maplibre";
3
- import { PointLayer, Scene } from "@antv/l7";
4
- import { MapLibre } from "@antv/l7-maps";
5
- import { Box, Stats } from "@react-three/drei";
6
- import { extend } from "@react-three/fiber";
7
- import { useRef } from "react";
8
- import Map from "react-map-gl/maplibre";
9
- import { Canvas } from "react-three-map/maplibre";
10
- import { LineMaterial, LineSegments2, LineSegmentsGeometry } from "three-stdlib";
11
-
12
- extend({ LineSegmentsGeometry, LineMaterial, LineSegments2 });
13
-
14
- declare module "@react-three/fiber" {
15
- interface ThreeElements {
16
- lineSegmentsGeometry: ThreeElements["bufferGeometry"];
17
- lineMaterial: ThreeElements["material"] & Partial<LineMaterial>;
18
- lineSegments2: ThreeElements["object3D"] & { children?: ReactNode };
19
- }
20
- }
21
-
22
- const latLon = {
23
- latitude: 31.215175,
24
- longitude: 121.417463,
25
- };
26
- const MAPTILER_KEY = import.meta.env.PUBLIC_MAPTILER_KEY;
27
-
28
- function App() {
29
- const ref = useRef<HTMLDivElement>(null!);
30
- const mapRef = useRef<MapRef>(null!);
31
- function initL7() {
32
- if (mapRef.current) {
33
- const scene = new Scene({
34
- id: "map",
35
- map: new MapLibre({
36
- mapInstance: mapRef.current.getMap(),
37
- }),
38
- });
39
- scene.on("loaded", () => {
40
- fetch("/BElVQFEFvpAKzddxFZxJ.txt")
41
- .then(res => res.text())
42
- .then((data) => {
43
- const pointLayer = new PointLayer({
44
- blend: "additive",
45
- })
46
- .source(data, {
47
- parser: {
48
- type: "csv",
49
- y: "lat",
50
- x: "lng",
51
- },
52
- })
53
- .size(0.5)
54
- .color("#080298");
55
-
56
- scene.addLayer(pointLayer);
57
- });
58
- });
59
- }
60
- }
61
- return (
62
- <div className="h-screen w-screen relative overflow-hidden" ref={ref}>
63
- <Map
64
- id="map"
65
- ref={mapRef}
66
- initialViewState={{
67
- ...latLon,
68
- zoom: 11,
69
- pitch: 64.88,
70
- }}
71
- mapStyle={`https://api.maptiler.com/maps/streets/style.json?key=${MAPTILER_KEY}`}
72
- onLoad={initL7}
73
- >
74
- <Stats className="stats" parent={ref} />
75
-
76
- <Canvas {...latLon}>
77
- <hemisphereLight
78
- args={["#ffffff", "#60666C"]}
79
- position={[1, 4.5, 3]}
80
- />
81
- <object3D scale={500}>
82
- <Box position={[-1.2, 1, 0]} />
83
- <Box position={[1.2, 1, 0]} />
84
- </object3D>
85
- </Canvas>
86
- </Map>
87
- </div>
88
- );
89
- }
90
-
91
- export default App;
File without changes