arcgis api for 4.x支持2D和3D地图的展示,3.x的版本我们通过自定义Layer实现了高德地图、谷歌地图和天地图的加载。本文介绍了,在线地图服务、高德地图、谷歌地图、天地图在4.x版本中的加载方法。
1、在线地图服务
import React, { Component } from "react";
import esriLoader from "esri-loader";
//在线切片底图服务
export default class GisServerMap extends Component {
constructor(props) {
super(props);
this.tileMapUrl =
"http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer";
}
componentDidMount() {
this.initMap();
}
initMap() {
const mapURL = {
url: "https://js.arcgis.com/4.7/"
};
esriLoader
.loadModules(
[
"esri/Map",
"esri/Basemap",
"esri/layers/TileLayer",
"esri/views/MapView",
"esri/views/SceneView",
"dojo/domReady!"
],
mapURL
)
.then(([Map, Basemap, TileLayer, MapView, SceneView]) => {
let layer = new TileLayer({
url: this.tileMapUrl
});
//实例化底图对象
let baseMap = new Basemap({
baseLayers: [layer],
title: "Custom Basemap",
id: "myBasemap"
});
//实例化地图对象
let map = new Map({
basemap: baseMap
});
//实例化view
//2D
let view2D = new MapView({
center: [120.2, 32.1],
map: map,
container: "mapDiv2D",
zoom: 5
});
//3D
let view3D = new SceneView({
center: [120.2, 32.1],
map: map,
container: "mapDiv3D",
zoom: 1
});
});
}
render() {
let style = {
width: "50%",
height: "100%",
float: 'left'
};
return (
<div id="GisServerMap" className="mapContent">
<div id="mapDiv2D" style={style} />
<div id="mapDiv3D" style={style} />
<div style={{clear: 'both'}} />
</div>
);
}
}
2、高德地图
import React, { Component } from "react";
import esriLoader from "esri-loader";
import {
onlineAMapDigitalURL,
onlineAMapSatelliteURL,
onlineAMapAnooMarkerURL
} from "./../config";
//在线高德地图
export default class GisAMap extends Component {
componentDidMount() {
this.initMap();
}
initMap() {
const mapURL = {
url: "https://js.arcgis.com/4.7/"
};
esriLoader
.loadModules(
[
"esri/Map",
"esri/config",
"esri/request",
"esri/Color",
"esri/views/SceneView",
"esri/widgets/LayerList",
"esri/layers/BaseTileLayer",
"esri/views/MapView",
"dojo/domReady!"
],
mapURL
)
.then(
([
Map,
esriConfig,
esriRequest,
Color,
SceneView,
LayerList,
BaseTileLayer,
MapView
]) => {
// *******************************************************
// Custom tile layer class code
// Create a subclass of BaseTileLayer
// *******************************************************
let TintLayer = BaseTileLayer.createSubclass({
properties: {
urlTemplate: null,
tint: {
value: null,
type: Color
}
},
// generate the tile url for a given level, row and column
getTileUrl: function(level, row, col) {
return this.urlTemplate
.replace("{z}", level)
.replace("{x}", col)
.replace("{y}", row);
},
// This method fetches tiles for the specified level and size.
// Override this method to process the data returned from the server.
fetchTile: function(level, row, col) {
// call getTileUrl() method to construct the URL to tiles
// for a given level, row and col provided by the LayerView
var url = this.getTileUrl(level, row, col);
// request for tiles based on the generated url
// set allowImageDataAccess to true to allow
// cross-domain access to create WebGL textures for 3D.
return esriRequest(url, {
responseType: "image",
allowImageDataAccess: true
}).then(
function(response) {
// when esri request resolves successfully
// get the image from the response
var image = response.data;
var width = this.tileInfo.size[0];
var height = this.tileInfo.size[0];
// create a canvas with 2D rendering context
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
// Draw the blended image onto the canvas.
context.drawImage(image, 0, 0, width, height);
return canvas;
}.bind(this)
);
}
});
// *******************************************************
// Start of JavaScript application
// *******************************************************
// Add stamen url to the list of servers known to support CORS specification.
esriConfig.request.corsEnabledServers.push("webst01.is.autonavi.com");
// Create a new instance of the TintLayer and set its properties
let digitallTileLayer = 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: "高德"
});
let satelliteTileLayer = new TintLayer({
urlTemplate: 'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
tint: new Color("#004FBB"),
title: "高德"
});
let stamenTileLayer = new TintLayer({
urlTemplate: 'http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
tint: new Color("#004FBB"),
title: "高德"
});
// add the new instance of the custom tile layer the map
let map = new Map({
layers: [satelliteTileLayer, stamenTileLayer]
});
// create a new scene view and add the map
//2d
let view2D = new MapView({
container: "mapDiv2D",
map: map,
center: [110.1, 23.8],
zoom: 3
});
//3d
let view3D = new SceneView({
container: "mapDiv3D",
map: map,
center: [110.1, 23.8],
zoom: 1
})
}
);
}
render() {
let style = {
width: "50%",
height: "100%",
float: 'left'
};
return (
<div id="GisAMap" className="mapContent">
<div id="mapDiv2D" style={style} />
<div id="mapDiv3D" style={style} />
<div style={{clear: 'both'}} />
</div>
);
}
}
3、谷歌地图
import React, { Component } from "react";
import esriLoader from "esri-loader";
import {
onlineDigitalURL,
onlineSatelliteURL,
onlineAnooMarkerURL
} from "./../config";
//在线谷歌地图
export default class GisGoogleMap3D extends Component {
componentDidMount() {
this.initMap();
}
initMap() {
const mapURL = {
url: "https://js.arcgis.com/4.7/"
};
esriLoader
.loadModules(
[
"esri/Map",
"esri/config",
"esri/request",
"esri/Color",
"esri/views/SceneView",
"esri/views/MapView",
"esri/widgets/LayerList",
"esri/layers/BaseTileLayer",
"esri/layers/support/TileInfo",
"dojo/domReady!"
],
mapURL
)
.then(
([
Map,
esriConfig,
esriRequest,
Color,
SceneView,
MapView,
LayerList,
BaseTileLayer,
TileInfo
]) => {
let TintLayer = BaseTileLayer.createSubclass({
properties: {
urlTemplate: null,
tint: {
value: null,
type: Color
}
},
// generate the tile url for NumericalForecastSlide given level, row and column
getTileUrl: function(level, row, col) {
return this.urlTemplate
.replace("{z}", level)
.replace("{x}", col)
.replace("{y}", row);
},
fetchTile: function(level, row, col) {
let url = this.getTileUrl(level, row, col);
return esriRequest(url, {
responseType: "image",
allowImageDataAccess: true
}).then(
function(response) {
// when esri request resolves successfully
// get the image from the response
var image = response.data;
var width = this.tileInfo.size[0];
var height = this.tileInfo.size[0];
// create NumericalForecastSlide canvas with 2D rendering context
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
// Draw the blended image onto the canvas.
context.drawImage(image, 0, 0, width, height);
return canvas;
}.bind(this)
);
}
});
esriConfig.request.corsEnabledServers.push("http://www.google.cn/");
let stamenTileLayer = new TintLayer({
urlTemplate:
"http://www.google.cn/maps/vt/lyrs=s@157&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=Galil",
tint: new Color("#004FBB"),
title: "影像"
});
let AnooMarkerLayer = new TintLayer({
urlTemplate:
"http://www.google.cn/maps/vt/lyrs=h@177000000&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=Galil",
tint: new Color("#004FBB"),
title: "标注"
});
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: "地图"
});
let map = new Map({
layers: [digitalTileLayer, AnooMarkerLayer]
});
//2D
let view2D = new MapView({
id: "2D",
container: "mapDiv2D",
map: map,
center: [110.1, 23.8],
zoom: 2
});
//3D
let view3D = new SceneView({
id: "3D",
container: "mapDiv3D",
map: map,
center: [110.1, 23.8],
zoom: 1
});
}
);
}
render() {
let style = {
width: "50%",
height: "100%",
float: "left"
};
return (
<div id="GisGoogleMap" className="mapContent">
<div id="mapDiv2D" style={style} />
<div id="mapDiv3D" style={style} />
<div style={{clear: 'both'}}></div>
</div>
);
}
}
4、天地图
通过如上的方法调用在线天地图的链接一直存在跨域的问题,所以先实现2D状态下的地图加载,高德地图和谷歌地图也可以通过该方法加载。
import React, { Component } from "react";
import esriLoader from "esri-loader";
import {
onlineTdtDigitalURL,
onlineTdtSatelliteURL,
onlineTdtAnooMarkerURL
} from "./../config";
//天地图2D
export default class GisTdtMap extends Component {
componentDidMount() {
this.initMap();
}
initMap() {
const mapURL = {
url: "https://js.arcgis.com/4.7/"
};
esriLoader
.loadModules(
[
"esri/Map",
"esri/Basemap",
"esri/config",
"esri/views/MapView",
"esri/views/SceneView",
"esri/geometry/Extent",
"esri/geometry/SpatialReference",
"esri/layers/TileLayer",
"esri/layers/WebTileLayer",
"esri/layers/support/TileInfo",
"esri/Ground",
"dojo/on",
"dojo/domReady!"
],
mapURL
)
.then(
([
Map,
Basemap,
esriConfig,
MapView,
SceneView,
Extent,
SpatialReference,
TileLayer,
WebTileLayer,
TileInfo,
Ground,
on
]) => {
//实例化坐标系
let spatialReference = new SpatialReference({ wkid: 4326 });
//实例化初始范围
//let extent = new Extent({xmax: 13371824.0074, xmin: 8175464.5009, ymax: 5180434.2587, ymin: 3109500.2107,spatialReference});
let extent = new Extent(
95.56,
36.28,
125.65,
45.33,
new SpatialReference({ wkid: 4326 })
);
let tileInfo = new TileInfo({
dpi: 90.71428571427429,
rows: 256,
cols: 256,
compressionQuality: 0,
origin: {
x: -180,
y: 90
},
spatialReference: {
wkid: 4326
},
lods: [
{
level: 2,
levelValue: 2,
resolution: 0.3515625,
scale: 147748796.52937502
},
{
level: 3,
levelValue: 3,
resolution: 0.17578125,
scale: 73874398.264687508
},
{
level: 4,
levelValue: 4,
resolution: 0.087890625,
scale: 36937199.132343754
},
{
level: 5,
levelValue: 5,
resolution: 0.0439453125,
scale: 18468599.566171877
},
{
level: 6,
levelValue: 6,
resolution: 0.02197265625,
scale: 9234299.7830859385
},
{
level: 7,
levelValue: 7,
resolution: 0.010986328125,
scale: 4617149.8915429693
},
{
level: 8,
levelValue: 8,
resolution: 0.0054931640625,
scale: 2308574.9457714846
},
{
level: 9,
levelValue: 9,
resolution: 0.00274658203125,
scale: 1154287.4728857423
},
{
level: 10,
levelValue: 10,
resolution: 0.001373291015625,
scale: 577143.73644287116
},
{
level: 11,
levelValue: 11,
resolution: 0.0006866455078125,
scale: 288571.86822143558
},
{
level: 12,
levelValue: 12,
resolution: 0.00034332275390625,
scale: 144285.93411071779
},
{
level: 13,
levelValue: 13,
resolution: 0.000171661376953125,
scale: 72142.967055358895
},
{
level: 14,
levelValue: 14,
resolution: 8.58306884765625e-5,
scale: 36071.483527679447
},
{
level: 15,
levelValue: 15,
resolution: 4.291534423828125e-5,
scale: 18035.741763839724
},
{
level: 16,
levelValue: 16,
resolution: 2.1457672119140625e-5,
scale: 9017.8708819198619
},
{
level: 17,
levelValue: 17,
resolution: 1.0728836059570313e-5,
scale: 4508.9354409599309
},
{
level: 18,
levelValue: 18,
resolution: 5.3644180297851563e-6,
scale: 2254.4677204799655
},
{
level: 19,
levelValue: 19,
resolution: 2.68220901489257815e-6,
scale: 1127.23386023998275
},
{
level: 20,
levelValue: 2,
resolution: 1.341104507446289075e-6,
scale: 563.616930119991375
}
]
});
//实例化电子地图
let digitalLayer = new WebTileLayer({
id: "digitalMap",
title: "digitalMap",
urlTemplate: 'http://{subDomain}.tianditu.com/DataServer?T=vec_c&x={col}&y={row}&l={level}',
subDomains: ["t0"],
tileInfo: tileInfo,
spatialReference: spatialReference
});
//实例化影像图
let satelliteLayer = new WebTileLayer({
urlTemplate: 'http://{subDomain}.tianditu.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=c&TileMatrix={level}&TileRow={row}&TileCol={col}&style=default&format=tiles',
subDomains: ["t0"],
tileInfo: tileInfo,
spatialReference: spatialReference
});
//实例化地图标注
let anooMarkerLayer = new WebTileLayer({
id: "anooMarkerMap",
title: "anooMarkerMap",
urlTemplate: 'http://{subDomain}.tianditu.com/DataServer?T=cva_c&x={col}&y={row}&l={level}',
subDomains: ["t0"],
tileInfo: tileInfo,
spatialReference: spatialReference
});
//实例化Map对象
let mapControl = new Map({
//spatialReference:spatialReference,
basemap: {
baseLayers: [digitalLayer, anooMarkerLayer]
}
});
//实例化MapView对象
let mapView = new MapView({
map: mapControl,
container: "mapDiv",
center: [110.1, 23.8],
extent: extent,
zoom: 2
});
}
);
}
render() {
let style = {
width: "100%",
height: "100%"
};
return (
<div id="GisTdtMap" className="mapContent">
<div id="mapDiv" style={style} />
</div>
);
}
}
5、谷歌地图2D
import React, { Component } from "react";
import esriLoader from "esri-loader";
import {
onlineDigitalURL,
onlineSatelliteURL,
onlineAnooMarkerURL
} from "./../config";
//谷歌地图2D
export default class GisGoogleMap extends Component {
componentDidMount() {
this.initMap();
}
initMap() {
const mapURL = {
url: "https://js.arcgis.com/4.7/"
};
esriLoader
.loadModules(
[
"esri/Map",
"esri/Basemap",
"esri/config",
"esri/views/MapView",
"esri/views/SceneView",
"esri/geometry/Extent",
"esri/geometry/SpatialReference",
"esri/layers/TileLayer",
"esri/layers/WebTileLayer",
"esri/layers/support/TileInfo",
"esri/Ground",
"dojo/on",
"dojo/domReady!"
],
mapURL
)
.then(
([
Map,
Basemap,
esriConfig,
MapView,
SceneView,
Extent,
SpatialReference,
TileLayer,
WebTileLayer,
TileInfo,
Ground,
on
]) => {
//实例化坐标系
let spatialReference = new SpatialReference({ wkid: 102100 });
//实例化初始范围
//let extent = new Extent({xmax: 13371824.0074, xmin: 8175464.5009, ymax: 5180434.2587, ymin: 3109500.2107,spatialReference});
let extent = new Extent(
95.56,
36.28,
125.65,
45.33,
new SpatialReference({ wkid: 4326 })
);
//实例化TileInfo
let tileInfo = new TileInfo({
rows: 256,
cols: 256,
compressionQuality: 0,
origin: { x: -20037508.342787, y: 20037508.342787 },
spatialReference: { wkid: 102113 },
lods: [
{
level: 3,
scale: 73957190.948944,
resolution: 19567.8792409999
},
{
level: 4,
scale: 36978595.474472,
resolution: 9783.93962049996
},
{
level: 5,
scale: 18489297.737236,
resolution: 4891.96981024998
},
{ level: 6, scale: 9244648.868618, resolution: 2445.98490512499 },
{ level: 7, scale: 4622324.434309, resolution: 1222.99245256249 },
{ level: 8, scale: 2311162.217155, resolution: 611.49622628138 },
{ level: 9, scale: 1155581.108577, resolution: 305.748113140558 },
{ level: 10, scale: 577790.554289, resolution: 152.874056570411 },
{ level: 11, scale: 288895.277144, resolution: 76.4370282850732 },
{ level: 12, scale: 144447.638572, resolution: 38.2185141425366 },
{ level: 13, scale: 72223.819286, resolution: 19.1092570712683 },
{ level: 14, scale: 36111.909643, resolution: 9.55462853563415 },
{ level: 15, scale: 18055.954822, resolution: 4.77731426794937 },
{ level: 16, scale: 9027.977411, resolution: 2.38865713397468 },
{ level: 17, scale: 4513.988705, resolution: 1.19432856685505 },
{ level: 18, scale: 2256.994353, resolution: 0.597164283559817 },
{ level: 19, scale: 1128.497176, resolution: 0.298582141647617 }
]
});
//实例化电子地图
let digitalLayer = new WebTileLayer({
id: "digitalMap",
title: "digitalMap",
urlTemplate: 'http://mt1.google.cn/vt/lyrs=m@226000000&hl=zh-CN&gl=cn&src=app&x=${col}&y=${row}&z=${level}&s=Gali',
tileInfo: tileInfo,
spatialReference: new SpatialReference({ wkid: 102100 })
});
//实例化影像图
let satelliteLayer = new WebTileLayer({
id: "satelliteMap",
title: "satelliteMap",
urlTemplate: 'http://mt1.google.cn/vt/lyrs=s@157&hl=zh-CN&gl=cn&x=${col}&y=${row}&z=${level}&s=Gali',
tileInfo: tileInfo,
spatialReference: new SpatialReference({ wkid: 102100 })
});
//实例化地图标注
let AnooMarkerLayer = new WebTileLayer({
id: "anooMarkerMap",
title: "anooMarkerMap",
urlTemplate: 'http://mt1.google.cn/vt/lyrs=h@177000000&hl=zh-CN&gl=cn&x=${col}&y=${row}&z=${level}&s=Gali',
tileInfo: tileInfo,
spatialReference: new SpatialReference({ wkid: 102100 })
});
//实例化Basemap对象
let baseMap = new Basemap({
baseLayers: [digitalLayer]
});
//实例化Map对象
let mapControl = new Map({
basemap: baseMap
});
//实例化MapView对象
let mapView = new MapView({
map: mapControl,
container: "mapDiv",
center: [10754619.8603, 4269984.3426],
extent: extent,
zoom: 1
});
}
);
}
render() {
let style = {
width: "100%",
height: "100%"
};
return (
<div id="GisGoogleMap" className="mapContent">
<div id="mapDiv" style={style} />
</div>
);
}
}