今天我给大家分享一个纯技术类的文章,相信好多搞GIS的朋友都会熟悉Web AppBuilder for ArcGIS,这个产品很强大,用户不需要写一行代码就可以配置出他们所需要的系统,但是前提必须绑定Portal for ArcGIS产品。据我所知,目前大部分公司还是没有购买Portal这个产品的,这就导致了他们不能直接利用Web AppBuilder这个框架做系统了,原来Esri也提供过类似的产品,叫做FlexViewer,它只需要开发者直接修改服务地址就可以转变成客户想要的专题地图,但由于Web AppBuilder绑定了Portal产品,故开发者就不能直接这么干了。
今天给大家分享的这篇文章就是如何去掉Web AppBuilder中的Portal,改成如何直接通过读取服务地址的方式去实现地图的加载,从而得到客户所需要的系统。具体方法及步骤如下:
1.本地部署ArcGIS API for JS
下载ArcGIS API for JS v3.23,下载地址:https://developers.arcgis.com/downloads/apis-and-sdks?product=javascript,解压下载后的压缩包,直接复制到tomcat 下的webapps文件下面,分别打开init.js和dojo/dojo.js文件,查找”https://[HOSTNAME_AND_PATH_TO_JSAPI]dojo“,修改成服务器指定的路径,如我自己本机上” http://localhost:8080/arcgis_js_api/3.23/dojo”。
2.下载应用程序并配置地图
下载Web AppBuilder for ArcGIS v2.7,下载地址:https://developers.arcgis.com/downloads/apis-and-sdks?product=web-appbuilder,解压下载后的压缩包,直接双击里面的startup.bat,启动服务后浏览器会自动打开应用程序,输入portal地址http://www.arcgisonline.cn/portal以及注册的App ID(自己portal账户中应用程序中注册的ID),则进入了WebAppBuilder的主界面。点击新建按钮,选择默认(2D),输入应用程序标题及说明,点击确定按钮,这个时候一个应用程序就自动建好了,可以选择相应主题、地图、微件进行配置保存。注意:当选择底图库微件的时候,需要对此微件进行配置,而且需要选择配置自定义底图选项,并保存。找到arcgis-web-appbuilder-2.7\WebAppBuilderForArcGIS\server\apps,将自动生成的id文件夹拷贝到tomcat的webapps下面,修改文件夹名称,如WebApp2DNoPortal。启动tomcat服务,在浏览器中输入http://localhost:8080/WebApp2D 可浏览查看刚才配置好的地图,但这个时候读取的都是通过Portal的ItemId获取的地图。
3. 修改env.js文件
去掉 //apiUrl ='https://js.arcgis.com/3.23';的注释,并修改apiURL=本地服务器部署的路径,如apiUrl = 'http://localhost:8080/arcgis_js_api/3.22/',这个时候ArcGISAPI直接就读取本地路径了。
4. 修改主config.json文件
去掉与portal有关的所有属性信息,分别为theme.sharedTheme、portalUrl、AppId、map.itemId、map.PortalUrl、isWebTier属性。去掉BasemapGallery Widget的config属性,同时删除configs文件夹下面的BasemapGallery文件夹,添加map.itemData属性,如
"itemData": {
"baseMap": {
"title": "地图",
"baseMapLayers": [
{
"opacity": 1,
"url": "http://services.arcgisonline.com/arcgis/rest/services/ESRI_StreetMap_World_2D/MapServer",
"visibility": true
}
]
},
"operationalLayers": [
{
"disablePopup": true,
"layerDefinition": {
"drawingInfo": {
"labelingInfo": [
{
"labelExpression": "[NAME]",
"useCodedValues": true,
"labelPlacement": "esriServerPolygonPlacementAlwaysHorizontal",
"symbol": {
"type": "esriTS",
"horizontalAlignment": "center",
"verticalAlignment": "bottom",
"color": { "r": 76, "g": 76, "b": 76, "a": 1 },
"font": {
"size": 9,
"family": "MicrosoftYaHei"
}
},
"minScale": 1000000,
"maxScale": 0
}
]
}
},
"opacity": 1,
"showLabels": true,
"title": "行政区划",
"url": "http://localhost:6080/arcgis/rest/services/**/MapServer/0",
"visibility": true
},
{
"layerDefinition": {
"drawingInfo": {
"renderer": {
"type": "simple",
"symbol": {
"type": "esriPMS",
"url": "images/icons/house.png",
"contentType": "image/png",
"width": 16,
"height": 16
}
}
}
},
"opacity": 1,
"popupInfo": {
"title": "{XQMC}",
"description": null,
"fieldInfos": [
{
"fieldName": "XQMC",
"label": "小区名称",
"visible": true
},
{
"fieldName": "XQDZ",
"label": "小区地址",
"visible": true
}
],
"showAttachments": true,
"mediaInfos": []
},
"title": "住房小区",
"url": "http://localhost:6080/arcgis/rest/services/**/MapServer/5",
"visibility": true
}
]
}
// 修改"keepAppState": false,去掉”isTemplateApp”属性,在map对象下添加"units": "metric",修改mapOptions
"mapOptions": {
"extent": {
"xmin": 120.3512019420001,
"xmax": 120.9005245010001,
"ymin": 30.760025127000063,
"ymax": 31.228560263000062,
"spatialReference": {
"wkid": 4326
}
}
}
其中operationalLayers属性也可以添加整个Map服务,可通过visibleLayers和layers属性去控制图层的显示和每个图层的弹出窗口及过滤器。
5.修改Coordinate/Widget.js和Scalebar/Widget.js
搜索portalUtils.getUnits,注释掉通过portalUtils.getUnits方法获取units,直接在getUnits回调中添加 var units = this.appConfig.map.units;
6.修改Search/utils.js
搜索mo.getConfigInfo方法,修改第一个if else语句中的else语句,注释掉_getSoucesFromPortalAndWebmap方法,直接
return {
"allPlaceholder":"",
"showInfoWindowOnSelect": true,
"sources": []
};
7. 修改BasemapGallery/Widget.js
修改initBasemaps方法,找到var basemaps = result.basemaps;注释掉获取result相关的方法,将result改为config。注释掉config.bingMapsKey= result.portalSelf.bingKey,可在BasemapGallery路径下的config.json文件中添加新的底图。
8.修改MapManager.js
找到_showMap方法,将appConfig.map.itemId改为appConfig.map.itemData;找到_show2DwebMap方法,在mapOptions.isZoomSlider= false;后面添加
mapOptions.isKeyboardNavigation = false;
mapOptions.showAttribution = false;
mapOptions.logo = false;
注释掉 var webMapPortalUrl = appConfig.map.portalUrl;
var webMapItemId = appConfig.map.itemId;这两行代码,将
this._createWebMapRaw(webMapPortalUrl,webMapItemId,this.mapDivId,webMapOptions)
修改成this._createWebMapRaw(webMap, this.mapDivId, webMapOptions),对应修改此
方法,如下:
_createWebMapRaw: function (webMap, mapDivId, webMapOptions) {
var mapDef =jimuUtils.createWebMap(webMap, mapDivId, webMapOptions);
return mapDef.then(lang.hitch(this, function (response) {
return response;
}), lang.hitch(this, function (error) {
console.error(error);
throw
error;
}));
},
mo.createWebMap = function (webmap, mapDiv, options) {
var def = arcgisUtils.createMap(webmap, mapDiv, options);
return def;
};
9.修改ConfigManager.js
找到_onAppConfigSet方法,注释掉有关Portal的代码,如下:
this.configLoader.loadAndUpgradeAllWidgetsConfig(c).then(lang.hitch(this, function (c) {
this._addDefaultValues(c);
// tokenUtils.setPortalUrl(c.portalUrl);
// window.portalUrl = c.portalUrl;
if (this.appConfig) {
//remove theoptions that are relative to map's display when map is changed.
jimuUtils.deleteMapOptions(c.map.mapOptions);
this.appConfig = c;
this._deleteDataSourcesFromMap();
topic.publish('appConfigChanged', this.getAppConfig(), 'resetConfig', c);
} else {
this.appConfig = c;
// var portal =portalUtils.getPortal(c.portalUrl);
// portal.loadSelfInfo().then(lang.hitch(this,function (portalSelf) {
// this.portalSelf = portalSelf;
topic.publish("appConfigLoaded", this.getAppConfig());
// }));
}
}));
注释掉 topic.subscribe('builder/sharedThemeChanged', lang.hitch(this,this._onSharedThemeChanged));
注释掉loadConfig方法中的this.portalSelf = this.configLoader.portalSelf;
注释掉_getAppConfigFromTheme方法中的有关portal信息,如下:
// if (this.portalSelf.portalProperties&& this.portalSelf.portalProperties.sharedTheme) {
// config.theme.sharedTheme = {
// "useHeader": true,
// "useLogo": true,
// isPortalSupport: true
// };
// config.theme.customStyles = {
// mainBackgroundColor:this.portalSelf.portalProperties.sharedTheme.header.background
// };
// } else {
// config.theme.sharedTheme = {
// "useHeader": false,
// "useLogo": false,
// isPortalSupport: false
// };
// config.theme.customStyles = {
// mainBackgroundColor: ''
// };
// }
注释掉_addDefaultValues方法下的this._addDefaultPortalUrl(config);this._addDefaultSharedTheme(config);两个方法;
注释掉_addDefaultGeometryService方法中的else;
注释掉_addDefaultMap方法中的portal信息;
注释掉_onStyleChanged方法中的sharedTheme信息,注释代码如下:
// this.appConfig.theme.sharedTheme = {
// isPortalSupport:this.appConfig.theme.sharedTheme.isPortalSupport,
// useHeader: false,
// useLogo: false
// };
10.修改ConfigLoad.js文件
重写_tryLoadConfig方法,如下:
_tryLoadConfig: function () {
if (this.urlParams.id === 'stemapp') {
this.urlParams.config = window.appInfo.appPath + 'config.json';
delete this.urlParams.id;
}
if (this.urlParams.config) {
this.configFile = this.urlParams.config;
return xhr(this.configFile, {
handleAs: 'json',
headers: {
"X-Requested-With": null
}
}).then(lang.hitch(this, function (appConfig) {
return appConfig;
}));
} else {
this.configFile = "config.json";
return xhr(this.configFile, {handleAs: 'json'}).then(lang.hitch(this, function (appConfig) {
return appConfig;
}));
}
}
重写loadConfig方法,如下:
loadConfig: function () {
console.time('Load Config');
return this._tryLoadConfig().then(lang.hitch(this, function (appConfig) {
this.rawAppConfig = lang.clone(appConfig);
AppStateManager.getInstance().setRawAppConfig(this.rawAppConfig);
appConfig = this._upgradeAppConfig(appConfig);
this.appConfig = appConfig;
this._processAfterTryLoad(appConfig);
return this.loadWidgetsManifest(appConfig);
return this.loadAndUpgradeAllWidgetsConfig(appConfig);
this._configLoaded = true;
this._setDocumentTitle(appConfig);
return this.getAppConfig();
}), lang.hitch(this, function (err) {
this.showError(err);
//we still return arejected deferred
var def = new Deferred();
def.reject(err);
return def;
}));
}
11.修改HeaderController/Widget.js和HeaderController/ Widget.html
Widget.html文件中注释代码如下:
data-dojo-attach-point="signinLinkNode">${nls.signin}
data-dojo-attach-point="userNameLinkNode">
data-dojo-attach-point="signoutLinkNode">${nls.signout}
Widget.js文件,postCreate方法,注释代码如下:
// if (!this.appConfig.portalUrl) {
// html.setStyle(this.signInSectionNode, 'display', 'none');
// } else {
// html.setStyle(this.signInSectionNode, 'display', '');
// }
// this.own(on(this.domNode, mouse.enter,lang.hitch(this, function () {
// var title = '';
// var portalUrl = this.appConfig&& this.appConfig.portalUrl || '';
// var server =portalUrlUtils.getServerByUrl(portalUrl);
// if(portalUrlUtils.isArcGIScom(server)) {
// server = 'ArcGIS.com';
// }
// if (server) {
// title = this.nls.signInTo + '' + server;
// }
// this.signinLinkNode.title = title;
// })));
12.修改WidgetManager.js
注释掉_onAppConfigLoaded方法中的有关token代码;
注释掉 topic.subscribe('userSignIn',lang.hitch(this, this._onUserSignIn));
topic.subscribe('userSignOut', lang.hitch(this, this._onUserSignOut));
注释掉_postWidgetStartup方法下的portal信息,如下:
// var portalUrl = this.appConfig.portalUrl;
// var credential = tokenUtils.getPortalCredential(portalUrl);
// if (credential) {
// widgetObject.onSignIn(credential);
// } else {
// widgetObject.onSignOut();
// }
// this._triggerMissedAction(widgetObject);
剩下的就是修改服务地址,以及创建新的theme、widget、panel了,同时config中的服务支持OGC以及WebTile类型的服务,服务样例在2.6版本中的config-OGC、config-WebTile文件中。就这样,一个成型的GIS系统就这样创建好了,只需更换服务地址就ok了。下图为修改之后的简单地图展示。
image image
网友评论