前端加載本地shapefile格式檔案轉成geojson格式資料,本文将通過介紹兩個開源utils進行展示
一、加載 .shp
| .dbf
格式檔案
.shp
.dbf
1.安裝依賴
npm install shapefile --save-dev
https://github.com/mbostock/shapefile
2.使用
const loadShp = () => {
// 建立input标簽
let input = document.createElement('input');
input.type = 'file';
input.accept = ".shp"
input.onchange = e => {
let file = e.target.files[0];
let [name,format] = file.name.split('.');
if (file?.size / 1024 / 1024 > 10) {
alert("請選擇内容小于10MB的檔案!")
}
if ('.shp'.includes(format)) {
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = function () {
let shapefile = require('shapefile');
shapefile.read(this.result).then((geojson) => {
console.log("shp加載", geojson);
addGeoJsonToMap(geojson, name)
});
}
} else {
alert("暫不支援該類型資料檔案")
}
}
input.click();
}
3.效果
這個讀取隻能讀取幾何資訊并轉成geojson格式,至于坐标系還是屬性資訊,都是讀取不到的

但是我們可以使用
openDbf
方法單獨讀取
dbf
格式檔案
點選檢視代碼
const loadDbf = () => {
// 建立input标簽
let input = document.createElement('input');
input.type = 'file';
input.accept = ".dbf"
input.onchange = e => {
let file = e.target.files[0];
let [name, format] = file.name.split('.');
if (file?.size / 1024 / 1024 > 10) {
alert("請選擇内容小于10MB的檔案!")
}
if ('.dbf'.includes(format)) {
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = function () {
let shapefile = require('shapefile');
shapefile.openDbf(this.result).then((geotable) => {
console.log("dbf加載", geotable);
});
}
} else {
alert("暫不支援該類型資料檔案")
}
}
input.click();
}
二、加載shapefile所有檔案壓縮成 .zip
格式的檔案
.zip
1.安裝依賴
npm install shpjs --save-dev
https://github.com/calvinmetcalf/shapefile-js
2.使用
const loadZip = () => {
// 建立input标簽
let input = document.createElement('input');
input.type = 'file';
input.accept = ".zip"
input.onchange = e => {
let file = e.target.files[0];
let [name, format] = file.name.split('.');
if (file?.size / 1024 / 1024 > 10) {
alert("請選擇内容小于10MB的檔案!")
}
if ('.zip'.includes(format)) {
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = function () {
let shapefile = require('shpjs/dist/shp');
shapefile.parseZip(this.result).then((geojson) => {
console.log("zip加載", geojson);
addGeoJsonToMap(geojson, name)
});
}
} else {
alert("暫不支援該類型資料檔案")
}
}
input.click();
}
3.效果
可以看到,加載打包成zip格式的shapefile檔案,在這裡可以讀取到幾何資訊和屬性資訊,但坐标依舊是讀取不到
值得注意,這個zip加載好像會把坐标轉成4326的坐标
如圖,shp格式本來是3857坐标系的,打包成zip用這個庫解析後,變成了4326的坐标系了
// proj4js包将坐标從4326轉換為3857
import Proj4 from "./proj4.js";
不想轉成4326的話,我趕時間暫時如下處理,有想法的自行去鑽研了
// 把這個shp.js檔案14479行改成如下格式,因為它會把坐标轉換成4326,本系統預設坐标3857
// parsed = shp.combine([parseShp(zip[name + '.shp'], zip[name + '.prj']), dbf]);
// ==>> parsed = shp.combine([parseShp(zip[name + '.shp']), dbf]);
JS 讀取本地Shp的壓縮包(zip)轉換為geojson
三、其它
如圖,我們可以知道這個檔案的路徑
那麼我們可以直接把這個檔案複制出來,放到拓展檔案夾下(這裡可以把檔案改名)
用的時候,直接引用
另外一個庫也是如此!
(2022-11-11) 好像不行,它有其它的依賴庫o(╥﹏╥)o~~,單獨用的話,還需要下載下傳齊它的依賴庫.
arcgis api加載geojson資料至地圖
geojsonToArcGIS
是把geojson的feature格式轉出arcgis的geometry格式的一個方法
我用的是Arcgis for js 4.24版本,直接調用下面的方法,就可以把圖層加載至地圖了
geojsonToArcGIS()是一個arcgis-to-geojson-utils庫裡方法,更多詳情請點選檢視
// 添加geojson檔案圖層
const addGeoJsonToMap = (geoJson, name) => {
// 圖形集
let graphics = [];
// 圖形類型
let layerStyleType;
// 圖形渲染
let symbol;
switch (geoJson.features?.at(0).geometry.type ?? 'Polygon') {
case 'Point':
symbol = {
type: "simple-marker",
color: 'rgba(226, 119, 40)',
outline: {
color: 'rgba(255, 255, 255)',
width: 2
}
}
layerStyleType = 'point';
break;
case 'LineString':
symbol = {
type: "simple-line",
color: 'rgba(227, 139, 79, 0.8)',
width: 3,
cap: "round",
join: "round"
}
layerStyleType = 'polyline';
break;
case 'Polygon':
case 'MultiPolygon':
symbol = {
type: "simple-fill",
color: 'rgba(227, 139, 79, 0.8)',
outline: {
color: 'rgba(255, 255, 255)',
width: 1
}
}
layerStyleType = 'polygon';
break;
default:
console.log('default');
}
if (!layerStyleType) return;
geoJson.features.forEach(value => {
let graphic = geojsonToArcGIS(value);
graphic.geometry.spatialReference = new SpatialReference({ wkid: 3857 });
graphic.geometry.type = layerStyleType;
graphic.symbol = symbol;
graphics.push(graphic)
})
let layer = new GraphicsLayer({
title: name,
graphics,
symbol,
layerStyleType,
spatialReference: new SpatialReference({ wkid: 3857 }),
attributes
})
map.layers.add(layer);
// 縮放至于該圖層
layer.when(() => {
let geometries = layer.graphics.items.map(e => e.geometry);
let g = geometryEngine.union(geometries);
if (g) {
view.goTo(g).catch((error) => {
console.error(error);
});
}
})
}