webappbuilder改为不依赖portal之arcgis for js4.系列
?
夜已深,天很冷,簡單寫點,以慰藉這幾天的成果。
由于項目需要,也源于程序員的強迫,總是想基于webappbuilder+arcgis for js4.系列,做一個不依賴portal的源碼。
經過測試,已經試驗成功,并成功添加天地圖。
環境:webappbuilder2.6+arcgis for js 4.5。
還是基于webstorm開發,在vs2017下弄過,雖然可以調試js,但感覺很慢,反正就是結合vs、記事本、webstorm等,你懂的。
一、前期準備
很簡單,有portal,官網上下載web appbuilder,經過一路下來,生成一個3D的應用程序。
注意:一定要生成一個3D的應用程序,因為,webappbuilder的3D程序是基于arcgis js 4系列,因此,生成一個3D應用程序,在該代碼基礎上進行修改。
準備完成后,就需要改造代碼了。
?
二、代碼改造
其實代碼改造很簡單,就改幾個地方就可以了。
1、拷貝jimu.js文件夾下的WebSceneLoader.js文件,重命名為WebMapLoader.js,對其進行改造,使其能夠加載二維地圖數據,代碼如下:
/ Copyright ? 2014 - 2017 Esri. All Rights Reserved. Licensed under the Apache License Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at ???http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.///define([
????'dojo/Deferred',
????'dojo/_base/lang',
????'dojo/_base/array',
????'dojo/_base/html',
????'dojo/promise/all',
????'esri/kernel',
????'esri/Map',
????'esri/WebMap',
????'esri/views/MapView',
????"esri/layers/GraphicsLayer",
????'esri/portal/Portal',
????'esri/portal/PortalItem',
????'esri/core/sniff',
????'./utils',
????'./portalUtils',
????'./portalUrlUtils'], function(Deferred, lang, array, html, all, esriNS, Map,WebMap, MapView,GraphicsLayer,Portal, PortalItem,has,
????????????jimuUtils, portalUtils, portalUrlUtils) {
?
????var mo = {
????????createMap: function(mapDivId, portalUrl, itemId,mapOptions) {
????????????var def = new Deferred();
????????????def = this._createMap(mapDivId, portalUrl, itemId,mapOptions);
????????????return def;
????????},
?
????????_createMapNoPortal: function(mapDivId,mapOptions) {
????????????var def = new Deferred();
????????????var map = new Map();
????????????map.id = mapDivId;
????????????if(!mapOptions)
????????????{
????????????????mapOptions = {};
????????????}
????????????mapOptions.map = map;
????????????mapOptions.container = mapDivId;
????????????var mapView = new MapView(mapOptions);
????????????//, ???????????//extent:new Extent({ ???????????// ???xmin:-180, ???????????// ???ymin:-90, ???????????// ???xmax:180, ???????????// ???yamx:90, ???????????// ???sptialReference:new SpatialReference({ ???????????// ???????wkid:4326 ???????????// ???}) ???????????//必須加上這個圖層,否則,球不顯示 ???????????var graphicsLayer = new GraphicsLayer();
????????????mapView.map.add(graphicsLayer); //addLayer ???????????//this._handleLocalScene(mapView); ???????????def.resolve(mapView);
????????????return def;
????????},
????????_createMap: function (mapDivId, portalUrl, itemId,mapOptions) {
????????????if (!portalUrl)
????????????{
????????????????return this._createMapNoPortal(mapDivId,mapOptions);
????????????}
????????????var esriConfig = jimuUtils.getEsriConfig();
????????????esriConfig.portalUrl = portalUrlUtils.getStandardPortalUrl(portalUrl);
?
????????????var def = new Deferred();
????????????var defs = [];
?
????????????/************************************************************ ????????????* Creates a new WebScene instance. A WebScene must reference ????????????* a PortalItem ID that represents a WebScene saved to ????????????* arcgis.com or an on premise portal. ????????????* ????????????* To load a WebScene from an onpremise portal, set the portal ????????????* url in esriConfig.portalUrl. ????????????************************************************************/ ???????????Portal._default = null;
????????????var map = new WebMap({
????????????????portalItem: new PortalItem({
????????????????????id: itemId
????????????????})
????????????});
?
????????????/************************************************************ ????????????* Set the WebScene instance to the map property in a SceneView. ????????????************************************************************/ ???????????//we add extra attribute 'view' for scene ???????????// View can emit 'resize' event ???????????var mapView = new MapView({
????????????????map: map,
????????????????container: mapDivId
????????????});
?
????????????defs.push(map);
????????????defs.push(mapView);
?
????????????var portal = portalUtils.getPortal(portalUrl);
????????????defs.push(portal.getItemById(itemId));
????????????defs.push(portal.getItemData(itemId));
?
????????????all(defs).then(lang.hitch(this, function(results) {
????????????????if(mapView.popup){
????????????????????mapView.popup.closeOnViewChangeEnabled = true;
????????????????}
????????????????map.id = mapDivId;
????????????????map.itemId = itemId;
????????????????map.itemInfo = {
????????????????????item: results[2],
????????????????????itemData: results[3]
????????????????};
????????????????this._handleLocalScene(mapView);
????????????????def.resolve(mapView);
????????????????//this._handleAttribution(sceneView); ???????????}), lang.hitch(this, function(err) {
????????????????console.error(err);
????????????????def.reject(err);
????????????}));
?
????????????return def;
????????},
????????_handleLocalScene: function (sceneView) {
????????????try {
????????????????if (sceneView.viewingMode && sceneView.viewingMode.toLowerCase() === 'local') {
????????????????????lang.setObject("constraints.collision.enabled", false, sceneView);
????????????????????lang.setObject("constraints.tilt.max", 179.99, sceneView);
????????????????}
????????????} catch (e) {
????????????????console.error(e);
????????????}
????????}
????};
????return mo;
});
?
WebSceneLoader.js文件也做相應改造,其實和map的差不多,不貼代碼了。
?
?
2、MapManager.js文件改造
(1)添加webmaploader.js文件的支持
define([
??'dojo/_base/declare',
??'dojo/_base/lang',
??'dojo/_base/array',
??'dojo/_base/html',
??'dojo/topic',
??'dojo/on',
??// 'dojo/aspect', ?'dojo/keys',
??// 'dojo/Deferred', ?// 'esri/dijit/InfoWindow', ?// "esri/dijit/PopupMobile", ?// 'esri/InfoTemplate', ?'esri/geometry/Extent',
??'esri/geometry/Point',
??'./utils',
?
??'./dijit/LoadingShelter',
??// 'jimu/LayerInfos/LayerInfos', ?// './MapUrlParamsHandler', ?'./AppStateManager',
????'./WebSceneLoader',
??'./WebMapLoader',
??'esri/Viewpoint','esri/geometry/SpatialReference'], function(declare, lang, array, html, topic, on,/* aspect,*/ keys,/* Deferred, InfoWindow, ?PopupMobile, InfoTemplate,*/ Extent, Point, jimuUtils, LoadingShelter, /*LayerInfos, ?MapUrlParamsHandler,*/ AppStateManager, WebSceneLoader, WebMapLoader, Viewpoint,SpatialReference) {
?
(2)
_showMap函數改造
_showMap: function(appConfig) {
??// console.timeEnd('before map'); ?console.time('Load Map');
??this.loading = new LoadingShelter();
??this.loading.placeAt(this.mapDivId);
??this.loading.startup();
??//for now, we can't create both 2d and 3d map ?if (appConfig.map['3D']) {
??????this._show3DWebScene(appConfig,true);
??} else {
????this._show3DWebScene(appConfig,false);
??}
?
},
(3)_show3DWebScene函數改造
_show3DWebScene: function(appConfig,is3D) {
??var portalUrl = appConfig.map.portalUrl;
??var itemId = appConfig.map.itemId;
??this._destroySceneView();
??var def;
??if(is3D)
??{
????def = WebSceneLoader.createMap(this.mapDivId, portalUrl, itemId,appConfig.map.mapOptions);
??}
?else ?{
????def = WebMapLoader.createMap(this.mapDivId, portalUrl, itemId,appConfig.map.mapOptions);
??}
??def.then(lang.hitch(this, function(sceneView){
????this._publishSceneViewEvent(sceneView);
????if(appConfig.map.mapOptions){
??????var initialState = appConfig.map.mapOptions.initialState;
??????if(initialState && initialState.viewpoint){
????????try{
??????????var vp = Viewpoint.fromJSON(initialState.viewpoint);
??????????if(vp){
????????????this.sceneView.map.initialViewProperties.viewpoint = vp;
????????????this.sceneView.viewpoint = vp.clone();
??????????}
????????}catch(e){
??????????console.error(e);
????????}
??????}
????}
??}), lang.hitch(this, function(){
????if (this.loading) {
??????this.loading.destroy();
????}
????topic.publish('mapCreatedFailed');
??}));
},
(4)添加根據配置文件添加函數
主要代碼如下:
_publishSceneViewEvent: function(sceneView){
??window._sceneView = sceneView;
?
??console.timeEnd('Load Map');
?
??if(this.loading){
????this.loading.destroy();
??}
?
??if(this.sceneView){
????this.sceneView = sceneView;
????//this.resetInfoWindow(true); ???console.log("sceneView changed");
????topic.publish('sceneViewChanged', this.sceneView);
??}else{
????this.sceneView = sceneView;
????//this.resetInfoWindow(true); ???console.log("sceneView loaded");
????topic.publish('sceneViewLoaded', this.sceneView);
??}
??//添加圖層 ?this._visitConfigMapLayers(this.appConfig, lang.hitch(this, function(layerConfig,i) {
????this.createLayer(sceneView.map, layerConfig,i);
??}));
},_visitConfigMapLayers: function(appConfig, cb) {
??array.forEach(appConfig.map.basemaps, function(layerConfig, i) {
????cb(layerConfig, i);
??}, this);
},createLayer: function(map, layerConfig,index) {
??if(!map || !layerConfig || !layerConfig.type)
??{
????return;
??}
??var layMap = {
????'mapserver': 'esri/layers/MapImageLayer',
????'imageserver': 'esri/layers/ImageryLayer',
????'feature': 'esri/layers/FeatureLayer',
????"elevation":'esri/layers/ElevationLayer',
????'tile': 'esri/layers/TileLayer',
????'kml': 'esri/layers/KMLLayer',
????'webtile': 'esri/layers/WebTileLayer',
????'wms': 'esri/layers/WMSLayer',
????'wmts': 'esri/layers/WMTSLayer',
????'google':'jimu/layers/GoogleLayer',
????'tianditu':'jimu/layers/TianDiTuLayer' ?};
??require([layMap[layerConfig.type.toLowerCase()]], lang.hitch(this, function(layerClass) {
????var layer;
????layer = new layerClass(layerConfig.options);
????var lyrIndex = layerConfig.index;
????if(layer.customLayer)
????{
??????map.add(layer.customLayer,undefined == lyrIndex ? index : lyrIndex);
????}
????else ???{
??????map.add(layer,undefined == lyrIndex ? index : lyrIndex);
????}
??}));
},
?
3、ConfigLoader.js文件改造
(1)loadConfig函數
直接上圖
loadConfig: function () {
??console.time('Load Config');
??return this._tryLoadConfig().then(lang.hitch(this, function(appConfig) {
????var err = this.checkConfig(appConfig);
????if (err) {
??????throw err;
????}
????this.rawAppConfig = lang.clone(appConfig);
????AppStateManager.getInstance().setRawAppConfig(this.rawAppConfig);
????appConfig = this._upgradeAppConfig(appConfig);
????this._processAfterTryLoad(appConfig);
????this.appConfig = appConfig;
????if (!appConfig.portalUrl) {
??????return this._processNotInPortalAppProtocol(appConfig).then(lang.hitch(this, function () {
????????this._processAfterTryLoad(appConfig);
????????this.appConfig = appConfig;
??????})).then(lang.hitch(this, function () {
????????return this.loadWidgetsManifest(appConfig);
??????})).then(lang.hitch(this, function () {
????????return this._upgradeAllWidgetsConfig(appConfig)
??????})).then(lang.hitch(this, function () {
????????this.appConfig = appConfig;
????????this._configLoaded = true;
????????if (appConfig.title) {
??????????document.title = jimuUtils.stripHTML(appConfig.title);
????????}
????????this._readAndSetSharedTheme(appConfig);
????????return this.getAppConfig();
??????}), lang.hitch(this, function (err) {
????????this.showError(err);
??????}));
????}
????else if(this.urlParams.id){
?
(2)_processAfterTryLoad函數
直接上圖
_processAfterTryLoad: function(appConfig){
??if (appConfig.portalUrl) {
??????this._setPortalUrl(appConfig);
??????this._tryUpdateAppConfigByLocationUrl(appConfig);
??????this._processUrlParams(appConfig);
??}
??this.addNeedValues(appConfig);
??this.processProxy(appConfig);
?
??IdentityManager.tokenValidity = 60 * 24 * 7;//token is valid in 7 days ?return appConfig;
},
?
4、添加天地圖
經過上面改造,已經能夠脫離portal運行了,為了添加天地圖,制作了一個添加天地圖的類,命名為TiantiTuLayer.js文件,代碼如下
define([ "dojo/_base/declare", "dijit/_TemplatedMixin", "esri/layers/WebTileLayer" ,"esri/geometry/SpatialReference","esri/geometry/Extent","esri/layers/support/TileInfo"],
????function(declare, _TemplatedMixin, TiledMapServiceLayer,SpatialReference,Extent,TileInfo) {
????????return declare("tianditu",[], { // create WMTSLayer by extending esri.layers.TiledMapServiceLayer ???????????_hosts: new Array("t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"),
????????????constructor: function(options){
????????????????if(!options){
????????????????????options = {};
????????????????}
????????????????options.spatialReference = new SpatialReference({
????????????????????wkid: 4326 ???????????????});
????????????????options.initialExtent = new Extent({
????????????????????xmin:-180,
????????????????????ymin:-90,
????????????????????xmax:180,
????????????????????ymax:90,
????????????????????sptialReference:options.spatialReference ???????????????});
????????????????options.fullExtent = new Extent({
????????????????????xmin:-180,
????????????????????ymin:-90,
????????????????????xmax:180,
????????????????????ymax:90,
????????????????????sptialReference:options.spatialReference ???????????????});
????????????????// ???????????????options.tileInfo = new TileInfo({
????????????????????"dpi": "90.71428571427429",
????????????????????"format": "image/png",
????????????????????"compressionQuality": 0,
????????????????????"spatialReference": {
????????????????????????"wkid": 4326 ???????????????????},
????????????????????"rows": 256,
????????????????????"cols": 256,
????????????????????"origin": {
????????????????????????"x": -180,
????????????????????????"y": 90 ???????????????????},
????????????????????// Scales in DPI 96 ???????????????????"lods": [
????????????????????????{"level": 1,"scale": 2.95498e+008,"resolution": ?0.703125 ???????????????????????}, {"level": 2,"scale": 1.47749e+008,"resolution": 0.351563 ???????????????????????}, {"level": 3,"scale": 7.38744e+007,"resolution": 0.175781 ???????????????????????}, {"level": 4,"scale": 3.69372e+007,"resolution": 0.0878906 ???????????????????????}, {"level": 5,"scale": 1.84686e+007,"resolution": 0.0439453 ???????????????????????}, {"level": 6,"scale": 9.2343e+006,"resolution": 0.0219727 ???????????????????????}, {"level": 7,"scale": 4.61715e+006,"resolution": 0.0109863 ???????????????????????}, {"level": 8,"scale": 2.30857e+006,"resolution": 0.00549316 ???????????????????????}, {"level": 9,"scale": 1.15429e+006,"resolution": 0.00274658 ???????????????????????}, {"level": 10,"scale": 577144,"resolution": 0.00137329 ???????????????????????}, {"level": 11,"scale": 288572,"resolution": 0.000686646 ???????????????????????}, {"level": 12,"scale": 144286,"resolution": 0.000343323 ???????????????????????}, {"level": 13,"scale": 72143,"resolution": 0.000171661 ???????????????????????}, {"level": 14,"scale": 36071.5,"resolution": 8.58307e-005 ???????????????????????}, {"level": 15,"scale": 18035.7,"resolution": 4.29153e-005 ???????????????????????}, {"level": 16,"scale": 9017.87,"resolution": 2.14577e-005 ???????????????????????}, {"level": 17,"scale": 4508.9,"resolution": 1.07289e-005 ???????????????????????}, {"level": 18,"scale": 2254.47,"resolution": 5.36445e-006 ???????????????????????}]
?
????????????????});
????????????????var ty = options.whichlayer ? options.whichlayer.toLowerCase() : "map";
????????????????var typeT;
????????????????var crt;
????????????????if(ty == "map")
????????????????{
????????????????????typeT = "vec_c";
????????????????????crt = "地圖";
????????????????}
????????????????else if(ty == "mapi")
????????????????{
????????????????????typeT = "cva_c";
????????????????????crt = "地圖注記";
????????????????}
????????????????else if(ty == "trrain")
????????????????{
????????????????????typeT = "ter_c";
????????????????????crt = "地形";
????????????????}
????????????????else if(ty == "image")
????????????????{
????????????????????typeT = "img_c";
????????????????????crt = "影像";
????????????????}
????????????????else if(ty == "imagei")
????????????????{
????????????????????typeT = "cia_c";
????????????????????crt = "影像注記";
????????????????}
????????????????options.urlTemplate="http://{subDomain}.tianditu.com/DataServer?T=" + typeT + "&X={col}&Y={row}&L={level}";
????????????????//options.urlTemplate="http://{subDomain}.tianditu.cn/cva_w/wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={level}&TileRow={rows}&TileCol={cols}&style=default&format=tiles"; ???????????????options.id = "tianditu";
????????????????options.copyright = "天地圖" + crt;
????????????????options.subDomains = this._hosts;
????????????????this.customLayer = new TiledMapServiceLayer(options);
????????????}
????????});
????});
?
5、成果
經過以上改造,并配置config.json文件,加載天地圖效果如下:
也可以切換到三維顯示,只是沒有數據,顯示為一個白球:
需要源代碼的到我的資源里面下載。
?
?
總結
以上是生活随笔為你收集整理的webappbuilder改为不依赖portal之arcgis for js4.系列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目中的MD5、盐值加密
- 下一篇: 招聘 | 北京-内推-好未来-NLP算法