Arcgis Online - GeoJson篇
1.什么是GeoJson
GeoJSON是一种对各种地理数据结构进行编码的格式,基于Javascript对象表示法的地理空间信息数据交换格式。
GeoJSON对象可以表示几何、特征或者特征集合。GeoJSON支持下面几何类型:点、线、面、多点、多线、多面和几何集合。GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。
- GeoJSON对象可能有任何数目成员(名/值对)。
- GeoJSON对象必须有一个名字为"type"的成员。这个成员的值是由GeoJSON对象的类型所确定的字符串。
- type成员的值必须是下面之一:“Point”, “MultiPoint”, “LineString”,
“MultiLineString”, “Polygon”, “MultiPolygon”, “GeometryCollection”,
“Feature”, 或者 “FeatureCollection”。- GeoJSON对象可能有一个可选的"crs"成员,它的值必须是一个坐标参考系统的对象。
- GeoJSON对象可能有一个"bbox"成员,它的值必须是边界框数组。
2.怎样获得GeoJson
当你拥有.shp文件或是.mdb文件时,使用ArcMap软件(本案例中使用的ArcMap版本为10.6)将其打开,操作如下图:
(1)使用ArcMap添加数据
点击添加后,可以看到所需要的要素图层已经加入到ArcMap中了。
(2)转换为GeoJson文件
使用ArcMap中的转换工具进行格式转换,获取GeoJson文件。
选择选要转换的要素图层,勾选下方“GeoJSON(可选)”。
(此处的“格式化的JSON”不勾选可以减小文件的大小,因为使用不格式化的方式会使文件的内容进行压缩,类似于js文件中的min.js文件)
点击确定即可进行转换。
转换完成后,打开GeoJSON文件,格式如下:
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"features": [
{
"type": "Feature",
"id": 0,
"geometry": {
"type": "LineString",
"coordinates": [
[
118.81748098990269,
32.031701848104085
],
[
118.81764035969546,
32.031691692101084
]
]
},
"properties": {
"FID": 0,
"OBJECTID": 1,
"OID_": 0,
"PipePointN": "f4a4785a35bf4f6d94a50b6a45afa3e5",
"StartPotio": 332747.46000000002,
"StartPot_1": 345603.83500000002,
"EndPotionX": 332762.47600000002,
"EndPotionY": 345602.76199999999,
"Shape_Leng": 15.054287927300001,
"StartPoint": "qhqys8528",
"EndPointNu": "qhqys8529",
"StartBuryi": "2.1",
"EndBurying": "2.1",
"StartAltit": "5.654",
"EndAltitud": "5.654",
"Texture": "砼",
"BuryingMet": "4",
"LineType": "0",
"PipeDiamet": "600",
"Constructi": "未知",
"OwnershipU": "南京市排水管理处",
"UsageStatu": "2",
"FlowDirect": "0",
"Subordinat": "瑞金路",
"NorthAzimu": 94.087243753899998
}
},
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "LineString",
"coordinates": [
[
118.81727411207272,
32.031720870277802
],
[
118.81748098990269,
32.031701848104085
]
]
},
"properties": {
"FID": 1,
"OBJECTID": 2,
"OID_": 0,
"PipePointN": "fcfcfc817ce347f79c8581bbcee0431a",
"StartPotio": 332727.96899999998,
"StartPot_1": 345605.87300000002,
"EndPotionX": 332747.46000000002,
"EndPotionY": 345603.83500000002,
"Shape_Leng": 19.597258099299999,
"StartPoint": "qhqys8530",
"EndPointNu": "qhqys8528",
"StartBuryi": "2.07",
"EndBurying": "2.14",
"StartAltit": "5.654",
"EndAltitud": "5.654",
"Texture": "砼",
"BuryingMet": "4",
"LineType": "0",
"PipeDiamet": "600",
"Constructi": "未知",
"OwnershipU": "南京市排水管理处",
"UsageStatu": "2",
"FlowDirect": "0",
"Subordinat": "瑞金路",
"NorthAzimu": 95.969217759499998
}
},
{
"type": "Feature",
"id": 2,
"geometry": {
"type": "LineString",
"coordinates": [
[
118.81762183376144,
32.031793328940623
],
[
118.81764035969546,
32.031691692101084
]
]
},
"properties": {
"FID": 2,
"OBJECTID": 3,
"OID_": 0,
"PipePointN": "973708c023264a75a849564f49a275dc",
"StartPotio": 332760.75199999998,
"StartPot_1": 345613.98599999998,
"EndPotionX": 332762.47600000002,
"EndPotionY": 345602.76199999999,
"Shape_Leng": 11.355630849300001,
"StartPoint": "qhqys8531",
"EndPointNu": "qhqys8529",
"StartBuryi": "0.97",
"EndBurying": "1.31",
"StartAltit": "6.443",
"EndAltitud": "6.443",
"Texture": "砼",
"BuryingMet": "4",
"LineType": "0",
"PipeDiamet": "300",
"Constructi": "未知",
"OwnershipU": "南京市排水管理处",
"UsageStatu": "2",
"FlowDirect": "0",
"Subordinat": "后标营路",
"NorthAzimu": 171.267647646
}
}
]
}
由于文件内容非常多,此处仅展示部分数据,仅供参考GeoJSON文件的格式。
3.使用ArcGIS API for JavaScript展示GeoJson要素
案例完整效果如下图:
图中可以看出,已经将GeoJson文件加入到图层中,在地图中进行展示,但此时该要素图层可以看出位置并不准确,与地图上的道路发生了偏移,这种情况是因为本案例使用了谷歌的地图底层,使用百度、高德也会发生类似的问题,主要是因为本国所使用的地图均使用了加密算法,不能直接与wgs84的坐标进行直接匹配,因此需要使用ArcMap对.shp文件或是mdb文件提前进行空间偏移,以此做到两边的坐标统一,再加入到地图中即可。
此处的实现代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>GeoJSONLayer - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.15/"></script>
<script>require([
"esri/config",
"esri/request",
"esri/Color",
"esri/layers/BaseTileLayer",
"esri/Map",
"esri/layers/GeoJSONLayer",
"esri/views/MapView"
], function (esriConfig, esriRequest, Color, BaseTileLayer,Map, GeoJSONLayer, MapView) {
// 如果GeoJSON文件与你的网站不在同一个域中,则需要启用CORS的服务器或代理。
const url = "http://localhost:8888/GeoJson/qhqys_ln_geo.json";
const geojsonLayer = new GeoJSONLayer({
url: url,
copyright: "USGS Earthquakes"
});
const map = new Map({
basemap: "gray"
});
let TintLayer = BaseTileLayer.createSubclass({
properties: {
urlTemplate: null,
tint: {
value: null,
type: Color
}
},
getTileUrl: function (level, row, col) {
return this.urlTemplate
.replace("{z}", level)
.replace("{x}", col)
.replace("{y}", row);
},
fetchTile: function (level, row, col) {
var url = this.getTileUrl(level, row, col);
return esriRequest(url, {
responseType: "image",
allowImageDataAccess: true
}).then(
function (response) {
var image = response.data;
var width = this.tileInfo.size[0];
var height = this.tileInfo.size[0];
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
context.drawImage(image, 0, 0, width, height);
return canvas;
}.bind(this)
);
}
});
//高德地图底层
//esriConfig.request.corsEnabledServers.push("webst01.is.autonavi.com");
//gaoDeLayer = new TintLayer({
// urlTemplate:
// "http://webst01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
// tint: new Color("#004FBB"),
// title: "高德地图"
//});
//谷歌地图底层
esriConfig.request.corsEnabledServers.push("http://www.google.cn/");
let digitalTileLayer = new TintLayer({
urlTemplate:
"http://www.google.cn/maps/vt/lyrs=m@226000000&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=Galil",
tint: new Color("#004FBB"),
title: "谷歌地图"
});
map.add(digitalTileLayer);
const view = new MapView({
container: "viewDiv",
center: [118.829248, 32.026729],
zoom: 14,
map: map
});
map.add(geojsonLayer);
});</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
4.结束
使用GeoJson的方式展示地图要素整篇看起来难度应该不大,但是对于不太了解地图测绘、GIS开发的程序员来说过程其实非常艰辛,可能短短的一段代码都是经过了很长时间的调试才能确定问题的,希望这篇文章能帮助到其他遇到类似问题的同学,本人也是第一次编写博客,不足之处还请谅解。
后续会陆续发出如何使用ArcMap进行坐标转换、空间校正的方法,以及本人使用Arcgis Online进行开发的案例,敬请期待。