@exterio/react-native-yamap-lite 1.0.1
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.
- package/LICENSE +20 -0
- package/README.md +510 -0
- package/YamapLite.podspec +21 -0
- package/android/build.gradle +101 -0
- package/android/gradle.properties +14 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/yamaplite/ClusteredYamapLiteViewManager.kt +181 -0
- package/android/src/main/java/com/yamaplite/Components/ClusteredYamapLiteView.kt +169 -0
- package/android/src/main/java/com/yamaplite/Components/YamapLiteCircleView.kt +145 -0
- package/android/src/main/java/com/yamaplite/Components/YamapLiteMarkerView.kt +214 -0
- package/android/src/main/java/com/yamaplite/Components/YamapLitePolygon.kt +149 -0
- package/android/src/main/java/com/yamaplite/Components/YamapLitePolyline.kt +171 -0
- package/android/src/main/java/com/yamaplite/Components/YamapLiteView.kt +678 -0
- package/android/src/main/java/com/yamaplite/Events/CameraPositionChangeEvent.kt +38 -0
- package/android/src/main/java/com/yamaplite/Events/MapLoadEvent.kt +34 -0
- package/android/src/main/java/com/yamaplite/Events/PressEvent.kt +24 -0
- package/android/src/main/java/com/yamaplite/Utils/ImageCache.kt +45 -0
- package/android/src/main/java/com/yamaplite/Utils/PointParser.kt +39 -0
- package/android/src/main/java/com/yamaplite/Utils/ResolveImageHelper.kt +122 -0
- package/android/src/main/java/com/yamaplite/Utils/YamapUtils.kt +169 -0
- package/android/src/main/java/com/yamaplite/YamapLiteCircleViewManager.kt +67 -0
- package/android/src/main/java/com/yamaplite/YamapLiteMarkerViewManager.kt +82 -0
- package/android/src/main/java/com/yamaplite/YamapLitePackage.kt +41 -0
- package/android/src/main/java/com/yamaplite/YamapLitePolygonViewManager.kt +61 -0
- package/android/src/main/java/com/yamaplite/YamapLitePolylineViewManager.kt +75 -0
- package/android/src/main/java/com/yamaplite/YamapLiteViewManager.kt +176 -0
- package/ios/ClusteredYamapLiteView.h +15 -0
- package/ios/ClusteredYamapLiteView.mm +325 -0
- package/ios/ClusteredYamapLiteViewManager.mm +17 -0
- package/ios/Components/Circle.swift +108 -0
- package/ios/Components/ClusteredYamap.swift +190 -0
- package/ios/Components/Marker.swift +187 -0
- package/ios/Components/Polygon.swift +108 -0
- package/ios/Components/Polyline.swift +125 -0
- package/ios/Components/Yamap.swift +585 -0
- package/ios/Listeners/CameraListener.swift +54 -0
- package/ios/Listeners/ClusterListener.swift +38 -0
- package/ios/Listeners/MapInputListener.swift +35 -0
- package/ios/Listeners/MapLoadListener.swift +35 -0
- package/ios/Listeners/MapObjectTap.swift +12 -0
- package/ios/Listeners/UserLocationObjectListener.swift +29 -0
- package/ios/Models/YamapModels.swift +77 -0
- package/ios/Utils/ImageCache.swift +20 -0
- package/ios/Utils/PointsEqual.h +45 -0
- package/ios/Utils/ResolveImageHelper.swift +142 -0
- package/ios/YamapLiteCircleView.h +15 -0
- package/ios/YamapLiteCircleView.mm +102 -0
- package/ios/YamapLiteMarkerView.h +15 -0
- package/ios/YamapLiteMarkerView.mm +102 -0
- package/ios/YamapLitePolygonView.h +15 -0
- package/ios/YamapLitePolygonView.mm +120 -0
- package/ios/YamapLitePolylineView.h +15 -0
- package/ios/YamapLitePolylineView.mm +115 -0
- package/ios/YamapLiteView.h +15 -0
- package/ios/YamapLiteView.mm +361 -0
- package/ios/YamapLiteViewManager.mm +17 -0
- package/ios/YamapUtils.h +5 -0
- package/ios/YamapUtils.mm +205 -0
- package/lib/module/@types/index.js +8 -0
- package/lib/module/@types/index.js.map +1 -0
- package/lib/module/ClusteredYamapLiteViewNativeComponent.ts +98 -0
- package/lib/module/Components/Circle.js +20 -0
- package/lib/module/Components/Circle.js.map +1 -0
- package/lib/module/Components/ClusteredYamap.js +133 -0
- package/lib/module/Components/ClusteredYamap.js.map +1 -0
- package/lib/module/Components/Marker.js +40 -0
- package/lib/module/Components/Marker.js.map +1 -0
- package/lib/module/Components/Polygon.js +25 -0
- package/lib/module/Components/Polygon.js.map +1 -0
- package/lib/module/Components/Polyline.js +25 -0
- package/lib/module/Components/Polyline.js.map +1 -0
- package/lib/module/Components/Yamap.js +124 -0
- package/lib/module/Components/Yamap.js.map +1 -0
- package/lib/module/Components/index.js +9 -0
- package/lib/module/Components/index.js.map +1 -0
- package/lib/module/NativeYamapUtils.js +5 -0
- package/lib/module/NativeYamapUtils.js.map +1 -0
- package/lib/module/Utils/YamapUtils.js +14 -0
- package/lib/module/Utils/YamapUtils.js.map +1 -0
- package/lib/module/YamapCircleViewNativeComponent.ts +28 -0
- package/lib/module/YamapLiteViewNativeComponent.ts +93 -0
- package/lib/module/YamapMarkerViewNativeComponent.ts +32 -0
- package/lib/module/YamapPolygonViewNativeComponent.ts +28 -0
- package/lib/module/YamapPolylineViewNativeComponent.ts +31 -0
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/@types/index.d.ts +257 -0
- package/lib/typescript/src/@types/index.d.ts.map +1 -0
- package/lib/typescript/src/ClusteredYamapLiteViewNativeComponent.d.ts +82 -0
- package/lib/typescript/src/ClusteredYamapLiteViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/Components/Circle.d.ts +4 -0
- package/lib/typescript/src/Components/Circle.d.ts.map +1 -0
- package/lib/typescript/src/Components/ClusteredYamap.d.ts +3 -0
- package/lib/typescript/src/Components/ClusteredYamap.d.ts.map +1 -0
- package/lib/typescript/src/Components/Marker.d.ts +3 -0
- package/lib/typescript/src/Components/Marker.d.ts.map +1 -0
- package/lib/typescript/src/Components/Polygon.d.ts +4 -0
- package/lib/typescript/src/Components/Polygon.d.ts.map +1 -0
- package/lib/typescript/src/Components/Polyline.d.ts +4 -0
- package/lib/typescript/src/Components/Polyline.d.ts.map +1 -0
- package/lib/typescript/src/Components/Yamap.d.ts +3 -0
- package/lib/typescript/src/Components/Yamap.d.ts.map +1 -0
- package/lib/typescript/src/Components/index.d.ts +7 -0
- package/lib/typescript/src/Components/index.d.ts.map +1 -0
- package/lib/typescript/src/NativeYamapUtils.d.ts +30 -0
- package/lib/typescript/src/NativeYamapUtils.d.ts.map +1 -0
- package/lib/typescript/src/Utils/YamapUtils.d.ts +27 -0
- package/lib/typescript/src/Utils/YamapUtils.d.ts.map +1 -0
- package/lib/typescript/src/YamapCircleViewNativeComponent.d.ts +20 -0
- package/lib/typescript/src/YamapCircleViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/YamapLiteViewNativeComponent.d.ts +80 -0
- package/lib/typescript/src/YamapLiteViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/YamapMarkerViewNativeComponent.d.ts +25 -0
- package/lib/typescript/src/YamapMarkerViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/YamapPolygonViewNativeComponent.d.ts +20 -0
- package/lib/typescript/src/YamapPolygonViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/YamapPolylineViewNativeComponent.d.ts +23 -0
- package/lib/typescript/src/YamapPolylineViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +189 -0
- package/src/@types/index.ts +314 -0
- package/src/ClusteredYamapLiteViewNativeComponent.ts +98 -0
- package/src/Components/Circle.tsx +22 -0
- package/src/Components/ClusteredYamap.tsx +194 -0
- package/src/Components/Marker.tsx +50 -0
- package/src/Components/Polygon.tsx +27 -0
- package/src/Components/Polyline.tsx +27 -0
- package/src/Components/Yamap.tsx +176 -0
- package/src/Components/index.ts +6 -0
- package/src/NativeYamapUtils.ts +47 -0
- package/src/Utils/YamapUtils.ts +63 -0
- package/src/YamapCircleViewNativeComponent.ts +28 -0
- package/src/YamapLiteViewNativeComponent.ts +93 -0
- package/src/YamapMarkerViewNativeComponent.ts +32 -0
- package/src/YamapPolygonViewNativeComponent.ts +28 -0
- package/src/YamapPolylineViewNativeComponent.ts +31 -0
- package/src/index.tsx +5 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 hydromoll
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="./images/banner.png" alt="@exterio/react-native-yamap-lite" width="420" />
|
|
4
|
+
|
|
5
|
+
# @exterio/react-native-yamap-lite
|
|
6
|
+
|
|
7
|
+
**Легковесная библиотека для интеграции Yandex Maps (Яндекс Карт) в React Native.**
|
|
8
|
+
|
|
9
|
+
Yandex Maps · React Native · Fabric
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/@exterio/react-native-yamap-lite)
|
|
12
|
+
[](#требования)
|
|
13
|
+
[](#требования)
|
|
14
|
+
[](#тесты)
|
|
15
|
+
[](./LICENSE)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
Lite-обёртка над [Yandex MapKit SDK](https://yandex.ru/dev/maps/mapkit/) — карты, маркеры,
|
|
22
|
+
круги, полигоны, полилинии и кластеризация без лишнего веса: в ней нет маршрутов,
|
|
23
|
+
геокодера и поиска, только то, что нужно для отображения карты в приложении.
|
|
24
|
+
|
|
25
|
+
Библиотека собрана целиком на **новой архитектуре React Native** (**Fabric** +
|
|
26
|
+
**TurboModules**), что даёт нативную скорость рендеринга на iOS и Android.
|
|
27
|
+
|
|
28
|
+
## ✨ Возможности
|
|
29
|
+
|
|
30
|
+
- 🗺️ **Карты Yandex** — типы `map` / `satellite` / `hybrid`, ночной режим, кастомные стили MapKit.
|
|
31
|
+
- 📍 **Маркеры** — локальные (`require`) и удалённые (`{ uri }`) изображения, якорь, масштаб, z-index.
|
|
32
|
+
- ⭕ **Круги, полигоны, полилинии** — оверлеи с настраиваемыми цветами заливки и обводки.
|
|
33
|
+
- 🔗 **Кластеризация** — компонент `ClusteredYamap` для автоматической группировки маркеров.
|
|
34
|
+
- 📱 **Позиция пользователя** — отслеживание геолокации, кастомная иконка и зона точности.
|
|
35
|
+
- 🎯 **Управление камерой** — `setCenter`, `setZoom`, `fitAllMarkers`, чтение позиции и видимой области через `ref`.
|
|
36
|
+
- 🎨 **Жесты и UI** — гибкая настройка жестов, частоты кадров и позиции логотипа Яндекса.
|
|
37
|
+
|
|
38
|
+
> 💡 Знакомы с [`react-native-yamap`](https://github.com/volga-volga/react-native-yamap)?
|
|
39
|
+
> API близок по духу — миграция требует минимальных изменений.
|
|
40
|
+
|
|
41
|
+
## Требования
|
|
42
|
+
|
|
43
|
+
Библиотека использует **Fabric (новую архитектуру React Native)** и требует:
|
|
44
|
+
|
|
45
|
+
- **React Native >= 0.70.0** с включенной новой архитектурой
|
|
46
|
+
|
|
47
|
+
## Установка
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
yarn add @exterio/react-native-yamap-lite
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
или
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm install @exterio/react-native-yamap-lite --save
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### iOS
|
|
60
|
+
|
|
61
|
+
После установки выполните:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
cd ios && pod install && cd ..
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Инициализация карт
|
|
68
|
+
|
|
69
|
+
Инициализация выполняется **полностью из JavaScript** — не нужно править
|
|
70
|
+
`AppDelegate.swift` или `MainApplication`. Достаточно один раз вызвать
|
|
71
|
+
`YamapUtils.init(apiKey)` до того, как карта отрендерится (например, в `index.js`
|
|
72
|
+
или в корне `App.tsx`). Этот вызов сам устанавливает API-ключ и запускает MapKit
|
|
73
|
+
на обеих платформах.
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
// index.js
|
|
77
|
+
import { AppRegistry } from 'react-native';
|
|
78
|
+
import { YamapUtils } from '@exterio/react-native-yamap-lite';
|
|
79
|
+
import App from './App';
|
|
80
|
+
import { name as appName } from './app.json';
|
|
81
|
+
|
|
82
|
+
// Замените на ваш API-ключ от Yandex MapKit
|
|
83
|
+
YamapUtils.init('YOUR_API_KEY').catch((error) => {
|
|
84
|
+
console.warn('YamapUtils.init failed:', error);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// (необязательно) язык интерфейса карты
|
|
88
|
+
YamapUtils.setLocale('ru_RU');
|
|
89
|
+
|
|
90
|
+
AppRegistry.registerComponent(appName, () => App);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
> 💡 `init` возвращает `Promise` — карту можно рендерить сразу, она дождётся
|
|
94
|
+
> завершения инициализации. Метод идемпотентен: повторные вызовы безопасны.
|
|
95
|
+
|
|
96
|
+
> ℹ️ Android-зависимость MapKit (`com.yandex.android:maps.mobile`) уже входит в
|
|
97
|
+
> библиотеку — добавлять её в `android/app/build.gradle` вручную не нужно.
|
|
98
|
+
|
|
99
|
+
## Миграция с react-native-yamap
|
|
100
|
+
|
|
101
|
+
Это **не форк** [`react-native-yamap`](https://github.com/volga-volga/react-native-yamap) (volga-volga) — нативная часть написана с нуля на Swift и Kotlin под Fabric. Но публичный JS-API я старался держать максимально совместимым, чтобы переезд был как можно ближе к «поменять импорт». Для большинства проектов, использующих карту, маркеры и оверлеи, миграция сводится к нескольким правкам.
|
|
102
|
+
|
|
103
|
+
### Что совместимо
|
|
104
|
+
|
|
105
|
+
Компоненты и их основные пропсы совпадают по именам и форме данных:
|
|
106
|
+
|
|
107
|
+
| Сущность | react-native-yamap | react-native-yamap-lite |
|
|
108
|
+
|--|--|--|
|
|
109
|
+
| Карта | `YaMap` (default + named) | ✅ так же |
|
|
110
|
+
| Примитивы | `Marker`, `Circle`, `Polygon`, `Polyline` | ✅ так же |
|
|
111
|
+
| Кластеры | `ClusteredYamap` | ✅ так же |
|
|
112
|
+
| Координата | `{ lat, lon }` (`Point`) | ✅ так же |
|
|
113
|
+
| Управление камерой | `setCenter`, `setZoom`, `fitAllMarkers` (через `ref`) | ✅ так же |
|
|
114
|
+
|
|
115
|
+
```diff
|
|
116
|
+
- import YaMap, { Marker, Circle } from 'react-native-yamap';
|
|
117
|
+
+ import YaMap, { Marker, Circle } from '@exterio/react-native-yamap-lite';
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Что изменилось
|
|
121
|
+
|
|
122
|
+
- **Инициализация.** Вместо статического `YaMap.init(apiKey)` / `YaMap.setLocale(...)` используйте модуль `YamapUtils`:
|
|
123
|
+
|
|
124
|
+
```diff
|
|
125
|
+
- import YaMap from 'react-native-yamap';
|
|
126
|
+
- YaMap.init('YOUR_API_KEY');
|
|
127
|
+
- YaMap.setLocale('ru_RU');
|
|
128
|
+
+ import { YamapUtils } from '@exterio/react-native-yamap-lite';
|
|
129
|
+
+ await YamapUtils.init('YOUR_API_KEY');
|
|
130
|
+
+ YamapUtils.setLocale('ru_RU');
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **`getCameraPosition` возвращает `Promise`**, а не принимает колбэк:
|
|
134
|
+
|
|
135
|
+
```diff
|
|
136
|
+
- mapRef.current.getCameraPosition((pos) => console.log(pos));
|
|
137
|
+
+ const pos = await mapRef.current.getCameraPosition();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Аналогично промисы возвращают `getVisibleRegion`, `getScreenPoints`, `getWorldPoints`. Для совместимости со старым событийным стилем оставлены колбэк-пропсы `onCameraPositionReceived`, `onVisibleRegionReceived`, `onWorldToScreenPointsReceived`, `onScreenToWorldPointsReceived`.
|
|
141
|
+
|
|
142
|
+
- **Только новая архитектура.** Библиотека работает исключительно на Fabric + TurboModules. Если проект ещё на старой архитектуре — нужно сначала включить New Architecture.
|
|
143
|
+
|
|
144
|
+
### Чего нет (ограничения lite SDK)
|
|
145
|
+
|
|
146
|
+
Библиотека построена на **MapKit Lite**, поэтому всё, что связано с сетевыми сервисами Яндекса, в неё не входит:
|
|
147
|
+
|
|
148
|
+
- ❌ **Маршруты** (`findRoutes` / `findMasstransitRoutes` / `findDrivingRoutes` и компоненты маршрутов)
|
|
149
|
+
- ❌ **Геокодер, поиск и подсказки** (`Suggest`, поиск по адресу)
|
|
150
|
+
- ❌ **Слой пробок** — `setTrafficVisible(visible)` оставлен как no-op для совместимости
|
|
151
|
+
- ⚠️ **`fitMarkers(markers)`** — это алиас для `fitAllMarkers()`: lite SDK не умеет нацеливаться на конкретные маркеры
|
|
152
|
+
- ⚠️ **`marker.animatedMoveTo()` / `animatedRotateTo()`** не поддерживаются — обновляйте проп `point` маркера вместо императивной анимации
|
|
153
|
+
|
|
154
|
+
Если проект использует маршрутизацию, геокодер или поиск — этот пакет их не заменит, тут нужен полноценный `react-native-yamap`.
|
|
155
|
+
|
|
156
|
+
## Использование
|
|
157
|
+
|
|
158
|
+
### Базовый пример
|
|
159
|
+
|
|
160
|
+
```jsx
|
|
161
|
+
import React from 'react';
|
|
162
|
+
import { YaMap, Marker, Circle } from '@exterio/react-native-yamap-lite';
|
|
163
|
+
|
|
164
|
+
const Map = () => {
|
|
165
|
+
return (
|
|
166
|
+
<YaMap
|
|
167
|
+
initialRegion={{
|
|
168
|
+
lat: 55.751244,
|
|
169
|
+
lon: 37.618423,
|
|
170
|
+
zoom: 10
|
|
171
|
+
}}
|
|
172
|
+
style={{ flex: 1 }}
|
|
173
|
+
>
|
|
174
|
+
<Marker
|
|
175
|
+
point={{ lat: 55.751244, lon: 37.618423 }}
|
|
176
|
+
source={require('./marker.png')}
|
|
177
|
+
/>
|
|
178
|
+
<Circle
|
|
179
|
+
center={{ lat: 55.751244, lon: 37.618423 }}
|
|
180
|
+
radius={1000}
|
|
181
|
+
fillColor="#0000ff"
|
|
182
|
+
strokeColor="#ff0000"
|
|
183
|
+
strokeWidth={2}
|
|
184
|
+
/>
|
|
185
|
+
</YaMap>
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Типы
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface Point {
|
|
194
|
+
lat: number;
|
|
195
|
+
lon: number;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
interface InitialRegion {
|
|
199
|
+
lat: number;
|
|
200
|
+
lon: number;
|
|
201
|
+
zoom?: number;
|
|
202
|
+
azimuth?: number;
|
|
203
|
+
tilt?: number;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface CameraPosition {
|
|
207
|
+
nativeEvent: {
|
|
208
|
+
zoom: number;
|
|
209
|
+
tilt: number;
|
|
210
|
+
azimuth: number;
|
|
211
|
+
point: { lat: number; lon: number };
|
|
212
|
+
finished: boolean;
|
|
213
|
+
target: number;
|
|
214
|
+
reason: 'GESTURES' | 'APPLICATION';
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
interface MapLoaded {
|
|
219
|
+
nativeEvent: {
|
|
220
|
+
renderObjectCount: number;
|
|
221
|
+
curZoomModelsLoaded: number;
|
|
222
|
+
curZoomPlacemarksLoaded: number;
|
|
223
|
+
curZoomLabelsLoaded: number;
|
|
224
|
+
curZoomGeometryLoaded: number;
|
|
225
|
+
tileMemoryUsage: number;
|
|
226
|
+
delayedGeometryLoaded: number;
|
|
227
|
+
fullyAppeared: number;
|
|
228
|
+
fullyLoaded: number;
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
type YandexLogoPosition = {
|
|
233
|
+
horizontal?: 'left' | 'center' | 'right';
|
|
234
|
+
vertical?: 'top' | 'bottom';
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
type YandexLogoPadding = {
|
|
238
|
+
horizontal?: number;
|
|
239
|
+
vertical?: number;
|
|
240
|
+
};
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Компонент YaMap
|
|
244
|
+
|
|
245
|
+
### Props
|
|
246
|
+
|
|
247
|
+
| Название | Тип | По умолчанию | Описание |
|
|
248
|
+
|--|--|--|--|
|
|
249
|
+
| `initialRegion` | `InitialRegion` | - | Изначальное местоположение карты при загрузке |
|
|
250
|
+
| `showUserPosition` | `boolean` | `false` | Отслеживание геоданных и отображение позиции пользователя |
|
|
251
|
+
| `followUser` | `boolean` | `false` | Слежение камеры за пользователем |
|
|
252
|
+
| `userLocationIcon` | `ImageSource` | - | Иконка для позиции пользователя |
|
|
253
|
+
| `userLocationIconScale` | `number` | `1` | Масштабирование иконки пользователя |
|
|
254
|
+
| `userLocationAccuracyFillColor` | `string` | `#00FF00` | Цвет фона зоны точности определения позиции пользователя |
|
|
255
|
+
| `userLocationAccuracyStrokeColor` | `string` | `#000000` | Цвет границы зоны точности определения позиции пользователя |
|
|
256
|
+
| `userLocationAccuracyStrokeWidth` | `number` | `2` | Толщина зоны точности определения позиции пользователя |
|
|
257
|
+
| `nightMode` | `boolean` | `false` | Использование ночного режима |
|
|
258
|
+
| `mapStyle` | `string` | - | Стили карты согласно [документации](https://yandex.ru/dev/maps/mapkit/doc/dg/concepts/style.html) |
|
|
259
|
+
| `mapType` | `'map' \| 'satellite' \| 'hybrid'` | `'map'` | Тип карты |
|
|
260
|
+
| `scrollGesturesEnabled` | `boolean` | `true` | Включены ли жесты скролла |
|
|
261
|
+
| `zoomGesturesEnabled` | `boolean` | `true` | Включены ли жесты зума |
|
|
262
|
+
| `tiltGesturesEnabled` | `boolean` | `true` | Включены ли жесты наклона камеры двумя пальцами |
|
|
263
|
+
| `rotateGesturesEnabled` | `boolean` | `true` | Включены ли жесты поворота камеры |
|
|
264
|
+
| `fastTapEnabled` | `boolean` | `true` | Убрана ли задержка в 300мс при клике/тапе |
|
|
265
|
+
| `maxFps` | `number` | `60` | Максимальная частота обновления карты |
|
|
266
|
+
| `logoPosition` | `YandexLogoPosition` | - | Позиция логотипа Яндекса на карте |
|
|
267
|
+
| `logoPadding` | `YandexLogoPadding` | - | Отступ логотипа Яндекса на карте |
|
|
268
|
+
| `onMapLoaded` | `(event: MapLoaded) => void` | - | Колбек на загрузку карты |
|
|
269
|
+
| `onCameraPositionChange` | `(event: CameraPosition) => void` | - | Колбек на изменение положения камеры |
|
|
270
|
+
| `onCameraPositionChangeEnd` | `(event: CameraPosition) => void` | - | Колбек при завершении изменения положения камеры |
|
|
271
|
+
| `onMapPress` | `(event: Point) => void` | - | Событие нажатия на карту |
|
|
272
|
+
| `onMapLongPress` | `(event: Point) => void` | - | Событие долгого нажатия на карту |
|
|
273
|
+
|
|
274
|
+
### Методы (через ref)
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
interface YaMapRef {
|
|
278
|
+
getCameraPosition: () => Promise<{
|
|
279
|
+
lat: number;
|
|
280
|
+
lon: number;
|
|
281
|
+
zoom: number;
|
|
282
|
+
azimuth: number;
|
|
283
|
+
tilt: number;
|
|
284
|
+
}>;
|
|
285
|
+
setZoom: (
|
|
286
|
+
zoom: number,
|
|
287
|
+
duration?: number,
|
|
288
|
+
animation?: 'LINEAR' | 'SMOOTH'
|
|
289
|
+
) => void;
|
|
290
|
+
setCenter: (
|
|
291
|
+
center: { lat: number; lon: number },
|
|
292
|
+
zoom?: number,
|
|
293
|
+
azimuth?: number,
|
|
294
|
+
tilt?: number,
|
|
295
|
+
duration?: number,
|
|
296
|
+
animation?: 'LINEAR' | 'SMOOTH'
|
|
297
|
+
) => void;
|
|
298
|
+
fitAllMarkers: () => void;
|
|
299
|
+
getMapObjectCount: () => Promise<number>;
|
|
300
|
+
getVisibleRegion: () => Promise<VisibleRegion>;
|
|
301
|
+
getScreenPoints: (points: Point[]) => Promise<ScreenPoint[]>;
|
|
302
|
+
getWorldPoints: (points: ScreenPoint[]) => Promise<Point[]>;
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Пример использования:**
|
|
307
|
+
|
|
308
|
+
```jsx
|
|
309
|
+
import React, { useRef } from 'react';
|
|
310
|
+
import { YaMap } from '@exterio/react-native-yamap-lite';
|
|
311
|
+
|
|
312
|
+
const Map = () => {
|
|
313
|
+
const mapRef = useRef(null);
|
|
314
|
+
|
|
315
|
+
const handleSetCenter = () => {
|
|
316
|
+
mapRef.current?.setCenter(
|
|
317
|
+
{ lat: 55.751244, lon: 37.618423 },
|
|
318
|
+
15,
|
|
319
|
+
0,
|
|
320
|
+
0,
|
|
321
|
+
1000,
|
|
322
|
+
'SMOOTH'
|
|
323
|
+
);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const handleGetCameraPosition = async () => {
|
|
327
|
+
const position = await mapRef.current?.getCameraPosition();
|
|
328
|
+
console.log(position);
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
return (
|
|
332
|
+
<YaMap
|
|
333
|
+
ref={mapRef}
|
|
334
|
+
initialRegion={{
|
|
335
|
+
lat: 55.751244,
|
|
336
|
+
lon: 37.618423,
|
|
337
|
+
zoom: 10
|
|
338
|
+
}}
|
|
339
|
+
style={{ flex: 1 }}
|
|
340
|
+
/>
|
|
341
|
+
);
|
|
342
|
+
};
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Примитивы
|
|
346
|
+
|
|
347
|
+
### Marker
|
|
348
|
+
|
|
349
|
+
```jsx
|
|
350
|
+
<YaMap>
|
|
351
|
+
<Marker
|
|
352
|
+
point={{ lat: 55.751244, lon: 37.618423 }}
|
|
353
|
+
source={require('./marker.png')}
|
|
354
|
+
scale={1.5}
|
|
355
|
+
anchor={{ x: 0.5, y: 0.5 }}
|
|
356
|
+
zInd={100}
|
|
357
|
+
visible={true}
|
|
358
|
+
onPress={(point) => console.log('Marker pressed', point)}
|
|
359
|
+
/>
|
|
360
|
+
</YaMap>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### Props для Marker
|
|
364
|
+
|
|
365
|
+
| Название | Тип | Описание |
|
|
366
|
+
|--|--|--|
|
|
367
|
+
| `point` | `Point` | Координаты точки для отображения маркера |
|
|
368
|
+
| `source` | `ImageSource` | Данные для изображения маркера |
|
|
369
|
+
| `scale` | `number` | Масштабирование иконки маркера |
|
|
370
|
+
| `anchor` | `{ x: number, y: number }` | Якорь иконки маркера. Координаты принимают значения от 0 до 1 |
|
|
371
|
+
| `zInd` | `number` | Отображение элемента по оси Z |
|
|
372
|
+
| `visible` | `boolean` | Отображение маркера на карте |
|
|
373
|
+
| `rotated` | `boolean` | Вращение маркера при движении |
|
|
374
|
+
| `size` | `number` | Размер маркера в пикселях |
|
|
375
|
+
| `handled` | `boolean` | Включение(**false**)/отключение(**true**) всплытия события нажатия для родителя `default: true` |
|
|
376
|
+
| `onPress` | `(event: Point) => void` | Действие при нажатии/клике |
|
|
377
|
+
|
|
378
|
+
### Circle
|
|
379
|
+
|
|
380
|
+
```jsx
|
|
381
|
+
<YaMap>
|
|
382
|
+
<Circle
|
|
383
|
+
center={{ lat: 55.751244, lon: 37.618423 }}
|
|
384
|
+
radius={1000}
|
|
385
|
+
fillColor="#0000ff"
|
|
386
|
+
strokeColor="#ff0000"
|
|
387
|
+
strokeWidth={2}
|
|
388
|
+
zInd={100}
|
|
389
|
+
onPress={(point) => console.log('Circle pressed', point)}
|
|
390
|
+
/>
|
|
391
|
+
</YaMap>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
#### Props для Circle
|
|
395
|
+
|
|
396
|
+
| Название | Тип | Описание |
|
|
397
|
+
|--|--|--|
|
|
398
|
+
| `center` | `Point` | Координаты центра круга |
|
|
399
|
+
| `radius` | `number` | Радиус круга в метрах |
|
|
400
|
+
| `fillColor` | `string` | Цвет заливки |
|
|
401
|
+
| `strokeColor` | `string` | Цвет границы |
|
|
402
|
+
| `strokeWidth` | `number` | Толщина границы |
|
|
403
|
+
| `zInd` | `number` | Отображение элемента по оси Z |
|
|
404
|
+
| `handled` | `boolean` | Включение(**false**)/отключение(**true**) всплытия события нажатия для родителя `default: true` |
|
|
405
|
+
| `onPress` | `(event: Point) => void` | Действие при нажатии/клике |
|
|
406
|
+
|
|
407
|
+
## ClusteredYamap
|
|
408
|
+
|
|
409
|
+
Компонент для отображения кластеризованных маркеров:
|
|
410
|
+
|
|
411
|
+
```jsx
|
|
412
|
+
import { ClusteredYamap, Marker } from '@exterio/react-native-yamap-lite';
|
|
413
|
+
|
|
414
|
+
<ClusteredYamap
|
|
415
|
+
clusterColor="#ff00ff"
|
|
416
|
+
clusteredMarkers={[
|
|
417
|
+
{ point: { lat: 55.751244, lon: 37.618423 }, data: {} },
|
|
418
|
+
{ point: { lat: 55.752244, lon: 37.619423 }, data: {} },
|
|
419
|
+
]}
|
|
420
|
+
renderMarker={({ point, data }) => (
|
|
421
|
+
<Marker
|
|
422
|
+
point={point}
|
|
423
|
+
source={{ uri: data.source }}
|
|
424
|
+
size={data.size}
|
|
425
|
+
/>
|
|
426
|
+
)}
|
|
427
|
+
style={{ flex: 1 }}
|
|
428
|
+
/>
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### Props для ClusteredYamap
|
|
432
|
+
|
|
433
|
+
Все props из `YaMap` плюс:
|
|
434
|
+
|
|
435
|
+
| Название | Тип | По умолчанию | Описание |
|
|
436
|
+
|--|--|--|--|
|
|
437
|
+
| `clusteredMarkers` | `Array<{ point: Point, data: any }>` | `[]` | Массив маркеров для кластеризации |
|
|
438
|
+
| `renderMarker` | `(info: { point: Point, data: any }, index: number) => ReactElement` | - | Функция для рендеринга каждого маркера |
|
|
439
|
+
| `clusterColor` | `string` | `#FF0000` | Цвет фона метки-кластера |
|
|
440
|
+
|
|
441
|
+
## Запуск Example приложения
|
|
442
|
+
|
|
443
|
+
Перед запуском example приложения необходимо собрать нативный код для вашей платформы:
|
|
444
|
+
|
|
445
|
+
**Для iOS:**
|
|
446
|
+
```sh
|
|
447
|
+
cd example
|
|
448
|
+
cd ios && pod install && cd ..
|
|
449
|
+
yarn ios
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Для Android:**
|
|
453
|
+
```sh
|
|
454
|
+
cd example
|
|
455
|
+
yarn build:android
|
|
456
|
+
yarn android
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
После сборки можно запускать приложение как обычно используя `yarn ios` или `yarn android`.
|
|
460
|
+
|
|
461
|
+
**Примечание:** Все методы и примеры использования карты можно запустить и посмотреть в папке `example` проекта.
|
|
462
|
+
|
|
463
|
+
## Тесты
|
|
464
|
+
|
|
465
|
+
Библиотека покрыта тестами на двух уровнях:
|
|
466
|
+
|
|
467
|
+
- **Jest** — модульные тесты JS-слоя (компоненты, парсинг пропсов, преобразование
|
|
468
|
+
координат, мосты к нативным модулям). Запускаются без устройства/эмулятора:
|
|
469
|
+
|
|
470
|
+
```sh
|
|
471
|
+
yarn test
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
- **Harness** — интеграционные тесты, которые гоняют реальные нативные Fabric-компоненты
|
|
475
|
+
на **iOS и Android** через [`react-native-harness`](https://github.com/callstack/react-native-harness).
|
|
476
|
+
Покрыты `YaMap`, `Marker`, `Circle`, `Polygon`, `Polyline`, `ClusteredYamap`,
|
|
477
|
+
события карты, методы `YamapUtils` и набор регрессионных сценариев
|
|
478
|
+
(см. `example/harness/tests`):
|
|
479
|
+
|
|
480
|
+
```sh
|
|
481
|
+
# обе платформы
|
|
482
|
+
yarn test:harness
|
|
483
|
+
|
|
484
|
+
# по отдельности
|
|
485
|
+
yarn test:harness:ios
|
|
486
|
+
yarn test:harness:android
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Так нативный код проверяется на настоящих картах, а не на моках, — это покрывает баги,
|
|
490
|
+
которые JS-тесты увидеть не могут.
|
|
491
|
+
|
|
492
|
+
## Важные замечания
|
|
493
|
+
|
|
494
|
+
1. Компонент карт стилизуется, как и `View` из React Native. Если карта не отображается, после инициализации с валидным ключом API, вероятно необходимо прописать стиль, который опишет размеры компонента (`height + width` или `flex`).
|
|
495
|
+
|
|
496
|
+
2. Для маркеров и иконки локации пользователя можно использовать как локальные изображения (через `require('./img.png')`), так и удаленные (через `{ uri: 'https://...' }`).
|
|
497
|
+
|
|
498
|
+
3. Для отображения позиции пользователя на Android нужно запросить разрешение `android.permission.ACCESS_FINE_LOCATION`. На iOS нужно добавить `NSLocationWhenInUseUsageDescription` в `Info.plist`.
|
|
499
|
+
|
|
500
|
+
## Contributing
|
|
501
|
+
|
|
502
|
+
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
503
|
+
|
|
504
|
+
## License
|
|
505
|
+
|
|
506
|
+
MIT
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "YamapLite"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/hydromoll/react-native-yamap-lite.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
|
+
s.dependency 'YandexMapsMobile', '4.16.0-lite'
|
|
19
|
+
|
|
20
|
+
install_modules_dependencies(s)
|
|
21
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.getExtOrDefault = { name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['YamapLite_' + name]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
ext {
|
|
7
|
+
minSdkVersion = 26
|
|
8
|
+
compileSdkVersion = 34
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
repositories {
|
|
12
|
+
google()
|
|
13
|
+
mavenCentral()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
dependencies {
|
|
17
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
18
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def isNewArchitectureEnabled() {
|
|
23
|
+
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
apply plugin: "com.android.library"
|
|
27
|
+
apply plugin: "org.jetbrains.kotlin.android"
|
|
28
|
+
|
|
29
|
+
if (isNewArchitectureEnabled()) {
|
|
30
|
+
apply plugin: "com.facebook.react"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
def getExtOrIntegerDefault(name) {
|
|
34
|
+
return rootProject.ext.has(name)
|
|
35
|
+
? rootProject.ext.get(name)
|
|
36
|
+
: (project.properties["YamapLite_" + name]).toInteger()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
android {
|
|
40
|
+
namespace = "com.yamaplite"
|
|
41
|
+
compileSdk = getExtOrIntegerDefault("compileSdkVersion")
|
|
42
|
+
|
|
43
|
+
defaultConfig {
|
|
44
|
+
minSdk = getExtOrIntegerDefault("minSdkVersion")
|
|
45
|
+
targetSdk = getExtOrIntegerDefault("targetSdkVersion")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
buildFeatures {
|
|
49
|
+
buildConfig = true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
buildTypes {
|
|
53
|
+
release {
|
|
54
|
+
minifyEnabled = false
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
lint {
|
|
59
|
+
disable 'GradleCompatible'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
compileOptions {
|
|
63
|
+
sourceCompatibility = JavaVersion.VERSION_17
|
|
64
|
+
targetCompatibility = JavaVersion.VERSION_17
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
kotlinOptions {
|
|
68
|
+
jvmTarget = "17"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
sourceSets {
|
|
72
|
+
main {
|
|
73
|
+
java.srcDirs += [
|
|
74
|
+
"build/generated/source/codegen/java",
|
|
75
|
+
"generated/java",
|
|
76
|
+
"generated/jni"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
repositories {
|
|
83
|
+
google()
|
|
84
|
+
mavenCentral()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
88
|
+
|
|
89
|
+
dependencies {
|
|
90
|
+
implementation "com.facebook.react:react-android:0.79.2"
|
|
91
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
92
|
+
implementation 'com.yandex.android:maps.mobile:4.24.0-lite'
|
|
93
|
+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
afterEvaluate {
|
|
97
|
+
def react = rootProject.ext.has("react") ? rootProject.ext.get("react") : null
|
|
98
|
+
if (react != null && react.hasProperty("registerReactNativeModule")) {
|
|
99
|
+
react.registerReactNativeModule(project)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
YamapLite_kotlinVersion=2.0.21
|
|
2
|
+
YamapLite_minSdkVersion=24
|
|
3
|
+
YamapLite_targetSdkVersion=34
|
|
4
|
+
YamapLite_compileSdkVersion=35
|
|
5
|
+
YamapLite_ndkVersion=27.1.12297006
|
|
6
|
+
|
|
7
|
+
# AndroidX
|
|
8
|
+
android.useAndroidX=true
|
|
9
|
+
android.enableJetifier=true
|
|
10
|
+
|
|
11
|
+
# JVM settings
|
|
12
|
+
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
|
13
|
+
org.gradle.parallel=true
|
|
14
|
+
org.gradle.caching=true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rootProject.name = 'react-native-yamap-lite'
|