Mars3D基础项目 是基于Mars3D平台 做的一个应用系统,提供的一个基础项目模版,包含常用基础地图功能,可在该基础项目上快速开发搭建新项目。方便快速搭建三维地图产品,敏捷开发,可复用,支持各种配置,适合各种场景使用。
原生JS版 (widget方式) 的特点:
访问基础项目在线 体验效果和功能
widget模块化设计方式是我们在2016年设计的一种基于传统JS的模块化设计架构。设计思想主要是借鉴了gis行业的arcgis flexviewer和jsviewer,也借鉴了前端行业的React和Vue。当前最流行和通用的方式是整个项目用Vue、React或angular下开发最佳,用现代化的技术栈来做开发。
目前还保留widget模块化的方式,是因为:
保留使用 widget模块化 方式,并不是指我们不用vue等现代化技术栈,而是具体按公司人员研发水平和技术栈情况按需选择,适合自己的才是最好的。
我们通过vscode打开该项目,项目中最重要的是2个点是,json配置文件
和 widget模块化
开发,一般开发项目只用修改配置文件和开发新的widget即可。
config/config.json
是地图初始化构造参数配置文件config/widget.json
为项目widget的模块配置信息文件widgets目录
为模块功能目录,也可以按业务分在多个目录中,比如widgetsTS目录
目前我们已经开源了基础项目的基础框架和一些部分widget。可以从下面链接下载代码:
在任意开发编辑器(如vscode等)或http服务器(如node、nginx、tomcat、IIS等)下直接运行浏览index.html即可
电子沙盘、综合态势等系统代码内部结构和基础项目类同,只是在widget功能数量和样式上有所不同。
如果需要所有功能模块的widget和其他一些项目模板,需要联系我们付费购买 项目源代码。
#mars3d-widget插件
为了更容易理解内部逻辑,您可以下载mars3d-widget插件源码 进行查阅。
#下载最新lib
建议从http://mars3d.cn/download 下载最新mars3d类库后覆盖至lib/
目录下即可。
#压缩及混淆
build整站压缩及混淆:GitHub - muyao1987/web-dist-pro: 传统模式开发的web站点 进行整站所有文件压缩及混淆处理[高级版]
我们当前项目内的第三方类库及我们的sdk类库都存放在lib目录下,每个目录均有README.md
文件说明该类库的github地址、官网和用途等信息。
为了方便切换和引入第3方lib,我们编写了一个独立的js文件include-lib.js 来统一调用使用第3方lib,在需要的页面按下面方式引入lib:
该方式等价于(如不习惯include-lib.js,也可以改为下面演示的直接引入方式):
目前平台示例和项目中使用到的widget.json 是静态json文件方式 文件中配置参数与mars3d.widget.init方法API 的方法参数是完成相同一致的,代码中加载json后传入到init方法中。
widget初始化方法:
//初始化widget管理器
mars3d.widget.init(map, widgetCfg, './') //tip: 第3个参数支持定义widget目录的相对路径。
在外部调用widget功能,都是通过mars3d.widget静态类 来统一管理的,更多方法可以参阅该类的API文档。
比如激活widet:在需要外部使用的地方通过 mars3d.widget.activate(参数 ) 来激活widget模块, 参数支持多种模式可多样化兼容使用, 比如:
//常用,直接使用uri
mars3d.widget.activate("widgets/bookmark/widget.js");
//支持所有可配参数和自定义参数,在widget.js内部通过this.config可获取传入的参数
mars3d.widget.activate({name:"书签", uri: "widgets/bookmark/widget.js "});
每个widget模块必须存在 widget.js 文件,该文件内部定义了一个继承了 BaseWidget类 的子类。
类内最重要的几个属性和方法如下:
分类 | 名称 | 功能 |
---|---|---|
get属性 | resources | 需要预先加载到主页面的js、css资源文件 |
get属性 | view | 存在弹窗或界面时配置,具体详见后节说明 |
内部变量 | config | 对应widget定义的或传入的配置信息 |
内部变量 | path | 当前widget所在目录的相对于网页的路径 |
内部变量 | map | 当前Map地图对象 |
方法 | create | 插件初始化触发,仅执行1次 |
方法 | winCreateOK | view属性定义的界面每次初始化后调用 |
方法 | activate | 打开激活插件 触发 |
方法 | disable | 关闭释放插件 触发 |
默认每个插件是无界面或弹窗的, 如果需要有对应的弹窗或界面(如弹窗、输入栏、菜单等)请定义view
属性。
请参考贝widgets\_example*
命名的示例widget来新建widget模块,建议直接复制后改下目录名称即可。
view配置中必须存在2个属性:type标识类型,url为html地址。 目前view有下面3种模式供使用:
type属性 | 功能 | 对应的示例 | 说明 |
---|---|---|---|
window | iframe模式弹窗 | _example | 独立的html子页面,比较自由,简单粗暴、无任何限制;可以每个页面用不同的UI和第三方插件不用考虑冲突问题;任何水平的开发人员均容易快速开发。 |
divwindow | div元素模式弹窗 | _example_divwin | 可直接互相访问,这种模式弊端是易引起模块间id命名冲突,在css和html中命名时需注意。 |
append | 任意html元素 | _example_append | 任意div节点,比较自由. |
#window时:
view.html页面(或引入的view.js中)必须定义一个initWidgetView方法,框架会自动调用进行传入当前widget对象,用于页面中调用widget中的方法属性。 可以配置windowOptions参数来定义弹窗的大小、位置等。
get view() {
return {
type: 'window',
url: 'view.html',
windowOptions: { width: 250 },
}
}
此时的view.html和view.js是iframe的子页面,与地图所在的index.html是父子关系,相关js代码时需要注意这个层次才能更好的编码。
#divwindow时:
此模式不用单独的js, view界面相关js逻辑全部写在widget.js中 同样支持windowOptions参数配置。
get view() {
return {
type: 'divwindow',
url: 'view.html',
windowOptions: { width: 210, height: 210 },
}
}
#append时:
将view的html直接添加至主页面中指定id的DOM节点下,通过parent
属性配置指定,默认是body
。
get view() {
return { type: 'append', url: 'view.html', parent: '#centerDiv' }
}
widget激活后页面执行流程:
widget激活后执行方法顺序: create => winCreateOK => activate => view中的 initWidgetView
当还没有菜单时,需要测试widget功能,可以2种方式:
一是在url中传入widget参数方式激活对应widget来测试.比如:
Mars3D基础项目系统
二是在widget.json中可以加配置"debugger": true,
打开 widget测试栏 功能,方便测试及触发激活widget,发布的正式版本记得改回 false 或删除。
{
"debugger":true,
"version": "20210803",
"defaultOptions": {
"style": "dark",
"windowOptions": {
"skin": "layer-mars-dialog animation-scale-up",
"position": { "top": 50, "right": 10 },
"maxmin": true,
"resize": true
},
"autoReset": false,
"autoDisable": true,
"disableOther": true
},
"openAtStart": [],
"widgets": []
}
运行后效果:
在qyPoint模块中(widgetsTS\qyPoint\widget.js)单击地图上的点后,激活弹出详情窗口qyDetailsView模块
showDetails(item) {
mars3d.widget.activate({
uri: 'widgetsTS/qyDetailsView/widget.js',
dataQy: item,
})
}
qyDetailsView模块(widgetsTS\qyDetailsView\widget.js)中通过this.config获取传过来的值
getData() {
var item = this.config.dataQy //传入过来的参数
return item
}
可以利用mars3d.widget作为桥梁,通过事件的方式交互,这种比较自由方便,注意项目内事件名称唯一即可。
//演示:抛出事件,在其他widget或vue中监听使用 widgets\centerXY\widget.js
mars3d.widget.fire("centerXY",{position:position })
//演示:接收的widget内抛出的事件 js、vue或其他widget.js中
mars3d.widget.on('centerXY', function (event) {
console.log('在widget进行了坐标定位1', event)
})
//如果在弹窗的view.js中
parent.mars3d.widget.on('centerXY', function (event) {
console.log('在widget进行了坐标定位2', event)
})
下面演示在【POI查询栏】单击查询按钮后勾选【图层控制】面板中的文庙图层。
在roamFly模块中,动态去更新已打开的roamChars模块,更新显示数据
//持续更新
updateCharsWidgeFlyOk(alllen) {
//抛出事件
mars3d.widget.fire("updateRoamChars",{ data:alllen })
}
roamChars模块中监听事件
create() {
//接收roamFly的widget内抛出的事件
mars3d.widget.on('updateRoamChars', function (event) {
console.log('接收到了数据', data)
})
}
A、B两个都是iframe弹窗模式的widget模块时,在A模块中的view.html中需要调用B模块的view.html
【主页面】widget.js都在index.html主页面; 【iframe子页面】 2个view.html(含view.js)是iframe子页面。
如果不用事件时,其调用流程是下图过程:
如果通过事件方式可以下面的方式:
//演示:在A模块中的view.html中抛出事件
parent.mars3d.widget.fire("widget2widget",{ data: position })
//演示:如果在弹窗的view.js中
parent.mars3d.widget.on('widget2widget', function (event) {
console.log('接收到了A模块抛出的事件', event)
})
以上介绍的这么只是让大家对Mars3D基础项目的基本情况和架构做了概览了解。下一步就需要大家静下心来阅读代码了,学习没有捷径,可以按下面路线一步步来学习。
查看已有的3个 “example示例”空白模版的代码、配置信息、运行效果。熟悉widget机制。
_example模块 => 已有的widgets模块 => 编写全新的widget