├── .eslintignore ├── .gitignore ├── src ├── components │ ├── SeamlessScroll │ │ ├── index.ts │ │ ├── __docs__ │ │ │ ├── index.zh-CN.md │ │ │ ├── demo-base.vue │ │ │ ├── demo-props.vue │ │ │ └── demo-css-reset.vue │ │ └── seamless-scroll.vue │ └── Map │ │ └── __docs__ │ │ ├── index.zh-CN.md │ │ ├── 01-show-map.vue │ │ ├── 03-geojson-map.vue │ │ ├── 04-geojson-map.vue │ │ └── 02-show-biz-info.vue ├── index.ts └── index.md ├── .prettierrc.js ├── .devcontainer └── devcontainer.json ├── docs ├── .vitepress │ ├── sidebar.js │ ├── theme │ │ ├── index.ts │ │ └── var.css │ └── config.js └── public │ └── logo.svg ├── vite.config.ts ├── scripts ├── fetch.js ├── configs.js └── merge.js ├── .eslintrc.cjs ├── tsconfig.json └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .docs 3 | dist 4 | .temp -------------------------------------------------------------------------------- /src/components/SeamlessScroll/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './seamless-scroll.vue'; 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import SeamlessScroll from './components/SeamlessScroll' 2 | 3 | export { 4 | SeamlessScroll 5 | } 6 | -------------------------------------------------------------------------------- /src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | map: 3 | path: / 4 | --- 5 | 6 | 欢迎你,这里是 `windstorm-ui`,**风暴UI**。 7 | 8 | > 一款不专业、不完善的小组件库。 -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | singleQuote: true, 4 | tabWidth: 2, 5 | trailingComma: 'all', 6 | printWidth: 80, 7 | }; 8 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/universal:2", 3 | "features": { 4 | }, 5 | "ghcr.io/NicoVIII/devcontainer-features/pnpm:1": { 6 | "version": 16 7 | }, 8 | "ghcr.io/devcontainers/features/node:1": {} 9 | } 10 | -------------------------------------------------------------------------------- /docs/.vitepress/sidebar.js: -------------------------------------------------------------------------------- 1 | export const sidebar = { 2 | '/': [ 3 | { 4 | text: '组件', 5 | items: [ 6 | { text: '无限滚动', link: '/seamless-scroll/' }, 7 | ], 8 | }, 9 | { 10 | text: '地图开发', 11 | items: [ 12 | { text: 'demo', link: '/map-demo/' }, 13 | ], 14 | }, 15 | ], 16 | }; 17 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme'; 2 | import DemoBlock from '@ruabick/vitepress-demo-block'; 3 | import '@ruabick/vitepress-demo-block/dist/style.css'; 4 | import './var.css'; 5 | 6 | export default { 7 | ...DefaultTheme, 8 | 9 | enhanceApp({ app, router, siteData }) { 10 | // app is the Vue 3 app instance from `createApp()`. 11 | // router is VitePress' custom router. `siteData` is 12 | // a `ref` of current site-level metadata. 13 | app.component('demo', DemoBlock); 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/SeamlessScroll/__docs__/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | map: 3 | path: /seamless-scroll/ 4 | --- 5 | 6 | ## 基本使用 7 | 8 | 效果如下 9 | 10 | 13 | 14 | 15 | ## 设置停留和滚动时间 16 | 17 | 效果如下 18 | 19 | 22 | 23 | 24 | ## 样式覆写(如何达成斑马线) 25 | 26 | 效果如下 27 | 28 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/components/Map/__docs__/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | map: 3 | path: /map-demo/ 4 | --- 5 | 6 | ## 【瓦片风】基本使用 7 | 8 | 效果如下 9 | 10 | 13 | 14 | 15 | ## 【瓦片风】在地图上显示业务属性 16 | 17 | 效果如下 18 | 19 | 22 | 23 | 24 | ## 【线框风】渲染基础 “湖北省” 基础轮廓 25 | 26 | 效果如下 27 | 28 | 31 | 32 | 33 | ## 【线框风】 “湖北省” 高亮 + 下钻 34 | 35 | 效果如下 36 | 37 | 40 | 41 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path'; 2 | import { defineConfig } from 'vite'; 3 | import vue from '@vitejs/plugin-vue'; 4 | import dts from 'vite-plugin-dts'; 5 | import packageJson from './package.json' 6 | 7 | export default defineConfig({ 8 | plugins: [vue(), dts()], 9 | build: { 10 | lib: { 11 | entry: resolve(__dirname, './src/index.ts'), 12 | name: 'windstorm-ui', 13 | // the proper extensions will be added 14 | fileName: 'windstorm-ui', 15 | }, 16 | rollupOptions: { 17 | // 确保外部化处理那些你不想打包进库的依赖 18 | // @ts-ignore 19 | external: ['vue', ...Object.keys(packageJson.dependencies || {}), ...Object.keys(packageJson.peerDependencies || {})], 20 | output: { 21 | // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 22 | globals: { 23 | vue: 'Vue', 24 | }, 25 | }, 26 | }, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /src/components/SeamlessScroll/__docs__/demo-base.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 20 | 21 | 32 | -------------------------------------------------------------------------------- /src/components/SeamlessScroll/__docs__/demo-props.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 20 | 21 | 32 | -------------------------------------------------------------------------------- /scripts/fetch.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const fs = require('fs-extra'); 3 | const path = require('path') 4 | const config = require('./configs.js') 5 | 6 | 7 | const getGeojson = async (code) => { 8 | const res = await axios.get(`https://geo.datav.aliyun.com/areas_v3/bound/${code}.json`) 9 | return res.data 10 | } 11 | 12 | const writeGeojson = async (code, geojson) => { 13 | const fileName = `${code}.json` 14 | const filePath = path.resolve(config.ORIGIN_GEOJSON_DIR, fileName) 15 | await fs.writeJSON(filePath, geojson) 16 | } 17 | 18 | 19 | const begin = async () => { 20 | await fs.remove(config.ORIGIN_GEOJSON_DIR) 21 | await fs.ensureDir(config.ORIGIN_GEOJSON_DIR) 22 | const tasks = config.codes.map(t => getGeojson(t)) 23 | const jsons = await Promise.all(tasks) 24 | const writeTasks = jsons.map((json, index) => writeGeojson(config.codes[index], json)) 25 | await Promise.all(writeTasks) 26 | } 27 | 28 | begin() 29 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const { defineConfig } = require('eslint-define-config'); 3 | 4 | module.exports = defineConfig({ 5 | root: true, 6 | extends: [ 7 | 'eslint:recommended', 8 | 'plugin:node/recommended', 9 | 'plugin:@typescript-eslint/recommended', 10 | ], 11 | plugins: ['import'], 12 | parser: '@typescript-eslint/parser', 13 | parserOptions: { 14 | sourceType: 'module', 15 | ecmaVersion: 2021, 16 | }, 17 | rules: { 18 | 'no-debugger': ['error'], 19 | '@typescript-eslint/no-var-requires': 'off', 20 | 'node/no-unpublished-require': 'off', 21 | 'node/no-extraneous-import': 'off', 22 | 'node/no-extraneous-require': 'off', 23 | 'node/no-missing-import': 'off', 24 | 'node/no-missing-require': 'off', 25 | 'no-undef': 'off', 26 | 'node/no-unpublished-import': 'off', 27 | 'node/no-unsupported-features/es-syntax': 'off', 28 | 'no-process-exit': 'off', 29 | '@typescript-eslint/ban-ts-comment': 'off', 30 | 'no-constant-condition': 'off', 31 | '@typescript-eslint/no-non-null-assertion': 'off', 32 | '@typescript-eslint/no-explicit-any': 'off', 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "outDir": "dist", 5 | "sourceMap": false, 6 | "target": "ES2022", 7 | "module": "ES2022", 8 | "moduleResolution": "node", 9 | "allowJs": false, 10 | "noUnusedLocals": true, 11 | "strictNullChecks": true, 12 | "noImplicitAny": true, 13 | "noImplicitThis": true, 14 | "experimentalDecorators": true, 15 | "resolveJsonModule": true, 16 | "esModuleInterop": true, 17 | "removeComments": false, 18 | "declaration": true, 19 | "isolatedModules": true, 20 | "jsx": "preserve", 21 | "lib": [ 22 | "esnext", 23 | "dom", 24 | ], 25 | "types": [], 26 | "skipLibCheck": true, 27 | // "files": "src/index.ts", 28 | "emitDeclarationOnly": true, 29 | "declarationDir": "dist", 30 | "rootDir": ".", 31 | "paths": { 32 | "@/*": [ 33 | "src/*" 34 | ], 35 | "windstorm-ui": [ 36 | "src/index.ts" 37 | ] 38 | } 39 | }, 40 | "include": [ 41 | "src/**/*" 42 | ], 43 | "exclude": [ 44 | "node_modules", 45 | "dist", 46 | "packages/**/__tests__" 47 | ] 48 | } -------------------------------------------------------------------------------- /src/components/SeamlessScroll/__docs__/demo-css-reset.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 20 | 21 | 48 | -------------------------------------------------------------------------------- /docs/public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress'; 2 | import { applyPlugins } from '@ruabick/md-demo-plugins'; 3 | import { genTemp } from '@ruabick/vite-plugin-gen-temp'; 4 | import { genApiDoc } from '@ruabick/vite-plugin-gen-api-doc'; 5 | import { sidebar } from './sidebar.js'; 6 | import { resolve } from 'path'; 7 | 8 | export default defineConfig({ 9 | lang: 'zh-CN', 10 | lastUpdated: true, 11 | base: process.env.NODE_ENV === 'production' ? '/windstorm-ui' : '/', 12 | locales: { 13 | '/': { 14 | lang: 'zh-CN', 15 | title: 'windstorm-ui', 16 | description: '', 17 | }, 18 | // '/en/': { 19 | // lang: 'en-US', 20 | // title: 'windstorm-ui', 21 | // description: '', 22 | // }, 23 | }, 24 | themeConfig: { 25 | logo: '/logo.svg', 26 | localeLinks: { 27 | text: '', 28 | items: [ 29 | { text: '简体中文', link: '/' }, 30 | // { text: 'English', link: '/en/' }, 31 | ], 32 | }, 33 | // nav: [{ text: '指南', link: '/guide' }],s 34 | sidebar, 35 | algolia: {}, 36 | socialLinks: [ 37 | { icon: 'github', link: 'https://github.com/zhangshichun/windstorm-ui' }, 38 | ], 39 | }, 40 | vue: {}, 41 | vite: { 42 | plugins: [genTemp(), genApiDoc()], 43 | resolve: { 44 | alias: { 45 | 'windstorm-ui': resolve('./src/'), 46 | }, 47 | }, 48 | }, 49 | markdown: { 50 | config: (md) => { 51 | applyPlugins(md); 52 | }, 53 | theme: { 54 | light: 'github-light', 55 | dark: 'github-dark', 56 | }, 57 | }, 58 | }); 59 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/var.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --vp-code-block-bg: #f9fafb; 3 | /* --vp-code-block-bg: var(--vp-c-bg-alt); */ 4 | 5 | --vp-code-line-highlight-color: rgba(0, 0, 0, 0.5); 6 | --vp-code-line-number-color: var(--vp-c-text-dark-3); 7 | 8 | --vp-code-copy-code-hover-bg: rgba(255, 255, 255, 0.05); 9 | --vp-code-copy-code-active-text: var(--vp-c-bg-alt); 10 | 11 | --demi-border-color: #ebedf1; 12 | } 13 | 14 | .dark { 15 | --vp-code-block-bg: var(--vp-c-bg-alt); 16 | } 17 | 18 | .vp-doc [class*='language-']:before { 19 | color: var(--vp-c-text-2); 20 | } 21 | 22 | @media (min-width: 640px) { 23 | .vp-doc div[class*='language-'] { 24 | border-radius: 4px; 25 | margin: 16px 0; 26 | } 27 | } 28 | 29 | @media (max-width: 639px) { 30 | .vp-doc div[class*='language-'] { 31 | border-radius: 4px; 32 | } 33 | } 34 | 35 | /* 中文字太大了 */ 36 | @media (min-width: 640px) { 37 | .name, 38 | .text { 39 | font-size: 28px !important; 40 | } 41 | } 42 | 43 | @media (min-width: 960px) { 44 | .name, 45 | .text { 46 | font-size: 32px !important; 47 | } 48 | } 49 | 50 | .vp-doc table { 51 | display: table; 52 | width: 100%; 53 | font-size: 15px; 54 | } 55 | 56 | .vp-doc tr { 57 | border-top: 1px solid var(--demi-border-color); 58 | } 59 | 60 | .vp-doc tr:nth-child(2n) { 61 | background-color: unset; 62 | } 63 | 64 | .vp-doc th, 65 | .vp-doc td { 66 | border: 1px solid var(--demi-border-color); 67 | padding: 10px 20px; 68 | } 69 | 70 | .vp-doc th { 71 | font-size: 15px; 72 | font-weight: 600; 73 | background-color: var(--vp-c-white-soft); 74 | } 75 | 76 | .vp-doc table td:first-child { 77 | font-size: 15px; 78 | font-weight: 600; 79 | } 80 | -------------------------------------------------------------------------------- /src/components/Map/__docs__/01-show-map.vue: -------------------------------------------------------------------------------- 1 | 4 | 59 | -------------------------------------------------------------------------------- /src/components/Map/__docs__/03-geojson-map.vue: -------------------------------------------------------------------------------- 1 | 4 | 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "windstorm-ui", 3 | "version": "0.0.0", 4 | "description": "", 5 | "homepage": "https://zhangshichun.github.io/windstorm-ui", 6 | "types": "./dist/index.d.ts", 7 | "main": "./dist/windstorm-ui.umd.cjs", 8 | "module": "./dist/windstorm-ui.js", 9 | "exports": { 10 | ".": { 11 | "import": "./dist/windstorm-ui.js", 12 | "require": "./dist/windstorm-ui.umd.cjs" 13 | }, 14 | "./dist/style.css": "./dist/style.css" 15 | }, 16 | "scripts": { 17 | "dev": "initial-scan docs && vitepress dev .docs --host", 18 | "build": "vite build", 19 | "site:build": "initial-scan docs && cross-env NODE_ENV=production vitepress build .docs", 20 | "serve": "vitepress serve .docs --host", 21 | "deploy": "gh-pages -d .docs/.vitepress/dist -t true", 22 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", 23 | "lint": "eslint src/**/*.{vue,js,ts,tsx}", 24 | "lint-fix": "yarn lint -- --fix", 25 | "release": "np", 26 | "geojson:fetch": "node scripts/fetch.js", 27 | "geojson:merge": "node scripts/merge.js" 28 | }, 29 | "keywords": [], 30 | "author": "zhangshichun", 31 | "license": "MIT", 32 | "dependencies": { 33 | "@vueuse/core": "^9.4.0", 34 | "gsap": "^3.11.2", 35 | "@turf/turf": "^6.5.0" 36 | }, 37 | "devDependencies": { 38 | "@ruabick/md-demo-plugins": "latest", 39 | "@ruabick/vite-plugin-gen-api-doc": "latest", 40 | "@ruabick/vite-plugin-gen-temp": "latest", 41 | "@ruabick/vitepress-demo-block": "latest", 42 | "@typescript-eslint/eslint-plugin": "^5.33.1", 43 | "@typescript-eslint/parser": "^5.33.1", 44 | "@vitejs/plugin-vue": "^3.0.1", 45 | "cross-env": "^7.0.3", 46 | "eslint": "^8.20.0", 47 | "eslint-define-config": "^1.6.0", 48 | "eslint-plugin-import": "^2.26.0", 49 | "eslint-plugin-node": "^11.1.0", 50 | "gh-pages": "^4.0.0", 51 | "maplibre-gl": "^2.4.0", 52 | "np": "^7.6.2", 53 | "prettier": "^2.7.1", 54 | "sass": "^1.56.1", 55 | "vite": "3.2.5", 56 | "vite-plugin-dts": "^1.4.0", 57 | "vitepress": "1.0.0-alpha.29", 58 | "vue": "latest", 59 | "axios": "^1.1.2", 60 | "fs-extra": "^10.1.0", 61 | "lodash": "^4.17.21" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /scripts/configs.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | 4 | const codes = [ 5 | 420000, 6 | 420100, 7 | 420102, 8 | 420103, 9 | 420104, 10 | 420105, 11 | 420106, 12 | 420107, 13 | 420111, 14 | 420112, 15 | 420113, 16 | 420114, 17 | 420115, 18 | 420116, 19 | 420117, 20 | 420200, 21 | 420202, 22 | 420203, 23 | 420204, 24 | 420205, 25 | 420222, 26 | 420281, 27 | 420300, 28 | 420302, 29 | 420303, 30 | 420304, 31 | 420322, 32 | 420323, 33 | 420324, 34 | 420325, 35 | 420381, 36 | 420500, 37 | 420502, 38 | 420503, 39 | 420504, 40 | 420505, 41 | 420506, 42 | 420525, 43 | 420526, 44 | 420527, 45 | 420528, 46 | 420529, 47 | 420581, 48 | 420582, 49 | 420583, 50 | 420600, 51 | 420602, 52 | 420606, 53 | 420607, 54 | 420624, 55 | 420625, 56 | 420626, 57 | 420682, 58 | 420683, 59 | 420684, 60 | 420700, 61 | 420702, 62 | 420703, 63 | 420704, 64 | 420800, 65 | 420802, 66 | 420804, 67 | 420822, 68 | 420881, 69 | 420882, 70 | 420900, 71 | 420902, 72 | 420921, 73 | 420922, 74 | 420923, 75 | 420981, 76 | 420982, 77 | 420984, 78 | 421000, 79 | 421002, 80 | 421003, 81 | 421022, 82 | 421024, 83 | 421081, 84 | 421083, 85 | 421087, 86 | // 421088, 87 | 421100, 88 | 421102, 89 | 421121, 90 | 421122, 91 | 421123, 92 | 421124, 93 | 421125, 94 | 421126, 95 | 421127, 96 | 421181, 97 | 421182, 98 | 421200, 99 | 421202, 100 | 421221, 101 | 421222, 102 | 421223, 103 | 421224, 104 | 421281, 105 | 421300, 106 | 421303, 107 | 421321, 108 | 421381, 109 | 422800, 110 | 422801, 111 | 422802, 112 | 422822, 113 | 422823, 114 | 422825, 115 | 422826, 116 | 422827, 117 | 422828, 118 | 429004, 119 | 429005, 120 | 429006, 121 | 429021, 122 | ] 123 | 124 | const ORIGIN_GEOJSON_DIR = path.resolve(__dirname, '../.temp/origin-geojson') 125 | 126 | const MERGED_GEOJSON_DIR = path.resolve(__dirname, '../.temp/merged-geojson') 127 | 128 | module.exports = { 129 | codes, 130 | ORIGIN_GEOJSON_DIR, 131 | MERGED_GEOJSON_DIR, 132 | } -------------------------------------------------------------------------------- /src/components/Map/__docs__/04-geojson-map.vue: -------------------------------------------------------------------------------- 1 | 4 | 134 | -------------------------------------------------------------------------------- /src/components/SeamlessScroll/seamless-scroll.vue: -------------------------------------------------------------------------------- 1 | 120 | 121 | 136 | -------------------------------------------------------------------------------- /scripts/merge.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra'); 2 | const path = require('path') 3 | const config = require('./configs.js') 4 | const _ = require('lodash'); 5 | const { set } = require('lodash'); 6 | 7 | const readOriginJson = async (code) => { 8 | const filePath = path.resolve(config.ORIGIN_GEOJSON_DIR, `${code}.json`) 9 | return fs.readJSON(filePath) 10 | } 11 | 12 | const readJsons = async (codes) => { 13 | const tasks = codes.map(t => readOriginJson(t)) 14 | const jsons = await Promise.all(tasks) 15 | return jsons; 16 | } 17 | 18 | const getAllFeatures = (jsons) => { 19 | const features = [] 20 | jsons.forEach((json) => { 21 | const feature = _.get(json, 'features.0') 22 | const acroutes = _.get(feature, 'properties.acroutes') 23 | set(feature, 'properties.deep', acroutes.length) 24 | features.push(feature) 25 | // const parentCode = _.get(feature, 'properties.parent.adcode') 26 | // if (!codes.includes(parentCode)) { 27 | // rootNodes.push(feature) 28 | // return 29 | // } 30 | // const parentJson = jsons.find(t => _.get(t,'features.0.properties.adcode') == parentCode) 31 | // const parentNode = _.get(parentJson, 'features.0') 32 | // const parentChildren = _.get(parentNode, 'children') ?? [] 33 | // parentChildren.push(feature) 34 | // _.set(parentNode, 'children', parentChildren) 35 | // return; 36 | }) 37 | return features; 38 | } 39 | 40 | const genChildrenMap = (features) => { 41 | const map = {} 42 | features.forEach(feature => { 43 | const adcode = _.get(feature, 'properties.adcode') 44 | const parentCode = _.get(feature, 'properties.parent.adcode') 45 | if (!features.some(t => _.get(t, 'properties.adcode') == parentCode)) { 46 | return 47 | } 48 | const parentChildren = _.get(map, parentCode) ?? [] 49 | parentChildren.push(adcode) 50 | _.set(map, parentCode, parentChildren) 51 | }) 52 | return map; 53 | } 54 | 55 | const outputMergedJsons = async (childrenMap, allFeatures) => { 56 | await fs.remove(config.MERGED_GEOJSON_DIR) 57 | await fs.ensureDir(config.MERGED_GEOJSON_DIR) 58 | const tasksWithChildren = Object.keys(childrenMap).map(key => { 59 | const childrenCodes = childrenMap[key] 60 | const feature = allFeatures.find(t => _.get(t, 'properties.adcode') == key) 61 | const features = childrenCodes.map(code => allFeatures.find(t => _.get(t, 'properties.adcode') == code)) 62 | const geojson = {"type":"FeatureCollection", features, properties: feature.properties} 63 | const filePath = path.resolve(config.MERGED_GEOJSON_DIR, `${key}.json`) 64 | return fs.writeJSON(filePath, geojson) 65 | }) 66 | await Promise.all(tasksWithChildren) 67 | 68 | const tasksWithoutChildren = allFeatures.filter(t => !childrenMap[_.get(t, 'properties.adcode')]) 69 | .map(t => { 70 | const code = _.get(t, 'properties.adcode') 71 | const filePath = path.resolve(config.MERGED_GEOJSON_DIR, `${code}.json`) 72 | 73 | return fs.writeJSON(filePath, t) 74 | }) 75 | await Promise.all(tasksWithoutChildren) 76 | } 77 | 78 | const genAreaNames = (allFeatures) => { 79 | const features = allFeatures.map(feature => { 80 | const areaCode = _.get(feature, 'properties.adcode') 81 | const center = _.get(feature, 'properties.centroid') || _.get(feature, 'properties.center') 82 | const name = _.get(feature, 'properties.name') 83 | const parentCode = _.get(feature, 'properties.parent.adcode') 84 | const deep = _.get(feature, 'properties.deep') 85 | return { 86 | type: 'Feature', 87 | geometry: { 88 | type: 'Point', 89 | coordinates: center 90 | }, 91 | properties: { 92 | name, 93 | areaCode, 94 | deep, 95 | parentCode 96 | } 97 | } 98 | }) 99 | return { 100 | "type": "FeatureCollection", 101 | "features": features 102 | } 103 | } 104 | 105 | const outputAreaNames = async (areaNames) => { 106 | const filePath = path.resolve(config.MERGED_GEOJSON_DIR, 'area-names.json') 107 | return fs.writeJSON(filePath, areaNames) 108 | } 109 | 110 | const outputCodePropertiesMap = async (allFeatures) => { 111 | const codePropertiesMap = allFeatures.reduce((pre, feature) => { 112 | const code = _.get(feature, 'properties.adcode') 113 | const properties = _.get(feature, 'properties') 114 | return { 115 | ...pre, 116 | [code]: properties 117 | } 118 | }, {}) 119 | const filePath = path.resolve(config.MERGED_GEOJSON_DIR, 'code-properties.json') 120 | return fs.writeJSON(filePath, codePropertiesMap) 121 | } 122 | 123 | const begin = async () => { 124 | const jsons = await readJsons(config.codes) 125 | const allFeatures = getAllFeatures(jsons) 126 | const childrenMap = genChildrenMap(allFeatures) 127 | await outputMergedJsons(childrenMap, allFeatures) 128 | const areaNames = genAreaNames(allFeatures) 129 | await outputAreaNames(areaNames) 130 | await outputCodePropertiesMap(allFeatures) 131 | } 132 | 133 | begin() -------------------------------------------------------------------------------- /src/components/Map/__docs__/02-show-biz-info.vue: -------------------------------------------------------------------------------- 1 | 4 | 303 | --------------------------------------------------------------------------------