前端解析csv或geojson文件并展示

2023-07-11 13:54:10 浏览数 (2)

概述

本位通过FileReader实现csv或geojson文件的前端解析并在地图上展示。

效果

实现

1.文件选择

文件选择用element-ui的el-upload组件实现。

代码语言:javascript复制
<el-upload
  drag
  ref="file"
  :action="uploadAction"
  :multiple="false"
  :auto-upload="false"
  :limit="1"
  :on-exceed="handleExceed"
  :on-change="changeDataFile"
  :on-success="successMethod"
  :accept="uploadFormatDict[dataFormat]"
>
  <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  <div class="el-upload__text">
    拖动文件到此或 <em>点击上传</em>
  </div>
  <template #tip>
    <div class="el-upload__tip">
      {{ uploadTipDict[dataFormat] }}
    </div>
  </template>
</el-upload>

2. csv文件解析

代码语言:javascript复制
// csv文件
if(uploadFile && this.dataFormat === 'csv') {
  const reader = new FileReader();
  reader.readAsText(uploadFile.raw,'GB2312');
  reader.onload = function () {
    const csvContent = reader.result;
    let {geomType, features} = csv2geojson(csvContent)
    geomType = geomType.toLowerCase()
    this.geomType = geomType
    if(geomType) {
      const geojson = new Geojson(features)
      if(geomType.indexOf('point') !== -1) map.getSource(`${DATA_LAYER}-point`).setData(geojson)
      if(geomType.indexOf('linestring') !== -1) map.getSource(`${DATA_LAYER}-line`).setData(geojson)
      if(geomType.indexOf('polygon') !== -1) {
        map.getSource(`${DATA_LAYER}-line`).setData(geojson)
        map.getSource(`${DATA_LAYER}-polygon`).setData(geojson)
      }
      const [xmin, ymin, xmax, ymax] = turf.bbox(geojson);
      const bbox = [[xmin, ymin], [xmax, ymax]];
      that.fitBbox(bbox)
    } else {
      ElMessage({
        message: '文件不包含空间字段!',
        type: 'warning',
      })
    }
  }
}

import {Feature} from './geojson'
import { wktToGeoJSON } from "@terraformer/wkt"
export function csv2geojson(csvContent) {
  const splitChar = csvContent.indexOf('r') ? 'r' : 'rn'
  const lines = csvContent.split(splitChar)
  const headers = lines[0].split(',').map(header => header.toLowerCase())
  let geomType = '', features = [], isWkt = false
  if(headers.includes('lon') && headers.includes('lat')) {
    geomType = 'Point'
  } else if(headers.includes('wkt')) {
    isWkt = true
    const geom = wktToGeoJSON(lines[1].split(',')[headers.indexOf('wkt')])
    geomType = geom.type
  }
  if(geomType) {
    for (let i = 1; i < lines.length; i  ) {
      const line = lines[i].split(',')
      if(line.length === headers.length) {
        let props = {}
        headers.forEach((header, index) => {
          if(!['wkt', 'lon', 'lat'].includes(header))  props[header] = line[index]
        })
        const lonIndex = headers.indexOf('lon')
        const latIndex = headers.indexOf('lat')
        const geometry = isWkt ?  wktToGeoJSON(line[headers.indexOf('wkt')]) : [line[lonIndex], line[latIndex]].map(Number)
        features.push(new Feature(geomType, props, geometry))
      }
    }
  }
  return {
    headers,
    geomType,
    features
  }
}

3.geojson文件解析

代码语言:javascript复制
// geojson文件
if(uploadFile && this.dataFormat === 'geojson') {
  const reader = new FileReader();
  reader.readAsText(uploadFile.raw,'utf-8');
  reader.onload = function () {
    const json = JSON.parse(reader.result);
    that.showGeojson(json)
  }
}
showGeojson(json) {
  const that = this
  const type = json.type
  const geoTypes = Object.values(GEOMETRY_TYPE)
  let geomType = ''
  if(type === "FeatureCollection") {
    geomType = json.features[0].geometry.type.toLowerCase()
  } else if (type === "Feature") {
    geomType = json.geometry.type.toLowerCase()
  } else if (geoTypes.includes(type)) {
    geomType = json.type.toLowerCase()
  }
  if(geomType) {
    if(geomType.indexOf('point') !== -1) map.getSource(`${DATA_LAYER}-point`).setData(json)
    if(geomType.indexOf('linestring') !== -1) map.getSource(`${DATA_LAYER}-line`).setData(json)
    if(geomType.indexOf('polygon') !== -1) {
      map.getSource(`${DATA_LAYER}-line`).setData(json)
      map.getSource(`${DATA_LAYER}-polygon`).setData(json)
    }
    const [xmin, ymin, xmax, ymax] = turf.bbox(json);
    const bbox = [[xmin, ymin], [xmax, ymax]];
    that.fitBbox(bbox)
  } else {
    ElMessage({
      message: '不是合法的geojson数据文件!',
      type: 'warning',
    })
  }
},

0 人点赞