react-native-mapsforge-vtm-ext-grib 0.2.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.
- package/LICENSE +21 -0
- package/README.md +118 -0
- package/android/CMakeLists.txt +13 -0
- package/android/build.gradle +108 -0
- package/android/generated/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/NativeWeatherOverlaySpec.java +95 -0
- package/android/generated/jni/CMakeLists.txt +28 -0
- package/android/generated/jni/RNMapsforgeVtmExtGribSpec-generated.cpp +62 -0
- package/android/generated/jni/RNMapsforgeVtmExtGribSpec.h +31 -0
- package/android/generated/jni/react/renderer/components/RNMapsforgeVtmExtGribSpec/RNMapsforgeVtmExtGribSpecJSI.h +521 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/ExtGribPackage.java +62 -0
- package/android/src/main/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/modules/WeatherOverlay.java +343 -0
- package/android/src/main/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/tiles/ColorRamp.java +165 -0
- package/android/src/main/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/tiles/WeatherGridData.java +103 -0
- package/android/src/main/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/tiles/WeatherTileDataSource.java +147 -0
- package/android/src/main/java/com/jhotadhari/reactnative/mapsforge/vtm/ext/grib/tiles/WeatherTileSource.java +80 -0
- package/lib/commonjs/NativeModules/NativeWeatherOverlay.js +9 -0
- package/lib/commonjs/NativeModules/NativeWeatherOverlay.js.map +1 -0
- package/lib/commonjs/components/WeatherOverlay.js +180 -0
- package/lib/commonjs/components/WeatherOverlay.js.map +1 -0
- package/lib/commonjs/index.js +21 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/reanimated/index.js +13 -0
- package/lib/commonjs/reanimated/index.js.map +1 -0
- package/lib/commonjs/reanimated/useWeatherAnimation.js +86 -0
- package/lib/commonjs/reanimated/useWeatherAnimation.js.map +1 -0
- package/lib/commonjs/reportNativeError.js +14 -0
- package/lib/commonjs/reportNativeError.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/NativeModules/NativeWeatherOverlay.js +5 -0
- package/lib/module/NativeModules/NativeWeatherOverlay.js.map +1 -0
- package/lib/module/components/WeatherOverlay.js +174 -0
- package/lib/module/components/WeatherOverlay.js.map +1 -0
- package/lib/module/index.js +16 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/reanimated/index.js +4 -0
- package/lib/module/reanimated/index.js.map +1 -0
- package/lib/module/reanimated/useWeatherAnimation.js +81 -0
- package/lib/module/reanimated/useWeatherAnimation.js.map +1 -0
- package/lib/module/reportNativeError.js +10 -0
- package/lib/module/reportNativeError.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/NativeModules/NativeWeatherOverlay.d.ts +63 -0
- package/lib/typescript/commonjs/src/NativeModules/NativeWeatherOverlay.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/components/WeatherOverlay.d.ts +10 -0
- package/lib/typescript/commonjs/src/components/WeatherOverlay.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +11 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/reanimated/index.d.ts +3 -0
- package/lib/typescript/commonjs/src/reanimated/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/reanimated/useWeatherAnimation.d.ts +44 -0
- package/lib/typescript/commonjs/src/reanimated/useWeatherAnimation.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/reportNativeError.d.ts +3 -0
- package/lib/typescript/commonjs/src/reportNativeError.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/types.d.ts +51 -0
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/NativeModules/NativeWeatherOverlay.d.ts +63 -0
- package/lib/typescript/module/src/NativeModules/NativeWeatherOverlay.d.ts.map +1 -0
- package/lib/typescript/module/src/components/WeatherOverlay.d.ts +10 -0
- package/lib/typescript/module/src/components/WeatherOverlay.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +11 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/reanimated/index.d.ts +3 -0
- package/lib/typescript/module/src/reanimated/index.d.ts.map +1 -0
- package/lib/typescript/module/src/reanimated/useWeatherAnimation.d.ts +44 -0
- package/lib/typescript/module/src/reanimated/useWeatherAnimation.d.ts.map +1 -0
- package/lib/typescript/module/src/reportNativeError.d.ts +3 -0
- package/lib/typescript/module/src/reportNativeError.d.ts.map +1 -0
- package/lib/typescript/module/src/types.d.ts +51 -0
- package/lib/typescript/module/src/types.d.ts.map +1 -0
- package/package.json +159 -0
- package/react-native.config.js +13 -0
- package/src/NativeModules/NativeWeatherOverlay.ts +73 -0
- package/src/components/WeatherOverlay.tsx +173 -0
- package/src/index.ts +22 -0
- package/src/reanimated/index.ts +2 -0
- package/src/reanimated/useWeatherAnimation.ts +118 -0
- package/src/reportNativeError.ts +15 -0
- package/src/types.ts +56 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-native-mapsforge-vtm-ext-grib
|
|
3
|
+
*
|
|
4
|
+
* Weather GRIB overlay extension for react-native-mapsforge-vtm.
|
|
5
|
+
*/
|
|
6
|
+
export { default as WeatherOverlay } from './components/WeatherOverlay.js';
|
|
7
|
+
export type { WeatherOverlayProps } from './NativeModules/NativeWeatherOverlay.js';
|
|
8
|
+
export type { WeatherGrid, WeatherMetadata, ColorMapName, ResponseBase, ErrorBase, } from './types.js';
|
|
9
|
+
export { useWeatherAnimation } from './reanimated/useWeatherAnimation.js';
|
|
10
|
+
export type { WeatherAnimationControls } from './reanimated/useWeatherAnimation.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gCAA6B,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yCAAsC,CAAC;AAGhF,YAAY,EACX,WAAW,EACX,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,SAAS,GACT,MAAM,YAAS,CAAC;AAGjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAkC,CAAC;AACvE,YAAY,EAAE,wBAAwB,EAAE,MAAM,qCAAkC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/reanimated/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAAuB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type SharedValue } from 'react-native-reanimated';
|
|
2
|
+
export interface WeatherAnimationControls {
|
|
3
|
+
/** The current animation progress (0.0 to timeSteps.length - 1). */
|
|
4
|
+
progressSv: SharedValue<number>;
|
|
5
|
+
/** Start playing the animation. */
|
|
6
|
+
play: () => void;
|
|
7
|
+
/** Pause the animation. */
|
|
8
|
+
pause: () => void;
|
|
9
|
+
/** Reset to the first time step. */
|
|
10
|
+
reset: () => void;
|
|
11
|
+
/** Seek to a specific time step index (fractional for interpolation). */
|
|
12
|
+
seek: (timeIndex: number) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a reanimated shared value that drives smooth time-step animation
|
|
16
|
+
* for a weather overlay.
|
|
17
|
+
*
|
|
18
|
+
* The progress value ranges from 0.0 to (numTimeSteps - 1), where the
|
|
19
|
+
* fractional part represents the interpolation between adjacent time steps.
|
|
20
|
+
*
|
|
21
|
+
* Usage with WeatherOverlay:
|
|
22
|
+
* - Pass `Math.floor(progress.value)` as `timeIndex` to the "current" layer
|
|
23
|
+
* - Pass `Math.ceil(progress.value)` as `timeIndex` to the "next" layer
|
|
24
|
+
* - Set the "next" layer's opacity to `progress.value - Math.floor(progress.value)`
|
|
25
|
+
*
|
|
26
|
+
* @param numTimeSteps - Total number of forecast time steps available.
|
|
27
|
+
* @param durationMs - Duration of the full animation in milliseconds.
|
|
28
|
+
* @returns Animation controls including the progress shared value.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* const { progressSv, play, pause } = useWeatherAnimation(
|
|
33
|
+
* weatherData.timeSteps.length,
|
|
34
|
+
* 10000
|
|
35
|
+
* );
|
|
36
|
+
*
|
|
37
|
+
* // In a worklet or useDerivedValue:
|
|
38
|
+
* const currentIdx = Math.floor(progressSv.value);
|
|
39
|
+
* const nextAlpha = progressSv.value - currentIdx;
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function useWeatherAnimation(numTimeSteps: number, durationMs?: number): WeatherAnimationControls;
|
|
43
|
+
export default useWeatherAnimation;
|
|
44
|
+
//# sourceMappingURL=useWeatherAnimation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWeatherAnimation.d.ts","sourceRoot":"","sources":["../../../../../src/reanimated/useWeatherAnimation.ts"],"names":[],"mappings":"AACA,OAAO,EAGN,KAAK,WAAW,EAChB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,wBAAwB;IACxC,oEAAoE;IACpE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,mCAAmC;IACnC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,oCAAoC;IACpC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,yEAAyE;IACzE,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,mBAAmB,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,MAAc,GACxB,wBAAwB,CAgE1B;AAED,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reportNativeError.d.ts","sourceRoot":"","sources":["../../../../src/reportNativeError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAS,CAAC;AAEzC,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACxC,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC,GACzC,IAAI,CASN"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base types shared across the ext-grib library.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the pattern from react-native-mapsforge-vtm's types.ts.
|
|
5
|
+
*/
|
|
6
|
+
export interface ResponseBase {
|
|
7
|
+
uuid: string;
|
|
8
|
+
nativeNodeHandle: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ErrorBase {
|
|
11
|
+
userInfo?: {
|
|
12
|
+
errorMsg?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Represents one time step of gridded weather data.
|
|
17
|
+
* This is the format produced by server-side GRIB to JSON conversion
|
|
18
|
+
* (and later by on-device JGribX parsing).
|
|
19
|
+
*/
|
|
20
|
+
export interface WeatherGrid {
|
|
21
|
+
/** UTC ISO timestamp e.g. "2026-07-03T00:00:00Z" */
|
|
22
|
+
validTime: string;
|
|
23
|
+
/** Minimum latitude of the grid (southern edge) */
|
|
24
|
+
minLat: number;
|
|
25
|
+
/** Maximum latitude of the grid (northern edge) */
|
|
26
|
+
maxLat: number;
|
|
27
|
+
/** Minimum longitude of the grid (western edge) */
|
|
28
|
+
minLng: number;
|
|
29
|
+
/** Maximum longitude of the grid (eastern edge) */
|
|
30
|
+
maxLng: number;
|
|
31
|
+
/** Number of grid points in the longitude direction */
|
|
32
|
+
ni: number;
|
|
33
|
+
/** Number of grid points in the latitude direction */
|
|
34
|
+
nj: number;
|
|
35
|
+
/** Row-major grid values, length = ni * nj. Missing values are NaN. */
|
|
36
|
+
values: number[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Metadata for a weather data source (returned after loading).
|
|
40
|
+
*/
|
|
41
|
+
export interface WeatherMetadata {
|
|
42
|
+
parameter: string;
|
|
43
|
+
levelType?: string;
|
|
44
|
+
unit: string;
|
|
45
|
+
timeSteps: WeatherGrid[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Built-in color ramp identifiers.
|
|
49
|
+
*/
|
|
50
|
+
export type ColorMapName = 'temperature' | 'wind' | 'pressure' | 'rainfall' | 'waves' | 'grayscale';
|
|
51
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC3B,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,uEAAuE;IACvE,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GACvB,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-mapsforge-vtm-ext-grib",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Weather GRIB overlay extension for react-native-mapsforge-vtm. Renders gridded weather data (wind, temperature, pressure, etc.) as colored overlays on offline vector maps. Android only.",
|
|
5
|
+
"source": "./src/index.ts",
|
|
6
|
+
"main": "./lib/commonjs/index.js",
|
|
7
|
+
"module": "./lib/module/index.js",
|
|
8
|
+
"types": "./lib/typescript/commonjs/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./lib/typescript/module/src/index.d.ts",
|
|
13
|
+
"default": "./lib/module/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./lib/typescript/commonjs/src/index.d.ts",
|
|
17
|
+
"default": "./lib/commonjs/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json",
|
|
21
|
+
"./reanimated": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./lib/typescript/module/src/reanimated/index.d.ts",
|
|
24
|
+
"default": "./lib/module/reanimated/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./lib/typescript/commonjs/src/reanimated/index.d.ts",
|
|
28
|
+
"default": "./lib/commonjs/reanimated/index.js"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"src",
|
|
34
|
+
"lib",
|
|
35
|
+
"android",
|
|
36
|
+
"react-native.config.js",
|
|
37
|
+
"!ios/build",
|
|
38
|
+
"!android/build",
|
|
39
|
+
"!android/gradle",
|
|
40
|
+
"!android/gradlew",
|
|
41
|
+
"!android/gradlew.bat",
|
|
42
|
+
"!android/local.properties",
|
|
43
|
+
"!**/__tests__",
|
|
44
|
+
"!**/__fixtures__",
|
|
45
|
+
"!**/__mocks__",
|
|
46
|
+
"!**/.*"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"example": "yarn workspace react-native-mapsforge-vtm-ext-grib-example",
|
|
50
|
+
"test": "jest",
|
|
51
|
+
"typecheck": "tsc",
|
|
52
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
53
|
+
"format": "prettier . --write",
|
|
54
|
+
"clean": "del-cli android/build example/android/build example/android/app/build lib",
|
|
55
|
+
"prepare": "bob build",
|
|
56
|
+
"postinstall": "node -e \"['react','react-native','react-native-mapsforge-vtm'].forEach(m=>{const t='node_modules/'+m,s='example/'+t;require('fs').existsSync(s)&&!require('fs').lstatSync(t).isSymbolicLink()&&(require('fs').rmSync(t,{recursive:true,force:true}),require('fs').symlinkSync(require('path').relative(require('path').dirname(t),require('path').resolve(s)),t,'dir'))})\"",
|
|
57
|
+
"release": "release-kit"
|
|
58
|
+
},
|
|
59
|
+
"keywords": [
|
|
60
|
+
"react-native",
|
|
61
|
+
"android",
|
|
62
|
+
"maps",
|
|
63
|
+
"offline",
|
|
64
|
+
"weather",
|
|
65
|
+
"grib",
|
|
66
|
+
"mapsforge",
|
|
67
|
+
"vtm"
|
|
68
|
+
],
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git+https://github.com/jhotadhari/react-native-mapsforge-vtm-ext-grib.git"
|
|
72
|
+
},
|
|
73
|
+
"author": "jhotadhari <tellme@waterproof-webdesign.de> (https://github.com/jhotadhari)",
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"registry": "https://registry.npmjs.org/"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@eslint/compat": "^2.1.0",
|
|
80
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
81
|
+
"@eslint/js": "^9.22.0",
|
|
82
|
+
"@evilmartians/lefthook": "^2.1.9",
|
|
83
|
+
"@jhotadhari/release-kit": "^0.0.6",
|
|
84
|
+
"@react-native/eslint-config": "^0.86.0",
|
|
85
|
+
"@types/jest": "^29.5.5",
|
|
86
|
+
"@types/react": "^19.2.17",
|
|
87
|
+
"del-cli": "^7.0.0",
|
|
88
|
+
"eslint": "^9.22.0",
|
|
89
|
+
"eslint-config-prettier": "^10.1.8",
|
|
90
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
91
|
+
"jest": "^29.7.0",
|
|
92
|
+
"prettier": "^3.8.4",
|
|
93
|
+
"prettier-plugin-embed": "^0.5.1",
|
|
94
|
+
"prettier-plugin-multiline-arrays": "^4.1.9",
|
|
95
|
+
"react": "19.2.7",
|
|
96
|
+
"react-native": "0.86.0",
|
|
97
|
+
"react-native-builder-bob": "^0.43.0",
|
|
98
|
+
"react-native-reanimated": ">=3.0.0",
|
|
99
|
+
"react-native-worklets": ">=0.1.0",
|
|
100
|
+
"typescript": "^6.0.3"
|
|
101
|
+
},
|
|
102
|
+
"peerDependencies": {
|
|
103
|
+
"react": "*",
|
|
104
|
+
"react-native": ">=0.80.0",
|
|
105
|
+
"react-native-mapsforge-vtm": "^0.9.0",
|
|
106
|
+
"react-native-reanimated": ">=3.0.0",
|
|
107
|
+
"react-native-worklets": ">=0.1.0"
|
|
108
|
+
},
|
|
109
|
+
"peerDependenciesMeta": {
|
|
110
|
+
"react-native-reanimated": {
|
|
111
|
+
"optional": true
|
|
112
|
+
},
|
|
113
|
+
"react-native-worklets": {
|
|
114
|
+
"optional": true
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"workspaces": [
|
|
118
|
+
"example"
|
|
119
|
+
],
|
|
120
|
+
"packageManager": "yarn@3.6.1",
|
|
121
|
+
"react-native-builder-bob": {
|
|
122
|
+
"source": "src",
|
|
123
|
+
"output": "lib",
|
|
124
|
+
"targets": [
|
|
125
|
+
"codegen",
|
|
126
|
+
[
|
|
127
|
+
"module",
|
|
128
|
+
{
|
|
129
|
+
"esm": true
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
"commonjs",
|
|
134
|
+
{
|
|
135
|
+
"esm": true
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
"typescript",
|
|
140
|
+
{
|
|
141
|
+
"project": "tsconfig.build.json"
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"codegenConfig": {
|
|
147
|
+
"name": "RNMapsforgeVtmExtGribSpec",
|
|
148
|
+
"type": "modules",
|
|
149
|
+
"jsSrcsDir": "src",
|
|
150
|
+
"outputDir": {
|
|
151
|
+
"ios": "ios/generated",
|
|
152
|
+
"android": "android/generated"
|
|
153
|
+
},
|
|
154
|
+
"android": {
|
|
155
|
+
"javaPackageName": "com.jhotadhari.reactnative.mapsforge.vtm.ext.grib"
|
|
156
|
+
},
|
|
157
|
+
"includesGeneratedCode": true
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
dependency: {
|
|
3
|
+
platforms: {
|
|
4
|
+
android: {
|
|
5
|
+
sourceDir: './android',
|
|
6
|
+
cmakeListsPath: 'CMakeLists.txt',
|
|
7
|
+
packageImportPath:
|
|
8
|
+
'import com.jhotadhari.reactnative.mapsforge.vtm.ext.grib.ExtGribPackage;',
|
|
9
|
+
packageInstance: 'new ExtGribPackage()',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
import type { Double, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
|
+
import type { ErrorBase, ResponseBase } from '../types';
|
|
5
|
+
|
|
6
|
+
export interface ModuleParams {
|
|
7
|
+
dataUrl?: string;
|
|
8
|
+
parameter?: string;
|
|
9
|
+
timeIndex?: Int32;
|
|
10
|
+
colorMap?: string;
|
|
11
|
+
opacity?: Double;
|
|
12
|
+
zoomMin?: Int32;
|
|
13
|
+
zoomMax?: Int32;
|
|
14
|
+
enabledZoomMin?: Int32;
|
|
15
|
+
enabledZoomMax?: Int32;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface CreateLayerParams extends ModuleParams {
|
|
19
|
+
nativeNodeHandle?: Int32;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface RemoveLayerParams {
|
|
23
|
+
nativeNodeHandle: Int32;
|
|
24
|
+
uuid: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface UpdateEnabledZoomMinMaxParams {
|
|
28
|
+
nativeNodeHandle: Int32;
|
|
29
|
+
uuid: string;
|
|
30
|
+
enabledZoomMin?: Int32;
|
|
31
|
+
enabledZoomMax?: Int32;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface SetOpacityParams {
|
|
35
|
+
nativeNodeHandle: Int32;
|
|
36
|
+
uuid: string;
|
|
37
|
+
opacity?: Double;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface SetTimeIndexParams {
|
|
41
|
+
nativeNodeHandle: Int32;
|
|
42
|
+
uuid: string;
|
|
43
|
+
timeIndex: Int32;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type WeatherOverlayProps = {
|
|
47
|
+
dataUrl?: string;
|
|
48
|
+
parameter?: string;
|
|
49
|
+
timeIndex?: number;
|
|
50
|
+
colorMap?: string;
|
|
51
|
+
opacity?: number;
|
|
52
|
+
zoomMin?: number;
|
|
53
|
+
zoomMax?: number;
|
|
54
|
+
enabledZoomMin?: number;
|
|
55
|
+
enabledZoomMax?: number;
|
|
56
|
+
onCreate?: null | ((result: ResponseBase) => void);
|
|
57
|
+
onRemove?: null | ((result: ResponseBase) => void);
|
|
58
|
+
onChange?: null | ((result: ResponseBase) => void);
|
|
59
|
+
onError?: null | ((err: ErrorBase) => void);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export interface Spec extends TurboModule {
|
|
63
|
+
getConstants(): ModuleParams;
|
|
64
|
+
createLayer(params: CreateLayerParams): Promise<string>;
|
|
65
|
+
removeLayer(params: RemoveLayerParams): Promise<string>;
|
|
66
|
+
updateEnabledZoomMinMax(
|
|
67
|
+
params: UpdateEnabledZoomMinMaxParams
|
|
68
|
+
): Promise<string>;
|
|
69
|
+
setOpacity(params: SetOpacityParams): Promise<string>;
|
|
70
|
+
setTimeIndex(params: SetTimeIndexParams): Promise<string>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('WeatherOverlay');
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useContext, useEffect } from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import WeatherOverlayModule, {
|
|
10
|
+
type WeatherOverlayProps,
|
|
11
|
+
} from '../NativeModules/NativeWeatherOverlay';
|
|
12
|
+
import type { ErrorBase } from '../types';
|
|
13
|
+
import reportNativeError from '../reportNativeError';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Peer dependencies (from react-native-mapsforge-vtm)
|
|
17
|
+
*/
|
|
18
|
+
import {
|
|
19
|
+
MapHandleContext,
|
|
20
|
+
useLayerAnchor,
|
|
21
|
+
useSceneUuidBinding,
|
|
22
|
+
useNativeLayerLifecycle,
|
|
23
|
+
} from 'react-native-mapsforge-vtm';
|
|
24
|
+
|
|
25
|
+
const WeatherOverlay = ({
|
|
26
|
+
dataUrl,
|
|
27
|
+
parameter,
|
|
28
|
+
timeIndex,
|
|
29
|
+
colorMap,
|
|
30
|
+
opacity,
|
|
31
|
+
zoomMin,
|
|
32
|
+
zoomMax,
|
|
33
|
+
enabledZoomMin,
|
|
34
|
+
enabledZoomMax,
|
|
35
|
+
onCreate,
|
|
36
|
+
onRemove,
|
|
37
|
+
onChange,
|
|
38
|
+
onError,
|
|
39
|
+
}: WeatherOverlayProps) => {
|
|
40
|
+
const { nativeNodeHandle } = useContext(MapHandleContext);
|
|
41
|
+
|
|
42
|
+
const { uid: anchorUid, element: anchorElement } = useLayerAnchor({
|
|
43
|
+
kind: 'layer',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const { uuid, triggerCreate, triggerRemove } = useNativeLayerLifecycle({
|
|
47
|
+
enabled: !!nativeNodeHandle && !!dataUrl,
|
|
48
|
+
create: ({ triggerOnCreate, triggerOnChange }) => {
|
|
49
|
+
if (!nativeNodeHandle) {
|
|
50
|
+
return Promise.reject<string>({
|
|
51
|
+
userInfo: { errorMsg: 'Missing nativeNodeHandle' },
|
|
52
|
+
} as ErrorBase);
|
|
53
|
+
}
|
|
54
|
+
return WeatherOverlayModule.createLayer({
|
|
55
|
+
nativeNodeHandle,
|
|
56
|
+
...(dataUrl && { dataUrl }),
|
|
57
|
+
...(parameter && { parameter }),
|
|
58
|
+
...(timeIndex != null && { timeIndex: Math.round(timeIndex) }),
|
|
59
|
+
...(colorMap && { colorMap }),
|
|
60
|
+
...(opacity != null && { opacity }),
|
|
61
|
+
...(zoomMin != null && { zoomMin: Math.round(zoomMin) }),
|
|
62
|
+
...(zoomMax != null && { zoomMax: Math.round(zoomMax) }),
|
|
63
|
+
...(enabledZoomMin != null && {
|
|
64
|
+
enabledZoomMin: Math.round(enabledZoomMin),
|
|
65
|
+
}),
|
|
66
|
+
...(enabledZoomMax != null && {
|
|
67
|
+
enabledZoomMax: Math.round(enabledZoomMax),
|
|
68
|
+
}),
|
|
69
|
+
}).then((newUuid) => {
|
|
70
|
+
triggerOnCreate && onCreate
|
|
71
|
+
? onCreate({ nativeNodeHandle, uuid: newUuid })
|
|
72
|
+
: null;
|
|
73
|
+
triggerOnChange && onChange
|
|
74
|
+
? onChange({ nativeNodeHandle, uuid: newUuid })
|
|
75
|
+
: null;
|
|
76
|
+
return newUuid;
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
remove: (currentUuid, { triggerOnRemove }) => {
|
|
80
|
+
if (!nativeNodeHandle) {
|
|
81
|
+
return Promise.resolve(false);
|
|
82
|
+
}
|
|
83
|
+
return WeatherOverlayModule.removeLayer({
|
|
84
|
+
nativeNodeHandle,
|
|
85
|
+
uuid: currentUuid,
|
|
86
|
+
})
|
|
87
|
+
.then((removedUuid) => {
|
|
88
|
+
triggerOnRemove && onRemove
|
|
89
|
+
? onRemove({ nativeNodeHandle, uuid: removedUuid })
|
|
90
|
+
: null;
|
|
91
|
+
return true;
|
|
92
|
+
})
|
|
93
|
+
.catch((err: ErrorBase) => {
|
|
94
|
+
reportNativeError(err, onError);
|
|
95
|
+
return false;
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
onError,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
useSceneUuidBinding(anchorUid, uuid);
|
|
102
|
+
|
|
103
|
+
// Update enabledZoomMin/enabledZoomMax in place.
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (nativeNodeHandle && uuid) {
|
|
106
|
+
WeatherOverlayModule.updateEnabledZoomMinMax({
|
|
107
|
+
nativeNodeHandle,
|
|
108
|
+
uuid,
|
|
109
|
+
...(enabledZoomMin != null && {
|
|
110
|
+
enabledZoomMin: Math.round(enabledZoomMin),
|
|
111
|
+
}),
|
|
112
|
+
...(enabledZoomMax != null && {
|
|
113
|
+
enabledZoomMax: Math.round(enabledZoomMax),
|
|
114
|
+
}),
|
|
115
|
+
}).catch((err: ErrorBase) => {
|
|
116
|
+
reportNativeError(err, onError);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}, [
|
|
120
|
+
enabledZoomMin,
|
|
121
|
+
enabledZoomMax,
|
|
122
|
+
nativeNodeHandle,
|
|
123
|
+
uuid,
|
|
124
|
+
onError,
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
// Update opacity in place.
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (nativeNodeHandle && uuid && opacity != null) {
|
|
130
|
+
WeatherOverlayModule.setOpacity({
|
|
131
|
+
nativeNodeHandle,
|
|
132
|
+
uuid,
|
|
133
|
+
opacity,
|
|
134
|
+
}).catch((err: ErrorBase) => {
|
|
135
|
+
reportNativeError(err, onError);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}, [
|
|
139
|
+
opacity,
|
|
140
|
+
nativeNodeHandle,
|
|
141
|
+
uuid,
|
|
142
|
+
onError,
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
// Recreate on these prop changes (baked into native construction).
|
|
146
|
+
// timeIndex is included here because changing it requires a fresh data
|
|
147
|
+
// fetch and tile source — same as dataUrl or parameter changes.
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
triggerRemove({ triggerOnRemove: false }).then((success) => {
|
|
150
|
+
if (success) {
|
|
151
|
+
triggerCreate({
|
|
152
|
+
triggerOnCreate: false,
|
|
153
|
+
triggerOnChange: true,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}, [
|
|
158
|
+
dataUrl,
|
|
159
|
+
parameter,
|
|
160
|
+
timeIndex,
|
|
161
|
+
colorMap,
|
|
162
|
+
zoomMin,
|
|
163
|
+
zoomMax,
|
|
164
|
+
triggerRemove,
|
|
165
|
+
triggerCreate,
|
|
166
|
+
]);
|
|
167
|
+
|
|
168
|
+
return anchorElement;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
WeatherOverlay.defaults = WeatherOverlayModule.getConstants();
|
|
172
|
+
|
|
173
|
+
export default WeatherOverlay;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-native-mapsforge-vtm-ext-grib
|
|
3
|
+
*
|
|
4
|
+
* Weather GRIB overlay extension for react-native-mapsforge-vtm.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Main component
|
|
8
|
+
export { default as WeatherOverlay } from './components/WeatherOverlay';
|
|
9
|
+
export type { WeatherOverlayProps } from './NativeModules/NativeWeatherOverlay';
|
|
10
|
+
|
|
11
|
+
// Shared types
|
|
12
|
+
export type {
|
|
13
|
+
WeatherGrid,
|
|
14
|
+
WeatherMetadata,
|
|
15
|
+
ColorMapName,
|
|
16
|
+
ResponseBase,
|
|
17
|
+
ErrorBase,
|
|
18
|
+
} from './types';
|
|
19
|
+
|
|
20
|
+
// Reanimated utilities (also available via /reanimated subpath export)
|
|
21
|
+
export { useWeatherAnimation } from './reanimated/useWeatherAnimation';
|
|
22
|
+
export type { WeatherAnimationControls } from './reanimated/useWeatherAnimation';
|