├── .editorconfig ├── .fatherrc.ts ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .umirc.ts ├── README.md ├── docs ├── control.md ├── demo │ ├── control.tsx │ ├── imageLayer.md │ ├── imageLayer.tsx │ ├── index.md │ ├── layer.control.md │ ├── layercontrol.tsx │ ├── map.tsx │ ├── mapv2.tsx │ ├── marker.md │ ├── marker.tsx │ ├── pointLayer.md │ ├── pointLayer.tsx │ ├── popup.md │ └── popup.tsx ├── layer.en.md ├── layer.zh.md ├── marker.en.md ├── marker.zh.md ├── popup.en.md ├── popup.zh.md ├── scene.en.md ├── scene.zh.md ├── start.en.md └── start.zh.md ├── package.json ├── postinstall.js ├── src ├── component │ ├── Control.tsx │ ├── CustomControl.tsx │ ├── Layer.ts │ ├── LayerAttribute │ │ ├── Active.tsx │ │ ├── Animate.tsx │ │ ├── Color.tsx │ │ ├── Filter.tsx │ │ ├── Layer.tsx │ │ ├── Scale.tsx │ │ ├── Select.tsx │ │ ├── Shape.tsx │ │ ├── Size.tsx │ │ ├── Source.tsx │ │ ├── Style.tsx │ │ └── index.ts │ ├── LayerContext.tsx │ ├── LayerEvent.tsx │ ├── Legend │ │ └── color.tsx │ ├── LoadImage.tsx │ ├── MapScene │ │ ├── AMapScene.tsx │ │ ├── AMapSceneV1.tsx │ │ ├── AMapSceneV2.tsx │ │ ├── MapScene.tsx │ │ ├── MapboxScene.tsx │ │ └── interface.ts │ ├── Marker.tsx │ ├── MarkerLayer.tsx │ ├── Popup.tsx │ ├── Scene.tsx │ ├── SceneContext.tsx │ ├── SceneEvent.tsx │ └── util.ts └── index.ts ├── tsconfig.json └── typings.d.ts /.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 | -------------------------------------------------------------------------------- /.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import commonjs from '@rollup/plugin-commonjs'; 2 | export default { 3 | esm: 'babel', 4 | cjs: 'babel', 5 | // extraRollupPlugins: [commonjs()], 6 | }; 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push,pull_request] 3 | jobs: 4 | build-and-deploy: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - name: Checkout 🛎️ 8 | uses: actions/checkout@v2.3.1 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly. 9 | with: 10 | persist-credentials: false 11 | 12 | - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built. 13 | run: | 14 | npm install 15 | npm run build 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | /docs-dist 13 | 14 | # misc 15 | .DS_Store 16 | 17 | # umi 18 | .umi 19 | .umi-production 20 | .umi-test 21 | .env.local 22 | 23 | /lib 24 | /es 25 | /.idea 26 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | **/*.ejs 3 | **/*.html 4 | package.json 5 | .umi 6 | .umi-production 7 | .umi-test 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'dumi'; 2 | 3 | export default defineConfig({ 4 | title: 'L7React', 5 | favicon: 6 | 'https://gw.alipayobjects.com/mdn/rms_08cc33/afts/img/A*aoGdSISB9soAAAAAAAAAAAAAARQnAQ', 7 | logo: 8 | 'https://gw.alipayobjects.com/mdn/rms_08cc33/afts/img/A*aoGdSISB9soAAAAAAAAAAAAAARQnAQ', 9 | outputPath: 'docs-dist', 10 | resolve: { 11 | previewLangs: [], 12 | }, 13 | publicPath: '/L7-react/', 14 | base: '/L7-react/', 15 | headScripts: [ 16 | `var _hmt = _hmt || []; 17 | (function() { 18 | var hm = document.createElement("script"); 19 | hm.src = "https://hm.baidu.com/hm.js?fd8a7d7a266eb8e8f50a04d1e4bee6c1"; 20 | var s = document.getElementsByTagName("script")[0]; 21 | s.parentNode.insertBefore(hm, s); 22 | })();`, 23 | ], 24 | // more config: https://d.umijs.org/config 25 | }); 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # L7-React 2 | 3 | L7-React 已全面 升级为 LarkMap,不在进行维护 。 4 | LarkMap 空间数据可视分析组件库 5 | 6 | ## LarkMap 7 | 8 | 新一代 React 地图可视分析组件库,提供丰富/高效/专业/易用的可视化组件,一站式满足地理可视化需求、 9 | 10 | [LarkMap 官网](https://larkmap.antv.antgroup.com/) 11 | 12 | ## Getting Started 13 | 14 | Install dependencies, 15 | 16 | ```bash 17 | $ npm i 18 | ``` 19 | 20 | Start the dev server, 21 | 22 | ```bash 23 | $ npm start 24 | ``` 25 | 26 | Build documentation, 27 | 28 | ```bash 29 | $ npm run docs:build 30 | ``` 31 | 32 | Build library via `father-build`, 33 | 34 | ```bash 35 | $ npm run build 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/control.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Control 地图组件 3 | order: 4 4 | --- 5 | 6 | ## Contorl Props 7 | 8 | - type: `'scale' | 'zoom' | 'logo' | 'layer'` 9 | 10 | - position: `'topright' | 'topleft' | 'bottomright' | 'bottomleft' | 'topcenter' | 'bottomcenter' | 'leftcenter' | 'rightcenter';` 11 | 12 | 13 | 14 | ## CustomControl 15 | 16 | 自定义 Control 17 | 18 | - position: `'topright' | 'topleft' | 'bottomright' | 'bottomleft' | 'topcenter' | 'bottomcenter' | 'leftcenter' | 'rightcenter';` 19 | - style controll Css 样式 20 | 21 | ```tsx 22 | 23 |

1

24 |

2

25 |
26 | ``` 27 | -------------------------------------------------------------------------------- /docs/demo/control.tsx: -------------------------------------------------------------------------------- 1 | import { AMapScene, Control, CustomControl } from '@antv/l7-react'; 2 | import * as React from 'react'; 3 | 4 | export default React.memo(function Map() { 5 | return ( 6 | 19 | 20 | 21 | 22 |

1

23 |

2

24 |
25 |
26 | ); 27 | }); 28 | -------------------------------------------------------------------------------- /docs/demo/imageLayer.md: -------------------------------------------------------------------------------- 1 | ## 图片图层 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/demo/imageLayer.tsx: -------------------------------------------------------------------------------- 1 | import { AMapScene, ImageLayer } from '@antv/l7-react'; 2 | import React from 'react'; 3 | export default () => { 4 | return ( 5 | 18 | 39 | 40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /docs/demo/index.md: -------------------------------------------------------------------------------- 1 | ## Hello react! 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/demo/layer.control.md: -------------------------------------------------------------------------------- 1 | ## 图层控件 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/demo/layercontrol.tsx: -------------------------------------------------------------------------------- 1 | import { AMapScene, ImageLayer, Control } from '@antv/l7-react'; 2 | import React from 'react'; 3 | export default () => { 4 | return ( 5 | 18 | 33 | 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /docs/demo/map.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | MapScene, 4 | AMapSceneV2, 5 | Control, 6 | PolygonLayer, 7 | HeatmapLayer, 8 | } from '@antv/l7-react'; 9 | import { useRequest } from 'ahooks'; 10 | async function getData(url: string) { 11 | const res = await fetch(url); 12 | return await res.json(); 13 | } 14 | const urls = { 15 | world: 16 | 'https://gw.alipayobjects.com/os/bmw-prod/79143b04-5fab-4d24-8cce-80b818a3d189.json', 17 | grid: 18 | 'https://gw.alipayobjects.com/os/bmw-prod/8990e8b4-c58e-419b-afb9-8ea3daff2dd1.json', 19 | }; 20 | export default () => { 21 | const { run, fetches } = useRequest(getData, { 22 | manual: true, 23 | fetchKey: url => url, 24 | }); 25 | React.useEffect(() => { 26 | run(urls.world); 27 | run(urls.grid); 28 | }, []); 29 | 30 | return ( 31 | 44 | {fetches[urls.grid]?.loading === false && ( 45 | 70 | )} 71 | {fetches[urls.world]?.loading === false && ( 72 | 94 | )} 95 | 96 | 97 | 98 | ); 99 | }; 100 | -------------------------------------------------------------------------------- /docs/demo/mapv2.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | AMapSceneV2, 4 | Control, 5 | PolygonLayer, 6 | HeatmapLayer, 7 | } from '@antv/l7-react'; 8 | import { useRequest } from 'ahooks'; 9 | async function getData(url: string) { 10 | const res = await fetch(url); 11 | return await res.json(); 12 | } 13 | const urls = { 14 | world: 15 | 'https://gw.alipayobjects.com/os/bmw-prod/79143b04-5fab-4d24-8cce-80b818a3d189.json', 16 | grid: 17 | 'https://gw.alipayobjects.com/os/bmw-prod/8990e8b4-c58e-419b-afb9-8ea3daff2dd1.json', 18 | }; 19 | export default () => { 20 | const { run, fetches } = useRequest(getData, { 21 | manual: true, 22 | fetchKey: url => url, 23 | }); 24 | React.useEffect(() => { 25 | run(urls.world); 26 | run(urls.grid); 27 | }, []); 28 | 29 | return ( 30 | 43 | {fetches[urls.grid]?.loading === false && ( 44 | 69 | )} 70 | {fetches[urls.world]?.loading === false && ( 71 | 93 | )} 94 | 95 | 96 | 97 | ); 98 | }; 99 | -------------------------------------------------------------------------------- /docs/demo/marker.md: -------------------------------------------------------------------------------- 1 | ## Marker 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/demo/marker.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { 3 | AMapScene, 4 | Marker, 5 | MapScene, 6 | Control, 7 | PolygonLayer, 8 | HeatmapLayer, 9 | } from '@antv/l7-react'; 10 | import { useInterval } from 'ahooks'; 11 | 12 | export default () => { 13 | const [positionData, setPositionData] = useState({ 14 | lng: 120, 15 | lat: 30, 16 | }); 17 | 18 | useInterval(() => { 19 | setPositionData({ 20 | lng: 120 + Math.random() * 10, 21 | lat: 30 + Math.random() * 10, 22 | }); 23 | }, 400); 24 | 25 | React.useEffect(() => {}, []); 26 | 27 | return ( 28 | 41 | 45 | 49 | 50 | 51 | ); 52 | }; 53 | -------------------------------------------------------------------------------- /docs/demo/pointLayer.md: -------------------------------------------------------------------------------- 1 | ## 测试 blend 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/demo/pointLayer.tsx: -------------------------------------------------------------------------------- 1 | import { AMapScene, PointLayer, CustomControl } from '@antv/l7-react'; 2 | import React, { useCallback, useEffect, useState } from 'react'; 3 | import { Select } from 'antd'; 4 | const { Option } = Select; 5 | 6 | export default () => { 7 | const [data, setData] = useState(); 8 | const [blend, setBlend] = useState('additive'); 9 | const ControlPosition = useCallback(() => { 10 | return ( 11 | 26 | ); 27 | }, []); 28 | useEffect(() => { 29 | const fetchData = async () => { 30 | const response = await fetch( 31 | 'https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json', 32 | ); 33 | const data = await response.json(); 34 | console.log(data); 35 | setData(data); 36 | }; 37 | fetchData(); 38 | }, []); 39 | return ( 40 | 53 | {data && ( 54 | 71 | )} 72 | 73 | 74 | 75 | 76 | ); 77 | }; 78 | -------------------------------------------------------------------------------- /docs/demo/popup.md: -------------------------------------------------------------------------------- 1 | ## 信息框 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/demo/popup.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | AMapScene, 3 | ImageLayer, 4 | PolygonLayer, 5 | LayerEvent, 6 | Popup, 7 | } from '@antv/l7-react'; 8 | import React, { useState } from 'react'; 9 | export default () => { 10 | const [selectFeature, setSelectFeature] = useState(); 11 | return ( 12 | 24 | 55 | { 58 | setSelectFeature(e); 59 | }} 60 | > 61 | 62 | {selectFeature && ( 63 | 69 |
{ 71 | e.stopPropagation(); 72 | // e.preventDefault(); 73 | alert('我被点击了'); 74 | }} 75 | > 76 | 84 |
85 |
86 | )} 87 |
88 | ); 89 | }; 90 | -------------------------------------------------------------------------------- /docs/layer.en.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Layer Component 3 | order: 2 4 | --- 5 | 6 | ## Layer 类型 7 | 8 | React 各个组件名称和 L7 名称保持一致 9 | 10 | - PointLayer 11 | - PolygonLayer 12 | - LineLayer 13 | - HeatmapLayer 14 | - RasterLayer 15 | - ImageLayer 16 | - CityBuildingLayer 17 | 18 | ### 使用方式 19 | 20 | ```jsx 21 | import { PointLayer } from '@antv/l7-react'; 22 | ``` 23 | 24 | ## Layer Props 25 | 26 | | prop name | Type | Default | Description | 27 | | ------------- | ------------------------------ | --------------------------------------------------------- | --------------------------------------- | 28 | | options | `layer options` | | layer 配置项 | 29 | | source | `sourceOption` | | 数据源配置项 | 30 | | color | `attributeOption` | | 颜色通道 | 31 | | shape | `attributeOption` | | 图层形状属性 | 32 | | size | `attributeOption` | | 图层大小属性 | 33 | | style | `Object` | | 图层样式 | 34 | | scale | `scale Option` | 默认会数值类设定 scale,数值类型 linear,字符串类型为 cat | 图层度量 | 35 | | filter | `Function` | | 图层数据过滤方法 | 36 | | select | `boolean` `interaction option` | | 图层选中高亮 | 37 | | active | `boolean` `interaction option` | `false` | 图层 hover 高亮 | 38 | | animate | `animate Option` | `null` | 图层动画配置 | 39 | | onLayerLoaded | `Function` | | 图层添加完成后回调,用于获取 layer 对象 | 40 | 41 | ### layer options 42 | 43 | | prop name | Type | Default | Description | 44 | | ------------- | --------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | 45 | | name | `string` | | 图层名字,可根据名称获取 layer | 46 | | visible | `boolean` | `true` | 图层是否可见 | 47 | | zIndex | `number` | 0 | 图层绘制顺序, | 48 | | minZoom | `number` | 0 | 设置 layer 最小可见等级,小于则不显示 | 49 | | maxZoom | `number` | 与 map 最大缩放等级一致 | 设置 layerd 的最大可见等级,大于则不显示 | 50 | | aotoFit | `boolean` | `false` | 是否缩放到图层范围 | 51 | | blend | 'string' | 'normal' | 图层元素混合效果 [详情](../layer/layer/#blend) | 52 | | pickingBuffer | 'number' | '0' | 图层拾取缓存机制,如 1px 宽度的线鼠标很难拾取(点击)到, 通过设置该参数可扩大拾取的范围 {number} default 0 | 53 | 54 | ### attribute Option 55 | 56 | color, size, shape 等图形映射通道,通过下面参数配置 57 | 58 | - field 映射字段,如果是常量设置为 null 59 | - values 映射值 支持 常量,数组,回调函数,如果 values 为数组或回调需要设置 field 字段 60 | 61 | 详细[配置项](../layer/layer/#size) 62 | 63 | ### source Option 64 | 65 | 数据源配置项 66 | 67 | - data 支持 geojson、csv、json 68 | - parser 数据解析配置项 69 | - transforms 数据处理配置项 70 | 71 | 详细[配置项](../source/source/#parser-1) 72 | 73 | ### scale Option 74 | 75 | 度量配置项 76 | 77 | - values scaleCfg 78 | 79 | **scaleCfg** 80 | 81 | - key 为字段名 fieldname | attributeName 82 | - value scale 配置项 83 | 84 | ```javascript 85 | const scales = { 86 | values: { 87 | name: { 88 | type: 'cat', 89 | }, 90 | }, 91 | }; 92 | ``` 93 | 94 | ### interaction option 95 | 96 | active,select 配置项 97 | 98 | **option** 99 | 100 | - color 设置交互的颜色,指滑过或者选中的 101 | 102 | ### 获取 layer 对象 103 | 104 | #### onLayerLoaded 105 | 106 | 回调函数获取 layer, scene 对象 107 | 108 | ```javascript 109 | onLayerLoaded = (layer, scene) => {}; 110 | ``` 111 | 112 | #### Context API 113 | 114 | ```jsx 115 | import { LayerContext } from '@antv/l7-react'; 116 | 117 | {(layer, scene) => { 118 | // use `scene` here 119 | }} 120 | ; 121 | ``` 122 | 123 | ### Layer 示例 124 | 125 | ```jsx 126 | import { PolygonLayer } from '@antv/l7-react'; 127 | ; 148 | ``` 149 | 150 | ## 子组件 151 | 152 | ### 事件组件 153 | 154 | | prop name | Type | Default | Description | 155 | | --------- | ---------- | ------- | ----------------------------------------- | 156 | | type | `string` | `null` | 事件类型 [详情](../layer/layer/#鼠标事件) | 157 | | handler | `Function` | `null` | layer 回调函数 | 158 | 159 | ### 示例 160 | 161 | ```jsx 162 | import { LayerEvent, PolygonLayer } from '@antv/l7-react'; 163 | 164 | {}} /> 165 | {}} /> 166 | ; 167 | ``` 168 | -------------------------------------------------------------------------------- /docs/layer.zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Layer 组件 3 | order: 2 4 | --- 5 | 6 | ## Layer 类型 7 | 8 | React 各个组件名称和 L7 名称保持一致 9 | 10 | - PointLayer 11 | - PolygonLayer 12 | - LineLayer 13 | - HeatmapLayer 14 | - RasterLayer 15 | - ImageLayer 16 | - CityBuildingLayer 17 | 18 | ### 使用方式 19 | 20 | ```jsx 21 | import { PointLayer } from '@antv/l7-react'; 22 | ``` 23 | 24 | ## Layer Props 25 | 26 | | prop name | Type | Default | Description | 27 | | ------------- | ------------------------------ | --------------------------------------------------------- | --------------------------------------- | 28 | | options | `layer options` | | layer 配置项 | 29 | | source | `sourceOption` | | 数据源配置项 | 30 | | color | `attributeOption` | | 颜色通道 | 31 | | shape | `attributeOption` | | 图层形状属性 | 32 | | size | `attributeOption` | | 图层大小属性 | 33 | | style | `Object` | | 图层样式 | 34 | | scale | `scale Option` | 默认会数值类设定 scale,数值类型 linear,字符串类型为 cat | 图层度量 | 35 | | filter | `Function` | | 图层数据过滤方法 | 36 | | select | `boolean` `interaction option` | | 图层选中高亮 | 37 | | active | `boolean` `interaction option` | `false` | 图层 hover 高亮 | 38 | | animate | `animate Option` | `null` | 图层动画配置 | 39 | | onLayerLoaded | `Function` | | 图层添加完成后回调,用于获取 layer 对象 | 40 | 41 | ### layer options 42 | 43 | | prop name | Type | Default | Description | 44 | | ------------- | --------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | 45 | | name | `string` | | 图层名字,可根据名称获取 layer | 46 | | visible | `boolean` | `true` | 图层是否可见 | 47 | | zIndex | `number` | 0 | 图层绘制顺序, | 48 | | minZoom | `number` | 0 | 设置 layer 最小可见等级,小于则不显示 | 49 | | maxZoom | `number` | 与 map 最大缩放等级一致 | 设置 layerd 的最大可见等级,大于则不显示 | 50 | | aotoFit | `boolean` | `false` | 是否缩放到图层范围 | 51 | | blend | 'string' | 'normal' | 图层元素混合效果 [详情](../layer/layer/#blend) | 52 | | pickingBuffer | 'number' | '0' | 图层拾取缓存机制,如 1px 宽度的线鼠标很难拾取(点击)到, 通过设置该参数可扩大拾取的范围 {number} default 0 | 53 | 54 | ### attribute Option 55 | 56 | color, size, shape 等图形映射通道,通过下面参数配置 57 | 58 | - field 映射字段,如果是常量设置为 null 59 | - values 映射值 支持 常量,数组,回调函数,如果 values 为数组或回调需要设置 field 字段 60 | 61 | 详细[配置项](../layer/layer/#size) 62 | 63 | ### source Option 64 | 65 | 数据源配置项 66 | 67 | - data 支持 geojson、csv、json 68 | - parser 数据解析配置项 69 | - transforms 数据处理配置项 70 | 71 | 详细[配置项](../source/source/#parser-1) 72 | 73 | ### scale Option 74 | 75 | 度量配置项 76 | 77 | - values scaleCfg 78 | 79 | **scaleCfg** 80 | 81 | - key 为字段名 fieldname | attributeName 82 | - value scale 配置项 83 | 84 | ```javascript 85 | const scales = { 86 | values: { 87 | name: { 88 | type: 'cat', 89 | }, 90 | }, 91 | }; 92 | ``` 93 | 94 | ### interaction option 95 | 96 | active,select 配置项 97 | 98 | **option** 99 | 100 | - color 设置交互的颜色,指滑过或者选中的 101 | 102 | ### 获取 layer 对象 103 | 104 | #### onLayerLoaded 105 | 106 | 回调函数获取 layer, scene 对象 107 | 108 | ```javascript 109 | onLayerLoaded = (layer, scene) => {}; 110 | ``` 111 | 112 | #### Context API 113 | 114 | ```jsx 115 | import { LayerContext } from '@antv/l7-react'; 116 | 117 | {(layer, scene) => { 118 | // use `scene` here 119 | }} 120 | ; 121 | ``` 122 | 123 | ### Layer 示例 124 | 125 | ```jsx 126 | import { PolygonLayer } from '@antv/l7-react'; 127 | ; 148 | ``` 149 | 150 | ## 子组件 151 | 152 | ### 事件组件 153 | 154 | | prop name | Type | Default | Description | 155 | | --------- | ---------- | ------- | ----------------------------------------- | 156 | | type | `string` | `null` | 事件类型 [详情](../layer/layer/#鼠标事件) | 157 | | handler | `Function` | `null` | layer 回调函数 | 158 | 159 | ### 示例 160 | 161 | ```jsx 162 | import { LayerEvent, PolygonLayer } from '@antv/l7-react'; 163 | 164 | {}} /> 165 | {}} /> 166 | ; 167 | ``` 168 | -------------------------------------------------------------------------------- /docs/marker.en.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Marker 3 | order: 3 4 | --- 5 | 6 | ## Marker Props 7 | 8 | | prop name | Type | Default | Description | 9 | | -------------- | ----------------- | ------- | ----------------- | 10 | | option | `string` | `null` | marker 配置项 | 11 | | lnglat | `Array | Object` | `null` | marker 经纬度位置 | 12 | | onMarkerLoaded | `Function` | `null` | layer 回调函数 | 13 | | children | `React.ReactNode` | `null` | 子组件 | 14 | 15 | ### option 16 | 17 | | prop name | Type | Default | Description | 18 | | --------- | ------------ | ------- | ------------------------------------------------------------------------------ | 19 | | color | `string` | `blue` | marker 配置项 | 20 | | anchor | `string` | `null` | center, top, top-left, top-right, bottom, bottom-left,bottom-right,left, right | 21 | | offsets | `Array[x,y]` | `null` | marker 位置偏移 | 22 | | extData | `object` | `null` | marker 属性数据 | 23 | 24 | ## 实例 25 | 26 | ```jsx 27 | import { Marker } from '@antv/l7-react'; 28 | ; 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/marker.zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Marker 组件 3 | order: 3 4 | --- 5 | 6 | ## Marker Props 7 | 8 | | prop name | Type | Default | Description | 9 | | -------------- | ----------------- | ------- | ----------------- | 10 | | option | `string` | `null` | marker 配置项 | 11 | | lnglat | `Array | Object` | `null` | marker 经纬度位置 | 12 | | onMarkerLoaded | `Function` | `null` | layer 回调函数 | 13 | | children | `React.ReactNode` | `null` | 子组件 | 14 | 15 | ### option 16 | 17 | | prop name | Type | Default | Description | 18 | | --------- | ------------ | ------- | ------------------------------------------------------------------------------ | 19 | | color | `string` | `blue` | marker 配置项 | 20 | | anchor | `string` | `null` | center, top, top-left, top-right, bottom, bottom-left,bottom-right,left, right | 21 | | offsets | `Array[x,y]` | `null` | marker 位置偏移 | 22 | | extData | `object` | `null` | marker 属性数据 | 23 | 24 | ## Maker 事件 25 | 26 | 通过 onMarkerLoaded 方法获取 Marker 实例监听 27 | 28 | ## 实例 29 | 30 | ```jsx 31 | import { Marker } from '@antv/l7-react'; 32 | ; 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/popup.en.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Popup Component 3 | order: 4 4 | --- 5 | 6 | ## Popup Props 7 | 8 | | prop name | Type | Default | Description | 9 | | --------- | ----------------- | ------- | ---------------- | 10 | | option | `string` | `null` | popup 配置项 | 11 | | lnglat | `Array | Object` | `null` | popup 经纬度位置 | 12 | | children | `React.ReactNode` | `null` | 子组件 | 13 | 14 | ### option 15 | 16 | | prop name | Type | Default | Description | 17 | | ------------ | ------------ | ------- | ------------------------------------------------------------------------------ | 18 | | closeButton | `string` | `true` | 是否显示关闭按钮 | 19 | | closeOnClick | `string` | `blue` | 点击是否关闭 popup | 20 | | anchor | `string` | `null` | center, top, top-left, top-right, bottom, bottom-left,bottom-right,left, right | 21 | | offsets | `Array[x,y]` | `null` | popup 位置偏移 | 22 | | className | `string` | `null` | 样式名称 | 23 | 24 | ```jsx 25 | import { Popup } from '@antv/l7-react'; 26 | ; 27 | ``` 28 | 29 | [popup 使用完整 demo](../../../examples/react/covid#covid_bubble) 30 | -------------------------------------------------------------------------------- /docs/popup.zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Popup 组件 3 | order: 4 4 | --- 5 | 6 | ## Popup Props 7 | 8 | | prop name | Type | Default | Description | 9 | | --------- | ----------------- | ------- | ---------------- | 10 | | option | `string` | `null` | popup 配置项 | 11 | | lnglat | `Array | Object` | `null` | popup 经纬度位置 | 12 | | children | `React.ReactNode` | `null` | 子组件 | 13 | 14 | ### option 15 | 16 | | prop name | Type | Default | Description | 17 | | ------------ | ------------ | ------- | ------------------------------------------------------------------------------ | 18 | | closeButton | `string` | `true` | 是否显示关闭按钮 | 19 | | closeOnClick | `string` | `blue` | 点击是否关闭 popup | 20 | | anchor | `string` | `null` | center, top, top-left, top-right, bottom, bottom-left,bottom-right,left, right | 21 | | offsets | `Array[x,y]` | `null` | popup 位置偏移 | 22 | | className | `string` | `null` | 样式名称 | 23 | 24 | ```jsx 25 | import { Popup } from '@antv/l7-react'; 26 | 27 | ; 33 | ``` 34 | 35 | [popup 使用完整 demo](../../../examples/react/covid#covid_bubble) 36 | -------------------------------------------------------------------------------- /docs/scene.en.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Scene 3 | order: 1 4 | --- 5 | 6 | ## 使用 7 | 8 | 在 React 版本中 Mapbox 和高德地图作为两个组件封装的。 9 | 10 | ```javascript 11 | import { MapboxScene, AmapScene } from '@antv/l7-react'; 12 | ``` 13 | 14 | ## Scene Props 15 | 16 | | prop name | Type | Default | Description | 17 | | ------------- | -------------- | ---------- | ----------------------------------------- | 18 | | style | `Object` | `null` | scene css 样式 | 19 | | className | `string` | `null` | 样式名称 | 20 | | map | `map option` | `Required` | map option [地图配置项](#map-option) | 21 | | option | `scene option` | `void` | scene option 配置项 [详情](#scene-option) | 22 | | onSceneLoaded | `Function` | `void` | scene 加载回调函数 | 23 | 24 | ### 高德地图场景 25 | 26 | ```jsx 27 | import { AMapScene } from '@antv/l7-react'; 28 | ; 36 | ``` 37 | 38 | ### Mapbox 地图场景 39 | 40 | ```jsx 41 | import { MapboxScene } from '@antv/l7-react'; 42 | ; 50 | ``` 51 | 52 | ### map option 53 | 54 | 地图配置项 55 | 56 | | option | Type | Default | Description | 57 | | -------- | ---------- | ------------------ | --------------------------------------------------------------------------------------------------------------- | 58 | | style | `string` | `light` | 地图样式 `dark|light|normal|blank` L7 默认提供四种样式,同时也支持自定义样式 | 59 | | token | `string` | `Required` | 地图密钥,需要平台申请 | 60 | | plugin | `string[]` | `null` | 高德地图[API 插件](https://lbs.amap.com/api/javascript-api/guide/abc/plugins) `['AMap.ToolBar','AMap.Driving']` | 61 | | center | `number` | null | 地图中心点 | 62 | | pitch | `number` | 0 | 地图倾角 | 63 | | rotation | `number` | 0 | 地图旋转角 | 64 | | zoom | `number` | null | 地图缩放等级 | 65 | | maxZoom | `number` | 0 | 最大缩放等级 | 66 | | minZoom | `number` | AMap 18 ,Mapbox 20 | 最小缩放等级 | 67 | 68 | 其他配置项见地图文档 69 | 高德地图 Map [配置项](https://lbs.amap.com/api/javascript-api/reference/map) 70 | 71 | Mapbox Map 地图配置项 [配置项](https://docs.mapbox.com/mapbox-gl-js/api/#map) 72 | 73 | 其他配置项和底图一致 74 | 75 | ### scene option 76 | 77 | | option | Type | Default | Description | 78 | | --------------------- | --------- | ------------ | --------------------------------------------------- | 79 | | logoPosition | string | `bottomleft` | logo 位置 `bottomright|topright|bottomleft|topleft` | 80 | | logoVisible | `boolean` | `true` | 是否显示 logo | 81 | | antialias | `boolean` | `true` | 是否开启抗锯齿 | 82 | | preserveDrawingBuffer | `boolean` | `false` | 是否保留缓冲区数据 | 83 | 84 | ### 获取 scene 对象 85 | 86 | #### onSceneLoaded 87 | 88 | onSceneLoaded 回调函数能够取到 scene 对象 89 | 90 | #### Context API 91 | 92 | ```jsx 93 | import { SceneContext } from '@antv/l7-react'; 94 | 95 | {scene => { 96 | // use `scene` here 97 | }} 98 | ; 99 | ``` 100 | 101 | ## 子组件 102 | 103 | ### LoadImage 104 | 105 | | prop name | Type | Default | Description | 106 | | --------- | -------- | ------- | ----------- | 107 | | name | `string` | `null` | 图标名称 | 108 | | url | `string` | `null` | 图标 url | 109 | 110 | ```jsx 111 | import LoadImage from '@antv/l7-react'; 112 | ; 113 | ``` 114 | 115 | ### Layer 组件 116 | 117 | 每个图层作为 scene 子组件添加 118 | 119 | ###  事件组件 120 | 121 | | prop name | Type | Default | Description | 122 | | --------- | ---------- | ------- | ----------------------------------- | 123 | | type | `string` | `null` | 事件类型 [详情](../scene/#地图事件) | 124 | | handler | `Function` | `null` | scene 回调函数 | 125 | 126 | ```javascript 127 | import { SceneEvent, MapboxScene } from '@antv/l7-react'; 128 | 129 | 130 | {}} /> 131 | ; 132 | ``` 133 | -------------------------------------------------------------------------------- /docs/scene.zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Scene 组件 3 | order: 1 4 | --- 5 | 6 | ## 使用 7 | 8 | 在 React 版本中 Mapbox 和高德地图作为两个组件封装的。 9 | 10 | ```javascript 11 | import { MapboxScene, AMapScene } from '@antv/l7-react'; 12 | ``` 13 | 14 | ## Scene Props 15 | 16 | | prop name | Type | Default | Description | 17 | | ------------- | -------------- | ---------- | ----------------------------------------- | 18 | | style | `Object` | `null` | scene css 样式 | 19 | | className | `string` | `null` | 样式名称 | 20 | | map | `map option` | `Required` | map option [地图配置项](#map-option) | 21 | | option | `scene option` | `void` | scene option 配置项 [详情](#scene-option) | 22 | | onSceneLoaded | `Function` | `void` | scene 加载回调函数 | 23 | 24 | ### 高德地图场景 25 | 26 | ```jsx 27 | import { AMapScene } from '@antv/l7-react'; 28 | ; 36 | ``` 37 | 38 | ### Mapbox 地图场景 39 | 40 | ```jsx 41 | import { MapboxScene } from '@antv/l7-react'; 42 | ; 50 | ``` 51 | 52 | ### map option 53 | 54 | 地图配置项 55 | 56 | | option | Type | Default | Description | 57 | | -------- | ---------- | ------------------ | --------------------------------------------------------------------------------------------------------------- | 58 | | style | `string` | `light` | 地图样式 `dark|light|normal|blank` L7 默认提供四种样式,同时也支持自定义样式 | 59 | | token | `string` | `Required` | 地图密钥,需要平台申请 | 60 | | plugin | `string[]` | `null` | 高德地图[API 插件](https://lbs.amap.com/api/javascript-api/guide/abc/plugins) `['AMap.ToolBar','AMap.Driving']` | 61 | | center | `number` | null | 地图中心点 | 62 | | pitch | `number` | 0 | 地图倾角 | 63 | | rotation | `number` | 0 | 地图旋转角 | 64 | | zoom | `number` | null | 地图缩放等级 | 65 | | maxZoom | `number` | 0 | 最大缩放等级 | 66 | | minZoom | `number` | AMap 18 ,Mapbox 20 | 最小缩放等级 | 67 | 68 | 其他配置项见地图文档 69 | 高德地图 Map [配置项](https://lbs.amap.com/api/javascript-api/reference/map) 70 | 71 | Mapbox Map 地图配置项 [配置项](https://docs.mapbox.com/mapbox-gl-js/api/#map) 72 | 73 | 其他配置项和底图一致 74 | 75 | ### scene option 76 | 77 | | option | Type | Default | Description | 78 | | --------------------- | --------- | ------------ | --------------------------------------------------- | 79 | | logoPosition | string | `bottomleft` | logo 位置 `bottomright|topright|bottomleft|topleft` | 80 | | logoVisible | `boolean` | `true` | 是否显示 logo | 81 | | antialias | `boolean` | `true` | 是否开启抗锯齿 | 82 | | preserveDrawingBuffer | `boolean` | `false` | 是否保留缓冲区数据 | 83 | 84 | ### 获取 scene 对象 85 | 86 | #### onSceneLoaded 87 | 88 | onSceneLoaded 回调函数能够取到 scene 对象 89 | 90 | #### Context API 91 | 92 | ```jsx 93 | import { SceneContext } from '@antv/l7-react'; 94 | 95 | {scene => { 96 | // use `scene` here 97 | }} 98 | ; 99 | ``` 100 | 101 | ## 子组件 102 | 103 | ### LoadImage 104 | 105 | | prop name | Type | Default | Description | 106 | | --------- | -------- | ------- | ----------- | 107 | | name | `string` | `null` | 图标名称 | 108 | | url | `string` | `null` | 图标 url | 109 | 110 | ```jsx 111 | import LoadImage from '@antv/l7-react'; 112 | ; 113 | ``` 114 | 115 | ### Layer 组件 116 | 117 | 每个图层作为 scene 子组件添加 118 | 119 | ###  事件组件 120 | 121 | | prop name | Type | Default | Description | 122 | | --------- | ---------- | ------- | ----------------------------------- | 123 | | type | `string` | `null` | 事件类型 [详情](../scene/#地图事件) | 124 | | handler | `Function` | `null` | scene 回调函数 | 125 | 126 | ```javascript 127 | import { SceneEvent, MapboxScene } from '@antv/l7-react'; 128 | 129 | 130 | {}} /> 131 | ; 132 | ``` 133 | -------------------------------------------------------------------------------- /docs/start.en.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Get Started 3 | order: 0 4 | --- 5 | 6 | ### 安装 7 | 8 | ```bash 9 | npm i @antv/l7-react 10 | ``` 11 | 12 | ### 示例 13 | 14 | ```javascript 15 | import { LineLayer, AMapScene } from '@antv/l7-react'; 16 | 17 | export default React.memo(function Map() { 18 | const [data, setData] = React.useState(); 19 | React.useEffect(() => { 20 | const fetchData = async () => { 21 | const response = await fetch( 22 | 'https://gw.alipayobjects.com/os/basement_prod/32e1f3ab-8588-46cb-8a47-75afb692117d.json', 23 | ); 24 | const raw = await response.json(); 25 | setData(raw); 26 | }; 27 | fetchData(); 28 | }, []); 29 | return ( 30 | <> 31 | 46 | {data && ( 47 | 65 | )} 66 | 67 | 68 | ); 69 | }); 70 | ``` 71 | -------------------------------------------------------------------------------- /docs/start.zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 快速开始 3 | order: 0 4 | --- 5 | 6 | ### 安装 7 | 8 | ```bash 9 | npm i @antv/l7-react 10 | ``` 11 | 12 | ### 示例 13 | 14 | ```javascript 15 | import { LineLayer, AMapScene } from '@antv/l7-react'; 16 | export default React.memo(function Map() { 17 | const [data, setData] = React.useState(); 18 | React.useEffect(() => { 19 | const fetchData = async () => { 20 | const response = await fetch( 21 | 'https://gw.alipayobjects.com/os/basement_prod/32e1f3ab-8588-46cb-8a47-75afb692117d.json', 22 | ); 23 | const raw = await response.json(); 24 | setData(raw); 25 | }; 26 | fetchData(); 27 | }, []); 28 | return ( 29 | <> 30 | 45 | {data && ( 46 | 64 | )} 65 | 66 | 67 | ); 68 | }); 69 | ``` 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/l7-react", 3 | "version": "2.4.3", 4 | "license": "MIT", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/antvis/L7-react" 8 | }, 9 | "scripts": { 10 | "start": "dumi dev", 11 | "docs:build": "dumi build", 12 | "docs:deploy": "gh-pages -d docs-dist", 13 | "build": "father-build", 14 | "deploy": "npm run docs:build && npm run docs:deploy", 15 | "release": "npm run build && npm publish", 16 | "prettier": "prettier --write \"src/**/*.{js,jsx,tsx,ts,less,md,json}\"", 17 | "test": "umi-test", 18 | "test:coverage": "umi-test --coverage", 19 | "postinstall": "node -e \"try{require('./postinstall')}catch(e){}\" || exit 0" 20 | }, 21 | "main": "lib/index.js", 22 | "module": "es/index.js", 23 | "typings": "lib/index.d.ts", 24 | "gitHooks": { 25 | "pre-commit": "lint-staged" 26 | }, 27 | "files": [ 28 | "dist", 29 | "lib", 30 | "es", 31 | "README.md", 32 | "postinstall.js" 33 | ], 34 | "lint-staged": { 35 | "*.{js,jsx,less,md,json}": [ 36 | "prettier --write" 37 | ], 38 | "*.ts?(x)": [ 39 | "prettier --parser=typescript --write" 40 | ] 41 | }, 42 | "dependencies": { 43 | "@babel/runtime": "^7.7.7", 44 | "@types/eslint": "^8.4.1", 45 | "@types/lodash": "^4.14.180", 46 | "@types/mapbox-gl": "^1.11.2", 47 | "ahooks": "^2.6.1", 48 | "load-styles": "^2.0.0", 49 | "lodash": "^4.17.21" 50 | }, 51 | "peerDependencies": { 52 | "@antv/l7": "^2.11.0", 53 | "mapbox-gl": "^1.2.1", 54 | "react": "^16.8.6 || ^17.0.2", 55 | "react-dom": "^16.8.6 || ^17.0.2" 56 | }, 57 | "devDependencies": { 58 | "@types/react": "^17.0.40", 59 | "@antv/l7": "^2.11.0", 60 | "@types/react-dom": "^17.0.13", 61 | "@types/react-router-config": "^5.0.6", 62 | "@types/react-router-dom": "^5.3.3", 63 | "@types/viewport-mercator-project": "^6.1.2", 64 | "@umijs/preset-react": "1.x", 65 | "@umijs/test": "^3.0.5", 66 | "dumi": "^1.0.9", 67 | "father-build": "^1.17.2", 68 | "gh-pages": "^3.0.0", 69 | "lint-staged": "^10.0.7", 70 | "prettier": "^1.19.1", 71 | "react": "^17.0.2", 72 | "react-dom": "^17.0.2", 73 | "yorkie": "^2.0.0" 74 | }, 75 | "publishConfig": { 76 | "registry": "https://registry.npmjs.org/" 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /postinstall.js: -------------------------------------------------------------------------------- 1 | function isTrue(value) { 2 | return !!value && value !== '0' && value !== 'false'; 3 | } 4 | 5 | let envDisable = isTrue(process.env.CI); 6 | let logLevel = process.env.npm_config_loglevel; 7 | let logLevelDisplay = ['silent', 'error', 'warn'].indexOf(logLevel) > -1; 8 | 9 | let BANNER = `\u001b[31m--------------------------------------------------------------------------------------- 10 | \u001b[31m--------------------------------------------------------------------------------------- 11 | \u001b[0mThank you for installing \u001b[35m${'@antv/l7-react'}\u001b[0m: built from \u001b[32m${'https://github.com/antvis/L7-react'} 12 | 13 | \u001b[31m L7-React 全面升级为 LarkMap\u001b[32m (${'https://github.com/antvis/LarkMap'})\u001b[31m, \u001b[31mL7-React 已经停止维护! 请手动升级。 14 | 15 | \u001b[0m\u001b[96mLarkMap 新一代 React 地图可视分析组件库,提供易用/丰富/易用/专业的可视化组件,一站式满足可视化需求。了解更多: 16 | \u001b[0m> \u001b[32m${'https://larkmap.antv.antgroup.com/guide'}\u001b[0m 17 | \u001b[31m--------------------------------------------------------------------------------------- 18 | \u001b[31m---------------------------------------------------------------------------------------\n`; 19 | 20 | // install后在控制台输出一段日志 21 | if (!envDisable && !logLevelDisplay) { 22 | console.log && console.log(BANNER); 23 | } 24 | -------------------------------------------------------------------------------- /src/component/Control.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | IControl, 3 | Logo, 4 | PositionName, 5 | Scale, 6 | Zoom, 7 | LayerSwitch, 8 | Fullscreen, 9 | Control, 10 | MouseLocation, 11 | MapTheme, 12 | GeoLocate, 13 | ExportImage, 14 | } from '@antv/l7'; 15 | import React, { useRef, useEffect } from 'react'; 16 | import { useSceneValue } from './SceneContext'; 17 | export interface IControlProps { 18 | type: 19 | | 'scale' 20 | | 'zoom' 21 | | 'logo' 22 | | 'layer' 23 | | 'layerSwitch' 24 | | 'mouseLocation' 25 | | 'mapTheme' 26 | | 'geoLocate' 27 | | 'exportImage' 28 | | 'fullscreen'; 29 | position?: PositionName; 30 | [key: string]: any; 31 | } 32 | 33 | const CONTROL_TYPE_MAP: Record> = { 34 | exportImage: ExportImage, 35 | fullscreen: Fullscreen, 36 | geoLocate: GeoLocate, 37 | layer: LayerSwitch, 38 | layerSwitch: LayerSwitch, 39 | logo: Logo, 40 | mapTheme: MapTheme, 41 | mouseLocation: MouseLocation, 42 | zoom: Zoom, 43 | scale: Scale 44 | }; 45 | 46 | export default React.memo(function MapControl(props: IControlProps) { 47 | const scene = useSceneValue(); 48 | const control = useRef(); 49 | const { type, position, ...rest } = props; 50 | useEffect(() => { 51 | const Control = CONTROL_TYPE_MAP[type]; 52 | const ctr = new Control({ 53 | position, 54 | ...rest 55 | }) 56 | control.current = ctr; 57 | scene.addControl(ctr); 58 | return () => { 59 | control.current = undefined; 60 | scene.removeControl(ctr); 61 | }; 62 | }, [type]); 63 | 64 | useEffect(() => { 65 | if (control.current) { 66 | // @ts-ignore 67 | control.current.setPosition((position as any) || 'bottomleft'); 68 | } 69 | }, [position]); 70 | 71 | return null; 72 | }); 73 | -------------------------------------------------------------------------------- /src/component/CustomControl.tsx: -------------------------------------------------------------------------------- 1 | import { Control, PositionName } from '@antv/l7'; 2 | import * as React from 'react'; 3 | import { createPortal } from 'react-dom'; 4 | import { useSceneValue } from './SceneContext'; 5 | const { useEffect, useState } = React; 6 | const hyphenateRE = /\B([A-Z])/g; 7 | const hyphenate = function(str: string) { 8 | return str.replace(hyphenateRE, '-$1').toLowerCase(); 9 | }; 10 | 11 | export interface IColorLegendProps { 12 | position: PositionName; 13 | className?: string; 14 | style?: React.CSSProperties; 15 | children?: JSX.Element | JSX.Element[] | Array; 16 | } 17 | 18 | export default function CustomControl( 19 | props: IColorLegendProps, 20 | ): React.ReactPortal { 21 | const { className, style, children, position } = props; 22 | const [control, setControl] = useState(); 23 | const mapScene = useSceneValue(); 24 | const [el] = useState(() => document.createElement('div')); 25 | 26 | useEffect(() => { 27 | const custom = new Control({ 28 | position, 29 | }); 30 | custom.onAdd = () => { 31 | if (className) { 32 | el.className = className; 33 | } 34 | if (style) { 35 | const cssText = Object.keys(style) 36 | .map((key: string) => { 37 | // @ts-ignore 38 | return `${hyphenate(key)}:${style[key]}`; 39 | }) 40 | .join(';'); 41 | el.style.cssText = cssText; 42 | } 43 | 44 | return el; 45 | }; 46 | custom.onRemove = () => {}; 47 | setControl(custom); 48 | mapScene.addControl(custom); 49 | return () => { 50 | mapScene.removeControl(custom); 51 | }; 52 | }, []); 53 | 54 | useEffect(() => { 55 | control && control.setPosition((position as any) || 'bottomleft'); 56 | }, [position]); 57 | 58 | return createPortal(children, el); 59 | } 60 | -------------------------------------------------------------------------------- /src/component/Layer.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ILayerProps } from './LayerAttribute'; 3 | import BaseLayer from './LayerAttribute/Layer'; 4 | 5 | const PolygonLayer = React.memo(function Layer(props: ILayerProps) { 6 | return BaseLayer('polygonLayer', props); 7 | }); 8 | 9 | const LineLayer = React.memo(function Layer(props: ILayerProps) { 10 | return BaseLayer('lineLayer', props); 11 | }); 12 | 13 | const PointLayer = React.memo(function Layer(props: ILayerProps) { 14 | return BaseLayer('pointLayer', props); 15 | }); 16 | 17 | const HeatmapLayer = React.memo(function Layer(props: ILayerProps) { 18 | return BaseLayer('heatmapLayer', props); 19 | }); 20 | 21 | const RasterLayer = React.memo(function Layer(props: ILayerProps) { 22 | return BaseLayer('rasterLayer', props); 23 | }); 24 | 25 | const ImageLayer = React.memo(function Layer(props: ILayerProps) { 26 | return BaseLayer('imageLayer', props); 27 | }); 28 | 29 | const CityBuildingLayer = React.memo(function Layer(props: ILayerProps) { 30 | return BaseLayer('citybuildingLayer', props); 31 | }); 32 | 33 | export { 34 | PolygonLayer, 35 | LineLayer, 36 | PointLayer, 37 | HeatmapLayer, 38 | RasterLayer, 39 | ImageLayer, 40 | CityBuildingLayer, 41 | }; 42 | -------------------------------------------------------------------------------- /src/component/LayerAttribute/Active.tsx: -------------------------------------------------------------------------------- 1 | import { IActiveOption, ILayer } from '@antv/l7'; 2 | import * as React from 'react'; 3 | import { isEqual } from '../util'; 4 | interface ILayerProps { 5 | layer: ILayer; 6 | active: { 7 | option: IActiveOption | boolean; 8 | }; 9 | } 10 | export default React.memo(function Chart(props: ILayerProps) { 11 | const { layer, active } = props; 12 | layer.active(active.option); 13 | 14 | return null; 15 | }, isEqual); 16 | -------------------------------------------------------------------------------- /src/component/LayerAttribute/Animate.tsx: -------------------------------------------------------------------------------- 1 | import { IAnimateOption, ILayer } from '@antv/l7'; 2 | import * as React from 'react'; 3 | import { isEqual } from '../util'; 4 | interface ILayerProps { 5 | layer: ILayer; 6 | animate: Partial; 7 | } 8 | export default React.memo(function Chart(props: ILayerProps) { 9 | const { layer, animate } = props; 10 | 11 | layer.animate(animate); 12 | return null; 13 | }, isEqual); 14 | -------------------------------------------------------------------------------- /src/component/LayerAttribute/Color.tsx: -------------------------------------------------------------------------------- 1 | import { ILayer, StyleAttrField } from '@antv/l7'; 2 | import * as React from 'react'; 3 | import { IAttributeOptions } from './'; 4 | import { isEqual } from '../util'; 5 | interface ILayerProps { 6 | layer: ILayer; 7 | color: Partial; 8 | } 9 | export default React.memo(function Chart(props: ILayerProps) { 10 | const { layer, color } = props; 11 | color.field 12 | ? layer.color(color.field as StyleAttrField, color.values) 13 | : layer.color(color.values as StyleAttrField); 14 | return null; 15 | }, isEqual); 16 | -------------------------------------------------------------------------------- /src/component/LayerAttribute/Filter.tsx: -------------------------------------------------------------------------------- 1 | import { ILayer, StyleAttrField } from '@antv/l7'; 2 | import * as React from 'react'; 3 | import { IAttributeOptions } from './'; 4 | import { isEqual } from '../util'; 5 | interface ILayerProps { 6 | layer: ILayer; 7 | filter: Partial; 8 | } 9 | export default React.memo(function Chart(props: ILayerProps) { 10 | const { layer, filter } = props; 11 | if (filter.field) { 12 | layer.filter(filter.field as string, filter.values as StyleAttrField); 13 | } 14 | return null; 15 | }, isEqual); 16 | -------------------------------------------------------------------------------- /src/component/LayerAttribute/Layer.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | CityBuildingLayer, 3 | HeatmapLayer, 4 | ILayer, 5 | ImageLayer, 6 | LineLayer, 7 | PointLayer, 8 | PolygonLayer, 9 | RasterLayer, 10 | } from '@antv/l7'; 11 | import * as React from 'react'; 12 | import { LayerContext } from '../LayerContext'; 13 | import { useSceneValue } from '../SceneContext'; 14 | import { 15 | Active, 16 | Animate, 17 | Color, 18 | Filter, 19 | ILayerProps, 20 | Scale, 21 | Select, 22 | Shape, 23 | Size, 24 | Source, 25 | Style, 26 | } from './'; 27 | 28 | const { useEffect, useState } = React; 29 | 30 | export default function BaseLayer(type: string, props: ILayerProps) { 31 | const { 32 | source, 33 | color, 34 | shape, 35 | style, 36 | size, 37 | scale, 38 | active, 39 | select, 40 | filter, 41 | animate, 42 | options, 43 | onLayerLoaded, 44 | } = props; 45 | const mapScene = useSceneValue(); 46 | const [layer] = useState(() => { 47 | let l: ILayer; 48 | switch (type) { 49 | case 'polygonLayer': 50 | l = new PolygonLayer(options); 51 | break; 52 | case 'lineLayer': 53 | l = new LineLayer(options); 54 | break; 55 | case 'pointLayer': 56 | l = new PointLayer(options); 57 | break; 58 | case 'heatmapLayer': 59 | l = new HeatmapLayer(options); 60 | break; 61 | case 'rasterLayer': 62 | l = new RasterLayer(options); 63 | break; 64 | case 'imageLayer': 65 | l = new ImageLayer(options); 66 | break; 67 | case 'citybuildingLayer': 68 | l = new CityBuildingLayer(options); 69 | break; 70 | default: 71 | l = new PolygonLayer(options); 72 | } 73 | l.on('inited', () => { 74 | if (onLayerLoaded) { 75 | onLayerLoaded(l, mapScene); 76 | } 77 | }); 78 | 79 | return l; 80 | }); 81 | 82 | useEffect(() => { 83 | mapScene.addLayer(layer); 84 | return () => { 85 | mapScene.removeLayer(layer); 86 | }; 87 | }, []); 88 | 89 | useEffect(() => { 90 | if (layer.inited && options) { 91 | layer.updateLayerConfig(options); 92 | } 93 | }, [options?.minZoom, options?.maxZoom, options?.visible]); 94 | 95 | useEffect(() => { 96 | if (layer.inited && options?.zIndex) { 97 | layer.setIndex(options.zIndex); 98 | } 99 | }, [options?.zIndex]); 100 | 101 | useEffect(() => { 102 | if (layer.inited && options?.blend) { 103 | layer.setBlend(options.blend); 104 | } 105 | }, [options?.blend]); 106 | 107 | useEffect(() => { 108 | // 重绘layer 109 | mapScene.render(); 110 | }); 111 | 112 | return ( 113 | 114 | 115 | {scale && } 116 | {color && } 117 | {size && } 118 | {shape && } 119 | {style &&