├── .browserslistrc
├── .commitlintrc.js
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .fatherrc.ts
├── .github
├── ISSUE_TEMPLATE
│ ├── ----bug-report.md
│ ├── ---ask-for-question.md
│ └── ---feature-request.md
├── PULL_REQUEST_TEMPLATE.md
├── release.yaml
└── workflows
│ ├── lint.yml
│ ├── preview.yml
│ ├── release-label.yml
│ ├── release-notify.yml
│ └── release.yml
├── .gitignore
├── .husky
├── commit-msg
└── pre-commit
├── .npmignore
├── .prettierignore
├── .prettierrc.js
├── .stylelintrc.js
├── .umirc.ts
├── LICENSE
├── README.en-US.md
├── README.md
├── __tests__
└── version.spec.ts
├── docs
├── CNAME
├── blocks
│ ├── administrative-select.md
│ ├── administrative-select
│ │ ├── administrative-select.tsx
│ │ └── demos
│ │ │ └── default.tsx
│ ├── draw-modal.md
│ ├── draw-modal
│ │ ├── DrawModal.tsx
│ │ ├── constants.ts
│ │ ├── default.tsx
│ │ ├── edit.tsx
│ │ ├── index.less
│ │ └── types.ts
│ └── layer-attribute
│ │ ├── bubble-layer-style-attribute
│ │ ├── demos
│ │ │ └── default.tsx
│ │ └── index.md
│ │ ├── choropleth-layer-style-attribute
│ │ ├── demos
│ │ │ └── default.tsx
│ │ └── index.md
│ │ ├── heatmap-layer-style-attribute
│ │ ├── demos
│ │ │ └── default.tsx
│ │ └── index.md
│ │ └── line-layer-style-attribute
│ │ ├── demos
│ │ └── default.tsx
│ │ └── index.md
├── common
│ └── layer
│ │ ├── attribute
│ │ ├── color.md
│ │ ├── scale.md
│ │ ├── size.md
│ │ └── state.md
│ │ ├── base-common
│ │ └── event.md
│ │ ├── composite-common
│ │ └── event.md
│ │ ├── heatmap-layer
│ │ ├── shape.md
│ │ ├── size.md
│ │ └── style.md
│ │ ├── image-layer
│ │ ├── source.md
│ │ └── style.md
│ │ ├── line-layer
│ │ ├── animate.md
│ │ ├── shape.md
│ │ ├── source.md
│ │ └── style.md
│ │ ├── point-layer
│ │ ├── animate.md
│ │ ├── shape.md
│ │ ├── source.md
│ │ └── style.md
│ │ ├── polygon-layer
│ │ ├── shape.md
│ │ ├── source.md
│ │ └── style.md
│ │ ├── raster-layer
│ │ ├── source.md
│ │ └── style.md
│ │ └── text-layer
│ │ └── style.md
├── examples
│ ├── beijingHousePrice.md
│ ├── beijingHousePrice
│ │ ├── index.less
│ │ ├── index.tsx
│ │ └── legend.tsx
│ ├── californiaEarthquakes.md
│ ├── californiaEarthquakes
│ │ └── index.tsx
│ ├── californiaEarthquakesHeatmap.md
│ ├── californiaEarthquakesHeatmap
│ │ └── index.tsx
│ ├── countyUnemployment.md
│ ├── countyUnemployment
│ │ ├── index.tsx
│ │ └── utils.tsx
│ ├── highSpeedRail.md
│ ├── highSpeedRail
│ │ └── index.tsx
│ ├── highspeedTime.md
│ ├── highspeedTime
│ │ ├── index.tsx
│ │ └── mock.ts
│ ├── iconFontLayer.md
│ ├── iconFontLayer
│ │ └── index.tsx
│ ├── iconImage.md
│ ├── iconImage
│ │ └── index.tsx
│ ├── losAngelesHomes.md
│ ├── losAngelesHomes
│ │ └── index.tsx
│ ├── marineConservation.md
│ ├── marineConservation
│ │ ├── Legend.tsx
│ │ ├── constants.tsx
│ │ └── index.tsx
│ ├── meteoriteLanding.md
│ ├── meteoriteLanding
│ │ └── index.tsx
│ ├── nycCensus.md
│ ├── nycCensus
│ │ └── index.tsx
│ ├── photoHotmap.md
│ ├── photoHotmap
│ │ └── index.tsx
│ ├── photoSpots.md
│ ├── photoSpots
│ │ └── index.tsx
│ ├── poiChart.md
│ ├── poiChart
│ │ └── index.tsx
│ ├── sanFranciscoStreetTreeMap.md
│ ├── sanFranciscoStreetTreeMap
│ │ ├── config.ts
│ │ ├── index.less
│ │ └── index.tsx
│ ├── sfContour.md
│ ├── sfContour
│ │ └── index.tsx
│ ├── shareBike
│ │ └── index.tsx
│ ├── sharedBike.md
│ ├── taxiTrips.md
│ ├── taxiTrips
│ │ └── index.tsx
│ ├── topicLayer.md
│ ├── topicLayer
│ │ └── index.tsx
│ ├── ukcommute.md
│ ├── ukcommute
│ │ ├── constants.tsx
│ │ └── index.tsx
│ ├── worldHeritageListDataResources.md
│ └── worldHeritageListDataResources
│ │ └── index.tsx
├── guide
│ ├── design.md
│ ├── faq.md
│ └── index.md
└── index.md
├── jest.config.js
├── package.json
├── scripts
├── babel-less-to-css.js
├── father-plugin-less.js
├── loader-less-to-css.js
└── sync-version.js
├── src
├── components
│ ├── ContextMenu
│ │ ├── ContextMenuItem.tsx
│ │ ├── constant.ts
│ │ ├── demos
│ │ │ ├── custom.tsx
│ │ │ └── default.tsx
│ │ ├── index.less
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ ├── Control
│ │ ├── CustomControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── ExportImageControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── FullscreenControl
│ │ │ ├── demos
│ │ │ │ ├── antd.tsx
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── type.ts
│ │ ├── GeoLocateControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── type.ts
│ │ ├── LayerSwitchControl
│ │ │ ├── demos
│ │ │ │ ├── default.tsx
│ │ │ │ ├── layerSwitchItem.tsx
│ │ │ │ └── singleSelection.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── LogoControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── MapThemeControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── MouseLocationControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── ScaleControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── type.ts
│ │ ├── ZoomControl
│ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── hooks
│ │ │ ├── index.ts
│ │ │ ├── useL7ComponentEvent.ts
│ │ │ ├── useL7ComponentPortal.tsx
│ │ │ └── useL7ComponentUpdate.ts
│ │ └── index.ts
│ ├── Draw
│ │ ├── types.ts
│ │ ├── use-draw-group
│ │ │ ├── demos
│ │ │ │ ├── default.less
│ │ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── use-draw
│ │ │ ├── constant.ts
│ │ │ ├── demos
│ │ │ ├── control.tsx
│ │ │ └── default.tsx
│ │ │ ├── index.md
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ ├── LarkMap
│ │ ├── demos
│ │ │ └── default.tsx
│ │ ├── helper.ts
│ │ ├── hooks
│ │ │ ├── index.ts
│ │ │ ├── use-control
│ │ │ │ └── index.ts
│ │ │ ├── use-layer-list
│ │ │ │ ├── demos
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── use-layer-list.md
│ │ │ ├── use-layer-manager
│ │ │ │ └── index.ts
│ │ │ ├── use-layer
│ │ │ │ ├── demos
│ │ │ │ │ ├── constants.ts
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── use-layer.md
│ │ │ ├── use-scene-event
│ │ │ │ ├── constant.ts
│ │ │ │ └── index.ts
│ │ │ └── use-scene
│ │ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── use-scene.md
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ ├── LayerPopup
│ │ ├── demos
│ │ │ └── default.tsx
│ │ ├── index.md
│ │ ├── index.tsx
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── Layers
│ │ ├── BaseLayers
│ │ │ ├── HeatmapLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── ImageLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── LineLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── PointLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── PolygonLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── RasterLayer
│ │ │ │ ├── demos
│ │ │ │ │ ├── default.tsx
│ │ │ │ │ ├── rasterData.tsx
│ │ │ │ │ └── rasterImage.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ └── TextLayer
│ │ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ ├── CompositeLayers
│ │ │ ├── BubbleLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── ChoroplethLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── FlowLayer
│ │ │ │ ├── constants.ts
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── IconFontLayer
│ │ │ │ ├── demos
│ │ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ └── IconImageLayer
│ │ │ │ ├── demos
│ │ │ │ └── default.tsx
│ │ │ │ ├── index.md
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ ├── hooks
│ │ │ ├── index.ts
│ │ │ ├── use-create-layer
│ │ │ │ └── index.ts
│ │ │ └── use-layer-event
│ │ │ │ ├── constant.ts
│ │ │ │ └── index.ts
│ │ └── index.ts
│ ├── Legend
│ │ ├── LegendCategories
│ │ │ ├── demos
│ │ │ │ ├── default.tsx
│ │ │ │ └── map-default.tsx
│ │ │ ├── index.less
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── LegendIcon
│ │ │ ├── demos
│ │ │ │ ├── custom.tsx
│ │ │ │ ├── default.tsx
│ │ │ │ └── map-default.tsx
│ │ │ ├── index.less
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── LegendProportion
│ │ │ ├── demos
│ │ │ │ ├── default.tsx
│ │ │ │ ├── index.less
│ │ │ │ └── map-default.tsx
│ │ │ ├── index.less
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ └── LegendRamp
│ │ │ ├── demos
│ │ │ ├── default.tsx
│ │ │ └── map-default.tsx
│ │ │ ├── index.less
│ │ │ ├── index.md
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ ├── LocationSearch
│ │ ├── Select
│ │ │ ├── index.less
│ │ │ └── index.tsx
│ │ ├── constant.ts
│ │ ├── demos
│ │ │ └── default.tsx
│ │ ├── index.less
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ ├── Marker
│ │ ├── demos
│ │ │ ├── custom.tsx
│ │ │ └── default.tsx
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ ├── Popup
│ │ ├── demos
│ │ │ └── default.tsx
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ ├── RegionLocation
│ │ ├── constant.ts
│ │ ├── demos
│ │ │ └── default.tsx
│ │ ├── index.less
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ ├── SyncScene
│ │ ├── demos
│ │ │ ├── default.tsx
│ │ │ ├── defaultUtils.tsx
│ │ │ ├── multiScenes.tsx
│ │ │ └── zoomGap.tsx
│ │ ├── helper.ts
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
│ └── Template
│ │ ├── constant.ts
│ │ ├── demos
│ │ └── default.tsx
│ │ ├── helper.ts
│ │ ├── index.less
│ │ ├── index.md
│ │ ├── index.tsx
│ │ └── types.ts
├── index.ts
├── types
│ ├── common.ts
│ ├── control.ts
│ ├── index.ts
│ └── layer.ts
├── utils
│ ├── color.ts
│ ├── index.ts
│ ├── layer-manager.ts
│ ├── style.ts
│ └── url.ts
└── version.ts
├── tsconfig.json
└── typings.d.ts
/.browserslistrc:
--------------------------------------------------------------------------------
1 | last 2 versions
2 |
--------------------------------------------------------------------------------
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | rules: {
4 | 'type-enum': [
5 | 2,
6 | 'always',
7 | ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'deps', 'wip'],
8 | ],
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [Makefile]
16 | indent_style = tab
17 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # don't ever lint node_modules
2 | node_modules
3 | # don't lint build output (make sure it's set to your correct build folder name)
4 | dist
5 | es
6 | lib
7 | # don't lint nyc coverage output
8 | coverage
9 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: [
4 | require.resolve('@umijs/fabric/dist/eslint'),
5 | 'plugin:import/errors',
6 | 'plugin:import/warnings',
7 | 'plugin:import/typescript',
8 | ],
9 | rules: {
10 | '@typescript-eslint/no-empty-interface': 'warn',
11 | '@typescript-eslint/no-empty-function': 'warn',
12 | '@typescript-eslint/no-explicit-any': 'off',
13 | '@typescript-eslint/no-unused-vars': 'warn',
14 | 'import/no-unresolved': 'warn',
15 | 'import/order': 'warn',
16 | },
17 | env: {
18 | node: true,
19 | jest: true,
20 | },
21 | settings: {
22 | react: {
23 | version: 'detect',
24 | },
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/.fatherrc.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'father';
2 | import { IFatherBundlessConfig } from 'father/dist/types';
3 |
4 | const less2CssConfig: IFatherBundlessConfig = {
5 | transformer: 'babel', // 使用 babel 编译
6 | extraBabelPlugins: [
7 | [
8 | './scripts/babel-less-to-css.js', // 把文件中的 '.less' 字符转为 '.css'
9 | { test: '\\.less' },
10 | ],
11 | ],
12 | };
13 |
14 | export default defineConfig({
15 | esm: {
16 | output: 'es',
17 | ...less2CssConfig,
18 | },
19 | cjs: {
20 | output: 'lib',
21 | ...less2CssConfig,
22 | alias: {
23 | // lodash-es 不支持 cjs 产物,将打包产物修改为从 lodash 引入
24 | 'lodash-es': 'lodash',
25 | },
26 | },
27 | plugins: [
28 | // less 编译为 css
29 | './scripts/father-plugin-less.js',
30 | ],
31 | // https://github.com/umijs/father/blob/master/docs/config.md#umd
32 | umd: {
33 | name: 'LarkMap',
34 | output: 'dist',
35 | extractCSS: true,
36 | externals: {
37 | lodash: '_',
38 | 'lodash-es': '_',
39 | react: 'React',
40 | 'react-dom': 'ReactDOM',
41 | '@antv/l7': 'L7',
42 | '@antv/l7-draw': { root: ['L7', 'Draw'], commonjs2: '@antv/l7-draw', commonjs: '@antv/l7-draw' },
43 | },
44 | chainWebpack(memo) {
45 | memo
46 | .plugin('webpack-bundle-analyzer')
47 | .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [
48 | { analyzerMode: 'static', openAnalyzer: false },
49 | ]);
50 | return memo;
51 | },
52 | },
53 | });
54 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/----bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F41B Bug report"
3 | about: Create a report to help us improve
4 | title: "\U0001F41B [BUG]"
5 | labels: Bug
6 | assignees: ''
7 | ---
8 |
9 |
10 |
11 | ### 🐛 Bug description [Please make everyone to understand it]
12 |
13 | > Please provide a link by forking these links [LarkMap](https://codesandbox.io/s/larkmap-issue-template-c9m1hr) or GitHub repo, a minimal reproduction.
14 |
15 | - _Required_ **Link to minimal reproduction**:
16 |
17 | ### 📷 Step to reproduce
18 |
19 | ### 🏞 Expected result
20 |
21 | ### 🚑 Any additional [like screenshots]
22 |
23 | - **LarkMap Version**:
24 | - **Platform**:
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/---ask-for-question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F914 Ask for question"
3 | about: Look for some help or ask question
4 | title: "\U0001F914 [QUESTION]"
5 | labels: Question
6 | assignees: ''
7 | ---
8 |
9 | ### 🐛 Question description [Please make everyone to understand it]
10 |
11 | ### 💻 Link to minimal reproduction
12 |
13 | Please provide a link by forking these links [LarkMap](https://codesandbox.io/s/larkmap-issue-template-c9m1hr) or GitHub repo. What is a minimal reproduction, and why is it required?
14 |
15 | ### 🏞 Expected result
16 |
17 | ### 🚑 Any additional [like screenshots]
18 |
19 | - **LarkMap Version**:
20 | - **Platform**:
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/---feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F970 Feature request"
3 | about: Suggest an idea for this project
4 | title: "\U0001F970 [FEATURE]"
5 | labels: Feature
6 | assignees: ''
7 | ---
8 |
9 | ### 💻 Features description [Please make everyone to understand it]
10 |
11 | ### 🏞 What problem does this feature solve
12 |
13 | ### 🧐 What does the proposed API look like
14 |
15 | ### 🚑 Any additional [like screenshots]
16 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### PR includes
2 |
3 |
4 |
5 | - [ ] fixed #0
6 | - [ ] add / modify test cases
7 | - [ ] documents, demos
8 |
9 | ### Screenshot
10 |
11 | | Before | After |
12 | | ------ | ----- |
13 | | ❌ | ✅ |
14 |
--------------------------------------------------------------------------------
/.github/release.yaml:
--------------------------------------------------------------------------------
1 | # for .github/workflows/release-label.yml
2 |
3 | changelog:
4 | exclude:
5 | labels:
6 | - ignore-for-release
7 | - chore
8 | categories:
9 | - title: 🎉 New Features
10 | labels:
11 | - feature
12 | - enhancement
13 | - title: 📖 Documentation Changes
14 | labels:
15 | - documentation
16 | - title: 🐛 Bug Fixes
17 | labels:
18 | - bugfix
19 | - title: 🛠 Breaking Changes
20 | labels:
21 | - breaking
22 | - title: Other Changes
23 | labels:
24 | - "*"
25 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: lint
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches:
8 | - '**'
9 |
10 | jobs:
11 | lint:
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | node-version: [18.x]
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v2
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 | - run: npm install
23 | - run: npm run ci
24 | # - name: coverall
25 | # if: success()
26 | # uses: coverallsapp/github-action@master
27 | # with:
28 | # github-token: ${{ secrets.GITHUB_TOKEN }}
29 |
--------------------------------------------------------------------------------
/.github/workflows/preview.yml:
--------------------------------------------------------------------------------
1 | name: Surge PR Preview
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | preview:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | matrix:
10 | node-version: [18.x]
11 | steps:
12 | - uses: actions/checkout@v2
13 | - name: Use Node.js ${{ matrix.node-version }}
14 | uses: actions/setup-node@v2
15 | with:
16 | node-version: ${{ matrix.node-version }}
17 | - uses: afc163/surge-preview@v1
18 | with:
19 | surge_token: ${{ secrets.SURGE_TOKEN }}
20 | github_token: ${{ secrets.GITHUB_TOKEN }}
21 | dist: docs-dist
22 | build: |
23 | npm install
24 | npm run docs:build
25 |
--------------------------------------------------------------------------------
/.github/workflows/release-label.yml:
--------------------------------------------------------------------------------
1 | # Warning, do not check out untrusted code with
2 | # the pull_request_target event.
3 | on:
4 | pull_request_target:
5 | types: [ opened, edited ]
6 | name: conventional-release-labels
7 | jobs:
8 | label:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: bcoe/conventional-release-labels@v1
12 | with:
13 | token: ${{ secrets.GITHUB_TOKEN }}
14 | type_labels: '{"feat": "feature", "fix": "bugfix", "breaking": "breaking", "docs": "documentation", "chore": "chore"}'
15 |
--------------------------------------------------------------------------------
/.github/workflows/release-notify.yml:
--------------------------------------------------------------------------------
1 | name: DingTalk Release Notify
2 |
3 | on:
4 | workflow_dispatch:
5 | release:
6 | types: [published, edited]
7 |
8 | jobs:
9 | notify:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: visiky/dingtalk-release-notify@main
13 | with:
14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15 | DING_TALK_TOKEN: ${{ secrets.DING_TALK_TOKENS}}
16 | notify_title: '🎉 LarkMap 发布 release {release_tag} 🎉'
17 | notify_body: '## { title }
{ body }
'
18 | notify_footer: '前往 [**LarkMap Releases**]({ release_url }) 查看完整信息.'
19 | at_all: false
20 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: release
2 |
3 | on:
4 | workflow_dispatch:
5 | release:
6 | types: [created, edited]
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 | - uses: actions/setup-node@v2
14 | with:
15 | node-version: 18
16 | - run: npm install
17 | - run: npm run ci
18 |
19 | publish-site:
20 | needs: build
21 | runs-on: ubuntu-latest
22 | steps:
23 | - uses: actions/checkout@v2
24 | - uses: actions/setup-node@v2
25 | with:
26 | node-version: 18
27 | - run: npm install
28 | - run: npm run docs:build
29 | - run: |
30 | cd docs-dist
31 | git init
32 | git config --local user.name antv
33 | git config --local user.email antv@antfin.com
34 | git add .
35 | git commit -m "update by release action"
36 | - uses: ad-m/github-push-action@master
37 | with:
38 | github_token: ${{secrets.GITHUB_TOKEN}}
39 | directory: docs-dist
40 | branch: gh-pages
41 | force: true
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Sys
10 | .DS_STORE
11 | .idea
12 |
13 | # Node
14 | node_modules/
15 |
16 | # Build
17 | lib
18 | es
19 | dist
20 | docs-dist
21 |
22 | # Test
23 | coverage
24 |
25 | # Packages lock
26 | package-lock.json
27 | yarn.lock
28 | pnpm-lock.yaml
29 |
30 | # umi
31 | .umi
32 | .umi-production
33 | .umi-test
34 | .env.local
35 | .vscode
36 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx --no-install commitlint --edit "$1"
5 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | # lint-staged
5 | npx lint-staged
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | dist/report.html
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .**/**
2 |
3 | node_modules
4 | dist
5 | coverage
6 |
7 | package.json
8 | package-lock.json
9 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | const fabric = require('@umijs/fabric');
2 |
3 | module.exports = {
4 | ...fabric.prettier,
5 | printWidth: 120,
6 | };
7 |
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [require.resolve('@umijs/fabric/dist/stylelint')],
3 | rules: {},
4 | };
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2021 AntV
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/__tests__/version.spec.ts:
--------------------------------------------------------------------------------
1 | import { version } from '../src';
2 | import pkg from '../package.json';
3 |
4 | describe('version', () => {
5 | it('should match the `version` field of package.json', () => {
6 | const expected = pkg.version;
7 | expect(version).toBe(expected);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | larkmap.antv.vision
2 |
--------------------------------------------------------------------------------
/docs/blocks/administrative-select.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 3
4 | nav:
5 | title: 区块
6 | path: /blocks
7 | order: 4
8 | ---
9 |
10 | ## 城市联级选择器
11 |
12 | ### 介绍
13 |
14 | 用于快速查找中国省/市/县行政区域并快速定位的控件,基于 Ant Design 中的 [Cascader](https://ant-design.antgroup.com/components/cascader-cn#api) 组件封装而成
15 |
16 | ### 代码演示
17 |
18 | #### 默认示例
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | autoFit | 是否控制地图自动平移到选项对应行政区域 | `boolean` | `true` |
27 | | enableBoundary | 是否在地图上展示行政区域边界 | `boolean` | `true` |
28 | | boundaryLayer | 边界线图层属性,可参考 [LineLayerProps](https://larkmap.antv.antgroup.com/components/layers/base-layers/line-layer#api) | `Omit` | `--` |
29 |
30 | 其他参数可以参照 [Ant Design 5.0 Cascader](https://ant-design.antgroup.com/components/cascader-cn#api)
31 |
--------------------------------------------------------------------------------
/docs/blocks/administrative-select/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps } from '@antv/larkmap';
2 | import { CustomControl, LarkMap } from '@antv/larkmap';
3 | import React from 'react';
4 | import { AdministrativeSelect } from '../administrative-select';
5 |
6 | const config: LarkMapProps = {
7 | mapType: 'Gaode',
8 | mapOptions: {
9 | style: 'light',
10 | center: [120.210792, 30.246026],
11 | zoom: 9,
12 | },
13 | };
14 |
15 | export default () => {
16 | return (
17 |
18 |
19 |
20 |
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/docs/blocks/draw-modal/constants.ts:
--------------------------------------------------------------------------------
1 | import type { DrawType } from '@antv/l7-draw/es/control/types';
2 | import type { DrawGroupData } from '@antv/larkmap';
3 | import type { Feature, Polygon } from 'geojson';
4 |
5 | export const CLS_PREFIX = 'larkmap-draw-modal';
6 |
7 | export const DRAW_ICON_TYPE_MAP: Record = {
8 | point: 'l7draw-point',
9 | line: 'l7draw-line',
10 | polygon: 'l7draw-polygon',
11 | rect: 'l7draw-rect',
12 | circle: 'l7draw-circle',
13 | };
14 |
15 | export const DRAW_TEXT_TYPE_MAP: Record = {
16 | point: '绘制点',
17 | line: '绘制线',
18 | polygon: '绘制面',
19 | rect: '绘制矩形',
20 | circle: '绘制圆',
21 | };
22 |
23 | export const DEFAULT_DRAW_DATA: DrawGroupData = {
24 | circle: [],
25 | line: [],
26 | point: [],
27 | polygon: [],
28 | rect: [],
29 | };
30 |
31 | export const DEFAULT_POLYGON_FEATURE: Feature = {
32 | type: 'Feature',
33 | properties: {},
34 | geometry: {
35 | type: 'Polygon',
36 | coordinates: [
37 | [
38 | [120.138761, 30.25156],
39 | [120.140241, 30.251803],
40 | [120.141412, 30.252336],
41 | [120.140802, 30.253083],
42 | [120.14229, 30.253511],
43 | [120.144149, 30.253709],
44 | [120.144584, 30.253561],
45 | [120.145593, 30.252685],
46 | [120.146464, 30.252505],
47 | [120.145852, 30.251835],
48 | [120.144858, 30.250632],
49 | [120.144546, 30.250363],
50 | [120.144338, 30.25039],
51 | [120.141746, 30.249919],
52 | [120.14128, 30.249983],
53 | [120.139795, 30.249946],
54 | [120.139311, 30.250069],
55 | [120.138722, 30.25033],
56 | [120.138761, 30.25156],
57 | ],
58 | ],
59 | },
60 | };
61 |
--------------------------------------------------------------------------------
/docs/blocks/draw-modal/default.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Input } from 'antd';
2 | import type { Feature } from 'geojson';
3 | import React, { useMemo, useState } from 'react';
4 | import { DrawModal } from './DrawModal';
5 |
6 | const Default: React.FC = () => {
7 | const [featureList, setFeatureList] = useState([]);
8 | const [visible, setVisible] = useState(false);
9 | const text = useMemo(() => {
10 | return JSON.stringify(featureList);
11 | }, [featureList]);
12 |
13 | return (
14 | <>
15 | {
25 | setFeatureList(
26 | Object.values(drawData)
27 | .flat()
28 | .map((feature) => {
29 | feature.properties = {};
30 | return feature;
31 | }),
32 | );
33 | setVisible(false);
34 | }}
35 | onCancel={() => {
36 | setVisible(false);
37 | }}
38 | locationSearchProps={{
39 | searchParams: {
40 | key: '4892acc9f825e343bcf1e25a56199826',
41 | location: '',
42 | },
43 | }}
44 | />
45 |
46 |
53 |
54 |
55 | >
56 | );
57 | };
58 |
59 | export default Default;
60 |
--------------------------------------------------------------------------------
/docs/blocks/draw-modal/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-draw-modal;
2 |
3 | .@{cls-prefix} {
4 | &__btn-group {
5 | display: flex;
6 | flex-direction: column;
7 | align-items: flex-start;
8 | .ant-btn {
9 | display: inline-flex;
10 | align-items: center;
11 | margin-bottom: 8px;
12 | .anticon {
13 | width: 18px;
14 | height: 18px;
15 | transform: scale(1.3);
16 | }
17 | &:hover .anticon {
18 | fill: #1990ff;
19 | }
20 | &.ant-btn-primary .anticon {
21 | fill: #fff;
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/blocks/draw-modal/types.ts:
--------------------------------------------------------------------------------
1 | import type { DrawGroupData, LarkMapProps, LocationSearchProps, UseDrawGroupConfig } from '@antv/larkmap';
2 | import type { ModalProps } from 'antd';
3 |
4 | export interface DrawModalProps extends Omit {
5 | /**
6 | * 地图部分配置
7 | */
8 | larkmapProps?: LarkMapProps;
9 | /**
10 | * 支持的绘制类型及其配置
11 | */
12 | drawConfig?: UseDrawGroupConfig;
13 | /**
14 | * 是否开启地点搜索框,以及搜索框的配置
15 | */
16 | locationSearchProps?: LocationSearchProps | false;
17 | /**
18 | * 点击弹框提交按钮时的回调函数
19 | * @param drawData
20 | */
21 | onOk: (drawData: DrawGroupData) => void;
22 | }
23 |
--------------------------------------------------------------------------------
/docs/blocks/layer-attribute/bubble-layer-style-attribute/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 1
4 | group:
5 | title: 属性面板
6 | order: 9
7 | nav:
8 | title: 区块
9 | path: /blocks
10 | order: 3
11 | ---
12 |
13 | ## 气泡图层样式属性面板
14 |
15 | ### 介绍
16 |
17 | [气泡图层 - BubbleLayer](/components/layers/composite-layers/bubble-layer) 的样式属性配置组件,用于图层配置可视化场景。
18 |
19 | ### 代码演示
20 |
21 | #### 默认示例
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/blocks/layer-attribute/choropleth-layer-style-attribute/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 2
4 | group:
5 | title: 属性面板
6 | order: 9
7 | nav:
8 | title: 区块
9 | path: /blocks
10 | order: 3
11 | ---
12 |
13 | ## 区域图层样式属性面板
14 |
15 | ### 介绍
16 |
17 | [区域图层 - ChoroplethLayer](/components/layers/composite-layers/choropleth-layer) 的样式属性配置组件,用于图层配置可视化场景。
18 |
19 | ### 代码演示
20 |
21 | #### 默认示例
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/blocks/layer-attribute/heatmap-layer-style-attribute/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 3
4 | group:
5 | title: 属性面板
6 | order: 9
7 | nav:
8 | title: 区块
9 | path: /blocks
10 | order: 3
11 | ---
12 |
13 | ## 热力图层样式属性面板
14 |
15 | ### 介绍
16 |
17 | [热力图层 - HeatmapLayer](/components/layers/base-layers/heatmap-layer) 的样式属性配置组件,用于图层配置可视化场景。
18 |
19 | ### 代码演示
20 |
21 | #### 默认示例
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/blocks/layer-attribute/line-layer-style-attribute/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 4
4 | group:
5 | title: 属性面板
6 | order: 9
7 | nav:
8 | title: 区块
9 | path: /blocks
10 | order: 3
11 | ---
12 |
13 | ## 线图层样式属性面板
14 |
15 | ### 介绍
16 |
17 | [线图层 - LineLayer](/components/layers/base-layers/line-layer) 的样式属性配置组件,用于图层配置可视化场景。
18 |
19 | ### 代码演示
20 |
21 | #### 默认示例
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/common/layer/attribute/color.md:
--------------------------------------------------------------------------------
1 | `string|ColorStyleAttribute|Function` optional default: `'#5FD3A6'`
2 |
3 | 元素颜色。
4 |
5 | ```js
6 | { color: 'red', }
7 | ```
8 |
9 | #### `color.`field
10 |
11 | `string` optional
12 |
13 | 元素颜色值映射关联字段。
14 |
15 | ```js
16 | {
17 | source: {
18 | data: [{ c: 'red', t: 20, n: 'chengdu' }],
19 | // ...
20 | },
21 | color: { field: 'c', }
22 | }
23 | ```
24 |
25 | #### `color.`value
26 |
27 | `string|string[]|Function` optional
28 |
29 | 元素颜色值映射值。
30 |
31 | ```js
32 | {
33 | color: {
34 | field: 't',
35 | value: ({ t }) => {
36 | return t > 20 ? 'red': 'blue'
37 | }
38 | }
39 | }
40 | ```
41 |
42 | #### `color.`scale
43 |
44 |
45 |
46 | ```js
47 | {
48 | color: {
49 | field: 't',
50 | value: ['#B8E1FF', '#7DAAFF', '#3D76DD', '#0047A5', '#001D70'],
51 | scale: { type: 'quantile' }
52 | }
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/docs/common/layer/attribute/scale.md:
--------------------------------------------------------------------------------
1 | ---
2 | hide: true
3 | ---
4 |
5 | `ScaleConfig` optional default: `{}`
6 |
7 | 关联字段的映射 scale 类型,有以下 scale 类型:
8 |
9 | - linear:线性
10 | - power:指数
11 | - log:对数
12 | - quantile:等分位
13 | - quantize:等间距
14 | - cat:枚举
15 |
--------------------------------------------------------------------------------
/docs/common/layer/attribute/size.md:
--------------------------------------------------------------------------------
1 | `number|SizeStyleAttribute|Function` optional
2 |
3 | 元素大小。
4 |
5 | ```js
6 | { size: 12, }
7 | ```
8 |
9 | #### `size.`field
10 |
11 | `string` optional
12 |
13 | 元素大小值映射关联字段。
14 |
15 | ```js
16 | {
17 | source: {
18 | data: [{ s: 12, t: 20, n: 'chengdu' }],
19 | // ...
20 | },
21 | size: { field: 's' },
22 | }
23 | ```
24 |
25 | #### `size.`value
26 |
27 | `number|number[]|Function` optional
28 |
29 | 元素大小值映射值。
30 |
31 | ```js
32 | {
33 | size: {
34 | field: 't',
35 | value: ({ t }) => {
36 | return t > 20 ? 15 : 12
37 | }
38 | }
39 | }
40 | ```
41 |
42 | #### `size.`scale
43 |
44 |
45 |
46 | ```js
47 | {
48 | size: {
49 | field: 't',
50 | value: [12, 15],
51 | scale: { type: 'quantile' },
52 | }
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/docs/common/layer/attribute/state.md:
--------------------------------------------------------------------------------
1 | `StateAttribute` optional
2 |
3 | 元素交互反馈效果。
4 |
5 | #### `state.`active
6 |
7 | `boolean|ActiveOption` optional default: `false`
8 |
9 | 标签 mousehover 高亮效果,开启 mousehover 元素高亮效果:
10 |
11 | ```js
12 | {
13 | state: { active: true, }
14 | }
15 | ```
16 |
17 | 开启 mousehover 元素高亮效果并自定义设置高亮颜色:
18 |
19 | ```js
20 | {
21 | state: {
22 | active: { color: 'red', }
23 | }
24 | }
25 | ```
26 |
27 | #### `state.`select
28 |
29 | `boolean|ActiveOption` optional default: `false`
30 |
31 | 元素 mouseclick 选中高亮效果,开启 mouseclick 元素高亮效果:
32 |
33 | ```js
34 | {
35 | state: { select: true, }
36 | }
37 | ```
38 |
39 | 开启 mousehover 元素高亮效果并自定义设置高亮颜色:
40 |
41 | ```js
42 | {
43 | state: {
44 | select: { color: 'red', }
45 | }
46 | }
47 | ```
48 |
--------------------------------------------------------------------------------
/docs/common/layer/composite-common/event.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/common/layer/heatmap-layer/shape.md:
--------------------------------------------------------------------------------
1 | `string` optional default: `'heatmap'`
2 |
3 | 支持三种热力类型,普通热力模式支持 2D 与 3D 热力:
4 |
5 | - heatmap
6 | - heatmap3D
7 |
8 | 蜂窝热力支持:
9 |
10 | - hexagon: 蜂窝
11 | - hexagonColumn: 蜂窝柱
12 |
13 | 网格热力支持:
14 |
15 | - 2D
16 | - circle: 圆形
17 | - square: 正方形
18 | - hexagon: 六边形
19 | - triangle: 三角形
20 | - 3D
21 | - cylinder: 圆柱
22 | - triangleColumn: 三角形柱
23 | - hexagonColumn: 六角形柱
24 | - squareColumn: 方柱
25 |
26 | ```js
27 | { shape: 'heatmap', }
28 | ```
29 |
--------------------------------------------------------------------------------
/docs/common/layer/heatmap-layer/size.md:
--------------------------------------------------------------------------------
1 | ### `options.`size
2 |
3 | `number|SizeStyleAttribute|Function` optional
4 |
5 | 当 shape 为普通热力(heatmap、heatmap3D)时,size 代表热力大小,配置如下:
6 |
7 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
8 | | ----- | -------------------- | -------------------- | -------- | -------- |
9 | | field | 热力大小映射字段 | `string` | | required |
10 | | value | 热力大小数据映射区间 | `number[]|Function` | `[0, 1]` | optional |
11 |
12 | ```js
13 | {
14 | source: {
15 | data: [{ lng: 104.101, lat: 30.649, t: 24.6, n: 'chengdu' }],
16 | parser: { type: 'json', x: 'lng', y: 'lat' }
17 | },
18 | size: {
19 | field: 't',
20 | value: [0, 1],
21 | },
22 | }
23 | ```
24 |
25 | 当 shape 为 3D 网格/蜂窝热力时,size 表示高度,shape 为 2D 时,size 无需设置
26 |
27 | ```js
28 | {
29 | size: {
30 | field: 'value',
31 | value: ({ value }) => value * 2
32 | }
33 | }
34 | ```
35 |
36 | #### `size.`field
37 |
38 | `string` required
39 |
40 | 网格大小映射字段。
41 |
42 | #### `size.`value
43 |
44 | `number|number[]|Function` optional
45 |
46 | 网格大小值映射值。
47 |
48 | #### `size.`scale
49 |
50 |
51 |
--------------------------------------------------------------------------------
/docs/common/layer/heatmap-layer/style.md:
--------------------------------------------------------------------------------
1 | `HeatmapLayerStyleOptions|GridHeatmapLayerStyleOptions` optional
2 |
3 | 普通热力样式,HeatmapLayerStyleOptions 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ---------- | ------------------ | ------------ | ------ | -------- |
7 | | intensity | 全局热力权重 | `number` | `3` | optional |
8 | | radius | 热力半径,单位像素 | `number` | `20` | optional |
9 | | opacity | 透明度 | `number` | `1` | optional |
10 | | rampColors | 热力色带 | `RampColors` | | optional |
11 |
12 | 热力色带,RampColors 配置如下:
13 |
14 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
15 | | --------- | ---------- | ---------- | ------ | -------- |
16 | | colors | 颜色 | `string[]` | | required |
17 | | positions | 热力映射值 | `number[]` | | required |
18 |
19 | ```js
20 | {
21 | style: {
22 | intensity: 3,
23 | radius: 20,
24 | opacity: 1,
25 | rampColors: {
26 | colors: ['#FF4818', '#F7B74A', '#FFF598', '#F27DEB', '#8C1EB2', '#421EB2'],
27 | positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
28 | },
29 | }
30 | }
31 | ```
32 |
33 | 网格/蜂窝热力样式,GridHeatmapLayerStyleOptions 配置如下:
34 |
35 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
36 | | -------- | ----------------------- | -------- | ------ | -------- |
37 | | opacity | 透明度 | `number` | `1` | optional |
38 | | coverage | 覆盖度,范围 0 到 1 | `string` | `0.9` | optional |
39 | | angle | 旋转角度,范围 0 到 360 | `number` | `0` | optional |
40 |
41 | ```js
42 | {
43 | style: {
44 | coverage: 0.9,
45 | angle: 0,
46 | opacity: 1.0,
47 | }
48 | }
49 | ```
50 |
--------------------------------------------------------------------------------
/docs/common/layer/image-layer/source.md:
--------------------------------------------------------------------------------
1 | `SourceOptions` required
2 |
3 | 数据配置,详见 source [文档](https://l7plot.antv.antgroup.com/zh/docs/api/source)
4 |
5 | ```js
6 | {
7 | source: {
8 | data: 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',
9 | parser: {
10 | type: 'image',
11 | extent: [121.168, 30.2828, 121.384, 30.4219],
12 | },
13 | },
14 | }
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/common/layer/image-layer/style.md:
--------------------------------------------------------------------------------
1 | `ImageLayerStyleOptions` optional
2 |
3 | 元素样式, ImageLayerStyleOptions 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ------- | ------ | -------- | ------ | -------- |
7 | | opacity | 透明度 | `number` | `1` | optional |
8 |
9 | ```js
10 | {
11 | style: {
12 | opacity: 0.8,
13 | }
14 | }
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/common/layer/line-layer/animate.md:
--------------------------------------------------------------------------------
1 | `boolean|AnimateAttr` optional
2 |
3 | 水波动画,AnimateAttr 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ----------- | ------------------------ | --------- | ------- | -------- |
7 | | enable | 是否开启动画 | `boolean` | `false` | optional |
8 | | interval | 轨迹间隔, 取值区间 0 - 1 | `number` | | optional |
9 | | duration | 动画时间,单位秒 | `number` | | optional |
10 | | trailLength | 轨迹长度 取值区间 0 - 1 | `number` | | optional |
11 |
12 | ```js
13 | {
14 | animate: {
15 | duration: 4,
16 | interval: 0.2,
17 | trailLength: 0.1,
18 | }
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/docs/common/layer/line-layer/shape.md:
--------------------------------------------------------------------------------
1 | `string` optional default: `'line'`
2 |
3 | 除直线外还支持 2D 与 3D 弧线及大圆航线:
4 |
5 | - arc
6 | - arc3d
7 | - greatcircle
8 |
9 | ```js
10 | { shape: 'line', }
11 | ```
12 |
--------------------------------------------------------------------------------
/docs/common/layer/line-layer/source.md:
--------------------------------------------------------------------------------
1 | `SourceOptions` required
2 |
3 | 数据配置,详见 source [文档](https://l7plot.antv.antgroup.com/zh/docs/api/source)
4 |
5 | ```js
6 | {
7 | source: {
8 | data: [{
9 | path: [[58.00, 32.84],[85.7, 25.161],[101.95, 41.77],[114.96, 39.63],[117.421, 28.61]],
10 | c: 'red',
11 | t: 20,
12 | n: 'chengdu'
13 | }],
14 | parser: { type: 'json', coordinates: 'path', }
15 | }
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/docs/common/layer/line-layer/style.md:
--------------------------------------------------------------------------------
1 | `LineLayerStyleOptions` optional
2 |
3 | 线样式,LineLayerStyleOptions 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ----------- | ---------------------- | ------------------ | ------- | -------- |
7 | | opacity | 透明度 | `number` | `1` | optional |
8 | | lineType | 线类型,支持实线与虚线 | `‘solid’|'dash'` | ‘solid’ | optional |
9 | | dashArray | 虚线间隔 | `[number, number]` | | optional |
10 | | sourceColor | 渐变起点颜色 | `string` | | optional |
11 | | targetColor | 渐变终点颜色 | `string` | | optional |
12 |
13 | > dashArray: 虚线间隔,第一个值为虚线每个分段的长度,第二个值为分段间隔的距离。dashArray 设为 `[0,0]` 的效果为没有虚线。
14 |
15 | ```js
16 | {
17 | style: {
18 | opacity: 0.8,
19 | lineType: 'dash',
20 | dashArray: [2, 2],
21 | }
22 | }
23 | ```
24 |
--------------------------------------------------------------------------------
/docs/common/layer/point-layer/animate.md:
--------------------------------------------------------------------------------
1 | `boolean|AnimateAttr` optional
2 |
3 | 水波动画,AnimateAttr 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ------ | ------------ | --------- | ------- | -------- |
7 | | enable | 是否开启动画 | `boolean` | `false` | optional |
8 | | speed | 水波速度 | `number` | | optional |
9 | | rings | 水波环数 | `number` | | optional |
10 |
--------------------------------------------------------------------------------
/docs/common/layer/point-layer/source.md:
--------------------------------------------------------------------------------
1 | `SourceOptions` required
2 |
3 | 数据配置,详见 source [文档](https://l7plot.antv.antgroup.com/zh/docs/api/source)
4 |
5 | ```js
6 | {
7 | source: {
8 | data: [{ lng: 104.101, lat: 30.649, c: 'red', t: 20, n: 'chengdu' }],
9 | parser: { type: 'json', x: 'lng', y: 'lat' }
10 | },
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/docs/common/layer/point-layer/style.md:
--------------------------------------------------------------------------------
1 | `PointLayerStyleOptions` optional
2 |
3 | 元素样式, PointLayerStyleOptions 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ----------- | ------------ | -------- | ------ | -------- |
7 | | opacity | 透明度 | `number` | `1` | optional |
8 | | stroke | 边线填充颜色 | `string` | | optional |
9 | | strokeWidth | 描边的宽度 | `number` | | optional |
10 |
11 | ```js
12 | {
13 | style: {
14 | opacity: 0.8,
15 | stroke: 'white',
16 | strokeWidth: 2,
17 | }
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/docs/common/layer/polygon-layer/shape.md:
--------------------------------------------------------------------------------
1 | `string` optional default: `'fill'`
2 |
3 | 内置两种 shape:
4 |
5 | - 2D 填充面:`'fill'`
6 | - 3D 立方体:`'extrude'`
7 |
--------------------------------------------------------------------------------
/docs/common/layer/polygon-layer/source.md:
--------------------------------------------------------------------------------
1 | `SourceOptions` required
2 |
3 | 数据配置,详见 source [文档](https://l7plot.antv.antgroup.com/zh/docs/api/source)
4 |
5 | ```js
6 | const data = {
7 | type: 'FeatureCollection',
8 | features: [
9 | {
10 | type: 'Feature',
11 | properties: { name: '上海市', code: 310000, c: 'red', t: 20 },
12 | geometry: {
13 | type: 'Polygon',
14 | coordinates: [
15 | [
16 | [115.1806640625, 30.637912028341123],
17 | [114.9609375, 29.152161283318915],
18 | [117.79541015625001, 27.430289738862594],
19 | [118.740234375, 29.420460341013133],
20 | [117.46582031249999, 31.50362930577303],
21 | [115.1806640625, 30.637912028341123],
22 | // ......
23 | ],
24 | ],
25 | },
26 | },
27 | ],
28 | };
29 | ```
30 |
31 | ```js
32 | {
33 | source: {
34 | data,
35 | parser: { type: 'geojson' }
36 | }
37 | }
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/common/layer/polygon-layer/style.md:
--------------------------------------------------------------------------------
1 | `PolygonLayerStyleOptions` optional
2 |
3 | 区域样式,PolygonLayerStyleOptions 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ------- | ------ | -------- | ------ | -------- |
7 | | opacity | 透明度 | `number` | `1` | optional |
8 |
9 | ```js
10 | {
11 | style: {
12 | opacity: 0.8,
13 | }
14 | }
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/common/layer/raster-layer/style.md:
--------------------------------------------------------------------------------
1 | `RasterImageTileLayerStyleOptions|RasterDataTileLayerStyleOptions` optional
2 |
3 | 栅格图层的图片栅格瓦片样式, `RasterImageTileLayerStyleOptions` 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | ------- | ------ | -------- | ------ | -------- |
7 | | opacity | 透明度 | `number` | `1` | optional |
8 |
9 | ```js
10 | {
11 | style: {
12 | opacity: 0.8,
13 | }
14 | }
15 | ```
16 |
17 | 栅格图层的数据栅格瓦片样式, `RasterDataTileLayerStyleOptions` 配置如下:
18 |
19 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
20 | | ----------- | ---------------------------- | ------------------ | ---------- | -------- |
21 | | opacity | 透明度 | `number` | `1` | optional |
22 | | domain | 定义域 | `[number, number]` | `[0, 1]` | optional |
23 | | noDataValue | 默认空数据 | `number` | `-9999999` | optional |
24 | | clampLow | 是否显示数值小于定义域的内容 | `number` | `true` | optional |
25 | | clampHigh | 是否显示数值大于定义域的内容 | `number` | `true` | optional |
26 | | rampColors | 值域色带 | `IColorRamp` | | required |
27 |
28 | 值域色带,IColorRamp 配置如下:
29 |
30 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
31 | | --------- | ---------- | ---------- | ------ | -------- |
32 | | colors | 颜色 | `string[]` | | required |
33 | | positions | 热力映射值 | `number[]` | | required |
34 |
35 | ```js
36 | {
37 | style: {
38 | opacity: 0.8,
39 | domain: [0, 2000],
40 | rampColors: {
41 | colors: [
42 | '#FF4818',
43 | '#F7B74A',
44 | '#FFF598',
45 | '#91EABC',
46 | '#2EA9A1',
47 | '#206C7C',
48 | ].reverse(),
49 | positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
50 | },
51 | }
52 | }
53 | ```
54 |
--------------------------------------------------------------------------------
/docs/common/layer/text-layer/style.md:
--------------------------------------------------------------------------------
1 | `TextLayerStyleOptions` optional
2 |
3 | 字体样式,TextLayerStyleOptions 配置如下:
4 |
5 | | 属性 | 描述 | 类型 | 默认值 | 是否必填 |
6 | | --- | --- | --- | --- | --- |
7 | | fill | 字体颜色 | `ColorAttr` | `'#fff'` | optional |
8 | | fontSize | 字体大小 | `SizeAttr` | `12` | optional |
9 | | opacity | 文字透明度 | `number` | `1` | optional |
10 | | stroke | 文字描边颜色 | `string` | `'#fff'` | optional |
11 | | strokeWidth | 文字描边宽度 | `number` | `0` | optional |
12 | | strokeOpacity | 文字描边透明度 | `number` | `1` | optional |
13 | | fontFamily | 文字字体 | `string` | | optional |
14 | | fontWeight | 字体粗细程度 | `string` | | optional |
15 | | textAllowOverlap | 是否允许文本覆盖 | `boolean` | `false` | optional |
16 | | textAnchor | 文本相对锚点的位置 | `string` | `'center'` | optional |
17 | | textOffset | 文本相对锚点的偏移量 | `number[]` | `[0, 0]` | optional |
18 | | spacing | 字符间距 | `number` | `0` | optional |
19 | | padding | 文本包围盒 padding (水平,垂直),影响碰撞检测结果,避免相邻文本靠的太近 | `number[]` | `[4, 4]` | optional |
20 |
21 | textAnchor 文本相对锚点的位置,支持以下相对锚点的位置:
22 |
23 | - 'right'
24 | - 'top-right'
25 | - 'left'
26 | - 'bottom-right'
27 | - 'left'
28 | - 'top-left'
29 | - 'bottom-left'
30 | - 'bottom'
31 | - 'bottom-right'
32 | - 'bottom-left'
33 | - 'top'
34 | - 'top-right'
35 | - 'top-left'
36 | - 'center'
37 |
--------------------------------------------------------------------------------
/docs/examples/beijingHousePrice.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 22
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 北京房价数据
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/beijingHousePrice/index.less:
--------------------------------------------------------------------------------
1 | .circle {
2 | width: 12px;
3 | height: 12px;
4 | margin-right: 10px;
5 | border-radius: 50%;
6 | }
7 |
--------------------------------------------------------------------------------
/docs/examples/californiaEarthquakes.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 12
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 加利福尼亚地震
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/californiaEarthquakesHeatmap.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 23
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 加利福尼亚地震 3D 热力图
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/californiaEarthquakesHeatmap/index.tsx:
--------------------------------------------------------------------------------
1 | import type { HeatmapLayerProps, LarkMapProps } from '@antv/larkmap';
2 | import { HeatmapLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const heatmapLayerOptions: Omit = {
6 | size: { field: 'Magnitude', value: [0, 1] },
7 | shape: 'heatmap3D',
8 | style: {
9 | intensity: 5,
10 | radius: 10,
11 | opacity: 1.0,
12 | rampColors: {
13 | colors: ['#2E8AE6', '#69D1AB', '#DAF291', '#FFD591', '#FF7A45', '#CF1D49'],
14 | positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
15 | },
16 | },
17 | };
18 |
19 | const config: LarkMapProps = {
20 | mapType: 'Gaode',
21 | mapOptions: {
22 | style: 'dark',
23 | zoom: 5,
24 | center: [-122.80009283836715, 37.05881309947238],
25 | pitch: 10,
26 | },
27 | };
28 |
29 | export default () => {
30 | const [pointData, SetPointData] = useState({
31 | data: [],
32 | parser: { type: 'json', x: 'Longitude', y: 'Latitude' },
33 | });
34 |
35 | useEffect(() => {
36 | fetch('https://gw.alipayobjects.com/os/bmw-prod/141ea8df-e674-4ce4-ac91-ee619f411e36.json')
37 | .then((res) => res.json())
38 | .then((data) => {
39 | SetPointData({ ...pointData, data: data });
40 | });
41 | }, []);
42 |
43 | return (
44 |
45 |
46 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/docs/examples/countyUnemployment.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 07
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 2017 年美国各城市失业率
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/countyUnemployment/utils.tsx:
--------------------------------------------------------------------------------
1 | export const colorList = [
2 | '#fff7f3',
3 | '#fde0dd',
4 | '#fcc5c0',
5 | '#fa9fb5',
6 | '#f768a1',
7 | '#dd3497',
8 | '#ae017e',
9 | '#7a0177',
10 | '#49006a',
11 | ];
12 |
--------------------------------------------------------------------------------
/docs/examples/highSpeedRail.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 1
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 高铁站点
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/highspeedTime.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 2
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 郑州高铁直达各省份时间
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/iconFontLayer.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 24
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 各地天气标注
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/iconImage.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 25
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 北京房价视觉分布
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/losAngelesHomes.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 17
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 洛杉矶房屋价值
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/marineConservation.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 3
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 中国海洋保护区在线地图
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/marineConservation/Legend.tsx:
--------------------------------------------------------------------------------
1 | import { CustomControl, LegendCategories } from '@antv/larkmap';
2 | import React from 'react';
3 | import { legendItems } from './constants';
4 |
5 | const Legend = () => {
6 | return (
7 |
8 | item.color)}
11 | labels={legendItems.map((item) => item.label)}
12 | />
13 |
14 | );
15 | };
16 |
17 | export default Legend;
18 |
--------------------------------------------------------------------------------
/docs/examples/marineConservation/constants.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps, PointLayerProps } from '@antv/larkmap';
2 |
3 | const legendItems = [
4 | {
5 | label: '水产种质资源保护区',
6 | color: '#4092ff',
7 | value: 'Aquatic Germplasm Reserve',
8 | },
9 | {
10 | label: '海洋自然保护区',
11 | color: '#ff3e3e',
12 | value: 'Marine Nature Reserves',
13 | },
14 | { label: '海洋公园', color: '#ffd94b', value: 'Marine Park' },
15 | {
16 | label: '特别海洋保护区',
17 | color: '#f137ff',
18 | value: 'Special Marine Protected Areas',
19 | },
20 | ];
21 |
22 | const config: LarkMapProps = {
23 | mapType: 'Gaode',
24 | mapOptions: {
25 | style: 'dark',
26 | center: [110.481623, 38.068625],
27 | zoom: 3.05,
28 | },
29 | };
30 |
31 | const layerConfig: Omit = {
32 | autoFit: false,
33 | shape: 'circle',
34 | blend: 'normal',
35 | color: {
36 | field: 'Type',
37 | // @ts-ignore
38 | value: ({ Type }) => {
39 | const typeItem = legendItems.find((item) => {
40 | return item.value === Type;
41 | });
42 | return typeItem?.color ?? '#808A87';
43 | },
44 | },
45 | size: {
46 | field: 'Area',
47 | // @ts-ignore
48 | value: ({ Area }) => {
49 | return 4 + Number(Area) / 1000;
50 | },
51 | },
52 | highlightColor: '#f00',
53 | state: {
54 | active: true,
55 | },
56 | style: {
57 | opacity: 1,
58 | stroke: '#fff',
59 | strokeWidth: 0.2,
60 | },
61 | };
62 |
63 | export { legendItems, config, layerConfig };
64 |
--------------------------------------------------------------------------------
/docs/examples/marineConservation/index.tsx:
--------------------------------------------------------------------------------
1 | import type { PointLayerProps } from '@antv/larkmap';
2 | import { LarkMap, LayerPopup, PointLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 | import { config, layerConfig } from './constants';
5 | import Legend from './Legend';
6 |
7 | export default () => {
8 | const [source, setSource] = useState({
9 | data: [] as any,
10 | parser: { type: 'json' },
11 | });
12 |
13 | useEffect(() => {
14 | fetch('https://gw.alipayobjects.com/os/bmw-prod/b056dc66-1d43-4167-a11e-9d0ada9cfec8.csv')
15 | .then((res) => res.text())
16 | .then((data) => {
17 | setSource({
18 | data,
19 | parser: { type: 'csv', x: 'Longitude', y: 'Latitude' },
20 | });
21 | });
22 | }, []);
23 |
24 | return (
25 |
26 |
27 |
28 |
29 |
30 | `${value}(km²)`,
47 | },
48 | ],
49 | },
50 | ]}
51 | trigger="hover"
52 | />
53 |
54 | );
55 | };
56 |
--------------------------------------------------------------------------------
/docs/examples/meteoriteLanding.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 18
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 全球陨石着地区域
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/meteoriteLanding/index.tsx:
--------------------------------------------------------------------------------
1 | import type { HeatmapLayerProps, LarkMapProps } from '@antv/larkmap';
2 | import { HeatmapLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const config: LarkMapProps = {
6 | mapType: 'Gaode',
7 | mapOptions: {
8 | style: 'normal',
9 | center: [48.6, 38],
10 | zoom: 0,
11 | },
12 | };
13 |
14 | const layerOptions: Omit = {
15 | autoFit: true,
16 | shape: 'heatmap',
17 | size: {
18 | field: 'year',
19 | value: [0, 1],
20 | },
21 | style: {
22 | intensity: 3,
23 | radius: 10,
24 | opacity: 1,
25 | rampColors: {
26 | colors: ['#FF4818', '#F7B74A', '#FFF598', '#F27DEB', '#8C1EB2', '#421EB2'],
27 | positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
28 | },
29 | },
30 | };
31 |
32 | export default () => {
33 | const [source, setSource] = useState({
34 | data: '',
35 | parser: { type: 'csv', x: 'reclong', y: 'reclat' },
36 | });
37 | useEffect(() => {
38 | fetch('https://gw.alipayobjects.com/os/bmw-prod/60177f74-5330-43f5-9a8c-9e3098640e87.csv')
39 | .then((res) => res.text())
40 | .then((data) => setSource({ ...source, data }));
41 | }, []);
42 | return (
43 |
44 |
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/docs/examples/nycCensus.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 9
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 纽约市人口普查区
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/photoHotmap.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 20
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 拍照景点-蜂窝聚合图
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/photoHotmap/index.tsx:
--------------------------------------------------------------------------------
1 | import type { HeatmapLayerProps, LarkMapProps } from '@antv/larkmap';
2 | import { HeatmapLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const heatmapCfg: Omit = {
6 | shape: 'hexagonColumn',
7 | color: {
8 | field: 'sum',
9 | value: [
10 | 'rgba(255, 255, 255,0.5)',
11 | 'rgb(253, 141, 255)',
12 | 'rgb(252, 100, 255)',
13 | 'rgb(227, 26, 28)',
14 | 'rgb(189, 0, 38)',
15 | 'rgb(155, 0, 100)',
16 | 'rgb(255, 0, 200)',
17 | 'rgb(255, 0, 0)',
18 | ],
19 | },
20 | size: {
21 | field: 'sum',
22 | value: ({ sum }) => {
23 | return sum * 200;
24 | },
25 | },
26 | style: {
27 | coverage: 0.9,
28 | angle: 0,
29 | opacity: 1.0,
30 | },
31 | };
32 |
33 | const config: LarkMapProps = {
34 | mapType: 'Gaode',
35 | mapOptions: {
36 | style: 'normal',
37 | center: [10, 44],
38 | pitch: 40,
39 | zoom: 3.7,
40 | },
41 | };
42 |
43 | export default () => {
44 | const [heatmapData, setHeatmapData] = useState({
45 | data: [],
46 | parser: { type: 'json', x: 'lat', y: 'lng' },
47 | transforms: [
48 | {
49 | type: 'hexagon',
50 | size: 50000,
51 | field: 'value',
52 | method: 'sum',
53 | },
54 | ],
55 | });
56 |
57 | useEffect(() => {
58 | fetch('https://gw.alipayobjects.com/os/bmw-prod/16cd4004-b21c-455e-a2e4-c396a5ecebe1.json')
59 | .then((res) => res.json())
60 | .then((res) => setHeatmapData({ ...heatmapData, data: res }));
61 | }, []);
62 |
63 | return (
64 |
65 |
66 |
67 | );
68 | };
69 |
--------------------------------------------------------------------------------
/docs/examples/photoSpots.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 4
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 全球拍照最多的景点
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/photoSpots/index.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps, PointLayerProps } from '@antv/larkmap';
2 | import { LarkMap, PointLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const config: LarkMapProps = {
6 | mapType: 'Gaode',
7 | mapOptions: {
8 | style: 'dark',
9 | center: [120.210792, 30.246026],
10 | zoom: 0,
11 | },
12 | };
13 |
14 | const layerOptions: Omit = {
15 | autoFit: true,
16 | shape: 'circle',
17 | size: 2,
18 | blend: 'additive',
19 | color: {
20 | field: 'value',
21 | value: [
22 | 'rgb(102,37,6)',
23 | 'rgb(153,52,4)',
24 | 'rgb(204,76,2)',
25 | 'rgb(236,112,20)',
26 | 'rgb(254,153,41)',
27 | 'rgb(254,196,79)',
28 | 'rgb(254,227,145)',
29 | ],
30 | },
31 | };
32 |
33 | export default () => {
34 | const [source, setSource] = useState({
35 | data: [],
36 | parser: { type: 'json', x: 'lat', y: 'lng' },
37 | });
38 |
39 | const fetchSourceData = async () => {
40 | const res = await fetch('https://gw.alipayobjects.com/os/bmw-prod/16cd4004-b21c-455e-a2e4-c396a5ecebe1.json');
41 | const result = await res.json();
42 | setSource({ ...source, data: result });
43 | };
44 |
45 | useEffect(() => {
46 | fetchSourceData();
47 | }, []);
48 |
49 | return (
50 |
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/docs/examples/poiChart.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 21
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## POI 聚合图
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/sanFranciscoStreetTreeMap.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 12
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 旧金山街道地图
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/sanFranciscoStreetTreeMap/index.less:
--------------------------------------------------------------------------------
1 | .panel {
2 | width: 200px;
3 | height: 50vh;
4 | margin-top: 10px;
5 | margin-right: -10px;
6 | padding: 10px;
7 | background: black;
8 | .setItem {
9 | margin-bottom: 10px;
10 | padding: 5px;
11 | color: #333;
12 | background: #fff;
13 | border-radius: 2px;
14 | :global {
15 | .ant-slider-handle {
16 | width: 25px;
17 | height: 25px;
18 | margin-top: -15px;
19 | background-color: transparent;
20 | background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/7fb22e05-4488-4597-8e33-fc03716d2b0a.svg');
21 | background-repeat: no-repeat;
22 | background-position: center center;
23 | background-size: 80% 80%;
24 | border: none;
25 | border-radius: 100%;
26 | }
27 | .ant-slider-handle:focus {
28 | box-shadow: none;
29 | }
30 | }
31 | }
32 | }
33 | .pickColor {
34 | display: flex;
35 | align-items: center;
36 | padding: 5px 0;
37 | }
38 |
--------------------------------------------------------------------------------
/docs/examples/sfContour.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 15
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 旧金山海拔等高线
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/shareBike/index.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps, PointLayerProps } from '@antv/larkmap';
2 | import { LarkMap, PointLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const config: LarkMapProps = {
6 | mapType: 'Gaode',
7 | mapOptions: {
8 | style: 'normal',
9 | center: [120.210792, 30.246026],
10 | zoom: 0,
11 | },
12 | };
13 |
14 | const layerOptions2: Omit = {
15 | autoFit: true,
16 | shape: 'circle',
17 | size: {
18 | field: 'point_count',
19 | value: [15, 20, 25, 30, 35],
20 | },
21 | blend: 'normal',
22 | color: {
23 | field: 'point_count',
24 | value: ['#FFDF80', '#FFCB33', '#FFB200', '#FF8C00'],
25 | },
26 | };
27 |
28 | const layerOption1: Omit = {
29 | autoFit: false,
30 | shape: { field: 'point_count', value: 'text' },
31 | size: 15,
32 | color: '#fff',
33 | style: {
34 | opacity: 1,
35 | strokeWidth: 0,
36 | stroke: '#fff',
37 | },
38 | };
39 |
40 | export default () => {
41 | const [pointData, setPointData] = useState({
42 | // @ts-ignore
43 | data: [],
44 | parser: { type: 'geojson' },
45 | cluster: true,
46 | clusterOption: {
47 | radius: 5,
48 | },
49 | });
50 |
51 | useEffect(() => {
52 | fetch('https://gw.alipayobjects.com/os/bmw-prod/b75db584-b143-491d-83cc-cb45653cd4ed.json')
53 | .then(async (res) => await res.json())
54 | .then((data) => {
55 | setPointData({ ...pointData, data });
56 | });
57 | }, []);
58 |
59 | return (
60 |
61 |
62 |
63 |
64 | );
65 | };
66 |
--------------------------------------------------------------------------------
/docs/examples/sharedBike.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 19
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 共享单单车区域和点位
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/taxiTrips.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 10
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 纽约公交路径
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/topicLayer.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 6
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 全国幼儿园分布数据
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/ukcommute.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 11
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 英格兰和威尔士的通勤地图
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/examples/ukcommute/constants.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps, LineLayerProps } from '@antv/larkmap';
2 |
3 | const config: LarkMapProps = {
4 | mapType: 'Gaode',
5 | mapOptions: {
6 | style: 'dark',
7 | center: [-0.9, 52.5],
8 | zoom: 6,
9 | pitch: 40,
10 | },
11 | };
12 |
13 | const layerConfig: Omit = {
14 | // autoFit: true,
15 | shape: 'arc3d',
16 | size: 1,
17 | blend: 'max',
18 | state: {
19 | active: false,
20 | },
21 | style: {
22 | opacity: 0.8,
23 | lineType: 'solid',
24 | sourceColor: '#f00',
25 | targetColor: '#f9f400',
26 | },
27 | };
28 |
29 | export { config, layerConfig };
30 |
--------------------------------------------------------------------------------
/docs/examples/ukcommute/index.tsx:
--------------------------------------------------------------------------------
1 | import type { LineLayerProps } from '@antv/larkmap';
2 | import { LarkMap, LineLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 | import { config, layerConfig } from './constants';
5 |
6 | export default () => {
7 | const [source, setSource] = useState({
8 | data: '',
9 | parser: {
10 | type: 'csv',
11 | x: 'workplace_lng',
12 | y: 'workplace_lat',
13 | x1: 'residence_lng',
14 | y1: 'residence_lat',
15 | },
16 | });
17 |
18 | useEffect(() => {
19 | fetch('https://gw.alipayobjects.com/os/bmw-prod/571cfe70-15ca-4542-934a-78f8c95b0bd3.csv')
20 | .then((res) => res.text())
21 | .then((data) => {
22 | setSource({ ...source, data: data });
23 | });
24 | }, []);
25 |
26 | return (
27 |
28 |
29 |
30 | );
31 | };
32 |
--------------------------------------------------------------------------------
/docs/examples/worldHeritageListDataResources.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 5
4 | nav:
5 | title: 示例
6 | path: /examples
7 | order: 4
8 | ---
9 |
10 | ## 世界遗产名录数据资源
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/guide/design.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 设计
3 | order: 2
4 | nav:
5 | title: 指南
6 | path: /guide
7 | ---
8 |
9 | ## 背景
10 |
11 | #### 为什么要做 LarkMap?
12 |
13 | 封装位置可视分析 React 组件库 LarkMap,沉底地图组件、分析组件、图层组件等,夯实位置可视分析组件基础,丰富 L7 技术栈生态,沉淀这样一套组件库可方便业务快速开发使用。
14 |
15 | #### LarkMap 关系?
16 |
17 | LarkMap 是 L7 技术栈的 React 组件库,上层业务直接使用,下游是 L7 技术栈。
18 |
19 | 
20 |
21 | ## 架构
22 |
23 | 
24 |
25 | ## 目标
26 |
27 | LarkMap 定位为位置可视分析组件库,组件可分为以下几大类:
28 |
29 | - 容器组件:不同底图有高德,Mapbox,L7Map
30 | - 图层组件:有基础图层与复合图层
31 | - 控件组件:地图控制组件,工具栏、鹰眼、比例尺等
32 | - 分析组件:下钻组件、位置搜索组件、行政区划查询等
33 | - 绘制组件:绘制工具、测量工具等
34 | - 属性组件:图层样式属性组件、数据属性组件等
35 |
36 | 规范组件生产原则:
37 |
38 | - 统一:API 设计不能风格迥异,保证使用心智统一
39 | - 灵活:在非共性或模糊地段,允许灵活定制
40 | - 专业:专注于位置“可视、分析”领域,沉淀好位置可视分析组件以及衍生的可视分析组件
41 |
42 | 规范组件研发:
43 |
44 | - 🔗 [组件研发流程规范](https://www.yuque.com/antv/l7/shlzof)
45 |
--------------------------------------------------------------------------------
/docs/guide/faq.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: FAQ
3 | order: 3
4 | nav:
5 | title: 指南
6 | path: /guide
7 | ---
8 |
9 | ### 1. LarkMap 是什么?
10 |
11 | LarkMap 定位为空间数据可视分析组件库,组件可分为以下几大类:
12 |
13 | - 容器组件:不同底图有高德,Mapbox,L7Map
14 | - 图层组件:有基础图层与复合图层
15 | - 控件组件:地图控制组件,工具栏、鹰眼、比例尺等
16 | - 分析组件:下钻组件、位置搜索组件、行政区划查询等
17 | - 绘制组件:绘制工具、测量工具等
18 | - 属性组件:图层样式属性组件、数据属性组件等
19 |
20 | ### 2. LarkMap 与之前的 L7React 什么关系?
21 |
22 | L7React 是 L7 组件的封装,设计之初也为了业务中更加方便的使用 React 版的 L7,未做任何能力的扩展,后续也计划下线。
23 |
24 | LarkMap 是基于 L7 技术栈的位置可视分析组件库,它的定位是位置可视分析领域的组件库,简单的来说,LarkMap 可替换 L7React 的全部能力,还集成了很多常用的位置可视分析组件。
25 |
26 | ### 3. 基础图层与复合图层组件区别是什么?
27 |
28 | LarkMap 里面图层分为基础图层与复合图层组件,基础图层组件对应 L7 的图层,复合图层组件是基于基础图层封装多图层组件,满足常见的多图层场景,比如点图层加文本图层完成点数据的标注。
29 |
30 | ### 4. 使用 LarkMap 过程中遇到问题了怎么办?
31 |
32 | 可以扫描下方二维码加入 L7 的钉钉答疑群进行提问
33 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: LarkMap | 空间数据可视分析组件库
3 | order: 0
4 | banner:
5 | title: LarkMap 空间数据可视分析组件库
6 | desc: 新一代 React 地图可视分析组件库,提供丰富/高效/专业/易用的可视化组件,一站式满足地理可视化需求。
7 | image: https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*ZdZcS5MKuAMAAAAAAAAAAAAADmJ7AQ/original
8 | actions:
9 | - text: 开始使用 →
10 | link: /guide
11 | type: primary
12 | notifications:
13 | - type: LocationInsight
14 | title: 空间数据可视分析平台
15 | date: 2022.11.22
16 | link: https://locationinsight.antv.antgroup.com
17 | - type: L7
18 | title: 从矢量到遥感,从引擎到平台,探索地理分析的远方
19 | date: 2022.11.22
20 | link: https://www.yuque.com/antv/blog/zrz77eat2m4wb7yk
21 | ideas:
22 | - icon: https://gw.alipayobjects.com/zos/bmw-prod/881dc458-f20b-407b-947a-95104b5ec82b/k79dm8ih_w144_h144.png
23 | title: 开箱即用
24 | description: 内置地图、图层、控件、分析、属性等组件,满足业务开箱即用
25 | - icon: https://gw.alipayobjects.com/zos/bmw-prod/d1ee0c6f-5aed-4a45-a507-339a4bfe076c/k7bjsocq_w144_h144.png
26 | title: 使用体验
27 | description: 需几行代码就生成一个地图,做到真正的简单使用,业务自定义需求可进行轻量化地定制
28 | - icon: https://gw.alipayobjects.com/zos/bmw-prod/d60657df-0822-4631-9d7c-e7a869c2f21c/k79dmz3q_w126_h126.png
29 | title: 开发效率
30 | description: TypeScript + React + Hooks,拥抱 React 生态同时也不丢掉命令式 API 的便捷
31 | ---
32 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | collectCoverage: false,
4 | testRegex: '(/__tests__/.*\\.(test|spec))\\.ts$',
5 | collectCoverageFrom: ['src/**/*.ts'],
6 | transform: {
7 | '\\.(less|css)$': 'jest-less-loader',
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/scripts/babel-less-to-css.js:
--------------------------------------------------------------------------------
1 | // https://github.com/umijs/father/blob/father-build%401.22.5/packages/father-build/src/getBabelConfig.ts#L25
2 |
3 | const transformImportLess2Css = () => {
4 | return {
5 | name: 'transform-import-less-to-css',
6 | visitor: {
7 | ImportDeclaration(path) {
8 | const re = /\.less$/;
9 | if (re.test(path.node.source.value)) {
10 | path.node.source.value = path.node.source.value.replace(re, '.css');
11 | }
12 | },
13 | },
14 | };
15 | };
16 |
17 | module.exports = transformImportLess2Css;
18 |
--------------------------------------------------------------------------------
/scripts/father-plugin-less.js:
--------------------------------------------------------------------------------
1 | // https://github.com/hexh250786313/blog/issues/30
2 | const { addLoader } = require('father/dist/builder/bundless');
3 |
4 | module.exports = async (api) => {
5 | const loaders = await api.applyPlugins({
6 | key: 'addPostcssLoader',
7 | initialValue: [
8 | {
9 | key: 'less-to-css',
10 | test: /\.less$/,
11 | loader: require.resolve('./loader-less-to-css'), // less 文件转 css 文件
12 | },
13 | ],
14 | });
15 |
16 | loaders.forEach((loader) => addLoader(loader));
17 | };
18 |
--------------------------------------------------------------------------------
/scripts/loader-less-to-css.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const less = require('less');
3 | const postcss = require('postcss');
4 | const syntax = require('postcss-less');
5 | const autoprefixer = require('autoprefixer');
6 |
7 | const loader = function (lessContent) {
8 | const cb = this.async();
9 | this.setOutputOptions({
10 | ext: '.css',
11 | });
12 | postcss([autoprefixer({})])
13 | .process(lessContent, { syntax })
14 | .then((result) => {
15 | // less 转 css
16 | less.render(result.content, (err, css) => {
17 | if (err) {
18 | console.error(err);
19 | return;
20 | }
21 | cb(null, css.css);
22 | });
23 | })
24 | .catch((err) => {
25 | console.error(err);
26 | });
27 | };
28 |
29 | module.exports = loader;
30 |
--------------------------------------------------------------------------------
/scripts/sync-version.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs-extra');
3 |
4 | const { version } = require('../package.json');
5 |
6 | fs.writeFileSync(path.join(__dirname, '..', 'src', 'version.ts'), `export default '${version}'`, 'utf8');
7 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/ContextMenuItem.tsx:
--------------------------------------------------------------------------------
1 | import React, { memo } from 'react';
2 | import { isEmpty } from 'lodash-es';
3 | import classNames from 'classnames';
4 | import type { ContextMenuItemProps } from './types';
5 | import { CLS_PREFIX } from './constant';
6 |
7 | export const ContextMenuItem: React.FC = memo(function ContextMenuItem(props) {
8 | const { text = '', onClick } = props;
9 |
10 | return !isEmpty(text) ? (
11 |
12 | {text}
13 |
14 | ) : null;
15 | });
16 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/constant.ts:
--------------------------------------------------------------------------------
1 | /** 组件名称, 前缀 */
2 | export const CLS_PREFIX = 'larkmap-context-menu';
3 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/demos/custom.tsx:
--------------------------------------------------------------------------------
1 | import { ContextMenu, LarkMap } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
8 | 面板内容
9 |
10 |
11 | );
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { Scene } from '@antv/l7';
2 | import { ContextMenu, LarkMap } from '@antv/larkmap';
3 | import React, { useRef } from 'react';
4 |
5 | export default () => {
6 | const mapScene = useRef();
7 |
8 | const handleMenu = (type: string) => {
9 | if (mapScene.current) {
10 | switch (type) {
11 | case 'zoomIn':
12 | mapScene.current.zoomIn();
13 | break;
14 | case 'zoomOut':
15 | mapScene.current.zoomOut();
16 | break;
17 | case 'center':
18 | mapScene.current.setZoomAndCenter(3, [108.946609, 34.262324]);
19 | break;
20 | }
21 | }
22 | };
23 |
24 | return (
25 | {
29 | mapScene.current = scene;
30 | }}
31 | >
32 |
33 | {
36 | handleMenu('zoomIn');
37 | }}
38 | />
39 | handleMenu('zoomOut')} />
40 | handleMenu('center')} />
41 |
42 |
43 | );
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-context-menu;
2 |
3 | .@{cls-prefix} {
4 | margin: 0;
5 | padding: 0;
6 | color: #000;
7 | list-style: none;
8 | background: #fff;
9 |
10 | &__menu-item {
11 | height: 35px;
12 | padding: 0 10px;
13 | font-size: 12px;
14 | line-height: 35px;
15 | }
16 |
17 | &__menu-item:hover {
18 | background: rgba(160, 160, 160, 0.3);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 5
4 | group:
5 | title: 分析组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | order: 2
11 | ---
12 |
13 | ## 右键菜单 - ContextMenu
14 |
15 | ### 介绍
16 |
17 | 地图右键菜单组件,由于当用户右键单击地图时,弹出展示对应菜单项。
18 |
19 | ### 代码演示
20 |
21 | #### 默认示例
22 |
23 |
24 |
25 | #### 自定义菜单示例
26 |
27 |
28 |
29 | ### API
30 |
31 | | 属性名 | 描述 | 类型 | 默认值 |
32 | | --------- | -------- | --------------- | ------ |
33 | | childern | 子组件 | `ReactNode` | -- |
34 | | className | 类名 | `string` | -- |
35 | | style | 行内样式 | `CSSProperties` | -- |
36 |
37 | #### ContextMenu.Item
38 |
39 | | 属性名 | 描述 | 类型 | 默认值 |
40 | | --------- | ------------ | --------------- | -------- |
41 | | text | 菜单文本 | `string` | `(必选)` |
42 | | onClick | 点击菜单事件 | `() => void` | `(必选)` |
43 | | className | 类名 | `string` | -- |
44 | | style | 行内样式 | `CSSProperties` | -- |
45 |
--------------------------------------------------------------------------------
/src/components/ContextMenu/types.ts:
--------------------------------------------------------------------------------
1 | import type { CommonProps } from '../../types/common';
2 |
3 | export interface ContextMenuItemProps extends CommonProps {
4 | text: string;
5 | onClick?: () => void;
6 | }
7 | export interface ContextMenuProps extends CommonProps {
8 | /** 子组件 */
9 | children?: React.ReactNode;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Control/CustomControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { CustomControl, LarkMap } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
12 | 自定义内容
13 |
14 |
15 | );
16 | };
17 |
--------------------------------------------------------------------------------
/src/components/Control/CustomControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 1
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 自定义控件 - CustomControl
13 |
14 | ### 介绍
15 |
16 | 地图自定义容器控件,用户可以通过 `CustomControl` 组件将自定义内容悬停在地图上。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | | 参数 | 说明 | 类型 | 默认值 |
23 | | --- | --- | --- | --- |
24 | | position | 控件被添加到地图中的位置以及排列方式,详情可见 [控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | `'topleft'` |
25 | | className | 自定义样式名 | `string` | - |
26 | | style | 自定义样式 | `CSSProperties` | - |
27 | | children | 控件内容 | `ReactNode` | - |
28 |
29 | #### Position
30 |
31 | ```ts
32 | export type Position =
33 | | 'topleft' // ↖ 左上角,纵向排列
34 | | 'lefttop' // ↖ 左上角,横向排列
35 | | 'topright' // ↗ 右上角,纵向排列
36 | | 'righttop' // ↗ 右上角,横向排列
37 | | 'bottomleft' // ↙ 左下角,纵向排列
38 | | 'leftbottom' // ↙ 左下角,横向排列
39 | | 'bottomright' // ↘ 右下角,纵向排列
40 | | 'rightbottom' // ↘ 右下角,横向排列
41 | | 'topcenter' // ↑ 上方中央,横向排列
42 | | 'bottomcenter' // ↓ 下方中间,横向排列
43 | | 'leftcenter' // ← 左边中间,纵向排列
44 | | 'rightcenter'; // → 右边中间,纵向排列
45 | ```
46 |
--------------------------------------------------------------------------------
/src/components/Control/CustomControl/index.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react';
2 | import { useCallback, useMemo, useRef } from 'react';
3 | import { createPortal } from 'react-dom';
4 | import type { IControlOption } from '@antv/l7';
5 | import { useControl } from '../../LarkMap/hooks';
6 | import { getStyleText } from '../../../utils';
7 | import type { CustomControlProps } from './types';
8 |
9 | export const CustomControl: React.FC = (props): React.ReactPortal => {
10 | const { className, style, children, position = 'topleft', name } = props;
11 | const containerRef = useRef(document.createElement('div'));
12 | const styleText = getStyleText(style);
13 |
14 | const onCreate = useCallback(() => {
15 | return containerRef.current;
16 | }, []);
17 |
18 | const controlOptions: IControlOption = useMemo(() => {
19 | return {
20 | position,
21 | name,
22 | className,
23 | style: styleText,
24 | };
25 | }, [position, name, className, styleText]);
26 |
27 | useControl(onCreate, undefined, controlOptions);
28 |
29 | // @ts-ignore
30 | return createPortal(children, containerRef.current);
31 | };
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/components/Control/CustomControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { IControlOption } from '@antv/l7';
2 | import type { CommonProps } from '../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface CustomControlProps extends CommonProps, Omit, 'style'> {
8 | /** 控件容器包含的内容 */
9 | children?: React.ReactNode;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Control/ExportImageControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 6
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 导出图片 - ExportImageControl
13 |
14 | ### 介绍
15 |
16 | 导出图片组件,用于对当前地图部分进行截图并生成图片的 `Base64` 字符串。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | imageType | 截图图片的格式 | `'png'|'jpeg'` | `'png'` |
27 | | onExport | 截图成功后,用于接收图片 Base64 字符串的回调函数 | `(base64: string) => void` | - |
28 | | btnIcon | 按钮图标 | `ReactNode` | - |
29 | | btnText | 按钮内容文本 | `string` | - |
30 | | title | 按钮的 title 属性 | `string` | `'导出图片'` |
31 | | vertical | 在 btnIcon 有值的情况下,按钮内的图标和文案是否纵向排列 | `boolean` | `false` |
32 | | position | 控件被添加到地图中的位置以及排列方式,详情可见 [控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | `'topright'` |
33 | | className | 自定义样式名 | `string` | - |
34 | | style | 自定义样式 | `CSSProperties` | - |
35 | | onAdd | 组件被添加时的回调 | `(this) => void` | - |
36 | | onRemove | 组件被移除时的回调 | `(this) => void` | - |
37 | | onShow | 组件显示时的回调 | `(this) => void` | - |
38 | | onHide | 组件隐藏时的回调 | `(this) => void` | - |
39 |
40 | #### Position
41 |
42 | ```ts
43 | export type Position =
44 | | 'topleft' // ↖ 左上角,纵向排列
45 | | 'lefttop' // ↖ 左上角,横向排列
46 | | 'topright' // ↗ 右上角,纵向排列
47 | | 'righttop' // ↗ 右上角,横向排列
48 | | 'bottomleft' // ↙ 左下角,纵向排列
49 | | 'leftbottom' // ↙ 左下角,横向排列
50 | | 'bottomright' // ↘ 右下角,纵向排列
51 | | 'rightbottom' // ↘ 右下角,横向排列
52 | | 'topcenter' // ↑ 上方中央,横向排列
53 | | 'bottomcenter' // ↓ 下方中间,横向排列
54 | | 'leftcenter' // ← 左边中间,纵向排列
55 | | 'rightcenter'; // → 右边中间,纵向排列
56 | ```
57 |
--------------------------------------------------------------------------------
/src/components/Control/ExportImageControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { IExportImageControlOption, ExportImage } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface ExportImageControlProps
9 | extends Omit, 'style' | 'btnIcon'>,
10 | IControlCallback {
11 | style?: CSSProperties;
12 | btnIcon?: ReactNode;
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/Control/FullscreenControl/demos/antd.tsx:
--------------------------------------------------------------------------------
1 | import type { Scene } from '@antv/l7';
2 | import { CustomControl, FullscreenControl, LarkMap } from '@antv/larkmap';
3 | import { Button, ConfigProvider, message, Tooltip } from 'antd';
4 | import React, { useCallback, useEffect, useState } from 'react';
5 |
6 | export default () => {
7 | const [scene, setScene] = useState(null);
8 |
9 | const getContainer = useCallback(() => {
10 | return scene?.getContainer() ?? document.body;
11 | }, [scene]);
12 |
13 | useEffect(() => {
14 | // 修正 message 框的挂载 DOM
15 | message.config({
16 | getContainer,
17 | });
18 | }, [getContainer]);
19 |
20 | return (
21 | // 修正 Dropdown、Tooltip、Popover 弹出框的挂载 DOM
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
40 |
41 |
42 |
43 | );
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/Control/FullscreenControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { FullscreenControl, LarkMap } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/Control/FullscreenControl/type.ts:
--------------------------------------------------------------------------------
1 | import type { IFullscreenControlOption, Fullscreen } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface FullscreenControlProps
9 | extends Omit, 'style' | 'btnIcon' | 'exitBtnIcon'>,
10 | IControlCallback {
11 | style?: CSSProperties;
12 | btnIcon?: ReactNode;
13 | exitBtnIcon?: ReactNode;
14 | onFullscreenChange?: (isFullscreen: boolean) => void;
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/Control/GeoLocateControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { GeoLocateControl, LarkMap } from '@antv/larkmap';
2 | import gcoord from 'gcoord';
3 | import React from 'react';
4 |
5 | export default () => {
6 | const transform = (position) => {
7 | return gcoord.transform(position, gcoord.WGS84, gcoord.GCJ02);
8 | };
9 |
10 | return (
11 |
12 |
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/Control/GeoLocateControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 5
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 定位 - GeoLocateControl
13 |
14 | ### 介绍
15 |
16 | 定位组件使用浏览器环境的 `nagigator` 的 `getlocation` 方法,使用浏览器打开位置感应能力获取当前用户所在经纬度。
17 |
18 | **注意:**
19 |
20 | 1. 在使用该能力时,会需要用户对浏览器打开位置感知能力进行鉴权。
21 | 2. 当前浏览器获取到的坐标是 WGS84 地理坐标系,在高德地图上使用会有偏差,可以使用 transform 配置进行坐标系的转换。
22 |
23 | ### 代码演示
24 |
25 |
26 |
27 | ### API
28 |
29 | | 参数 | 说明 | 类型 | 默认值 |
30 | | --- | --- | --- | --- |
31 | | transform | 格式化通过 getlocation 获取到的经纬度的函数,可以用于地理坐标系的转换 | `(position: [number, number]) => [number, number]` | - |
32 | | btnIcon | 按钮图标 | `ReactNode` | - |
33 | | btnText | 按钮内容文本 | `string` | - |
34 | | title | 按钮的 title 属性 | `string` | `'定位''` |
35 | | vertical | 在 btnIcon 有值的情况下,按钮内的图标和文案是否纵向排列 | `boolean` | `false` |
36 | | position | 控件被添加到地图中的位置以及排列方式,详情可见[控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | `'topright''` |
37 | | className | 自定义样式名 | `string` | - |
38 | | style | 自定义样式 | `CSSProperties` | - |
39 | | onAdd | 组件被添加时的回调 | `(this) => void` | - |
40 | | onRemove | 组件被移除时的回调 | `(this) => void` | - |
41 | | onShow | 组件显示时的回调 | `(this) => void` | - |
42 | | onHide | 组件隐藏时的回调 | `(this) => void` | - |
43 |
44 | #### Position
45 |
46 | ```ts
47 | export type Position =
48 | | 'topleft' // ↖ 左上角,纵向排列
49 | | 'lefttop' // ↖ 左上角,横向排列
50 | | 'topright' // ↗ 右上角,纵向排列
51 | | 'righttop' // ↗ 右上角,横向排列
52 | | 'bottomleft' // ↙ 左下角,纵向排列
53 | | 'leftbottom' // ↙ 左下角,横向排列
54 | | 'bottomright' // ↘ 右下角,纵向排列
55 | | 'rightbottom' // ↘ 右下角,横向排列
56 | | 'topcenter' // ↑ 上方中央,横向排列
57 | | 'bottomcenter' // ↓ 下方中间,横向排列
58 | | 'leftcenter' // ← 左边中间,纵向排列
59 | | 'rightcenter'; // → 右边中间,纵向排列
60 | ```
61 |
--------------------------------------------------------------------------------
/src/components/Control/GeoLocateControl/type.ts:
--------------------------------------------------------------------------------
1 | import type { IGeoLocateOption, GeoLocate } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface GeoLocateControlProps
9 | extends Omit, 'style' | 'btnIcon'>,
10 | IControlCallback {
11 | style?: CSSProperties;
12 | btnIcon?: ReactNode;
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/Control/LayerSwitchControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { PolygonLayerProps } from '@antv/larkmap';
2 | import { LarkMap, LayerSwitchControl, PolygonLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const polygonLayerOptions: Omit = {
6 | autoFit: true,
7 | shape: 'fill',
8 | color: {
9 | field: 'adcode',
10 | value: ['#0f9960', '#33a02c', '#477eb8'],
11 | },
12 | state: {
13 | active: true,
14 | },
15 | style: {
16 | opacity: 0.6,
17 | },
18 | };
19 |
20 | const lineLayerOptions: Omit = {
21 | shape: 'line',
22 | size: 2,
23 | color: '#595959',
24 | state: {
25 | active: false,
26 | },
27 | };
28 |
29 | export default () => {
30 | const [source, setSource] = useState({
31 | data: { type: 'FeatureCollection', features: [] },
32 | parser: { type: 'geojson' },
33 | });
34 |
35 | useEffect(() => {
36 | fetch('https://gw.alipayobjects.com/os/antfincdn/Y8eGLb9j9v/hangzhou-district.json')
37 | .then((response) => response.json())
38 | .then((data: any) => {
39 | setSource((prevState) => ({ ...prevState, data }));
40 | });
41 | }, []);
42 |
43 | return (
44 |
45 |
46 |
47 |
48 |
49 | );
50 | };
51 |
--------------------------------------------------------------------------------
/src/components/Control/LayerSwitchControl/demos/layerSwitchItem.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, LayerSwitchControl, RasterLayer, useLayer } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | const GOOGLE_TILE_MAP_URL = 'https://gac-geo.googlecnapps.cn/maps/vt?lyrs=s&gl=CN&x={x}&y={y}&z={z}';
5 |
6 | const GOOGLE_TILE_MAP_ROUTER_URL = 'https://gac-geo.googlecnapps.cn/maps/vt?lyrs=h&gl=CN&x={x}&y={y}&z={z}';
7 |
8 | const CustomComponent = () => {
9 | const googleTileMap = useLayer('googleTileMap');
10 | const googleTileMapRouter = useLayer('googleTileMapRouter');
11 |
12 | return (
13 |
27 | );
28 | };
29 |
30 | export default () => {
31 | return (
32 |
33 |
42 |
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/src/components/Control/LayerSwitchControl/demos/singleSelection.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, LayerSwitchControl, RasterLayer, useLayer } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | const GOOGLE_TILE_MAP_URL = 'https://gac-geo.googlecnapps.cn/maps/vt?lyrs=s&gl=CN&x={x}&y={y}&z={z}';
5 |
6 | const GOOGLE_TILE_MAP_ROUTER_URL = 'https://gac-geo.googlecnapps.cn/maps/vt?lyrs=h&gl=CN&x={x}&y={y}&z={z}';
7 |
8 | const CustomComponent = () => {
9 | const googleTileMap = useLayer('googleTileMap');
10 | const googleTileMapRouter = useLayer('googleTileMapRouter');
11 |
12 | return (
13 |
28 | );
29 | };
30 |
31 | export default () => {
32 | return (
33 |
34 |
43 |
52 |
53 |
54 | );
55 | };
56 |
--------------------------------------------------------------------------------
/src/components/Control/LayerSwitchControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { ILayerSwitchOption, LayerSwitch } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 | import type { IPopperControlCallback, Layer } from '../../../types';
4 |
5 | export type LayerSwitchItem = {
6 | layer: Layer | string;
7 | name?: string;
8 | img?: string;
9 | };
10 |
11 | export interface LayerSwitchControlProps
12 | extends Omit, 'style' | 'btnIcon' | 'layers'>,
13 | IPopperControlCallback {
14 | layers: (Layer | string | LayerSwitchItem)[];
15 | style?: CSSProperties;
16 | btnIcon?: ReactNode;
17 | onSelectChange?: (value: string[]) => void;
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/Control/LogoControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps } from '@antv/larkmap';
2 | import { LarkMap, LogoControl } from '@antv/larkmap';
3 | import React from 'react';
4 |
5 | const config: LarkMapProps = {
6 | mapType: 'Gaode',
7 | mapOptions: {
8 | style: 'light',
9 | center: [120.210792, 30.246026],
10 | zoom: 9,
11 | },
12 | style: {
13 | height: '200px',
14 | },
15 | logoVisible: false,
16 | };
17 |
18 | export default () => {
19 | return (
20 |
21 |
22 |
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/Control/LogoControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 1
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## Logo - LogoControl
13 |
14 | ### 介绍
15 |
16 | 用于在地图上展示 Logo 图片的控件,并且支持超链接点击跳转。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | img | Logo 展示的图片 url | `string` | --- |
27 | | href | 点击 Logo 跳转的超链接,不传则纯展示图片,点击不跳转 | `string` | --- |
28 | | position | 控件被添加到地图中的位置以及排列方式详情可见 [控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | --- |
29 | | className | 自定义样式名 | `string` | --- |
30 | | style | 自定义样式 | `CSSProperties` | - |
31 | | onAdd | 组件被添加时的回调 | `(this) => void` | - |
32 | | onRemove | 组件被移除时的回调 | `(this) => void` | - |
33 | | onShow | 组件显示时的回调 | `(this) => void` | - |
34 | | onHide | 组件隐藏时的回调 | `(this) => void` | - |
35 |
36 | #### Position
37 |
38 | ```ts
39 | export type Position =
40 | | 'topleft' // ↖ 左上角,纵向排列
41 | | 'lefttop' // ↖ 左上角,横向排列
42 | | 'topright' // ↗ 右上角,纵向排列
43 | | 'righttop' // ↗ 右上角,横向排列
44 | | 'bottomleft' // ↙ 左下角,纵向排列
45 | | 'leftbottom' // ↙ 左下角,横向排列
46 | | 'bottomright' // ↘ 右下角,纵向排列
47 | | 'rightbottom' // ↘ 右下角,横向排列
48 | | 'topcenter' // ↑ 上方中央,横向排列
49 | | 'bottomcenter' // ↓ 下方中间,横向排列
50 | | 'leftcenter' // ← 左边中间,纵向排列
51 | | 'rightcenter'; // → 右边中间,纵向排列
52 | ```
53 |
--------------------------------------------------------------------------------
/src/components/Control/LogoControl/index.tsx:
--------------------------------------------------------------------------------
1 | import type { ILogoControlOption } from '@antv/l7';
2 | import { Logo as L7Logo } from '@antv/l7';
3 | import { omitBy } from 'lodash-es';
4 | import type React from 'react';
5 | import { useEffect, useMemo, useState } from 'react';
6 | import { getStyleText } from '../../../utils';
7 | import { useScene } from '../../LarkMap/hooks';
8 | import { useL7ComponentEvent, useL7ComponentUpdate } from '../hooks';
9 | import type { LogoControlProps } from './types';
10 |
11 | export const LogoControl: React.FC = ({
12 | img,
13 | href,
14 | position,
15 | className,
16 | style,
17 | onShow,
18 | onHide,
19 | onAdd,
20 | onRemove,
21 | }) => {
22 | const scene = useScene();
23 | const [control, setControl] = useState();
24 | const styleText = useMemo(() => getStyleText(style), [style]);
25 |
26 | const controlOptions: Partial = useMemo(() => {
27 | return {
28 | img,
29 | href,
30 | position,
31 | className,
32 | style: styleText,
33 | };
34 | }, [img, href, position, className, styleText]);
35 |
36 | useEffect(() => {
37 | const logo = new L7Logo(omitBy(controlOptions, (value) => value === undefined));
38 | setControl(logo);
39 | scene.addControl(logo);
40 | return () => {
41 | scene.removeControl(logo);
42 | setControl(undefined);
43 | };
44 | // eslint-disable-next-line react-hooks/exhaustive-deps
45 | }, []);
46 |
47 | useL7ComponentUpdate(control, controlOptions);
48 |
49 | useL7ComponentEvent(control, {
50 | add: onAdd,
51 | remove: onRemove,
52 | show: onShow,
53 | hide: onHide,
54 | });
55 | return null;
56 | };
57 |
--------------------------------------------------------------------------------
/src/components/Control/LogoControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { GeoLocate, ILogoControlOption } from '@antv/l7';
2 | import type { CSSProperties } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface LogoControlProps extends Omit, 'style'>, IControlCallback {
9 | style?: CSSProperties;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Control/MapThemeControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, MapThemeControl } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/Control/MapThemeControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { ISelectControlOption, MapTheme } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 | import type { IPopperControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface MapThemeControlProps
9 | extends Omit, 'style' | 'btnIcon'>,
10 | IPopperControlCallback {
11 | style?: CSSProperties;
12 | btnIcon?: ReactNode;
13 | onSelectChange?: (value: string) => void;
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/Control/MouseLocationControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, MouseLocationControl } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/Control/MouseLocationControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 7
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 光标经纬度 - MouseLocationControl
13 |
14 | ### 介绍
15 |
16 | 光标经纬度组件,用于实时展示当前光标在地图上所对应的经纬度。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | transform | 转换光标所在经纬度的回调函数 | `(position: [number, number]) => [number, number]` | - |
27 | | position | 控件被添加到地图中的位置以及排列方式,详情可见 [控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | `'bottomleft'` |
28 | | className | 自定义样式名 | `string` | - |
29 | | style | 自定义样式 | `CSSProperties` | - |
30 | | onLocationChange | 光标所在经纬度发生变化时触发的回调 | `(position: [number, number]) => void` | - |
31 | | onAdd | 组件被添加时的回调 | `(this) => void` | - |
32 | | onRemove | 组件被移除时的回调 | `(this) => void` | - |
33 | | onShow | 组件显示时的回调 | `(this) => void` | - |
34 | | onHide | 组件隐藏时的回调 | `(this) => void` | - |
35 |
36 | #### Position
37 |
38 | ```ts
39 | export type Position =
40 | | 'topleft' // ↖ 左上角,纵向排列
41 | | 'lefttop' // ↖ 左上角,横向排列
42 | | 'topright' // ↗ 右上角,纵向排列
43 | | 'righttop' // ↗ 右上角,横向排列
44 | | 'bottomleft' // ↙ 左下角,纵向排列
45 | | 'leftbottom' // ↙ 左下角,横向排列
46 | | 'bottomright' // ↘ 右下角,纵向排列
47 | | 'rightbottom' // ↘ 右下角,横向排列
48 | | 'topcenter' // ↑ 上方中央,横向排列
49 | | 'bottomcenter' // ↓ 下方中间,横向排列
50 | | 'leftcenter' // ← 左边中间,纵向排列
51 | | 'rightcenter'; // → 右边中间,纵向排列
52 | ```
53 |
--------------------------------------------------------------------------------
/src/components/Control/MouseLocationControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { IMouseLocationControlOption, MouseLocation } from '@antv/l7';
2 | import type { CSSProperties } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface MouseLocationControlProps
9 | extends Omit, 'style'>,
10 | IControlCallback {
11 | style?: CSSProperties;
12 | onLocationChange?: (position: [number, number]) => void;
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/Control/ScaleControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, ScaleControl } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/Control/ScaleControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 3
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 比例尺 - ScaleControl
13 |
14 | ### 介绍
15 |
16 | 地图比例尺组件,用于显示地图上的距离与地面上相应距离的比率。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | lockWidth | 是否固定容器宽度 | `boolean` | `true` |
27 | | maxWidth | 组件的容器最大宽度 | `number` | `100` |
28 | | metric | 展示 `千米` 格式的比例尺 | `boolean` | `true` |
29 | | imperial | 展示 `英里` 格式的比例尺 | `boolean` | `false` |
30 | | updateWhenIdle | 是否只在拖拽和缩放结束后才更新比例尺 | `boolean` | `false` |
31 | | position | 控件被添加到地图中的位置以及排列方式,详情可见 [控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | `'bottomleft'` |
32 | | className | 自定义样式名 | `string` | - |
33 | | style | 自定义样式 | `CSSProperties` | - |
34 | | onAdd | 组件被添加时的回调 | `(this) => void` | - |
35 | | onRemove | 组件被移除时的回调 | `(this) => void` | - |
36 | | onShow | 组件显示时的回调 | `(this) => void` | - |
37 | | onHide | 组件隐藏时的回调 | `(this) => void` | - |
38 |
39 | #### Position
40 |
41 | ```ts
42 | export type Position =
43 | | 'topleft' // ↖ 左上角,纵向排列
44 | | 'lefttop' // ↖ 左上角,横向排列
45 | | 'topright' // ↗ 右上角,纵向排列
46 | | 'righttop' // ↗ 右上角,横向排列
47 | | 'bottomleft' // ↙ 左下角,纵向排列
48 | | 'leftbottom' // ↙ 左下角,横向排列
49 | | 'bottomright' // ↘ 右下角,纵向排列
50 | | 'rightbottom' // ↘ 右下角,横向排列
51 | | 'topcenter' // ↑ 上方中央,横向排列
52 | | 'bottomcenter' // ↓ 下方中间,横向排列
53 | | 'leftcenter' // ← 左边中间,纵向排列
54 | | 'rightcenter'; // → 右边中间,纵向排列
55 | ```
56 |
--------------------------------------------------------------------------------
/src/components/Control/ScaleControl/type.ts:
--------------------------------------------------------------------------------
1 | import type { IScaleControlOption, Scale } from '@antv/l7';
2 | import type { CSSProperties } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | /**
6 | * 组件类型定义
7 | */
8 | export interface ScaleControlProps extends Omit, 'style'>, IControlCallback {
9 | style?: CSSProperties;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Control/ZoomControl/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, ZoomControl } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
8 |
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/Control/ZoomControl/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 2
4 | group:
5 | title: 控件组件
6 | order: 2
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 缩放器 - ZoomControl
13 |
14 | ### 介绍
15 |
16 | 地图缩放组件,用于控制地图放大和缩小的控件,并且当地图达到最大或最小缩放比时,会禁用对应缩放按钮。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | zoomInText | 放大按钮的展示内容 | `ReactNode` | - |
27 | | zoomInTitle | 放大按钮的 `title` 属性 | `string` | `'Zoom in'` |
28 | | zoomOutText | 缩小按钮的展示内容 | `ReactNode` | - |
29 | | zoomOutTitle | 缩小按钮的 `title` 属性 | `string` | `'Zoom out'` |
30 | | position | 控件被添加到地图中的位置以及排列方式,详情可见 [控件插槽](https://l7.antv.antgroup.com/api/component/control/control#插槽) | [Position](#position) | `'bottomright'` |
31 | | showZoom | 是否展示地图当前实时 zoom 数值,默认向下取整 | `boolean` | `false` |
32 | | className | 自定义样式名 | `string` | - |
33 | | style | 自定义样式 | `CSSProperties` | - |
34 | | onAdd | 组件被添加时的回调 | `(this) => void` | - |
35 | | onRemove | 组件被移除时的回调 | `(this) => void` | - |
36 | | onShow | 组件显示时的回调 | `(this) => void` | - |
37 | | onHide | 组件隐藏时的回调 | `(this) => void` | - |
38 |
39 | #### Position
40 |
41 | ```ts
42 | export type Position =
43 | | 'topleft' // ↖ 左上角,纵向排列
44 | | 'lefttop' // ↖ 左上角,横向排列
45 | | 'topright' // ↗ 右上角,纵向排列
46 | | 'righttop' // ↗ 右上角,横向排列
47 | | 'bottomleft' // ↙ 左下角,纵向排列
48 | | 'leftbottom' // ↙ 左下角,横向排列
49 | | 'bottomright' // ↘ 右下角,纵向排列
50 | | 'rightbottom' // ↘ 右下角,横向排列
51 | | 'topcenter' // ↑ 上方中央,横向排列
52 | | 'bottomcenter' // ↓ 下方中间,横向排列
53 | | 'leftcenter' // ← 左边中间,纵向排列
54 | | 'rightcenter'; // → 右边中间,纵向排列
55 | ```
56 |
--------------------------------------------------------------------------------
/src/components/Control/ZoomControl/types.ts:
--------------------------------------------------------------------------------
1 | import type { IZoomControlOption, Zoom as L7Zoom } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 | import type { IControlCallback } from '../../../types';
4 |
5 | export interface ZoomControlProps
6 | extends Omit, 'style' | 'zoomInText' | 'zoomOutText'>,
7 | IControlCallback {
8 | style?: CSSProperties;
9 | zoomInText?: ReactNode;
10 | zoomOutText?: ReactNode;
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/Control/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useL7ComponentEvent';
2 | export * from './useL7ComponentUpdate';
3 | export * from './useL7ComponentPortal';
4 |
--------------------------------------------------------------------------------
/src/components/Control/hooks/useL7ComponentEvent.ts:
--------------------------------------------------------------------------------
1 | import { useUnmount } from 'ahooks';
2 | import type EventEmitter from 'eventemitter3';
3 | import { useEffect, useMemo } from 'react';
4 |
5 | type CallbackFunction = (...args: any[]) => any;
6 |
7 | /**
8 | * 为 Control 绑定对应事件的回调,并且在回调函数发生更新时重新绑定
9 | * @param control
10 | * @param props
11 | */
12 | export const useL7ComponentEvent = >(
13 | control: C,
14 | props: Record,
15 | ) => {
16 | const eventNameList = useMemo(() => Object.keys(props), [props]);
17 |
18 | useEffect(() => {
19 | if (control) {
20 | eventNameList.forEach((eventName) => {
21 | const callback = props[eventName];
22 | if (callback) {
23 | control.on(eventName, callback);
24 | }
25 | });
26 | }
27 |
28 | return () => {
29 | if (control) {
30 | eventNameList.forEach((eventName) => {
31 | const callback = props[eventName];
32 | if (callback) {
33 | control.off(eventName, callback);
34 | }
35 | });
36 | }
37 | };
38 | // eslint-disable-next-line react-hooks/exhaustive-deps
39 | }, [control, ...Object.values(props)]);
40 |
41 | useUnmount(() => {
42 | if (!control) {
43 | return;
44 | }
45 | eventNameList.forEach((eventName) => {
46 | const callback = props[eventName];
47 | if (callback) {
48 | control.off(eventName, callback);
49 | }
50 | });
51 | });
52 | };
53 |
--------------------------------------------------------------------------------
/src/components/Control/hooks/useL7ComponentPortal.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react';
2 | import type { ReactPortal } from 'react';
3 | import { useRef } from 'react';
4 | import { createPortal } from 'react-dom';
5 |
6 | /**
7 | * 将控件参数中的 ReactNode 转成 Element 格式,并返回对应的 DOM 和 Portal,其中 Portal 需要在对应的 React 组件中返回渲染
8 | * @param reactNode
9 | */
10 | // @ts-ignore
11 | export const useL7ComponentPortal: (reactNode?: React.ReactNode | null) => {
12 | portal: ReactPortal | null;
13 | dom: HTMLElement | undefined;
14 | } = (reactNode) => {
15 | const domRef = useRef(document.createElement('span'));
16 |
17 | return {
18 | portal: reactNode ? createPortal(reactNode, domRef.current) : null,
19 | dom: reactNode ? domRef.current : undefined,
20 | };
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/Control/hooks/useL7ComponentUpdate.ts:
--------------------------------------------------------------------------------
1 | import type { Control, Popup } from '@antv/l7';
2 | import { useTrackedEffect } from 'ahooks';
3 | import { useMemo, useRef } from 'react';
4 |
5 | /**
6 | * 监听 control 的 options 中各项是否发生变化,若有变化则调用 control.setOptions 传入更新的配置
7 | * @param control
8 | * @param options
9 | */
10 | export const useL7ComponentUpdate = >(
11 | control: C,
12 | options: Partial,
13 | ) => {
14 | const isFirst = useRef(true);
15 | const keyList = useMemo(() => Object.keys(options) as (keyof O)[], [options]);
16 |
17 | useTrackedEffect((updateIndexes) => {
18 | if (isFirst.current) {
19 | isFirst.current = false;
20 | return;
21 | }
22 | const updateOptions: Partial = {};
23 | updateIndexes.forEach((updateIndex) => {
24 | const key = keyList[updateIndex];
25 | updateOptions[key] = options[key];
26 | });
27 | control?.setOptions(updateOptions);
28 | }, Object.values(options));
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/Control/index.ts:
--------------------------------------------------------------------------------
1 | // organize-imports-ignore
2 |
3 | export { CustomControl } from './CustomControl';
4 | export type { CustomControlProps } from './CustomControl/types';
5 |
6 | export { ExportImageControl } from './ExportImageControl';
7 | export type { ExportImageControlProps } from './ExportImageControl/types';
8 |
9 | export { FullscreenControl } from './FullscreenControl';
10 | export type { FullscreenControlProps } from './FullscreenControl/type';
11 |
12 | export { GeoLocateControl } from './GeoLocateControl';
13 | export type { GeoLocateControlProps } from './GeoLocateControl/type';
14 |
15 | export { LayerSwitchControl } from './LayerSwitchControl';
16 | export type { LayerSwitchControlProps } from './LayerSwitchControl/types';
17 |
18 | export { MapThemeControl } from './MapThemeControl';
19 | export type { MapThemeControlProps } from './MapThemeControl/types';
20 |
21 | export { MouseLocationControl } from './MouseLocationControl';
22 | export type { MouseLocationControlProps } from './MouseLocationControl/types';
23 |
24 | export { ScaleControl } from './ScaleControl';
25 | export type { ScaleControlProps } from './ScaleControl/type';
26 |
27 | export { ZoomControl } from './ZoomControl';
28 | export type { ZoomControlProps } from './ZoomControl/types';
29 |
30 | export { LogoControl } from './LogoControl';
31 | export type { LogoControlProps } from './LogoControl/types';
32 |
--------------------------------------------------------------------------------
/src/components/Draw/types.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | DeepPartial,
3 | ICircleDrawerOptions,
4 | ILineDrawerOptions,
5 | IPointDrawerOptions,
6 | IPolygonDrawerOptions,
7 | IRectDrawerOptions,
8 | } from '@antv/l7-draw';
9 | import type { Feature, LineString, Point, Polygon } from 'geojson';
10 |
11 | export type FeatureData = Feature | Feature | Feature;
12 | export type DrawData = FeatureData[];
13 |
14 | export type PartialDrawPointOptions = DeepPartial;
15 | export type PartialDrawLineOptions = DeepPartial;
16 | export type PartialDrawPolygonOptions = DeepPartial;
17 | export type PartialDrawRectOptions = DeepPartial;
18 | export type PartialDrawCircleOptions = DeepPartial;
19 |
20 | export type DrawType = 'point' | 'line' | 'polygon' | 'rect' | 'circle';
21 |
--------------------------------------------------------------------------------
/src/components/Draw/use-draw-group/demos/default.less:
--------------------------------------------------------------------------------
1 | .control {
2 | button {
3 | padding: 3px 12px;
4 | outline: 0;
5 | margin-right: 4px;
6 | }
7 | .active {
8 | color: #4569D4;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Draw/use-draw-group/types.ts:
--------------------------------------------------------------------------------
1 | import type { DeepPartial, IBaseModeOptions } from '@antv/l7-draw';
2 | import type { Feature, LineString, Point, Polygon } from 'geojson';
3 | import type {
4 | PartialDrawCircleOptions,
5 | PartialDrawLineOptions,
6 | PartialDrawPointOptions,
7 | PartialDrawPolygonOptions,
8 | PartialDrawRectOptions,
9 | } from '../types';
10 |
11 | export type UseDrawGroupConfig = {
12 | point?: PartialDrawPointOptions | boolean;
13 | line?: PartialDrawLineOptions | boolean;
14 | polygon?: PartialDrawPolygonOptions | boolean;
15 | rect?: PartialDrawRectOptions | boolean;
16 | circle?: PartialDrawCircleOptions | boolean;
17 | };
18 |
19 | export type CommonDrawOptions = DeepPartial;
20 |
21 | export type DrawGroupData = {
22 | point: Feature[];
23 | line: Feature[];
24 | polygon: Feature[];
25 | rect: Feature[];
26 | circle: Feature[];
27 | };
28 |
--------------------------------------------------------------------------------
/src/components/Draw/use-draw/constant.ts:
--------------------------------------------------------------------------------
1 | import { DrawCircle, DrawLine, DrawPoint, DrawPolygon, DrawRect } from '@antv/l7-draw';
2 | import type { DrawType } from '../types';
3 |
4 | export const DRAW_TYPE_MAP: Record = {
5 | point: DrawPoint,
6 | line: DrawLine,
7 | polygon: DrawPolygon,
8 | rect: DrawRect,
9 | circle: DrawCircle,
10 | };
11 |
--------------------------------------------------------------------------------
/src/components/Draw/use-draw/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, useDraw } from '@antv/larkmap';
2 | import React, { useEffect } from 'react';
3 |
4 | /**
5 | * useDraw 必须在 LarkMap 的子孙组件中调用
6 | */
7 | const CustomDraw = () => {
8 | const { enable } = useDraw({
9 | type: 'polygon',
10 | options: {},
11 | });
12 |
13 | useEffect(() => {
14 | enable();
15 | }, [enable]);
16 |
17 | return null;
18 | };
19 |
20 | const Default = () => {
21 | return (
22 |
31 |
32 |
33 | );
34 | };
35 |
36 | export default Default;
37 |
--------------------------------------------------------------------------------
/src/components/Draw/use-draw/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | order: 4
3 | toc: content
4 | group:
5 | title: 绘制组件
6 | order: 10
7 | ---
8 |
9 | ## useDraw
10 |
11 | ### 介绍
12 |
13 | 用 Hook 的方式操作和管理 [L7Draw](https://antv.vision/L7Draw/docs/draw/point) 中的绘制实例,以及实例上的数据和方法,**该 Hook 需放到容器组件内部才能使用**。
14 |
15 | ### 代码演示
16 |
17 | #### 默认示例
18 |
19 |
20 |
21 | #### 绘制开关
22 |
23 |
24 |
25 | ### API
26 |
27 | ```tsx | pure
28 | const { draw } = useDraw({
29 | type: 'point' | 'line' | 'polygon' | 'rect' | 'circle',
30 | options: DrawOptions, // 详见 https://l7draw.antv.vision/docs/draw/point#%E9%85%8D%E7%BD%AE
31 | });
32 | ```
33 |
34 | ### Params
35 |
36 | | 参数 | 说明 | 类型 |
37 | | --- | --- | --- |
38 | | type | 绘制类型 | `'point' | 'line' | 'polygon' | 'rect' | 'circle'` |
39 | | options | 绘制的 `options` 参数,详见 [L7Draw Options](https://antv.vision/L7Draw/docs/draw/point#%E9%85%8D%E7%BD%AE) | `DrawOptions` |
40 |
41 | ### Result
42 |
43 | | 返回值 | 说明 | 类型 |
44 | | --- | --- | --- |
45 | | draw | 绘制类 `Draw` 实例 | `DrawPoint | DrawLine | DrawPolygon | DrawRect | DrawCircle` |
46 | | drawData | 绘制的 `GeoJson` 数据 | `Feature[]` |
47 | | setDrawData | 设置绘制数据的方法 | `(newData: Feature[]) => void` |
48 | | getDrawData | 获取绘制数据的方法 | `() => Feature[]` |
49 | | isEnable | 当前 `Draw` 是否激活 | `boolean` |
50 | | enable | 启用绘制 | `() => void` |
51 | | disable | 禁用绘制 | `() => void` |
52 |
--------------------------------------------------------------------------------
/src/components/Draw/use-draw/types.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | PartialDrawCircleOptions,
3 | PartialDrawLineOptions,
4 | PartialDrawPointOptions,
5 | PartialDrawPolygonOptions,
6 | PartialDrawRectOptions,
7 | } from '../types';
8 |
9 | export type UseDrawParams =
10 | | {
11 | type: 'point';
12 | options: PartialDrawPointOptions;
13 | }
14 | | {
15 | type: 'line';
16 | options: PartialDrawLineOptions;
17 | }
18 | | {
19 | type: 'polygon';
20 | options: PartialDrawPolygonOptions;
21 | }
22 | | {
23 | type: 'rect';
24 | options: PartialDrawRectOptions;
25 | }
26 | | {
27 | type: 'circle';
28 | options: PartialDrawCircleOptions;
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/LarkMap/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps } from '@antv/larkmap';
2 | import { LarkMap } from '@antv/larkmap';
3 | import React from 'react';
4 |
5 | const config: LarkMapProps = {
6 | mapType: 'Gaode',
7 | mapOptions: {
8 | style: 'light',
9 | center: [120.210792, 30.246026],
10 | zoom: 9,
11 | // token: '你申请的 Key',
12 | },
13 | };
14 |
15 | export default () => (
16 |
17 | LarkMap
18 |
19 | );
20 |
--------------------------------------------------------------------------------
/src/components/LarkMap/helper.ts:
--------------------------------------------------------------------------------
1 | import type { IMapConfig } from '@antv/l7';
2 | import { BaiduMap, GaodeMap, GaodeMapV1, GaodeMapV2, Map, TencentMap } from '@antv/l7';
3 | import type { LarkMapProps } from './types';
4 |
5 | export const createMap = async (mapType: LarkMapProps['mapType'], mapOptions: Partial) => {
6 | if (mapType === 'Map') {
7 | return new Map(mapOptions);
8 | }
9 |
10 | if (mapType === 'Gaode') {
11 | return new GaodeMap(mapOptions);
12 | } else if (mapType === 'GaodeV1') {
13 | return new GaodeMapV1(mapOptions);
14 | } else if (mapType === 'GaodeV2') {
15 | return new GaodeMapV2(mapOptions);
16 | }
17 |
18 | if (mapType === 'Tencent') {
19 | return new TencentMap(mapOptions);
20 | }
21 |
22 | if (mapType === 'Baidu') {
23 | return new BaiduMap(mapOptions);
24 | }
25 |
26 | return Promise.resolve(import('@antv/l7')).then(({ Mapbox }) => {
27 | return new Mapbox(mapOptions);
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './use-control';
2 | export * from './use-layer';
3 | export * from './use-layer-list';
4 | export * from './use-layer-manager';
5 | export * from './use-scene';
6 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-control/index.ts:
--------------------------------------------------------------------------------
1 | import type { IControlOption, Scene } from '@antv/l7';
2 | import { Control } from '@antv/l7';
3 | import { useUpdateEffect } from 'ahooks';
4 | import { useEffect, useRef } from 'react';
5 | import { useScene } from '../use-scene';
6 |
7 | export const useControl = (
8 | onCreate: (context: Scene) => HTMLElement,
9 | onRemove?: (context: Scene) => void,
10 | opts?: IControlOption,
11 | ) => {
12 | const scene = useScene();
13 | const controlRef = useRef();
14 |
15 | useEffect(() => {
16 | // @ts-ignore
17 | const custom = new Control(opts);
18 |
19 | custom.onAdd = () => onCreate(scene);
20 | // eslint-disable-next-line @typescript-eslint/no-empty-function
21 | custom.onRemove = () => {};
22 |
23 | controlRef.current = custom;
24 | scene.addControl(custom);
25 |
26 | return () => {
27 | if (typeof onRemove === 'function') {
28 | onRemove(scene);
29 | }
30 | controlRef.current = null;
31 | scene.removeControl(custom);
32 | };
33 | // eslint-disable-next-line react-hooks/exhaustive-deps
34 | }, []);
35 |
36 | useUpdateEffect(() => {
37 | controlRef.current?.setOptions(opts);
38 | }, [opts]);
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer-list/demos/constants.ts:
--------------------------------------------------------------------------------
1 | import type { PolygonLayerProps } from '@antv/larkmap';
2 |
3 | export const PolygonLayerOptions: Omit = {
4 | autoFit: true,
5 | shape: 'fill',
6 | color: {
7 | field: 'adcode',
8 | value: ['#0f9960', '#33a02c', '#477eb8'],
9 | },
10 | state: {
11 | active: true,
12 | },
13 | style: {
14 | opacity: 0.6,
15 | },
16 | };
17 |
18 | export const LineLayerOptions: Omit = {
19 | shape: 'line',
20 | size: 2,
21 | color: '#595959',
22 | state: {
23 | active: false,
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer-list/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { CustomControl, LarkMap, PolygonLayer, useLayerList } from '@antv/larkmap';
2 | import { Card } from 'antd';
3 | import React, { useEffect, useState } from 'react';
4 | import { LineLayerOptions, PolygonLayerOptions } from './constants';
5 |
6 | const CustomComponent = () => {
7 | const layerList = useLayerList();
8 |
9 | useEffect(() => {
10 | console.log(layerList);
11 | }, [layerList]);
12 |
13 | return (
14 |
15 |
16 | 当前已有图层:
17 |
18 | {layerList.map((layer) => {
19 | return - {layer.name}
;
20 | })}
21 |
22 |
23 |
24 | );
25 | };
26 |
27 | export default () => {
28 | const [source, setSource] = useState({
29 | data: { type: 'FeatureCollection', features: [] },
30 | parser: { type: 'geojson' },
31 | });
32 |
33 | useEffect(() => {
34 | fetch('https://gw.alipayobjects.com/os/antfincdn/Y8eGLb9j9v/hangzhou-district.json')
35 | .then((response) => response.json())
36 | .then((data: any) => {
37 | setSource((prevState) => ({ ...prevState, data }));
38 | });
39 | }, []);
40 |
41 | return (
42 |
43 |
44 |
45 |
46 |
47 |
48 | );
49 | };
50 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer-list/index.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 | import { useLayerManager } from '../use-layer-manager';
3 |
4 | export const useLayerList = () => {
5 | const layerManager = useLayerManager();
6 | const [layerList, setLayerList] = useState(layerManager?.getLayers() || []);
7 |
8 | useEffect(() => {
9 | if (layerManager) {
10 | const onUpdateLayerList = () => {
11 | setLayerList(layerManager.getLayers());
12 | };
13 | layerManager.on('add', onUpdateLayerList);
14 | layerManager.on('remove', onUpdateLayerList);
15 | return () => {
16 | layerManager.off('add', onUpdateLayerList);
17 | layerManager.off('remove', onUpdateLayerList);
18 | };
19 | }
20 | }, [layerManager]);
21 |
22 | return layerList;
23 | };
24 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer-list/use-layer-list.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: useLayerList
3 | hide: true
4 | order: 3
5 | toc: content
6 | group:
7 | title: 容器组件
8 | ---
9 |
10 | ## useLayerList
11 |
12 | ### 介绍
13 |
14 | 获取当前 LarkMap 下所有的图层实例,并且会根据图层组件增删情况动态更新返回的图层数组。
15 |
16 | ### 默认示例
17 |
18 |
19 |
20 | ### API
21 |
22 | ```ts
23 | const layerList: Layer[] = useLayerList();
24 | ```
25 |
26 | #### Result
27 |
28 | | 参数 | 说明 | 类型 |
29 | | --- | --- | --- |
30 | | layerList | 图层实例数组,详情可见 [L7Plot](https://l7plot.antv.antgroup.com/zh/docs/api/base-layers/point-layer) | `Array` |
31 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer-manager/index.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react';
2 | import { LarkMapContext } from '../../index';
3 |
4 | export const useLayerManager = () => {
5 | const context = useContext(LarkMapContext);
6 | if (!context) {
7 | throw new Error('The useLayerManager must be used in the LarkMap container');
8 | }
9 | const { layerManager } = context;
10 |
11 | return layerManager;
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer/demos/constants.ts:
--------------------------------------------------------------------------------
1 | export const source = {
2 | data: [
3 | { lng: 120.210792, lat: 30.246026, c: 'red', t: 20, n: '杭州' },
4 | { lng: 121.473667, lat: 31.230525, c: 'blue', t: 24, n: '上海' },
5 | ],
6 | parser: { type: 'json', x: 'lng', y: 'lat' },
7 | };
8 | export const layerOptions = {
9 | autoFit: false,
10 | radius: 40,
11 | fillColor: '#0f9960',
12 | opacity: 0.4,
13 | strokeColor: 'blue',
14 | lineWidth: 2,
15 | state: {
16 | active: { strokeColor: 'red', lineWidth: 2, lineOpacity: 1 },
17 | },
18 | label: {
19 | field: 't',
20 | visible: true,
21 | style: {
22 | fill: '#454d64',
23 | fontSize: 18,
24 | stroke: '#fff',
25 | strokeWidth: 2,
26 | textOffset: [0, -20] as [number, number],
27 | },
28 | },
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { BubbleLayer, LarkMap, useLayer } from '@antv/larkmap';
2 | import React, { useEffect } from 'react';
3 | import { layerOptions, source } from './constants';
4 |
5 | const MyComponent = () => {
6 | const myBubbleLayer = useLayer('myBubbleLayer');
7 |
8 | useEffect(() => {
9 | myBubbleLayer?.fitBounds();
10 | }, [myBubbleLayer]);
11 |
12 | return null;
13 | };
14 |
15 | export default () => {
16 | return (
17 |
18 |
19 |
20 |
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer/index.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 | import type { Layer } from '../../../../types';
3 | import { useLayerManager } from '../use-layer-manager';
4 |
5 | export const useLayer = (id: string): T | undefined => {
6 | const layerManager = useLayerManager();
7 | const [layer, setLayer] = useState(layerManager.getLayer(id) as T);
8 |
9 | useEffect(() => {
10 | const onLayerAdd = (_layer: T) => {
11 | if (id === _layer.id) {
12 | setLayer(_layer);
13 | }
14 | };
15 | const onLayerRemove = (layerId: string) => {
16 | if (id === layerId) {
17 | setLayer(undefined);
18 | }
19 | };
20 | const _layer = layerManager.getLayer(id);
21 |
22 | if (_layer) {
23 | setLayer(_layer as T);
24 | } else {
25 | layerManager.on('add', onLayerAdd);
26 | layerManager.on('remove', onLayerRemove);
27 | }
28 |
29 | return () => {
30 | if (_layer === undefined) {
31 | layerManager.off('add', onLayerAdd);
32 | layerManager.off('remove', onLayerRemove);
33 | }
34 | };
35 | // eslint-disable-next-line react-hooks/exhaustive-deps
36 | }, [id]);
37 |
38 | return layer;
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-layer/use-layer.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: useLayer
3 | order: 2
4 | toc: content
5 | group:
6 | title: 容器组件
7 | ---
8 |
9 | ## useLayer
10 |
11 | ### 介绍
12 |
13 | 获取图层实例 Hook,配合图层组件一起使用,用于子组件拿到图层实例,**该 Hook 需放到容器组件内部才能使用**。
14 |
15 | ### 默认示例
16 |
17 |
18 |
19 | ### API
20 |
21 | ```ts
22 | const layer: Layer = useLayer(id: string);
23 | ```
24 |
25 | #### Params
26 |
27 | | 参数 | 说明 | 类型 | 默认值 |
28 | | ---- | ------- | -------- | -------- |
29 | | id | 图层 ID | `string` | `(必选)` |
30 |
31 | #### Result
32 |
33 | | 参数 | 说明 | 类型 |
34 | | ----- | ------------------------------------------------------------------------------------------------- | ------- |
35 | | layer | 图层实例,详情可见 [L7Plot](https://l7plot.antv.antgroup.com/zh/docs/api/base-layers/point-layer) | `Layer` |
36 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-scene-event/constant.ts:
--------------------------------------------------------------------------------
1 | import type { SceneEventProps } from '../../types';
2 |
3 | /**
4 | * 从 LarkMap 的事件名到 Scene 事件名的映射
5 | */
6 | export const SceneEventMap: Record = {
7 | onLoaded: 'loaded',
8 | onDestroy: 'destroy',
9 |
10 | onResize: 'resize',
11 |
12 | onMapMove: 'mapmove',
13 | onMoveStart: 'movestart',
14 | onMoveEnd: 'moveend',
15 | onZoomChange: 'zoomchange',
16 | onZoomStart: 'zoomstart',
17 | onZoomEnd: 'zoomend',
18 |
19 | onClick: 'click',
20 | onDblclick: 'dblclick',
21 | onContextMenu: 'contextmenu',
22 |
23 | onMouseMove: 'mousemove',
24 | onMouseWheel: 'mousewheel',
25 | onMouseDown: 'mousedown',
26 | onMouseOver: 'mouseover',
27 | onMouseOut: 'mouseout',
28 | onMouseUp: 'mouseup',
29 |
30 | onDragStart: 'dragstart',
31 | onDragging: 'dragging',
32 | onDragEnd: 'dragend',
33 | };
34 |
35 | /**
36 | * LarkMap 事件名列表
37 | */
38 | export const SceneEventList = Object.keys(SceneEventMap) as (keyof SceneEventProps)[];
39 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-scene/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, useScene } from '@antv/larkmap';
2 | import React, { useEffect } from 'react';
3 |
4 | const ChildComponent = () => {
5 | const scene = useScene();
6 |
7 | useEffect(() => {
8 | scene.setMapStyle('dark');
9 | }, []);
10 |
11 | return null;
12 | };
13 |
14 | export default () => (
15 |
16 |
17 |
18 | );
19 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-scene/index.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react';
2 | import { LarkMapContext } from '../../index';
3 |
4 | export const useScene = () => {
5 | const context = useContext(LarkMapContext);
6 | if (!context) {
7 | throw new Error('The useScene must be used in the LarkMap container');
8 | }
9 | const { scene } = context;
10 |
11 | return scene;
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/LarkMap/hooks/use-scene/use-scene.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: useScene
3 | order: 1
4 | toc: content
5 | group:
6 | title: 容器组件
7 | ---
8 |
9 | ## useScene
10 |
11 | ### 介绍
12 |
13 | 获取 scene 实例 Hook,一般用于子组件拿到 scene 实例,**该 Hook 需放到容器组件内部才能使用**。
14 |
15 | ### 默认示例
16 |
17 |
18 |
19 | ### API
20 |
21 | ```ts
22 | const scene: Scene = useScene();
23 | ```
24 |
25 | #### Result
26 |
27 | | 参数 | 说明 | 类型 |
28 | | ----- | --------------------------------------------------------------------------- | ------- |
29 | | scene | scene 实例,实例方法详见 [L7 scene](https://l7.antv.antgroup.com/api/scene) | `Scene` |
30 |
--------------------------------------------------------------------------------
/src/components/LayerPopup/types.ts:
--------------------------------------------------------------------------------
1 | import type { ILayerPopupOption, LayerField, LayerPopupConfigItem } from '@antv/l7';
2 | import type { ReactNode } from 'react';
3 | import type { Layer } from '../../types';
4 | import type { PopupProps } from '../Popup/types';
5 |
6 | export interface ILayerField extends Omit {
7 | formatField?: ReactNode | ((field: string, feature: any) => ReactNode);
8 | formatValue?: ReactNode | ((value: any, feature: any) => ReactNode);
9 | }
10 |
11 | export interface ILayerPopupConfigItem
12 | extends Omit {
13 | title?: ReactNode | ((feature: any) => ReactNode);
14 | customContent?: ReactNode | ((feature: any) => ReactNode);
15 | fields?: (ILayerField | string)[];
16 | layer?: Layer | string;
17 | }
18 |
19 | export interface LayerPopupProps
20 | extends Omit,
21 | Pick {
22 | items: ILayerPopupConfigItem[];
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/LayerPopup/utils.ts:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | /**
5 | * 将 render 中的 JSX 格式转换成 DOM 和 Portal 的形式
6 | * @param render
7 | * @param tag
8 | */
9 | export const getElementTypePortal = (
10 | render: ReactNode | ((...args: any[]) => ReactNode),
11 | tag: keyof HTMLElementTagNameMap,
12 | ) => {
13 | // 若 render 为函数格式,则在其每次调用时重新生成 dom 和 portal
14 | if (render instanceof Function) {
15 | const dom = document.createElement(tag);
16 | return (...args: any[]) => {
17 | const reactNode = render(...args);
18 | const portal = ReactDOM.createPortal(reactNode, dom);
19 | ReactDOM.render(portal, dom);
20 | return dom;
21 | };
22 | } else {
23 | const dom = document.createElement(tag);
24 | const portal = ReactDOM.createPortal(render, dom);
25 | ReactDOM.render(portal, dom);
26 | return dom;
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/HeatmapLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { HeatmapLayerProps } from '@antv/larkmap';
2 | import { HeatmapLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | shape: 'heatmap' as const,
8 | size: {
9 | field: 't',
10 | value: [0, 1],
11 | },
12 | style: {
13 | intensity: 3,
14 | radius: 20,
15 | opacity: 1,
16 | rampColors: {
17 | colors: ['#FF4818', '#F7B74A', '#FFF598', '#F27DEB', '#8C1EB2', '#421EB2'],
18 | positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0],
19 | },
20 | },
21 | };
22 |
23 | export default () => {
24 | const [options, setOptions] = useState(layerOptions);
25 | const [source, setSource] = useState({
26 | data: [],
27 | parser: { type: 'json', x: 'lng', y: 'lat' },
28 | });
29 |
30 | useEffect(() => {
31 | fetch('https://gw.alipayobjects.com/os/antfincdn/o1GNZoJ2rK/points-center.json')
32 | .then((response) => response.json())
33 | .then((data: any) => {
34 | setSource((prevState) => ({ ...prevState, data }));
35 | });
36 | }, []);
37 |
38 | return (
39 |
40 |
41 |
42 | );
43 | };
44 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/HeatmapLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { HeatmapLayer as L7HeatmapLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { HeatmapLayerProps } from './types';
5 |
6 | export const HeatmapLayer = memo(
7 | forwardRef(function HeatmapLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7HeatmapLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/HeatmapLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { HeatmapLayer, HeatmapLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface HeatmapLayerProps extends HeatmapLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/ImageLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { ImageLayerProps } from '@antv/larkmap';
2 | import { ImageLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | style: {
8 | opacity: 0.8,
9 | },
10 | };
11 |
12 | export default () => {
13 | const [options, setOptions] = useState(layerOptions);
14 | const [source, setSource] = useState({
15 | data: 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',
16 | parser: {
17 | type: 'image',
18 | extent: [121.168, 30.2828, 121.384, 30.4219],
19 | },
20 | });
21 |
22 | return (
23 |
24 |
25 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/ImageLayer/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 6
4 | group:
5 | title: 基础图层
6 | order: 1
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 图片图层 - ImageLayer
13 |
14 | ### 介绍
15 |
16 | 基于 [ImageLayer](https://l7plot.antv.antgroup.com/zh/docs/api/base-layers/image-layer) 封装,用于图片数据展示。
17 |
18 | ### 代码演示
19 |
20 | #### 默认示例
21 |
22 |
23 |
24 | ### API
25 |
26 | | 参数 | 说明 | 类型 | 默认值 |
27 | | --- | --- | --- | --- |
28 | | ref | 组件 Ref | `Ref` | -- |
29 | | id | 图层 ID | `string` | -- |
30 | | name | 图层名称 | `string` | -- |
31 | | zIndex | 图层 | `number` | -- |
32 | | visible | 图层是否可见 | `boolean` | `true` |
33 | | minZoom | 图层最小可见层级 | `number` | -- |
34 | | maxZoom | 图层最大可见层级 | `number` | -- |
35 | | autoFit | 图层加载成功后是否自动定位到图层数据可见范围,`注意`开启后图层数据发生更新时,地图也会自动缩放到图层的数据边界范围 | `boolean` | `false` |
36 | | blend | 图层元素混合效果 | `"normal"|`
`"additive"|`
`"subtractive"|`
`"min"|`
`"max"|`
`"none"` | `"normal"` |
37 | | source | 数据配置,详情可见 [Source](#source) | `SourceOptions` | `(必选)` |
38 | | style | 元素样式,详情可见 [Style](#style) | `ImageLayerStyleOptions` | -- |
39 | | onCreated | 图层初始化完成后回调,用于获取 layer 对象 | `(layer: ImageLayer) => void` | -- |
40 |
41 | #### source
42 |
43 |
44 |
45 | #### style
46 |
47 |
48 |
49 | ### Event
50 |
51 |
52 |
53 | ### FAQ
54 |
55 | #### 1. 如何获取图层实例?
56 |
57 | 详见 [获取图层实例](/components/layers/composite-layers/bubble-layer#1-如何获取图层实例)
58 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/ImageLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { ImageLayer as L7ImageLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { ImageLayerProps } from './types';
5 |
6 | export const ImageLayer = memo(
7 | forwardRef(function ImageLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7ImageLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/ImageLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { ImageLayer, ImageLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface ImageLayerProps extends ImageLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/LineLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { LineLayerProps } from '@antv/larkmap';
2 | import { LarkMap, LineLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | shape: 'line' as const,
8 | size: 1.5,
9 | color: {
10 | field: 'line_name',
11 | value: ['#5B8FF9', '#5CCEA1', '#5D7092'],
12 | },
13 | state: { active: { color: '#FFF684' } },
14 | style: {
15 | opacity: 0.8,
16 | lineType: 'solid' as const,
17 | },
18 | };
19 |
20 | export default () => {
21 | const [options, setOptions] = useState(layerOptions);
22 | const [source, setSource] = useState({
23 | data: [],
24 | parser: { type: 'json', coordinates: 'lnglat' },
25 | });
26 |
27 | useEffect(() => {
28 | fetch('https://gw.alipayobjects.com/os/antfincdn/1atwIMvcMo/beijinggongjiaoluxian.json')
29 | .then((response) => response.json())
30 | .then((data: any) => {
31 | setSource((prevState) => ({ ...prevState, data }));
32 | });
33 | }, []);
34 |
35 | return (
36 |
37 |
38 |
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/LineLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { LineLayer as L7LineLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { LineLayerProps } from './types';
5 |
6 | export const LineLayer = memo(
7 | forwardRef(function LineLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7LineLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/LineLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { LineLayer, LineLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface LineLayerProps extends LineLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/PointLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { PointLayerProps } from '@antv/larkmap';
2 | import { LarkMap, PointLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | shape: 'circle',
8 | size: {
9 | field: 'temperature',
10 | value: ({ temperature }) => temperature,
11 | },
12 | color: {
13 | field: 'temperature',
14 | value: ['#0f9960', '#33a02c', '#377eb8'],
15 | },
16 | state: {
17 | active: true,
18 | },
19 | style: {
20 | opacity: 0.8,
21 | },
22 | };
23 |
24 | export default () => {
25 | const [options, setOptions] = useState(layerOptions);
26 | const [source, setSource] = useState({
27 | data: [],
28 | parser: { type: 'json', x: 'lng', y: 'lat' },
29 | });
30 |
31 | useEffect(() => {
32 | fetch('https://gw.alipayobjects.com/os/antfincdn/Lx96%24Pnwhw/city-weather.json')
33 | .then((response) => response.json())
34 | .then((data: any) => {
35 | setSource((prevState) => ({ ...prevState, data }));
36 | });
37 | }, []);
38 |
39 | return (
40 |
41 |
42 |
43 | );
44 | };
45 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/PointLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { PointLayer as L7PointLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { PointLayerProps } from './types';
5 |
6 | export const PointLayer = memo(
7 | forwardRef(function PointLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7PointLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/PointLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { PointLayer, PointLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface PointLayerProps extends PointLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/PolygonLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { PolygonLayerProps } from '@antv/larkmap';
2 | import { LarkMap, PolygonLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | shape: 'fill',
8 | color: {
9 | field: 'adcode',
10 | value: ['#0f9960', '#33a02c', '#477eb8'],
11 | },
12 | state: {
13 | active: true,
14 | },
15 | style: {
16 | opacity: 0.6,
17 | },
18 | };
19 |
20 | export default () => {
21 | const [options, setOptions] = useState(layerOptions);
22 | const [source, setSource] = useState({
23 | data: { type: 'FeatureCollection', features: [] },
24 | parser: { type: 'geojson' },
25 | });
26 |
27 | useEffect(() => {
28 | fetch('https://gw.alipayobjects.com/os/antfincdn/Y8eGLb9j9v/hangzhou-district.json')
29 | .then((response) => response.json())
30 | .then((data: any) => {
31 | setSource((prevState) => ({ ...prevState, data }));
32 | });
33 | }, []);
34 |
35 | return (
36 |
37 |
38 |
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/PolygonLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { PolygonLayer as L7PolygonLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { PolygonLayerProps } from './types';
5 |
6 | export const PolygonLayer = memo(
7 | forwardRef(function PolygonLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7PolygonLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/PolygonLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { PolygonLayer, PolygonLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface PolygonLayerProps extends PolygonLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/RasterLayer/demos/rasterImage.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps, RasterLayerProps } from '@antv/larkmap';
2 | import { LarkMap, RasterLayer } from '@antv/larkmap';
3 | import React from 'react';
4 |
5 | const config: LarkMapProps = {
6 | mapType: 'Map',
7 | mapOptions: {
8 | center: [120.210792, 30.246026] as [number, number],
9 | zoom: 9,
10 | },
11 | };
12 |
13 | const layerOptions: Omit = {
14 | visible: true,
15 | style: {},
16 | };
17 |
18 | export default () => {
19 | return (
20 |
21 |
28 |
29 | );
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/RasterLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { RasterLayer as L7RasterLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { RasterLayerProps } from './types';
5 |
6 | export const RasterLayer = memo(
7 | forwardRef(function PointLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7RasterLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/RasterLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { RasterLayer, RasterLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface RasterLayerProps extends RasterLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/TextLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { TextLayerProps } from '@antv/larkmap';
2 | import { LarkMap, TextLayer } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | field: 'text',
8 | style: {
9 | fill: {
10 | field: 't',
11 | value: [
12 | '#ffba08',
13 | '#faa307',
14 | '#f48c06',
15 | '#e85d04',
16 | '#dc2f02',
17 | '#d00000',
18 | '#9d0208',
19 | '#6a040f',
20 | '#370617',
21 | '#03071e',
22 | ],
23 | },
24 | opacity: 1,
25 | fontSize: 18,
26 | stroke: '#fff',
27 | strokeWidth: 2,
28 | textAllowOverlap: false,
29 | padding: [10, 10] as [number, number],
30 | },
31 | };
32 |
33 | export default () => {
34 | const [options, setOptions] = useState(layerOptions);
35 | const [source, setSource] = useState({
36 | data: [],
37 | parser: { type: 'json', x: 'j', y: 'w' },
38 | });
39 |
40 | useEffect(() => {
41 | fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
42 | .then((response) => response.json())
43 | .then((data: any) => {
44 | setSource((prevState) => ({
45 | ...prevState,
46 | data: data.list.map((item) => ({ ...item, text: `${item.m} ${item.t}` })),
47 | }));
48 | });
49 | }, []);
50 |
51 | return (
52 |
53 |
54 |
55 | );
56 | };
57 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/TextLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { TextLayer as L7TextLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { TextLayerProps } from './types';
5 |
6 | export const TextLayer = memo(
7 | forwardRef(function TextLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7TextLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/BaseLayers/TextLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { TextLayer, TextLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface TextLayerProps extends TextLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/BubbleLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { BubbleLayerProps } from '@antv/larkmap';
2 | import { BubbleLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const bubbleLayerOptions: Omit = {
6 | autoFit: true,
7 | radius: {
8 | field: 'temperature',
9 | value: ({ temperature }) => temperature,
10 | },
11 | fillColor: {
12 | field: 'temperature',
13 | value: ['#0f9960', '#33a02c', '#377eb8'],
14 | },
15 | opacity: 0.4,
16 | strokeColor: 'blue',
17 | lineWidth: 1,
18 | state: {
19 | active: { strokeColor: 'red', lineWidth: 2, lineOpacity: 1 },
20 | },
21 | label: {
22 | field: 'temperature',
23 | visible: true,
24 | style: { fill: '#454d64', fontSize: 18, stroke: '#fff', strokeWidth: 2, textOffset: [0, -20] as [number, number] },
25 | },
26 | };
27 |
28 | export default () => {
29 | const [layerOptions, setLayerOptions] = useState(bubbleLayerOptions);
30 | const [source, setSource] = useState({
31 | data: [],
32 | parser: { type: 'json', x: 'lng', y: 'lat' },
33 | });
34 |
35 | useEffect(() => {
36 | fetch('https://gw.alipayobjects.com/os/antfincdn/Lx96%24Pnwhw/city-weather.json')
37 | .then((response) => response.json())
38 | .then((data: any) => {
39 | setSource((prevState) => ({ ...prevState, data }));
40 | });
41 | }, []);
42 |
43 | return (
44 |
45 |
46 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/BubbleLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { BubbleLayer as L7BubbleLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { LayerEventMap } from '../../hooks/use-layer-event/constant';
4 | import { useCreateLayer, useLayerEvent } from '../../hooks';
5 | import type { BubbleLayerProps } from './types';
6 |
7 | const BubbleLayerEventMap = Object.assign(LayerEventMap, { onSelect: 'select', onUnselect: 'unselect' });
8 |
9 | export const BubbleLayer = memo(
10 | forwardRef(function BubbleLayer(props, ref) {
11 | const layerRef = useCreateLayer(L7BubbleLayer, props);
12 |
13 | useLayerEvent(layerRef.current, props, BubbleLayerEventMap);
14 | useImperativeHandle(ref, () => layerRef.current);
15 |
16 | return null;
17 | }),
18 | );
19 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/BubbleLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | BubbleLayer,
3 | BubbleLayerOptions,
4 | ColorAttr,
5 | SizeAttr,
6 | SourceOptions,
7 | TextLayerOptions,
8 | } from '@antv/l7-composite-layers';
9 | import type { LayerCommonProps, LayerEventCallback } from '../../../../types';
10 |
11 | export type { SourceOptions, ColorAttr, SizeAttr, TextLayerOptions };
12 |
13 | /**
14 | * 组件类型定义
15 | */
16 | export interface BubbleLayerProps extends BubbleLayerOptions, LayerCommonProps {
17 | /** 选择事件 */
18 | onSelect?: LayerEventCallback;
19 | /** 取消选择事件 */
20 | onUnselect?: LayerEventCallback;
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/ChoroplethLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { ChoroplethLayerProps } from '@antv/larkmap';
2 | import { ChoroplethLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | const layerOptions: Omit = {
6 | autoFit: true,
7 | fillColor: {
8 | field: 'adcode',
9 | value: ['#0f9960', '#33a02c', '#377eb8'],
10 | },
11 | opacity: 0.3,
12 | strokeColor: 'blue',
13 | lineWidth: 1,
14 | state: {
15 | active: { strokeColor: 'green', lineWidth: 1.5, lineOpacity: 0.8 },
16 | select: { strokeColor: 'red', lineWidth: 1.5, lineOpacity: 0.8 },
17 | },
18 | label: {
19 | field: 'name',
20 | visible: true,
21 | style: { fill: 'blue', fontSize: 12, stroke: '#fff', strokeWidth: 2 },
22 | },
23 | };
24 |
25 | export default () => {
26 | const [options, setOptions] = useState(layerOptions);
27 | const [source, setSource] = useState({
28 | data: { type: 'FeatureCollection', features: [] },
29 | parser: { type: 'geojson' },
30 | });
31 |
32 | useEffect(() => {
33 | fetch('https://gw.alipayobjects.com/os/antfincdn/Y8eGLb9j9v/hangzhou-district.json')
34 | .then((response) => response.json())
35 | .then((data: any) => {
36 | setSource((prevState) => ({ ...prevState, data }));
37 | });
38 | }, []);
39 |
40 | return (
41 |
42 |
43 |
44 | );
45 | };
46 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/ChoroplethLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { ChoroplethLayer as L7ChoroplethLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { LayerEventMap } from '../../hooks/use-layer-event/constant';
4 | import { useCreateLayer, useLayerEvent } from '../../hooks';
5 | import type { ChoroplethLayerProps } from './types';
6 |
7 | const ChoroplethLayerEventMap = Object.assign(LayerEventMap, { onSelect: 'select', onUnselect: 'unselect' });
8 |
9 | export const ChoroplethLayer = memo(
10 | forwardRef(function ChoroplethLayer(props, ref) {
11 | const layerRef = useCreateLayer(L7ChoroplethLayer, props);
12 |
13 | useLayerEvent(layerRef.current, props, ChoroplethLayerEventMap);
14 | useImperativeHandle(ref, () => layerRef.current);
15 |
16 | return null;
17 | }),
18 | );
19 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/ChoroplethLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | ChoroplethLayer,
3 | ChoroplethLayerActiveOptions,
4 | ChoroplethLayerOptions,
5 | ChoroplethLayerSourceOptions,
6 | } from '@antv/l7-composite-layers';
7 | import type { LayerCommonProps, LayerEventCallback } from '../../../../types';
8 |
9 | export type { ChoroplethLayerActiveOptions, ChoroplethLayerSourceOptions };
10 |
11 | /**
12 | * 组件类型定义
13 | */
14 | export interface ChoroplethLayerProps extends ChoroplethLayerOptions, LayerCommonProps {
15 | /** 选择事件 */
16 | onSelect?: LayerEventCallback;
17 | /** 取消选择事件 */
18 | onUnselect?: LayerEventCallback;
19 | }
20 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/FlowLayer/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { FlowLayerProps } from '@antv/larkmap';
2 | import { FlowLayer, LarkMap } from '@antv/larkmap';
3 | import React, { useEffect, useState } from 'react';
4 |
5 | export default () => {
6 | const [source, setSource] = useState({
7 | data: [],
8 | parser: {
9 | type: 'json',
10 | x: 'f_lon',
11 | y: 'f_lat',
12 | x1: 't_lon',
13 | y1: 't_lat',
14 | weight: 'weight',
15 | },
16 | });
17 |
18 | useEffect(() => {
19 | fetch('https://gw.alipayobjects.com/os/bmw-prod/f4f3e99a-1d6c-4ab0-b08f-ec730c576b62.json')
20 | .then((response) => response.json())
21 | .then((data: any) => {
22 | setSource((prevState) => ({ ...prevState, data }));
23 | });
24 | }, []);
25 |
26 | return (
27 |
36 | {source.data.length !== 0 && (
37 | console.log('circle layer click', e)}
40 | onLineLayerClick={(e) => console.log('line layer click', e)}
41 | />
42 | )}
43 |
44 | );
45 | };
46 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/FlowLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { FlowLayer as L7FlowLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import { FlowLayerEventMap } from './constants';
5 | import type { FlowLayerProps } from './types';
6 |
7 | export const FlowLayer = memo(
8 | forwardRef(function TrafficFlowLayer(props, ref) {
9 | const layerRef = useCreateLayer(L7FlowLayer, props);
10 | useLayerEvent(layerRef.current, props, FlowLayerEventMap);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/IconFontLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { IconFontLayer as L7IconFontLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { IconFontLayerProps } from './types';
5 |
6 | export const IconFontLayer = memo(
7 | forwardRef(function IconFontLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7IconFontLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/IconFontLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { IconFontLayer, IconFontLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface IconFontLayerProps extends IconFontLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/IconImageLayer/index.tsx:
--------------------------------------------------------------------------------
1 | import { IconImageLayer as L7IconImageLayer } from '@antv/l7-composite-layers';
2 | import { forwardRef, memo, useImperativeHandle } from 'react';
3 | import { useCreateLayer, useLayerEvent } from '../../hooks';
4 | import type { IconImageLayerProps } from './types';
5 |
6 | export const IconImageLayer = memo(
7 | forwardRef(function IconImageLayer(props, ref) {
8 | const layerRef = useCreateLayer(L7IconImageLayer, props);
9 |
10 | useLayerEvent(layerRef.current, props);
11 | useImperativeHandle(ref, () => layerRef.current);
12 |
13 | return null;
14 | }),
15 | );
16 |
--------------------------------------------------------------------------------
/src/components/Layers/CompositeLayers/IconImageLayer/types.ts:
--------------------------------------------------------------------------------
1 | import type { IconImageLayer, IconImageLayerOptions } from '@antv/l7-composite-layers';
2 | import type { LayerCommonProps } from '../../../../types';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface IconImageLayerProps extends IconImageLayerOptions, LayerCommonProps {}
8 |
--------------------------------------------------------------------------------
/src/components/Layers/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './use-create-layer';
2 | export * from './use-layer-event';
3 |
--------------------------------------------------------------------------------
/src/components/Layers/hooks/use-layer-event/constant.ts:
--------------------------------------------------------------------------------
1 | import type { LayerEventProps } from '../../../../types';
2 |
3 | /**
4 | * 从 LarkMap 的事件名到 Layer 事件名的映射
5 | */
6 | export const LayerEventMap: Record = {
7 | // 生命周期事件
8 | // 代理掉的事件
9 | // onCreated: 'created',
10 | // 不代理掉的事件
11 | // onInited: 'inited',
12 | // onAdd: 'add',
13 | onRemove: 'remove',
14 | onShow: 'show',
15 | onHide: 'hide',
16 | onDataUpdate: 'dataUpdate',
17 | onLegend: 'legend',
18 | onLegendColor: 'legend:color',
19 | onLegendSize: 'legend:size',
20 |
21 | // 点击事件
22 | onClick: 'click',
23 | onUnClick: 'unclick',
24 | onDblClick: 'dblclick',
25 | onUndblclick: 'undblclick',
26 | onContextMenu: 'contextmenu',
27 | onUnContextMenu: 'uncontextmenu',
28 |
29 | // 鼠标事件
30 | onMouseEnter: 'mouseenter',
31 | onMouseMove: 'mousemove',
32 | onMouseOut: 'mouseout',
33 | onMouseUp: 'mouseup',
34 | onMouseDown: 'mousedown',
35 | onUnMousemove: 'unmousemove',
36 | onUnMouseup: 'unmouseup',
37 | onUnMousedown: 'unmousedown',
38 | onUnPick: 'unpick',
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/Layers/hooks/use-layer-event/index.ts:
--------------------------------------------------------------------------------
1 | import { useUnmount } from 'ahooks';
2 | import { useEffect, useMemo, useRef } from 'react';
3 | import type { Layer, LayerEventProps } from '../../../../types';
4 | import { LayerEventMap } from './constant';
5 |
6 | export const useLayerEvent = (
7 | layer: Layer,
8 | props: LayerEventProps,
9 | layerEventMap: Record = LayerEventMap,
10 | ) => {
11 | // LarkMap 事件名列表
12 | const layerEventList = useMemo(() => Object.keys(layerEventMap), [layerEventMap]);
13 |
14 | // 绑定或解绑所有事件的回调函数
15 | const handleLayerEvents = (type: 'on' | 'off') => {
16 | layerEventList.forEach((callbackName) => {
17 | const eventName = layerEventMap[callbackName];
18 | const callback = props[callbackName];
19 |
20 | if (callbackName && callback) {
21 | layer[type](eventName, callback);
22 | }
23 | });
24 | };
25 |
26 | const bindLayerEvents = () => handleLayerEvents('on');
27 |
28 | const unbindLayerEvents = () => handleLayerEvents('off');
29 |
30 | const isFirstRef = useRef(true);
31 |
32 | // 保证图层初始化后同步执行事件绑定,而不是在 useEffect 中异步绑定事件
33 | if (isFirstRef.current) {
34 | bindLayerEvents();
35 | }
36 |
37 | useEffect(() => {
38 | if (isFirstRef.current) {
39 | isFirstRef.current = false;
40 | } else {
41 | bindLayerEvents();
42 | }
43 | return () => {
44 | unbindLayerEvents();
45 | };
46 | // eslint-disable-next-line react-hooks/exhaustive-deps
47 | }, layerEventList.map((eventName) => props[eventName]));
48 |
49 | useUnmount(() => {
50 | unbindLayerEvents();
51 | });
52 | };
53 |
--------------------------------------------------------------------------------
/src/components/Layers/index.ts:
--------------------------------------------------------------------------------
1 | export { HeatmapLayer } from './BaseLayers/HeatmapLayer';
2 | export type { HeatmapLayerProps } from './BaseLayers/HeatmapLayer/types';
3 | export { ImageLayer } from './BaseLayers/ImageLayer';
4 | export type { ImageLayerProps } from './BaseLayers/ImageLayer/types';
5 | export { LineLayer } from './BaseLayers/LineLayer';
6 | export type { LineLayerProps } from './BaseLayers/LineLayer/types';
7 | export { PointLayer } from './BaseLayers/PointLayer';
8 | export type { PointLayerProps } from './BaseLayers/PointLayer/types';
9 | export { PolygonLayer } from './BaseLayers/PolygonLayer';
10 | export type { PolygonLayerProps } from './BaseLayers/PolygonLayer/types';
11 | export { RasterLayer } from './BaseLayers/RasterLayer';
12 | export type { RasterLayerProps } from './BaseLayers/RasterLayer/types';
13 | export { TextLayer } from './BaseLayers/TextLayer';
14 | export type { TextLayerProps } from './BaseLayers/TextLayer/types';
15 | export { BubbleLayer } from './CompositeLayers/BubbleLayer';
16 | export type { BubbleLayerProps } from './CompositeLayers/BubbleLayer/types';
17 | export { ChoroplethLayer } from './CompositeLayers/ChoroplethLayer';
18 | export type { ChoroplethLayerProps } from './CompositeLayers/ChoroplethLayer/types';
19 | export { FlowLayer } from './CompositeLayers/FlowLayer';
20 | export type { FlowLayerProps } from './CompositeLayers/FlowLayer/types';
21 | export { IconFontLayer } from './CompositeLayers/IconFontLayer';
22 | export type { IconFontLayerProps } from './CompositeLayers/IconFontLayer/types';
23 | export { IconImageLayer } from './CompositeLayers/IconImageLayer';
24 | export type { IconImageLayerProps } from './CompositeLayers/IconImageLayer/types';
25 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendCategories/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LegendCategories } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
12 |
17 |
23 |
24 |
29 |
30 | );
31 | };
32 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendCategories/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-legend-category;
2 |
3 | .@{cls-prefix} {
4 | &__content {
5 | display: flex;
6 | align-items: center;
7 | margin-bottom: 5px;
8 | &__labels {
9 | letter-spacing: 2;
10 | text-transform: uppercase;
11 | font-family: PingFangSC;
12 | line-height: 2;
13 | }
14 |
15 | &__shape {
16 | margin-right: 15px;
17 | }
18 |
19 | &__square {
20 | width: 32px;
21 | height: 15px
22 | }
23 |
24 | &__circle {
25 | width: 14px;
26 | height: 14px;
27 | border-radius: 50%;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendCategories/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 1
4 | group:
5 | title: 图例组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 分类图例 - LegendCategories
13 |
14 | ### 介绍
15 |
16 | 分类图例,常用于当图层要素根据其类别映射不同颜色时,展示要素信息和颜色的对应关系。
17 |
18 | ### 代码演示
19 |
20 | #### 默认演示
21 |
22 |
23 |
24 | #### 在地图中展示
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendCategories/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames';
3 | import { getGradientColors } from '../../../utils/color';
4 | import './index.less';
5 | import type { LegendCategoriesProps } from './types';
6 |
7 | export const CLS_PREFIX = 'larkmap-legend-category';
8 |
9 | export function LegendCategories(props: LegendCategoriesProps) {
10 | const { labels, colors, geometryType = 'circle', isStrokeColor = false, style, className: cls_name } = props;
11 |
12 | function getColor(item: string) {
13 | return isStrokeColor ? { border: `2px solid ${item}` } : { background: item };
14 | }
15 |
16 | function Conent(color: string[]) {
17 | return (
18 |
19 | {labels.map((item, index) => (
20 |
29 | ))}
30 |
31 | );
32 | }
33 | function Renders() {
34 | if (Array.isArray(colors)) {
35 | return Conent(colors);
36 | }
37 | const colorGradient = getGradientColors(colors.startColor, colors.endColor, labels.length);
38 | return Conent(colorGradient);
39 | }
40 | return ;
41 | }
42 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendCategories/types.ts:
--------------------------------------------------------------------------------
1 | import type { CommonProps } from '../../../types/common';
2 |
3 | export interface LegendCategoriesProps extends CommonProps {
4 | /**
5 | * 图形形状
6 | * @default "circle"
7 | */
8 | geometryType?: 'circle' | 'square';
9 | /** 图例项名称 */
10 | labels: string[];
11 | /** 图例项颜色 */
12 | colors: string[] | { startColor: string; endColor: string };
13 | /**
14 | * 是否颜色填充
15 | * @default false
16 | */
17 | isStrokeColor?: boolean;
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendIcon/demos/custom.tsx:
--------------------------------------------------------------------------------
1 | import { LegendIcon } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
,
11 |

,
12 |

,
13 | ]}
14 | />
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendIcon/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LegendIcon } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendIcon/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-legend-icon;
2 |
3 | .@{cls-prefix} {
4 | &__content {
5 | display: flex;
6 | align-items: center;
7 | line-height: 2;
8 |
9 | > *:first-child {
10 | width: 16px;
11 | height: 16px;
12 | margin-right: 10px
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendIcon/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 2
4 | group:
5 | title: 图例组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 图标图例 - LegendIcon
13 |
14 | ### 介绍
15 |
16 | 图标图例,常用于配合字体标注图层或图片标注图层,展示要素信息与图标间的对应关系。
17 |
18 | ### 代码演示
19 |
20 | #### 默认演示
21 |
22 |
23 |
24 | #### 自定义 icons
25 |
26 |
27 |
28 | #### 在地图中展示
29 |
30 |
31 |
32 |
33 |
34 | #### IconType
35 |
36 | ```ts
37 | type IconType = string | React.ReactElement;
38 | ```
39 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendIcon/index.tsx:
--------------------------------------------------------------------------------
1 | import classnames from 'classnames';
2 | import React from 'react';
3 | import './index.less';
4 | import type { IconType, LegendIconProps } from './types';
5 |
6 | export const CLS_PREFIX = 'larkmap-legend-icon';
7 |
8 | export const LegendIcon = (props: LegendIconProps) => {
9 | const { labels, icons, className: cls, style } = props;
10 |
11 | const renderIcon = (icon: IconType) => {
12 | if (React.isValidElement(icon)) {
13 | return icon;
14 | } else if (typeof icon === 'string') {
15 | return
;
16 | }
17 | };
18 |
19 | return (
20 |
21 | {labels.map((item, index) => (
22 |
23 | {renderIcon(icons[index])}
24 |
{item}
25 |
26 | ))}
27 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendIcon/types.ts:
--------------------------------------------------------------------------------
1 | import type { CommonProps } from '../../../types/common';
2 |
3 | export type IconType = string | React.ReactElement;
4 |
5 | export interface LegendIconProps extends CommonProps {
6 | /** 图例项名称 */
7 | labels: string[];
8 | /** 图例项图标 */
9 | icons: IconType[];
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendProportion/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LegendProportion } from '@antv/larkmap';
2 | import React from 'react';
3 | import './index.less';
4 |
5 | export default () => {
6 | return (
7 |
8 |
9 |
10 |
11 | );
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendProportion/demos/index.less:
--------------------------------------------------------------------------------
1 | .demo_cls{
2 | background-color: #fff;
3 | border-radius: 4px;
4 | padding: 5px;
5 | width: 180px;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendProportion/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-legend-proportion;
2 |
3 | .@{cls-prefix} {
4 | display: flex;
5 | align-items: flex-end;
6 |
7 | &__circlebox {
8 | position: relative;
9 | display: flex;
10 | justify-content: flex-end;
11 | align-items: flex-end;
12 | margin-right: 10px;
13 |
14 | &__item {
15 | border-radius: 50%;
16 | position: absolute;
17 | border: 1px solid #e1e3e4;
18 | }
19 | }
20 |
21 | &__labelitem{
22 | font-size: 14px;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendProportion/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 3
4 | group:
5 | title: 图例组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 面积图例 - LegendProportion
13 |
14 | ### 介绍
15 |
16 | 面积图例,常用于图层元素在数值区间内进行值映射**大小**时,展示要素信息的值和大小的对应关系
17 |
18 | ### 代码演示
19 |
20 | #### 默认演示
21 |
22 |
23 |
24 | #### 在地图中展示
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendProportion/types.ts:
--------------------------------------------------------------------------------
1 | import type { CommonProps } from '../../../types/common';
2 |
3 | export interface LegendProportionProp extends CommonProps {
4 | /**图例项名称 */
5 | labels: number[];
6 | /**
7 | * 填充颜色
8 | * @default "#f9f9f9"
9 | */
10 | fillColor?: string;
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendRamp/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LegendRamp } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 |
7 |
12 |
24 |
37 |
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendRamp/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-legend-ramp;
2 |
3 | .@{cls-prefix} {
4 | width: 100%;
5 |
6 | &__dis-continuous {
7 | width: 100%;
8 |
9 | &__colors {
10 | display: flex;
11 | align-items: center;
12 | padding: 4px 0;
13 | }
14 |
15 | &__color {
16 | height: 10px;
17 |
18 | &:first-child {
19 | border-radius: 5px 0 0 5px;
20 | }
21 |
22 | &:last-child {
23 | border-radius: 0 5px 5px 0;
24 | }
25 | }
26 |
27 | &__labels {
28 | display: flex;
29 | align-items: center;
30 | width: 100%;
31 | }
32 |
33 | &__label {
34 | flex-basis: 0;
35 | flex-grow: 1;
36 | max-width: 100%;
37 | font-size: 12px;
38 | text-align: center;
39 | }
40 | }
41 |
42 | &__continuous {
43 | height: 10px;
44 | margin: 4px 0;
45 | border-radius: 5px;
46 | }
47 |
48 | &__continuous-labelbar {
49 | display: flex;
50 | align-items: center;
51 | justify-content: space-between;
52 | font-size: 12px;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendRamp/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 4
4 | group:
5 | title: 图例组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 色带图例 - LegendRamp
13 |
14 | ### 介绍
15 |
16 | 色带图例,常用于图层元素在数值区间内进行值映射**颜色**时,展示要素信息的值和颜色的对应关系
17 |
18 | ### 代码演示
19 |
20 | #### 默认演示
21 |
22 |
23 |
24 | #### 在地图中展示
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/components/Legend/LegendRamp/types.ts:
--------------------------------------------------------------------------------
1 | import type { CommonProps } from '../../../types/common';
2 |
3 | export interface LegendRampProps extends CommonProps {
4 | /** 图例项名称 */
5 | labels: string[] | number[];
6 | /**
7 | * 图例项单位
8 | * @default ""
9 | */
10 | labelUnit?: string;
11 | /**图例项颜色 */
12 | colors: string[];
13 | /**
14 | * 是否连续
15 | * @default false
16 | */
17 | isContinuous?: boolean;
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/LocationSearch/constant.ts:
--------------------------------------------------------------------------------
1 | /** 组件名称, 前缀 */
2 | export const CLS_PREFIX = 'larkmap-location-search';
3 |
4 | export const GAO_DE_API_URL = 'https://restapi.amap.com/v3/assistant/inputtips';
5 |
--------------------------------------------------------------------------------
/src/components/LocationSearch/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { Scene } from '@antv/l7';
2 | import type { LocationSearchOption } from '@antv/larkmap';
3 | import { CustomControl, LarkMap, LocationSearch } from '@antv/larkmap';
4 | import { message } from 'antd';
5 | import React, { useCallback, useEffect, useState } from 'react';
6 |
7 | export default () => {
8 | const [location, setLocation] = useState('');
9 | const [scene, setScene] = useState(null);
10 |
11 | // 同步地图中心点至 location 中
12 | const syncMapCenter = useCallback(() => {
13 | if (scene) {
14 | const { lng, lat } = scene.getCenter();
15 | setLocation(`${lng},${lat}`);
16 | }
17 | }, [scene]);
18 |
19 | useEffect(() => {
20 | if (scene) {
21 | syncMapCenter();
22 | scene?.on('moveend', syncMapCenter);
23 | scene?.on('zoomend', syncMapCenter);
24 | }
25 | }, [scene, syncMapCenter]);
26 |
27 | const onChange = (name?: string, item?: LocationSearchOption) => {
28 | if (item) {
29 | const { longitude, latitude } = item;
30 | scene.setZoomAndCenter(16, [longitude, latitude]);
31 | message.success(`地图移动至 ${name}`);
32 | }
33 | };
34 |
35 | return (
36 | <>
37 | {
41 | setScene(newScene);
42 | }}
43 | >
44 |
45 |
54 |
55 |
56 | >
57 | );
58 | };
59 |
--------------------------------------------------------------------------------
/src/components/LocationSearch/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-location-search;
2 |
3 | .@{cls-prefix} {
4 | min-width: 200px;
5 | &__option-name,
6 | &__option-tip {
7 | overflow: hidden;
8 | white-space: nowrap;
9 | text-overflow: ellipsis;
10 | }
11 | &__option-tip {
12 | color: #818181;
13 | font-size: 12px;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/LocationSearch/types.ts:
--------------------------------------------------------------------------------
1 | import type { SelectProps } from './Select';
2 |
3 | export interface LocationSearchProps extends Omit {
4 | /**
5 | * 高德搜索服务的API key 值
6 | */
7 | searchParams: GaodeLocationSearchParams;
8 |
9 | /**
10 | * 是否展示省市区地址
11 | */
12 | showDistrict?: boolean;
13 |
14 | /**
15 | * 选项中是否展示详细地址
16 | */
17 | showAddress?: boolean;
18 |
19 | /**
20 | * 当下拉选项发生改变的回调
21 | * @param options
22 | */
23 | onSearchFinish?: (options: LocationSearchOption[]) => void;
24 |
25 | /**
26 | * 选项发生改变时的回调
27 | * @param name
28 | * @param option
29 | */
30 | onChange?: (name?: string, option?: LocationSearchOption) => void;
31 | }
32 |
33 | export type GaodeLocationSearchParams = {
34 | key: string;
35 | keywords?: string;
36 | location?: string;
37 | type?: string;
38 | city?: string;
39 | citylimit?: boolean;
40 | sig?: string;
41 | datatype?: string;
42 | privateKey?: string;
43 | [key: string]: any;
44 | };
45 |
46 | export type LocationSearchOption = {
47 | id: string;
48 | name: string;
49 | location: string;
50 | longitude: number;
51 | latitude: number;
52 | district: string;
53 | adcode: string;
54 | address: string;
55 | };
56 |
--------------------------------------------------------------------------------
/src/components/Marker/demos/custom.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps } from '@antv/larkmap';
2 | import { LarkMap, Marker } from '@antv/larkmap';
3 | import { message } from 'antd';
4 | import React from 'react';
5 |
6 | const larkmapOptions: LarkMapProps = {
7 | mapType: 'Gaode',
8 | mapOptions: { center: [120.210792, 30.246026], zoom: 10 },
9 | };
10 |
11 | export default () => (
12 |
13 | message.success('Marker clicked!')}
17 | >
18 | 杭州
19 |
20 |
21 | );
22 |
--------------------------------------------------------------------------------
/src/components/Marker/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import type { LarkMapProps } from '@antv/larkmap';
2 | import { LarkMap, Marker } from '@antv/larkmap';
3 | import React from 'react';
4 |
5 | const larkmapOptions: LarkMapProps = {
6 | mapType: 'Gaode',
7 | mapOptions: { center: [120.104735, 30.261121], zoom: 10 },
8 | };
9 |
10 | export default () => (
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/src/components/Marker/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 1
4 | group:
5 | title: 分析组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 标注 - Marker
13 |
14 | ### 介绍
15 |
16 | 地图标注组件,用于在地图指定经纬度展示自定义内容,默认情况下用于展示定位点图标。
17 |
18 | ### 代码演示
19 |
20 | #### 默认示例
21 |
22 |
23 |
24 | #### 自定义标注
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/components/Marker/index.tsx:
--------------------------------------------------------------------------------
1 | import { Marker as L7Marker } from '@antv/l7';
2 | import { useDeepCompareEffect } from 'ahooks';
3 | import React, { memo, useEffect, useMemo, useRef } from 'react';
4 | import { createPortal } from 'react-dom';
5 | import { useScene } from '../LarkMap/hooks';
6 | import type { MarkerEventType, MarkerProps } from './types';
7 |
8 | export const Marker = memo(function Marker(props): React.ReactPortal {
9 | const scene = useScene();
10 | const thisRef = useRef({ props });
11 | thisRef.current.props = props;
12 |
13 | const marker = useMemo(() => {
14 | let hasChildren = false;
15 | React.Children.forEach(props.children, (el) => {
16 | if (el) {
17 | hasChildren = true;
18 | }
19 | });
20 | const options = {
21 | ...props,
22 | element: hasChildren ? document.createElement('div') : null,
23 | };
24 | // @ts-ignore
25 | const l7marker = new L7Marker(options);
26 |
27 | l7marker.on('click', (e: MarkerEventType) => {
28 | thisRef.current.props.onClick?.(e);
29 | });
30 |
31 | return l7marker;
32 | // eslint-disable-next-line react-hooks/exhaustive-deps
33 | }, []);
34 |
35 | useDeepCompareEffect(() => {
36 | marker.setLnglat(props.lngLat);
37 | }, [props.lngLat]);
38 |
39 | useEffect(() => {
40 | scene.addMarker(marker);
41 | return () => {
42 | marker.remove();
43 | };
44 | // eslint-disable-next-line react-hooks/exhaustive-deps
45 | }, []);
46 |
47 | // @ts-ignore
48 | return createPortal(props.children, marker.getElement());
49 | });
50 |
--------------------------------------------------------------------------------
/src/components/Marker/types.ts:
--------------------------------------------------------------------------------
1 | import type { ILngLat } from '@antv/l7';
2 |
3 | /**
4 | * 锚点事件类型
5 | */
6 | export type MarkerEventType = {
7 | data?: MarkerProps['extData'];
8 | lngLat: ILngLat;
9 | target: MouseEvent | TouchEvent;
10 | };
11 |
12 | /**
13 | * 锚点相对位置
14 | */
15 | export type AnchorType =
16 | | 'right'
17 | | 'top-right'
18 | | 'left'
19 | | 'bottom-right'
20 | | 'left'
21 | | 'top-left'
22 | | 'bottom-left'
23 | | 'bottom'
24 | | 'bottom-right'
25 | | 'bottom-left'
26 | | 'top'
27 | | 'top-right'
28 | | 'top-left'
29 | | 'center';
30 |
31 | /**
32 | * 组件类型定义
33 | */
34 | export interface MarkerProps {
35 | /** 锚点位置的经纬度 */
36 | lngLat: ILngLat;
37 | /** 锚点相对位置,支持 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'
38 | * @default "center"
39 | */
40 | anchor?: AnchorType;
41 | /** 设置默认 marker 的颜色
42 | * @default "#5B8FF9"
43 | */
44 | color?: string;
45 | /** marker 是否可以拖动到地图上的新位置
46 | * @default false
47 | */
48 | draggable?: boolean;
49 | /** 偏移量 [0, 0] 分别表示 X, Y 的偏移量,单位为像素。
50 | * @default [0, 0]
51 | */
52 | offsets?: [number, number];
53 | /** 用户自定义属性,支持任意数据类型,存储 marker 属性信息。*/
54 | extData?: Record;
55 | /** 点击事件 */
56 | onClick?: (e: MarkerEventType) => void;
57 | /** 子组件 */
58 | children?: React.ReactNode;
59 | }
60 |
--------------------------------------------------------------------------------
/src/components/Popup/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { LarkMap, Popup } from '@antv/larkmap';
2 | import React, { useState } from 'react';
3 |
4 | export default () => {
5 | const [lngLat, setLngLat] = useState({ lng: 120.210792, lat: 30.246026 });
6 | const onSceneLoaded = (scene) => {
7 | scene.on('mousemove', (e) => {
8 | const { lng, lat } = e.lnglat;
9 | setLngLat({ lng, lat });
10 | });
11 | };
12 |
13 | return (
14 |
15 | 实时展示经纬度} closeButton={false} closeOnClick={false}>
16 | lat: {lngLat.lat}
17 | lng: {lngLat.lng}
18 |
19 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/src/components/Popup/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 2
4 | group:
5 | title: 分析组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 信息框 - Popup
13 |
14 | ### 介绍
15 |
16 | Popup 是用于在地图上指定经纬度位置,展示自定义内容的气泡。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 参数 | 说明 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | lngLat | Popup 所在的经纬度 | `{ lng: number; lat: number }` | - |
27 | | title | Popup 标题 | `ReactNode` | - |
28 | | children | Popup 内容 | `ReactNode` | - |
29 | | className | Popup 自定义 `className` | `string` | - |
30 | | style | Popup 样式 | `CSSProperties` | - |
31 | | closeOnClick | 点击地图区域时,是否关闭当前 Popup | `boolean` | `true` |
32 | | closeOnEsc | 点击 Esc 键时,是否关闭当前 Popup | `boolean` | `false` |
33 | | maxWidth | Popup 的最大宽度 | `string` | `'240px'` |
34 | | anchor | Popup 箭头位置,可以控制 Popup 相对于经纬度点的展示位置 | [AnchorType](#anchortype) | `'bottom'` |
35 | | offsets | Popup 相对于锚点的偏移 | `[number, number]` | `[0, 0]` |
36 | | autoPan | 当 Popup 展示或者位置发生变化时,地图是否要自动平移至 Popup 所在位置 | `boolean` | `false` |
37 | | autoClose | 当有其他 Popup 展示时,是否自动关闭当前气泡 | `boolean` | `true` |
38 | | followCursor | Popup 是否跟随光标移动,若设为 true,则 lngLat 配置无效 | `boolean` | `false` |
39 | | closeButton | 是否展示关闭 Popup 图标 | `boolean` | `true` |
40 | | closeButtonOffsets | 关闭 Popup 图标的相对偏移 | `[number, number]` | - |
41 | | stopPropagation | Popup 上的鼠标事件是否要阻止其冒泡 | `boolean` | `true` |
42 | | onOpen | Popup 被添加时回调 | `() => void` | - |
43 | | onClose | Popup 被移除时回调 | `() => void` | - |
44 | | onShow | Popup 显示时回调 | `() => void` | - |
45 | | onHide | Popup 隐藏时回调 | `() => void` | - |
46 |
47 | #### AnchorType
48 |
49 | ```ts
50 | export type AnchorType =
51 | | 'center'
52 | | 'top'
53 | | 'top-left'
54 | | 'top-right'
55 | | 'bottom'
56 | | 'bottom-left'
57 | | 'bottom-right'
58 | | 'left'
59 | | 'right';
60 | ```
61 |
--------------------------------------------------------------------------------
/src/components/Popup/types.ts:
--------------------------------------------------------------------------------
1 | import type { IPopupOption } from '@antv/l7';
2 | import type { CSSProperties, ReactNode } from 'react';
3 |
4 | /**
5 | * 组件类型定义
6 | */
7 | export interface PopupProps extends Omit, 'title' | 'html' | 'style' | 'text'> {
8 | style?: CSSProperties;
9 | /** 打开信息框事件 */
10 | onOpen?: () => void;
11 | /** 关闭信息框事件 */
12 | onClose?: () => void;
13 | // 显示
14 | onShow?: () => void;
15 | // 隐藏
16 | onHide?: () => void;
17 | /** 子组件 */
18 | children?: ReactNode;
19 | // 标题
20 | title?: ReactNode;
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/RegionLocation/constant.ts:
--------------------------------------------------------------------------------
1 | /** 组件名称, 前缀 */
2 | export const CLS_PREFIX = 'larkmap-administrative-location';
3 |
4 | export const GAO_DE_API_URL = 'https://restapi.amap.com/v3/geocode/regeo';
5 |
--------------------------------------------------------------------------------
/src/components/RegionLocation/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { CustomControl, LarkMap, RegionLocation } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => {
5 | return (
6 | <>
7 |
8 |
9 |
10 |
11 |
12 | >
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/src/components/RegionLocation/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-administrative-location;
2 |
3 | .@{cls-prefix} {
4 | background-color: #fff;
5 | padding: 4px;
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/RegionLocation/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 5
4 | group:
5 | title: 分析组件
6 | order: 3
7 | nav:
8 | title: 组件
9 | path: /components
10 | ---
11 |
12 | ## 行政区域定位 - RegionLocation
13 |
14 | ### 介绍
15 |
16 | 展示当前地图所在的行政区域,默认情况下会拾取地图展示区域左上和右下角的经纬度,通过高德 API 分别获取两点对应行政区域(省/市/区/街道),然后自下而上取交集拼接生成行政区域文本。
17 |
18 | ### 代码演示
19 |
20 |
21 |
22 | ### API
23 |
24 | | 属性值 | 描述 | 类型 | 默认值 |
25 | | --- | --- | --- | --- |
26 | | searchParams | 调用高德查询接口时传递的参数,必传 | [GaodeRegionLocationParams](#gaodeRegionLocationparams) | - |
27 | | transformBounds | 对地图搜索区域对应左上和右下点进行自定义,默认不传则展示整个地图展示区域 | `(bounds: Bounds) => Bounds` | - |
28 | | className | 控件容器自定义样式 | `string` | - |
29 | | style | 控件容器自定义 style | `CSSProperties` | - |
30 | | onChange | 当展示的行政区域发生变更时的回调函数 | `(result: string, bounds: Bounds) => void` | - |
31 |
32 | #### GaodeRegionLocationParams
33 |
34 | | 属性值 | 描述 | 类型 | 默认值 |
35 | | ------ | --------------------------------- | -------- | ------ |
36 | | key | 高德 Web API 服务的 key 值 (必传) | `string` | - |
37 |
38 | 该其他配置可以查看高德的 [逆地理编码](https://lbs.amap.com/api/webservice/guide/api/georegeo#/regeo)
39 |
--------------------------------------------------------------------------------
/src/components/RegionLocation/types.ts:
--------------------------------------------------------------------------------
1 | import type { Bounds } from '@antv/l7';
2 |
3 | export type GaodeRegionLocationParams = {
4 | /**
5 | * 高德 Web API 服务的 key 值 (必传)
6 | */
7 | key: string;
8 |
9 | [key: string]: any;
10 | };
11 |
12 | export type RegionLocationProps = {
13 | /**
14 | * 调用高德查询接口时传递的参数
15 | */
16 | searchParams: GaodeRegionLocationParams;
17 | /**
18 | * class 名称
19 | */
20 | className?: string;
21 | /**
22 | * 内敛样式
23 | */
24 | style?: React.CSSProperties;
25 | /**
26 | * 自定义识别区域
27 | * @param bounds
28 | * @returns
29 | */
30 | transformBounds?: (bounds: Bounds) => Bounds;
31 | /**
32 | * 展示区域发生变更的回调函数
33 | * @param result 展示的行政区域文本
34 | * @param bounds 当前地图展示区域
35 | * @returns
36 | */
37 | onChange?: (result: string, bounds: Bounds) => void;
38 | };
39 |
--------------------------------------------------------------------------------
/src/components/SyncScene/demos/defaultUtils.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * compact: true
3 | */
4 | import type { Scene } from '@antv/l7';
5 | import { LarkMap, syncScene } from '@antv/larkmap';
6 | import React from 'react';
7 |
8 | export default () => {
9 | const [sceneArray, setSceneArray] = React.useState([]);
10 | const clearRef = React.useRef<() => void>();
11 | const onSceneLoaded = (scene: Scene) => {
12 | setSceneArray((oldValue) => [...oldValue, scene]);
13 | };
14 |
15 | const clearSync = () => {
16 | if (clearRef.current) clearRef.current();
17 | };
18 | const addSync = () => {
19 | clearRef.current = syncScene(sceneArray);
20 | };
21 |
22 | return (
23 |
24 |
25 |
26 |
27 |
34 | 地图1
35 |
36 |
42 | 地图2
43 |
44 |
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/src/components/SyncScene/demos/multiScenes.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * compact: true
3 | */
4 | import type { Scene } from '@antv/l7';
5 | import type { LarkMapProps } from '@antv/larkmap';
6 | import { LarkMap, SyncScene } from '@antv/larkmap';
7 | import React from 'react';
8 | const config: LarkMapProps = {
9 | mapType: 'Gaode',
10 | mapOptions: {
11 | style: 'light',
12 | center: [120.210792, 30.246026],
13 | zoom: 9,
14 | },
15 | };
16 | export default () => {
17 | const [sceneArray, setSceneArray] = React.useState([]);
18 | const onSceneLoaded = (scene: Scene) => {
19 | setSceneArray((oldValue) => [...oldValue, scene]);
20 | };
21 |
22 | return (
23 |
24 |
主地图与其余地图缩放层级差为 2
25 |
26 |
27 | 主地图
28 |
29 |
30 | 地图2
31 |
32 |
33 | 地图3
34 |
35 |
36 |
37 |
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/src/components/SyncScene/demos/zoomGap.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * compact: true
3 | */
4 | import type { Scene } from '@antv/l7';
5 | import { LarkMap, SyncScene } from '@antv/larkmap';
6 | import React from 'react';
7 |
8 | export default () => {
9 | const [sceneArray, setSceneArray] = React.useState([]);
10 | const [zoomGap, setZoomGap] = React.useState();
11 | const onSceneLoaded = (scene: Scene) => {
12 | setSceneArray((oldValue) => [...oldValue, scene]);
13 | };
14 | const changeHandler = (e) => {
15 | // 转为 Number 类型
16 | const gap = Number(e.target.value);
17 | setZoomGap(gap);
18 | };
19 |
20 | return (
21 |
22 | 设置zoomGap:
23 |
24 |
25 |
32 | 主地图
33 |
34 |
40 | 地图2
41 |
42 |
43 |
44 | );
45 | };
46 |
--------------------------------------------------------------------------------
/src/components/SyncScene/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: false
3 | order: 2
4 | group:
5 | title: 同步地图
6 | order: 2
7 | nav:
8 | title: 区块
9 | path: /blocks
10 | order: 3
11 | ---
12 |
13 | # 同步地图
14 |
15 | ## 介绍
16 |
17 | 用于同步地图状态「缩放层级、地图中心点、旋转角、倾斜角」。
18 |
19 | 支持 Gaode 和 Mapbox 两种地图引擎类型
20 |
21 | ### 使用场景
22 |
23 | 适用于同步多个场景的地图状态,适用于两幅或多幅地图的联动。有两种使用方式,一种为 React 组件,一种为工具方法。
24 |
25 | ## 代码演示
26 |
27 | ### 示例一:React 组件使用
28 |
29 |
30 |
31 | ### 示例二: 设置 zoomGap
32 |
33 |
34 |
35 | ### 示例三:多地图场景同步
36 |
37 |
38 |
39 | ### 示例四:函数使用
40 |
41 |
42 |
43 | ## API
44 |
45 | ### React 组件
46 |
47 | `interface SyncSceneProps {scenes: Scene[], options: { zoomGap: number, mainIndex: number }}`
48 |
49 | ### 函数方式
50 |
51 | `syncScene(scenes: Scene[], options: { zoomGap: number, mainIndex: number })`
52 |
53 | #### scenes
54 |
55 | LarkMap 加载完成的 Scene 实例数组
56 |
57 | #### options
58 |
59 | | 参数 | 说明 | 类型 | 默认值 |
60 | | ----------- | -------------------------------------------------------------------------- | -------- | ------ |
61 | | `zoomGap` | 用于设置同步场景的地图层级差 | `number` | 0 |
62 | | `mainIndex` | 搭配 `zoomGap` 使用,用于设置主场景,其余场景为主场景的 `zoom` + `zoomGap` | `number` | 0 |
63 |
--------------------------------------------------------------------------------
/src/components/SyncScene/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { syncScene } from './helper';
3 | import type { SyncSceneProps } from './types';
4 | export const SyncScene: React.FC = ({ scenes, options }) => {
5 | React.useEffect(() => {
6 | const callback = syncScene(scenes, options);
7 | return callback;
8 | }, [scenes, options]);
9 |
10 | return <>>;
11 | };
12 |
13 | export { syncScene };
14 |
--------------------------------------------------------------------------------
/src/components/SyncScene/types.ts:
--------------------------------------------------------------------------------
1 | import type { Scene } from '@antv/l7';
2 |
3 | export interface ISyncSceneOptions {
4 | zoomGap?: number;
5 | mainIndex?: number;
6 | }
7 | export interface SyncSceneProps {
8 | scenes: Scene[];
9 | options?: ISyncSceneOptions;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Template/constant.ts:
--------------------------------------------------------------------------------
1 | /** 组件名称, 前缀 */
2 | export const CLS_PREFIX = 'larkmap-template';
3 |
--------------------------------------------------------------------------------
/src/components/Template/demos/default.tsx:
--------------------------------------------------------------------------------
1 | import { Template } from '@antv/larkmap';
2 | import React from 'react';
3 |
4 | export default () => ;
5 |
--------------------------------------------------------------------------------
/src/components/Template/helper.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 获取随机数
3 | * @returns number
4 | */
5 | export const getRandom = () => {
6 | return Math.random();
7 | };
8 |
--------------------------------------------------------------------------------
/src/components/Template/index.less:
--------------------------------------------------------------------------------
1 | @cls-prefix: larkmap-template;
2 |
3 | .@{cls-prefix} {
4 | &_decoration {
5 | text-decoration: underline;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/components/Template/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | toc: content
3 | order: 3
4 | group:
5 | title: 示例分组
6 | order: 100
7 | nav:
8 | title: 组件
9 | path: /components
10 | hide: true
11 | ---
12 |
13 | ## 样例组件 - Template
14 |
15 | ### 介绍
16 |
17 | ### 使用场景
18 |
19 | ### 代码演示
20 |
21 | #### 默认示例
22 |
23 |
24 |
25 |
26 |
27 | More skills for writing demo: https://d.umijs.org/guide/basic#write-component-demo
28 |
--------------------------------------------------------------------------------
/src/components/Template/index.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 | import React from 'react';
3 | import { CLS_PREFIX } from './constant';
4 | import './index.less';
5 | import type { TemplateProps } from './types';
6 |
7 | export const Template: React.FC = ({ title, className, style }) => {
8 | return (
9 |
10 | {title}
11 |
12 | );
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/Template/types.ts:
--------------------------------------------------------------------------------
1 | import type { CommonProps } from '../../types/common';
2 |
3 | /**
4 | * 组件类型定义
5 | */
6 | export interface TemplateProps extends CommonProps {
7 | /** 名称 */
8 | title?: string;
9 | }
10 |
--------------------------------------------------------------------------------
/src/types/common.ts:
--------------------------------------------------------------------------------
1 | import type { CSSProperties } from 'react';
2 |
3 | export type CommonProps = {
4 | /** 容器类名 */
5 | className?: string;
6 | /** 容器内敛样式 */
7 | style?: CSSProperties;
8 | };
9 |
--------------------------------------------------------------------------------
/src/types/control.ts:
--------------------------------------------------------------------------------
1 | import type { Control } from '@antv/l7';
2 |
3 | export interface IControlCallback {
4 | onAdd?: (control: C) => void;
5 | onRemove?: (control: C) => void;
6 | onShow?: (control: C) => void;
7 | onHide?: (control: C) => void;
8 | }
9 |
10 | export interface IPopperControlCallback extends IControlCallback {
11 | onPopperShow?: (control: C) => void;
12 | onPopperHide?: (control: C) => void;
13 | }
14 |
--------------------------------------------------------------------------------
/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './common';
2 | export * from './layer';
3 | export * from './control';
4 |
--------------------------------------------------------------------------------
/src/utils/color.ts:
--------------------------------------------------------------------------------
1 | import Color from 'color';
2 | import { forEach, round } from 'lodash-es';
3 |
4 | export const getGradientColors = (colorStart: string, colorEnd: string, count = 5): string[] => {
5 | const singleColors: string[] = [colorStart]; // 初始颜色
6 |
7 | const colorMinInt = Color(colorStart).object();
8 | const colorMaxInt = Color(colorEnd).object();
9 |
10 | if (count < 2) {
11 | return count < 1 ? [] : singleColors;
12 | }
13 |
14 | const diffNumber = {
15 | r: (colorMinInt.r - colorMaxInt.r) / (count - 1),
16 | g: (colorMinInt.g - colorMaxInt.g) / (count - 1),
17 | b: (colorMinInt.b - colorMaxInt.b) / (count - 1),
18 | };
19 |
20 | forEach(new Array(count - 2), (item, index) =>
21 | singleColors.push(
22 | Color({
23 | r: round(colorMinInt.r - diffNumber.r * (index + 1), 0),
24 | g: round(colorMinInt.g - diffNumber.g * (index + 1), 0),
25 | b: round(colorMinInt.b - diffNumber.b * (index + 1), 0),
26 | }).hex(),
27 | ),
28 | );
29 |
30 | singleColors.push(colorEnd);
31 |
32 | return singleColors;
33 | };
34 |
--------------------------------------------------------------------------------
/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './layer-manager';
2 | export * from './style';
3 | export * from './url';
4 |
--------------------------------------------------------------------------------
/src/utils/style.ts:
--------------------------------------------------------------------------------
1 | import type { CSSProperties } from 'react';
2 | import { kebabCase } from 'lodash-es';
3 |
4 | /**
5 | * 将 React.CSSProperties 格式的样式对象 转成 字符串格式
6 | * @param style
7 | */
8 | export const getStyleText = (style: CSSProperties = {}) => {
9 | return Object.entries(style ?? {})
10 | .map(([key, value]) => {
11 | const cssKey = kebabCase(key);
12 | let cssValue = value as string | number;
13 | if (typeof cssValue === 'number') {
14 | cssValue = `${cssValue}px`;
15 | } else if (typeof cssValue === 'string') {
16 | cssValue = cssValue.replace("'", '');
17 | }
18 | return `${cssKey} :${cssValue}`;
19 | })
20 | .join('; ');
21 | };
22 |
--------------------------------------------------------------------------------
/src/utils/url.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 将 params 参数对象转换成 query string
3 | * @param params
4 | * @param encode
5 | * @returns
6 | */
7 | export function getQueryString(params: Record, encode = false) {
8 | return Object.entries(params)
9 | .sort(([key1], [key2]) => key1.localeCompare(key2))
10 | .map(([key, value]) => {
11 | let valueStr = String(value);
12 | if (encode) {
13 | valueStr = window.encodeURI(String(value));
14 | }
15 | return `${key}=${valueStr}`;
16 | })
17 | .join('&');
18 | }
19 |
20 | /**
21 | * 将 baseUrl 和 query 拼接成 url
22 | * @param baseUrl
23 | * @param params
24 | * @returns
25 | */
26 | export function urlStringify(baseUrl: string, params: Record) {
27 | return `${baseUrl}?${getQueryString(params, true)}`;
28 | }
29 |
--------------------------------------------------------------------------------
/src/version.ts:
--------------------------------------------------------------------------------
1 | export default '1.5.1';
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es5",
5 | "jsx": "react",
6 | "moduleResolution": "node",
7 | "experimentalDecorators": true,
8 | "declaration": true,
9 | "sourceMap": true,
10 | "allowSyntheticDefaultImports": true,
11 | "downlevelIteration": true,
12 | "esModuleInterop": true,
13 | "resolveJsonModule": true,
14 | "pretty": true,
15 | "lib": ["dom", "esnext"],
16 | "skipLibCheck": true,
17 | "baseUrl": "src",
18 | "outDir": "dist",
19 | "paths": {
20 | "@antv/larkmap": ["./src/index.ts"]
21 | }
22 | },
23 | "include": ["src/**/*", "__tests__/*", "typings.d.ts", "docs/**/*", "docs/**/**/**/*"],
24 | "exclude": ["node_modules", "es", "lib", "dist", "src/.umi/*"]
25 | }
26 |
--------------------------------------------------------------------------------
/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.less';
2 | declare module '*.png';
3 | declare module '*.svg';
4 |
--------------------------------------------------------------------------------