这次综合网上的一些方法找到了获取象征级别genjson数据的方法。比前面一篇更加合理。

先上一个效果图。

首先需要站在巨人的肩膀上,下载几个依赖。

svg2genjson  依靠这个可以将svg转为可使用的genjson。尽量用  yarn 来安装依赖,npm 会有问题(你的node.js版本在11以下或者gulp版本>4就没问题)

可以在package.json中加这个代码解决

  // 锁定版本
"resolutions": {
    "graceful-fs": "4.2.2"
  },

乡镇的svg数据获取可以在这里获取  获取乡镇的svg图片

这里获取的svg 并不能直接通过 svg2geojson 来进行转化,因为他只支持矢量地图。

这里是我自己写的一个方法将下载的svg  转化成可使用的 矢量地图。

 这里的svg标签是在 上面获取的乡镇的 svg 。用记事本打开后直接复制到代码里面。

记得给svg 加一个    id=‘svgEl’   不然会报错。

这是script 的代码    

yarn add svg-path-parser

init() {
      const svgEl = document.getElementById('svgEl')
      const nameList = []
      const data = []
      ;[...svgEl.children[1].children].forEach((v) => {
        nameList.push(v)
      })
      nameList.pop()
      let postion = nameList.reverse().findIndex((el) => el.nodeName === 'path')
      nameList.slice(0, postion).forEach((el) => {
        data.push({
          id: el.innerHTML.trim(),
        })
      })
      nameList.slice(postion, 2 * postion).forEach((el, i) => {
        data[i] = { ...data[i], path: el.attributes[1].value }
      })
      data.forEach((v) => {
        this.svg(v)
      })
// 这个log 输出的东西就是我们需要的矢量地图 直接在控制台copy 一下
      console.log(
        `
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	width="727px" height="911px" viewBox="-100 0 727 911" enable-background="new -297.5 420.5 727 911" xml:space="preserve">
 ${this.list}
  </svg>
  	`.trim()
      )
    },
 svg(svgData) {
      const { parseSVG, makeAbsolute } = require('svg-path-parser')
      function svgPathToPolygons(svgPathString, opts = {}) {
        if (!opts.tolerance) opts.tolerance = 1
        const polys = []
        const tolerance2 = opts.tolerance * opts.tolerance
        let poly = []
        let prev
        makeAbsolute(parseSVG(svgPathString)).forEach((cmd) => {
          let x1 = 0,
            y1 = 0

          switch (cmd.code) {
            case 'M':
              polys.push((poly = []))
              // intentional flow-through
              break
            case 'L':
            case 'H':
            case 'V':
            case 'Z':
              add(cmd.x, cmd.y)
              if (cmd.code === 'Z') poly.closed = true
              break

            case 'C':
              sampleCubicBézier(
                cmd.x0,
                cmd.y0,
                cmd.x1,
                cmd.y1,
                cmd.x2,
                cmd.y2,
                cmd.x,
                cmd.y
              )
              add(cmd.x, cmd.y)
              break

            case 'S':
              if (prev) {
                if (prev.code === 'C') {
                  x1 = prev.x * 2 - prev.x2
                  y1 = prev.y * 2 - prev.y2
                } else {
                  x1 = prev.x
                  y1 = prev.y
                }
              }
              sampleCubicBézier(
                cmd.x0,
                cmd.y0,
                x1,
                y1,
                cmd.x2,
                cmd.y2,
                cmd.x,
                cmd.y
              )
              add(cmd.x, cmd.y)
              break

            default:
              console.error(
                'Our deepest apologies, but ' +
                  cmd.command +
                  ' commands (' +
                  cmd.code +
                  ') are not yet supported.'
              )
              process.exit(2)
          }
          prev = cmd
        })
        return polys

        function sampleCubicBézier(x0, y0, x1, y1, x2, y2, x3, y3) {
        const x01 = (x0 + x1) / 2,
            y01 = (y0 + y1) / 2,
            x12 = (x1 + x2) / 2,
            y12 = (y1 + y2) / 2,
            x23 = (x2 + x3) / 2,
            y23 = (y2 + y3) / 2,
            x012 = (x01 + x12) / 2,
            y012 = (y01 + y12) / 2,
            x123 = (x12 + x23) / 2,
            y123 = (y12 + y23) / 2,
            x0123 = (x012 + x123) / 2,
            y0123 = (y012 + y123) / 2

          const dx = x3 - x0,
            dy = y3 - y0

          const d1 = Math.abs((x1 - x3) * dy - (y1 - y3) * dx),
            d2 = Math.abs((x2 - x3) * dy - (y2 - y3) * dx)

          if ((d1 + d2) * (d1 + d2) < tolerance2 * (dx * dx + dy * dy))
            add(x0123, y0123)
          else {
            sampleCubicBézier(x0, y0, x01, y01, x012, y012, x0123, y0123)
            sampleCubicBézier(x0123, y0123, x123, y123, x23, y23, x3, y3)
          }
        }

        function add(x, y) {
          if (opts.decimals && opts.decimals >= 0) {
            x = x.toFixed(opts.decimals) * 1
            y = y.toFixed(opts.decimals) * 1
          }
          poly.push([x, y])
        }
      }

      function compare(pathData, opts = {}) {
        var polys = svgPathToPolygons(pathData, opts)
        var minX = Infinity,
          maxX = -Infinity,
          minY = Infinity,
          maxY = -Infinity,
          cx,
          cy
        polys.forEach((poly) => {
          poly.forEach((pt) => {
            if (pt[0] < minX) minX = pt[0]
            if (pt[1] < minY) minY = pt[1]
            if (pt[0] > maxX) maxX = pt[0]
            if (pt[1] > maxY) maxY = pt[1]
          })
        })
       
        return `
  <g id="${svgData.id}">
  ${polys
    .map((poly) => {
      const cxArr = []
      const cyArr = []
      poly.forEach((el) => {
        cxArr.push(el[0])
        cyArr.push(el[1])
      })
      cx = (
        (Math.max.apply(null, cxArr) + Math.min.apply(null, cxArr)) /
        2
      ).toFixed(3)
      cy = (
        (Math.max.apply(null, cyArr) + Math.min.apply(null, cyArr)) /
        2
      ).toFixed(3)
      return `  <${
        poly.closed ? 'polygon' : 'polyline'
      } fill="none" stroke="#000000" stroke-miterlimit="10" points="${poly.join(
        ' '
      )}  "/>`
    })
    .join('\n')}
  <circle fill="none" stroke="#EAC613" stroke-miterlimit="10" cx="${cx}" cy="${cy}" r="8.083"/>
  </g>
  `.trim()
      }

      let str = compare(`${svgData.path}`)

      this.list += str
    },

通过这里获取init函数在控制台获取到的就是我们需要的矢量地图(大概就是这样)直接粘贴到 svg2geojson  的svg 中,可以直接覆盖他的zhongshan.svg的内容,也可以自己新建一个svg然后粘贴进去,然后运行 gulp 

 在dist 中就可以获取到想要的 genjson 数据了。可以在echarts,g6 等其他的可视化工具使用了。

生成的文件是没有 code 码 的,要用的话需要手动配置了。

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐