上傳並在地圖中顯示Shp文件

前段時間參與了一個項目,客戶有一個功能需求是上傳SHP文件並在地圖上顯示,然後在此基礎上做緩衝區處理。經過對比測試,最終選擇了shapefile.js工具,在此做個記錄。

shapfe.js能夠將Esri的Shapefile文件轉換爲GeoJSON,它能夠以Shapefile文件zip的壓縮文件和單獨的.shp文件作爲輸入參數。

shapefile.js安裝

項目是基於Vue開發的,因此選擇了npm的安裝方式,安裝非常簡單,執行下面的命令就可以了。

npm install shpjs

獲取上傳的SHP文件

在HTML中可使用type爲file的input標籤獲取上傳的.shp文件或者壓縮後的Shapefile文件。

<input type="file" id="uploadFileInput" name="zip" @change="selectShpFile()">
selectShpFile: function() {
  this.shpFile = document.getElementById("uploadFileInput").files[0];
}

使用FileReader處理上傳後的SHP文件

JavaScript中的FileReader用來讀取Blob或者File的內容。

FileReader共包含4個方法,其中三個用來讀取文件內容,一個用來打斷讀取。

方法名稱 方法參數 方法描述
abort 中斷文件讀取
readAsBinaryString File 將文件讀取爲二級制碼
readAsDataURL File 將文件讀取爲DataURL
readAsText File, [encoding] 將文件讀取爲文本

FileReader處理事件共有6個,具體描述如下:

事件名稱 事件描述
onabort 中斷時觸發
onerror 出錯時觸發
onload 文件讀取成功時觸發
onloadend 讀取完成時觸發,無論成功或失敗
onloadstart 讀取開始時觸發
onprogress 讀取中

這裏需要注意的一點是,文件一旦開始讀取,無論成功還是失敗,實例的result屬性都會被填充,也就是說如果讀取失敗,result的值爲null,讀取成功則爲讀取的結果。

在本項目中,我們使用了readAsBinaryString方法,並且監聽onload事件獲取文件的讀取內容。

let fileReader = new FileReader();

fileReader.readAsArrayBuffer(shpFile);
fileReader.onload = function() {
    // 獲取讀取的結果
    console.log(this.result);
}

使用shapefile.js將SHP文件讀取爲GeoJSON

shapefile.js使用也非常簡單,我們使用其read方法,並將上一步的文件的二進制讀取結果作爲read方法的參數,然後在其回調函數中獲取GeoJson。

這一步和上一步的整合後的代碼如下:

let fileReader = new FileReader();

fileReader.readAsArrayBuffer(shpFile);
fileReader.onload = function() {
    let shapefile = require("shapefile");
    shapefile
      .read(this.result)
      .then(geoJson => {
        console.log(geoJson);
      }
}

GeoJSON文件內容如下圖所示:
在這裏插入圖片描述

在地圖中加載GeoJson

在地圖中加載GeoJson需要遍歷其features屬性,將其中的每個feature轉爲對應的幾何對象(點、線或者面),然後將轉換的幾何對象構建成一個Graphic,最後將Graphic添加到GraphicLayer中。

遍歷features,構建Polygon對象

geoJson.features.map(feature => {
  const polygon = new EsriPolygon({
    spatialReference: new EsriSpatialReference({ wkid: 2380 })
  });

  feature.geometry.coordinates.forEach(function(coord) {
    const coordinates =
      feature.geometry.type === "MultiPolygon" ? coord[0] : coord;
    polygon.addRing(coordinates);
  });
}

Polygon構建Graphic,並添加到GraphicLayer

let graphics = [];
let graphicsExtent = null;

geoJson.features.map(feature => {
  const polygon = new EsriPolygon({
    spatialReference: new EsriSpatialReference({ wkid: 2380 })
  });

  feature.geometry.coordinates.forEach(function(coord) {
    const coordinates =
      feature.geometry.type === "MultiPolygon" ? coord[0] : coord;
    polygon.addRing(coordinates);
  });

  const graphic = new EsriGraphic({
    geometry: polygon,
    attributes: feature.properties,
    symbol: {
      type: "simple-fill", // autocasts as new SimpleFillSymbol()
      color: [51, 51, 204, 0.9],
      style: "solid",
      outline: {
        color: "white",
        width: 1
      }
    }
  });

  graphics.push(graphic);
});

graphicLayer.addMany(graphics);

至此,我們已經完成了上傳並在地圖中展示SHP文件的整個流程,下一步就可以調用相應的API函數創建緩衝區,並執行接下來的各種功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章