@react-native-ohos/react-native-map-clustering 3.4.1-rc.1 → 3.5.0-rc.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/CHANGELOG.md +25 -0
- package/COMMITTERS.md +6 -0
- package/LICENSE +21 -21
- package/OAT.xml +57 -57
- package/README.OpenSource +10 -10
- package/README.md +13 -13
- package/example/.eslintrc +19 -0
- package/example/.node-version +6 -0
- package/example/.prettierrc.js +7 -0
- package/example/.watchmanconfig +6 -0
- package/example/app.json +4 -0
- package/example/babel.config.js +6 -0
- package/example/contexts.ts +9 -0
- package/example/harmony/AppScope/app.json5 +10 -0
- package/example/harmony/AppScope/resources/base/element/string.json +8 -0
- package/example/harmony/AppScope/resources/base/media/app_icon.png +0 -0
- package/example/harmony/build-profile.template.json5 +36 -0
- package/example/harmony/codelinter.json +32 -0
- package/example/harmony/entry/build-profile.json5 +22 -0
- package/example/harmony/entry/hvigorfile.ts +8 -0
- package/example/harmony/entry/oh-package.json5 +11 -0
- package/example/harmony/entry/src/main/cpp/CMakeLists.txt +42 -0
- package/example/harmony/entry/src/main/cpp/PackageProvider.cpp +17 -0
- package/example/harmony/entry/src/main/ets/RNPackagesFactory.ets +15 -0
- package/example/harmony/entry/src/main/ets/assets/fonts/Pacifico-Regular.ttf +0 -0
- package/example/harmony/entry/src/main/ets/assets/fonts/StintUltraCondensed-Regular.ttf +0 -0
- package/example/harmony/entry/src/main/ets/entryability/EntryAbility.ets +27 -0
- package/example/harmony/entry/src/main/ets/pages/Index.ets +209 -0
- package/example/harmony/entry/src/main/ets/pages/SurfaceDeadlockTest.ets +135 -0
- package/example/harmony/entry/src/main/ets/pages/TouchDisplayer.ets +44 -0
- package/example/harmony/entry/src/main/module.json5 +72 -0
- package/example/harmony/entry/src/main/resources/base/element/color.json +8 -0
- package/example/harmony/entry/src/main/resources/base/element/string.json +20 -0
- package/example/harmony/entry/src/main/resources/base/media/icon.png +0 -0
- package/example/harmony/entry/src/main/resources/base/profile/main_pages.json +5 -0
- package/example/harmony/entry/src/main/resources/rawfile/1.txt +1 -0
- package/example/harmony/format.ps1 +18 -0
- package/example/harmony/hvigor/hvigor-config.json5 +21 -0
- package/example/harmony/hvigorfile.ts +9 -0
- package/example/harmony/oh-package.json5 +12 -0
- package/example/index.js +11 -0
- package/example/jest.config.js +11 -0
- package/example/metro.config.js +30 -0
- package/example/package.json +61 -0
- package/example/react-native.config.js +11 -0
- package/example/scripts/create-build-profile.js +46 -0
- package/example/src/App.tsx +186 -0
- package/example/src/Navigation.tsx +163 -0
- package/example/src/index.tsx +59 -0
- package/example/tsconfig.json +14 -0
- package/index.d.ts +40 -40
- package/index.js +2 -2
- package/lib/ClusterHarmony.js +21 -21
- package/lib/ClusteredMapView.js +310 -310
- package/package.json +42 -42
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const JSON5 = require('json5');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const templatePath = path.join(
|
|
13
|
+
__dirname,
|
|
14
|
+
'..',
|
|
15
|
+
'harmony',
|
|
16
|
+
'build-profile.template.json5',
|
|
17
|
+
);
|
|
18
|
+
const existingProfilePath = path.join(
|
|
19
|
+
__dirname,
|
|
20
|
+
'..',
|
|
21
|
+
'harmony',
|
|
22
|
+
'build-profile.json5',
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
if (fs.existsSync(existingProfilePath)) {
|
|
26
|
+
let existingProfile = JSON5.parse(
|
|
27
|
+
fs.readFileSync(existingProfilePath, 'utf-8'),
|
|
28
|
+
);
|
|
29
|
+
let template = JSON5.parse(fs.readFileSync(templatePath, 'utf-8'));
|
|
30
|
+
let signingConfigs =
|
|
31
|
+
existingProfile.app && existingProfile.app.signingConfigs;
|
|
32
|
+
|
|
33
|
+
existingProfile = {...template};
|
|
34
|
+
|
|
35
|
+
if (signingConfigs) {
|
|
36
|
+
existingProfile.app.signingConfigs = signingConfigs;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fs.writeFileSync(
|
|
40
|
+
existingProfilePath,
|
|
41
|
+
JSON5.stringify(existingProfile, null, 2),
|
|
42
|
+
);
|
|
43
|
+
} else {
|
|
44
|
+
// File doesn't exist, create a copy from the template
|
|
45
|
+
fs.copyFileSync(templatePath, existingProfilePath);
|
|
46
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
SafeAreaView,
|
|
4
|
+
StatusBar,
|
|
5
|
+
Text,
|
|
6
|
+
View,
|
|
7
|
+
Dimensions,
|
|
8
|
+
Button,
|
|
9
|
+
ScrollView
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import { NavigationContainer, Page } from './Navigation';
|
|
12
|
+
import { PortalProvider } from '@gorhom/portal';
|
|
13
|
+
import MapView from 'react-native-map-clustering';
|
|
14
|
+
import { Marker } from 'react-native-maps';
|
|
15
|
+
const { width, height } = Dimensions.get('window');
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
const INITIAL_REGION = {
|
|
19
|
+
latitude: 52.5,
|
|
20
|
+
longitude: 19.2,
|
|
21
|
+
latitudeDelta: 8.5,
|
|
22
|
+
longitudeDelta: 8.5,
|
|
23
|
+
};
|
|
24
|
+
const markers = [
|
|
25
|
+
{ coordinate: { latitude: 52.4, longitude: 18.7 } },
|
|
26
|
+
{ coordinate: { latitude: 52.1, longitude: 18.4 } },
|
|
27
|
+
{ coordinate: { latitude: 52.6, longitude: 18.3 } },
|
|
28
|
+
{ coordinate: { latitude: 51.6, longitude: 18.0 } },
|
|
29
|
+
{ coordinate: { latitude: 53.1, longitude: 18.8 } },
|
|
30
|
+
{ coordinate: { latitude: 52.9, longitude: 19.4 } },
|
|
31
|
+
{ coordinate: { latitude: 52.2, longitude: 21 } },
|
|
32
|
+
{ coordinate: { latitude: 52.4, longitude: 21 } },
|
|
33
|
+
{ coordinate: { latitude: 51.8, longitude: 20 } }
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
const App = () => {
|
|
39
|
+
const [onPressText, setOnPressText] = useState('');
|
|
40
|
+
const [onRegionChangeCompleteText, setOnRegionChangeCompleteText] = useState('');
|
|
41
|
+
const [onMarkerText, setOnMarkerText] = useState('');
|
|
42
|
+
const [rrefText, setRrefText] = useState('');
|
|
43
|
+
const rref = useRef(null);
|
|
44
|
+
const comList = [
|
|
45
|
+
{
|
|
46
|
+
name: 'onClusterPress',
|
|
47
|
+
prop: {
|
|
48
|
+
onClusterPress: (cluster, markers) => {
|
|
49
|
+
setOnPressText(`onClusterPress触发, cluster:${JSON.stringify(cluster)},markers:聚合数组长度${markers?.length}`);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
text: onPressText
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'width: 200',
|
|
56
|
+
prop: { width: 200 },
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'width: 250',
|
|
60
|
+
prop: { width: 250 },
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'radius: 20',
|
|
64
|
+
prop: { radius: 20 },
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'radius: 200',
|
|
68
|
+
prop: { radius: 200 },
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'extent: 512',
|
|
72
|
+
prop: { extent: 512 },
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'extent: 112',
|
|
76
|
+
prop: { extent: 112 },
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'minZoom: 4',
|
|
80
|
+
prop: { minZoom: 4 },
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'minZoom: 1',
|
|
84
|
+
prop: { minZoom: 1 },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'minPoints: 2',
|
|
88
|
+
prop: { minPoints: 2 },
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'minPoints: 4',
|
|
92
|
+
prop: { minPoints: 4 },
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'preserveClusterPressBehavior: false',
|
|
96
|
+
prop: { preserveClusterPressBehavior: false },
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'preserveClusterPressBehavior: true',
|
|
100
|
+
prop: { preserveClusterPressBehavior: true },
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'onRegionChangeComplete',
|
|
104
|
+
prop: {
|
|
105
|
+
onRegionChangeComplete: (region, markers) => {
|
|
106
|
+
setOnRegionChangeCompleteText(`onRegionChangeComplete触发, region:${JSON.stringify(region)},markers:聚合数组长度${markers?.length}`);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
text: onRegionChangeCompleteText
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'onMarkersChange',
|
|
113
|
+
prop: {
|
|
114
|
+
onMarkersChange: (markers) => {
|
|
115
|
+
setOnMarkerText(`onMarkersChange触发, markers:聚合数组长度${markers?.length}`);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
text: onMarkerText
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'superClusterRef',
|
|
122
|
+
prop: { superClusterRef: rref },
|
|
123
|
+
btn: () => {
|
|
124
|
+
setRrefText(`superClusterRef触发, superClusterRef.current.options:${JSON.stringify(rref?.current.options)}`);
|
|
125
|
+
},
|
|
126
|
+
text: rrefText
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'clusteringEnabled: false',
|
|
130
|
+
prop: { clusteringEnabled: false },
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'clusteringEnabled: true',
|
|
134
|
+
prop: { clusteringEnabled: true },
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
return (
|
|
138
|
+
<View style={{ backgroundColor: 'black' }}>
|
|
139
|
+
<StatusBar barStyle="light-content" />
|
|
140
|
+
<SafeAreaView>
|
|
141
|
+
<NavigationContainer>
|
|
142
|
+
<PortalProvider>
|
|
143
|
+
{comList.map((com: any) => {
|
|
144
|
+
return (
|
|
145
|
+
<Page
|
|
146
|
+
key={com.name}
|
|
147
|
+
name={`${com.name}`}>
|
|
148
|
+
<View style={{ height: height - 315 }}>
|
|
149
|
+
<MapView
|
|
150
|
+
initialRegion={INITIAL_REGION}
|
|
151
|
+
style={{ flex: 1 }}
|
|
152
|
+
//@ts-ignore
|
|
153
|
+
clusterDistance={100}
|
|
154
|
+
{...com.prop}
|
|
155
|
+
>
|
|
156
|
+
{markers.map((marker, idx) => <Marker key={idx} coordinate={marker.coordinate} />)}
|
|
157
|
+
</MapView>
|
|
158
|
+
{com?.text && <Text style={{ color: "red" }}>{com?.text}</Text>}
|
|
159
|
+
{com?.btn && <Button color="red" title={com.name} onPress={com?.btn} />}
|
|
160
|
+
</View>
|
|
161
|
+
</Page>
|
|
162
|
+
);
|
|
163
|
+
})}
|
|
164
|
+
</PortalProvider>
|
|
165
|
+
</NavigationContainer>
|
|
166
|
+
</SafeAreaView>
|
|
167
|
+
</View>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
export default App;
|
|
171
|
+
|
|
172
|
+
export const displayName = 'react-native-map-clustering';
|
|
173
|
+
export const framework = 'React';
|
|
174
|
+
export const category = 'UI';
|
|
175
|
+
export const title = 'react-native-map-clustering';
|
|
176
|
+
export const documentationURL = 'https://github.com/tomekvenits/react-native-map-clustering';
|
|
177
|
+
export const description = 'React Native Map Clustering';
|
|
178
|
+
|
|
179
|
+
export const examples = [
|
|
180
|
+
{
|
|
181
|
+
title: 'react-native-map-clustering',
|
|
182
|
+
render: function () {
|
|
183
|
+
return <App />;
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
];
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import React, {useEffect} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
FlatList,
|
|
4
|
+
Image,
|
|
5
|
+
Platform,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
Text,
|
|
8
|
+
TouchableOpacity,
|
|
9
|
+
View,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
|
|
12
|
+
export const PALETTE = {
|
|
13
|
+
REACT_CYAN_LIGHT: 'hsl(193, 95%, 68%)',
|
|
14
|
+
REACT_CYAN_DARK: 'hsl(193, 95%, 30%)',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const NavigationContext = React.createContext<
|
|
18
|
+
| {
|
|
19
|
+
currentPageName: string;
|
|
20
|
+
navigateTo: (pageName: string) => void;
|
|
21
|
+
registerPageName: (pageName: string) => void;
|
|
22
|
+
registeredPageNames: string[];
|
|
23
|
+
}
|
|
24
|
+
| undefined
|
|
25
|
+
>(undefined);
|
|
26
|
+
|
|
27
|
+
export function NavigationContainer({
|
|
28
|
+
initialPage = 'INDEX',
|
|
29
|
+
hasHeader = true,
|
|
30
|
+
children,
|
|
31
|
+
}: {
|
|
32
|
+
initialPage?: string;
|
|
33
|
+
children: any;
|
|
34
|
+
hasHeader?: boolean
|
|
35
|
+
}) {
|
|
36
|
+
const [currentPageName, setCurrentPageName] = React.useState(initialPage);
|
|
37
|
+
const [registeredPageNames, setRegisteredPageNames] = React.useState<
|
|
38
|
+
string[]
|
|
39
|
+
>([]);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<NavigationContext.Provider
|
|
43
|
+
value={{
|
|
44
|
+
currentPageName,
|
|
45
|
+
navigateTo: setCurrentPageName,
|
|
46
|
+
registerPageName: (pageName: string) => {
|
|
47
|
+
setRegisteredPageNames(pageNames => {
|
|
48
|
+
if (pageNames.includes(pageName)) {
|
|
49
|
+
return pageNames;
|
|
50
|
+
}
|
|
51
|
+
return [...pageNames, pageName];
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
registeredPageNames,
|
|
55
|
+
}}>
|
|
56
|
+
<View style={{width: '100%', height: '100%', flexDirection: 'column'}}>
|
|
57
|
+
<Page name="INDEX">
|
|
58
|
+
<IndexPage hasHeader={hasHeader} />
|
|
59
|
+
</Page>
|
|
60
|
+
{children}
|
|
61
|
+
</View>
|
|
62
|
+
</NavigationContext.Provider>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function useNavigation() {
|
|
67
|
+
return React.useContext(NavigationContext)!;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function Page({name, children}: {name: string; children: any}) {
|
|
71
|
+
const {currentPageName, navigateTo, registerPageName} = useNavigation();
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (name !== 'INDEX') {
|
|
75
|
+
registerPageName(name);
|
|
76
|
+
}
|
|
77
|
+
}, [name]);
|
|
78
|
+
|
|
79
|
+
return name === currentPageName ? (
|
|
80
|
+
<View style={{width: '100%', height: '100%'}}>
|
|
81
|
+
{name !== 'INDEX' && (
|
|
82
|
+
<View style={{backgroundColor: PALETTE.REACT_CYAN_DARK}}>
|
|
83
|
+
<TouchableOpacity
|
|
84
|
+
onPress={() => {
|
|
85
|
+
navigateTo('INDEX');
|
|
86
|
+
}}>
|
|
87
|
+
<Text
|
|
88
|
+
style={[styles.buttonText, {color: PALETTE.REACT_CYAN_LIGHT}]}>
|
|
89
|
+
{'‹ Back'}
|
|
90
|
+
</Text>
|
|
91
|
+
</TouchableOpacity>
|
|
92
|
+
</View>
|
|
93
|
+
)}
|
|
94
|
+
<View style={{width: '100%', flex: 1}}>{children}</View>
|
|
95
|
+
</View>
|
|
96
|
+
) : null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function IndexPage({ hasHeader }: { hasHeader: boolean }) {
|
|
100
|
+
const {navigateTo, registeredPageNames} = useNavigation();
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<FlatList
|
|
104
|
+
data={registeredPageNames}
|
|
105
|
+
ListHeaderComponent={
|
|
106
|
+
hasHeader ? <View
|
|
107
|
+
style={{
|
|
108
|
+
flexDirection: 'row',
|
|
109
|
+
alignItems: 'center',
|
|
110
|
+
paddingHorizontal: 16,
|
|
111
|
+
paddingVertical: 16,
|
|
112
|
+
}}>
|
|
113
|
+
<Text
|
|
114
|
+
style={{
|
|
115
|
+
color: '#EEE',
|
|
116
|
+
fontSize: 24,
|
|
117
|
+
fontWeight: 'bold',
|
|
118
|
+
padding: 16,
|
|
119
|
+
}}>
|
|
120
|
+
RN Map Clustering Capi Tester
|
|
121
|
+
{'rnohArchitecture' in Platform.constants
|
|
122
|
+
? (` (${Platform.constants.rnohArchitecture})` as string)
|
|
123
|
+
: ''}
|
|
124
|
+
</Text>
|
|
125
|
+
</View>
|
|
126
|
+
: null
|
|
127
|
+
}
|
|
128
|
+
renderItem={({item}) => {
|
|
129
|
+
return (
|
|
130
|
+
<View style={{backgroundColor: PALETTE.REACT_CYAN_DARK}}>
|
|
131
|
+
<TouchableOpacity
|
|
132
|
+
onPress={() => {
|
|
133
|
+
navigateTo(item);
|
|
134
|
+
}}>
|
|
135
|
+
<Text style={styles.buttonText}>{item}</Text>
|
|
136
|
+
</TouchableOpacity>
|
|
137
|
+
</View>
|
|
138
|
+
);
|
|
139
|
+
}}
|
|
140
|
+
ItemSeparatorComponent={() => (
|
|
141
|
+
<View
|
|
142
|
+
style={{height: StyleSheet.hairlineWidth, backgroundColor: '#666'}}
|
|
143
|
+
/>
|
|
144
|
+
)}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const styles = StyleSheet.create({
|
|
150
|
+
container: {
|
|
151
|
+
width: '100%',
|
|
152
|
+
height: '100%',
|
|
153
|
+
backgroundColor: '#888',
|
|
154
|
+
},
|
|
155
|
+
buttonText: {
|
|
156
|
+
width: '100%',
|
|
157
|
+
fontWeight: 'bold',
|
|
158
|
+
paddingHorizontal: 16,
|
|
159
|
+
paddingVertical: 24,
|
|
160
|
+
color: 'white',
|
|
161
|
+
backgroundColor: 'black',
|
|
162
|
+
},
|
|
163
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
import MapView from "react-native-map-clustering";
|
|
9
|
+
import { Marker } from "react-native-maps";
|
|
10
|
+
|
|
11
|
+
function getRandomLatitude(min = 48, max = 56) {
|
|
12
|
+
return Math.random() * (max - min) + min;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getRandomLongitude(min = 14, max = 24) {
|
|
16
|
+
return Math.random() * (max - min) + min;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const INITIAL_REGION = {
|
|
20
|
+
latitude: 52.5,
|
|
21
|
+
longitude: 19.2,
|
|
22
|
+
latitudeDelta: 8.5,
|
|
23
|
+
longitudeDelta: 8.5
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function MapClusteringExample() {
|
|
27
|
+
const _generateMarkers = (count: number) => {
|
|
28
|
+
const markers = [];
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < count; i++) {
|
|
31
|
+
markers.push(
|
|
32
|
+
<Marker
|
|
33
|
+
|
|
34
|
+
title='456'
|
|
35
|
+
key={i}
|
|
36
|
+
coordinate={{
|
|
37
|
+
latitude: getRandomLatitude(),
|
|
38
|
+
longitude: getRandomLongitude()
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return markers;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<MapView initialRegion={INITIAL_REGION}
|
|
49
|
+
style={{ flex: 1 }}
|
|
50
|
+
>
|
|
51
|
+
{_generateMarkers(200)}
|
|
52
|
+
</MapView>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
//export default App
|
|
59
|
+
export default MapClusteringExample;
|
package/index.d.ts
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
declare module "react-native-map-clustering" {
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { LayoutAnimationConfig } from "react-native";
|
|
4
|
-
import Map, { MapViewProps, Marker } from "react-native-maps";
|
|
5
|
-
|
|
6
|
-
export type Cluster = {};
|
|
7
|
-
|
|
8
|
-
interface MapClusteringProps {
|
|
9
|
-
clusteringEnabled?: boolean;
|
|
10
|
-
spiralEnabled?: boolean;
|
|
11
|
-
animationEnabled?: boolean;
|
|
12
|
-
preserveClusterPressBehavior?: boolean;
|
|
13
|
-
tracksViewChanges?: boolean;
|
|
14
|
-
layoutAnimationConf?: LayoutAnimationConfig;
|
|
15
|
-
radius?: number;
|
|
16
|
-
maxZoom?: number;
|
|
17
|
-
minZoom?: number;
|
|
18
|
-
extent?: number;
|
|
19
|
-
nodeSize?: number;
|
|
20
|
-
minPoints?: number;
|
|
21
|
-
edgePadding?: { top: number; left: number; right: number; bottom: number };
|
|
22
|
-
clusterColor?: string;
|
|
23
|
-
clusterTextColor?: string;
|
|
24
|
-
clusterFontFamily?: string;
|
|
25
|
-
selectedClusterId?: string;
|
|
26
|
-
selectedClusterColor?: string;
|
|
27
|
-
spiderLineColor?: string;
|
|
28
|
-
superClusterRef?: React.MutableRefObject<any>;
|
|
29
|
-
mapRef?: (ref: React.Ref<Map>) => void;
|
|
30
|
-
onClusterPress?: (cluster: Marker, markers?: Marker[]) => void;
|
|
31
|
-
getClusterEngine?: (ref: any) => void;
|
|
32
|
-
onMarkersChange?: (markers?: Marker[]) => void;
|
|
33
|
-
renderCluster?: (cluster: any) => React.ReactNode;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default class MapView extends React.Component<
|
|
37
|
-
MapViewProps & MapClusteringProps,
|
|
38
|
-
any
|
|
39
|
-
> {}
|
|
40
|
-
}
|
|
1
|
+
declare module "react-native-map-clustering" {
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { LayoutAnimationConfig } from "react-native";
|
|
4
|
+
import Map, { MapViewProps, Marker } from "react-native-maps";
|
|
5
|
+
|
|
6
|
+
export type Cluster = {};
|
|
7
|
+
|
|
8
|
+
interface MapClusteringProps {
|
|
9
|
+
clusteringEnabled?: boolean;
|
|
10
|
+
spiralEnabled?: boolean;
|
|
11
|
+
animationEnabled?: boolean;
|
|
12
|
+
preserveClusterPressBehavior?: boolean;
|
|
13
|
+
tracksViewChanges?: boolean;
|
|
14
|
+
layoutAnimationConf?: LayoutAnimationConfig;
|
|
15
|
+
radius?: number;
|
|
16
|
+
maxZoom?: number;
|
|
17
|
+
minZoom?: number;
|
|
18
|
+
extent?: number;
|
|
19
|
+
nodeSize?: number;
|
|
20
|
+
minPoints?: number;
|
|
21
|
+
edgePadding?: { top: number; left: number; right: number; bottom: number };
|
|
22
|
+
clusterColor?: string;
|
|
23
|
+
clusterTextColor?: string;
|
|
24
|
+
clusterFontFamily?: string;
|
|
25
|
+
selectedClusterId?: string;
|
|
26
|
+
selectedClusterColor?: string;
|
|
27
|
+
spiderLineColor?: string;
|
|
28
|
+
superClusterRef?: React.MutableRefObject<any>;
|
|
29
|
+
mapRef?: (ref: React.Ref<Map>) => void;
|
|
30
|
+
onClusterPress?: (cluster: Marker, markers?: Marker[]) => void;
|
|
31
|
+
getClusterEngine?: (ref: any) => void;
|
|
32
|
+
onMarkersChange?: (markers?: Marker[]) => void;
|
|
33
|
+
renderCluster?: (cluster: any) => React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default class MapView extends React.Component<
|
|
37
|
+
MapViewProps & MapClusteringProps,
|
|
38
|
+
any
|
|
39
|
+
> {}
|
|
40
|
+
}
|
package/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import * as MapView from "./lib/ClusteredMapView";
|
|
2
|
-
module.exports = MapView;
|
|
1
|
+
import * as MapView from "./lib/ClusteredMapView";
|
|
2
|
+
module.exports = MapView;
|
package/lib/ClusterHarmony.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
-
* Use of this source code is governed by a MIT license that can be
|
|
4
|
-
* found in the LICENSE file.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, { memo } from "react";
|
|
8
|
-
import { Cluster } from "react-native-maps";
|
|
9
|
-
|
|
10
|
-
const ClusterHarmony = ({ marker, distance, onPress }) => {
|
|
11
|
-
return (
|
|
12
|
-
<Cluster
|
|
13
|
-
clusterItems={marker.clusterChildItem}
|
|
14
|
-
distance={distance ? distance : 40}
|
|
15
|
-
onPress={onPress}
|
|
16
|
-
style={{ zIndex: marker.properties.point_count + 1 }}
|
|
17
|
-
></Cluster>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default memo(ClusterHarmony);
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React, { memo } from "react";
|
|
8
|
+
import { Cluster } from "react-native-maps";
|
|
9
|
+
|
|
10
|
+
const ClusterHarmony = ({ marker, distance, onPress }) => {
|
|
11
|
+
return (
|
|
12
|
+
<Cluster
|
|
13
|
+
clusterItems={marker.clusterChildItem}
|
|
14
|
+
distance={distance ? distance : 40}
|
|
15
|
+
onPress={onPress}
|
|
16
|
+
style={{ zIndex: marker.properties.point_count + 1 }}
|
|
17
|
+
></Cluster>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default memo(ClusterHarmony);
|