本文目录一览:
- 1、学习网络GIS的开发都需要学习哪些基本的东西?
- 2、想要学习arcgis for js,谁知道有什么书籍。
- 3、求大神指导,有没有前端学习视频,自己找了好多,感觉有点乱,觉得学的路线会错
- 4、用javascript怎么实现地图功能
- 5、初识 D3.js :打造专属可视化
- 6、如何使用百度地图API
学习网络GIS的开发都需要学习哪些基本的东西?
GISer入门指南电子书第一季 分享版.pptx免费下载
链接:
提取码: wttn
ArcGIS入门级教程,详细介绍了ArcGIS产品族及成员产品 1、GIS 的概念和需求 2、什么是ArcGIS 3、Geodatabase中的GIS数据概念 4、桌面GIS产品:ArcView, ArcEditor和ArcInfo等
想要学习arcgis for js,谁知道有什么书籍。
直接看这本书
《WebGIS从基础到开发实践(基于ArcGIS API for JavaScript)》
如果没有任何基础,最好旁边有个懂GIS的,帮你安装软件、处理数据、发布服务什么的
需要学习dojo、arcgis js api,官网都是英文
还是看上面的书合适
网上也很少有相关视频,不像java视频,到处都是
求大神指导,有没有前端学习视频,自己找了好多,感觉有点乱,觉得学的路线会错
1.首先零基础学习前端先要有一个计划,了解前端要学习哪些技术。
2.做好自己的时间规划,如何快速入门前端那肯定是需要不断的提高自己的学习效率,学习过程中尽量把手机调至静音给自己一个安静的学习环境和氛围。
3.快速入门顾名思义肯定是少走弯路,在学习过程中看下自己身边有没有前端这方面的大神尽量多问,多交流,如果是没有的话,可以多去找一些前端的交流群,学习肯定是不能闭门造车。
学习是一个循序渐进的过程,前端的学习也是如此。
不论前端开发还是后端开发的学习都要求我们多动手,既要反复的看书,也把学习到的知识点第一时间去实践。前端的学习入门快要三个月,慢的要 5-6 个月左右,看个人的理解速度来评估,只要入门了不论理解能力,还是学习的速度都会有明显的提升。
在学习前端的过程中,除了要把学到的知识点第一时间去实践,也要在学习的每个阶段自己创建课题,用所学到的知识去实现课题的内容。这样可以更好有助于理解和累计一定的项目经验。
前端的学习从来不是孤军奋战,需要一个前辈的领路,也需要一个平台不断交流和思维碰撞。这样可以快速入门和少走弯路,也能让自己发现问题的根本所在。
阶段一
在学习前端之前呢,你需要一个编辑器,在网上你可以看到很多编辑器用来编写前端,甚至 Windows 系统默认的文本文档也可以作为前端代码的编辑器。俗话说,没有金刚钻怎么揽瓷器活,所以一个好的编辑器很重要,我在这里推荐给大家的编辑器是 VSCode。
思维导图
前端开发工具
一、HTML+CSS
前端的入门门槛是极低的,主要体现在 HTML 和 CSS 部分,运行环境就是浏览器,不像如 Java 需要配置开发/运行环境。
HTML 和 CSS 不是编程语言,HTML 是结构标签,CSS 是结构标签的样式配置。
HTML
属性
事件
标签
字符集
CSS
CSS基础教程
CSS样式
CSS框模型
CSS定位
CSS选择器
CSS高级
思维导图
HTML+CSS以上内容的学习用时 20天左右,再花 2 天的时间项目实践,这部分总花费时间在 22天左右。
二、HTML5+CSS3
HTML5 作为 HTML 的最新版本,引入了多项新技术,大大增强了对于应用的支持能力,使得Web技术不再局限于呈现网页内容。
HTML5 可以使开发者的工作大大简化,理论上单次开发就可以在不同平台借助浏览器运行,降低开发的成本,这也是产业界普遍认为 HTML5 技术的主要优点之一。
CSS3使用了层叠样式表技术,可以对网页布局、字体、颜色、背景灯效果做出控制。css3作为css的进阶版,拆分和增加了盒子模型、列表模块、语言模块 、背景边框 、文字特效 、多栏布局等等。
CSS3的改变有很多,增加了文字特效,丰富了下划线样式,加入了圈重点的功能。在边框方面,有了更多的灵活性,可以更加轻松地操控渐变效果和动态效果等等。在文字效果方面,特意增加了投影。
CSS3在兼容上做了很大的功夫,并且网络浏览器也还将继续支持CSS2,因此原来的代码不需要做太多的改变,只会变得更加地轻松。
HTML5
HTML5视频
HTML5音频
HTML5拖放
HTML5画布
HTML5 SVG
HTML5地理定位
HTML5 Web存储
HTML5 应用缓存
HTML5表单
CSS3
CSS3边框
CSS3背景
CSS3文本效果
CSS3字体
CSS3 2D转换
CSS3 3D 转换
CSS3 过渡
CSS3 动画
CSS3 多列
思维导图
HTML5+CSS以上内容用时 10 天左右,这部分内容是在 HTML+CSS 做的升级改进,只需要了解他们的一些特性即可,再结合这些特性做一些小项目加深学习。
请点击输入图片描述
四、JavaScript
JavaScript 是 web 开发者必学的三种语言之一,这里我们需要区别 JavaScript 和 Java 他们是完全不同的语言,不论是概念还是设计。javascript 部分需要我们学习的知识点如下所示:
认识JavaScript
基本语法
变量
数据类型
字符串
数字
布尔
数组
对象
Null
Undefined
5. 函数
内置函数
自定义哈数
6. 运算符
7. 流程控制
8. DOM对象
String
Array
Date
Boolean
Math
Number
9. BOM对象
WIndow
Navigator
Screen
History
Location
10. 综合实例
思维导图
javascript以上内容的学习用时 35天 左右,这里推荐几本 Javascript 的书籍,如下:
《JavaScript 高级程序设计(第3版)》,俗称红宝书。前七章讲的是语言特性,是重点学习的部分,必须需要反复阅读,直至完全理解为止。DOM、事件流、表单、JSON、Ajax 与最后几章也需要重点学习,这是一些常用的 Web API。至于本书的其余部分大致读一下就可以,不做重点要求。
《JavaScript 语言精粹》,俗称蝴蝶书。很薄的一本书总页数就 147 页,花一天时间就能看完,快的话半天就能看完。这本书虽然很薄,但是承载的内容却非常的丰厚和深入。JavaScript是一门有很多坑的语言,所以这本书”取其精华,去其糟粕“就是精粹了。
《你不知道的 JS》非常精彩的一本书,将 JavaScript 的细节一网打尽。
阶段二
这部分内容是对 JavaScript 的补充学习
四、 Jquery学习
1. 基础语法
2. 选择器
基本选择器
层次选择器
过滤选择器
表单选择器
3. DOM操作
查找节点
创建节点
插入节点
删除节点
复制节点
替换节点
包裹节点
属性操作
样式操作
4. 事件
事件绑定
事件冒泡
5. 动画
show、hide
fadeIn、fadeOut
slideUp、slideDown
自定义动画animate
动画回调以及停止动画
6. 常用工具
浏览器及特性检测
数组和对象操作
Layer UI,主要学习栅格布局,图标,动画,按钮,表单,导航,选项卡,进度条,面板,表格,时间线等
7. Ajax
8. Jquery插件编写
思维导图
请点击输入图片描述
二、其他
JavaScript 进阶
DOM+BOM综合演练
网页特效
ES6 进阶
bootstrap
animate.css学习
请点击输入图片描述
以上内容的学习用时 10天左右
阶段三
这部分是框架和前后端交互技术的学习
一、Vue
Vue基础
模版语法
计算属性侦听器
Class与Style绑定
条件/列表渲染
事件处理
表单输入绑定
组件基础、注册
Prop
自定义事件
2. Vuex
State
Getter
Mutation
Action
Module
3. Vue-router
认识路由
动态路由
嵌套路由
编程式导航
路由组件传参
4. axios
认识axios
全局配置
发送POST、GET请求等
思维导图
请点击输入图片描述
二、React
认识React
React元素渲染
JSX
组件
State
Props
事件处理
条件渲染
列表
组件API
组件声明周期
思维导图
三、Node
基础
console(控制台)
crypto(加密)
debugger(调试器)
fs(文件系统)
http(网络)
os(操作系统)
path(路径)
2. 高级
NPM介绍及使用
MVC模式简介
Express框架学习
链接Mysql
链接Redis
项目实战
思维导图
Node
四、webpack
概念
主要讲什么是入口,出口,loader,插件等
2. 入口
单个入口语法
对象语法
常见场景
3. 输出
用法
多个入口起点
高级进阶
4. 模式
development
production
5. loader
实例
配置
6. 插件
剖析
用法
配置
7. 配置
基本配置
多个Target
使用其他语言配置
8. 模块
思维导图
webpack
以上内容用时 两个月 左右
阶段四(扩展部分,了解即可)
一、Mysql
阶段一
认识mysql
安装mysql
创建数据库、数据表
学习常用的SQL命令,完成增删查改
2. 阶段二
学习Mysql关联查询,子查询等
学习Mysql常用函数
学习Mysql分组、分页、排序等
3. 阶段三
学习Mysql高级查询
了解存储过程,自定义函数等
了解Mysql配置文件
二、Redis
认识Redis
学习redis的数据类型
redis常用操作
redis事务
思维导图
数据库
以上内容用时 7 天左右
阶段五
一、项目管理篇
SVN使用
认识svn
安装
生命周期
启动模式
创建版本库
检出操作
解决冲突
提交操作
版本回退
查看历史
分支
标签
2. GIT使用
认识git
安装配置
工作流程
工作区、暂存区和版本库
创建仓库
基本操作
分支管理
查看历史等
标签
github
二、扩展部分
小程序
1. 了解小程序开发流程
2. 视图容器
view
scroll-view
movable-view
cover-view
cover-image
3. 基础内容
icon
text
rich-text
progress
4. 表单组件
button
checkbox
form
input
label
picker
picker-view
radio
slider
switch
textarea
5. 导航
navigator
function-page-navigator
6. 媒体组件
audio
image
video
camera
live-player
live-pusher
7. 地图(map)
8. 画布(canvas)
9. 开放能力
open-data
web-view
ad
official-account
apicloud(移动app开发)
认识apicloud
开发工具讲解
端API
API对象
设备访问
功能扩展
界面布局
导航菜单
小程序模块
云服务对接
4. 云API
数据云API
统计云API
推送云API
云API SDK
5. 小程序模块使用
三、常用框架使用篇
iview (vue框架)
element ui (vue框架)
echarts (百度图标库)
阿里巴巴开源图标使用
Sass学习
Swiper学习
zoom.js 学习
四、综合项目实战
教务管理系统(node+express+mysql)实现
思维导图
扩展学习部分
参考资料:前端学习路线,如何学习前端
用javascript怎么实现地图功能
lol,楼上仗剑折花的方法太幽默了,他那个完全是在模仿一种效果,如果是需要模仿就够了的话还不如直接做成几张图片切换,还可以做的更加美观,我觉得楼主是希望获得能判断经纬度的动态效果,不过如果要自己重头创建的话几乎不可能.不仅要用到web技术还需要gis技术以及具有空间地理坐标的地理数据,每一项都不是几个人能在短期完成的工程,另一点楼主要实现实现显示有意义的动态区域框的功能,如果是bs模式的话需要使用支持画图功能的语言,而这类语言当前浏览器支持均非常有限,替代方法是使用java applet,即编写java,
直观的概念,google map即包含楼主所要的经纬度的坐标数据,因为有这些数据所以你才能在google map上实现精确定位,画图功能google map也没有实现,你可以找一些web gis的一些更加高级的应用网站应该有这项功能,所以,google map解决这个问题也不是一天两天一个人两个人能做好的,要不就不会成为google的产品了。
解决办法,
你可以基于google提供的google map提供的api来创建你的应用,这样经纬度,地图数据以及主要的技术问题都由google map提供,你只需基于它创建自己的应用即可,但要知道如何使用google api也不是轻松的事。网上有很多关于google api学习的文章和著作,可先学习一下
初识 D3.js :打造专属可视化
随着现在自定义可视化的需求日益增长,Highcharts、echarts等高度封装的可视化框架已经无法满足用户各种强定制性的可视化需求了,这个时候D3的无限定制的能力就脱颖而出。
如果想要通过D3完成可视化,除了对于D3本身API的学习, 关于web标准的HTML, SVG, CSS, Javascript 和 数据可视化的概念以及标准都是需要学习的。这无疑带来了较高的学习门槛,但这也是值得的,因为掌握 D3 后,我们几乎可以实现任何 2d 的可视化需求。
本文通过对D3核心模块分析以及进行具体案例实践的方式,来帮助初学者学习了解D3的绘图思路。
D3的全称是 Data-Driven Documents(数据驱动文档),是基于数据来操作文档的 JavaScript 库,其核心在于使用绘图指令对数据进行转换,在源数据的基础上创建新的可绘制数据, 生成SVG路径以及通过数据和方法在DOM中创建数据可视化元素(如轴)。
相对于Echats等开箱即用的可视化框架来说,D3更接近底层,它可以直接控制原生的SVG元素,并且不直接提供任何一种现成的可视化图表,所有的图表都需我们在它的库里挑选合适的方法构建而成,这也大大提高了它的可视化定制能力。而且D3 没有引入新的图形元素,它遵循了web标准(HTML, CSS, SVG 以及 Canvas )来展示数据 ,所以它可以不需要依赖其他框架独立运行在现代浏览器中。
在V4版本后,D3的 API 现在已经被拆分成一个个模块,我们可以根据自己的可视化需求进行按需加载。根据泛义可以将D3 API模块分为以下的几大类: DOM操作、数据处理,数据分析转换、地理路径,行为等 。
这里我们主要对 D3-selection 和 D3-scale 模块进行解析:
D3-selection (选择集) 是 D3js的核心模块,主要是用来进行选择元素,设置属性、数据绑定,事件绑定等操作。
选择元素: D3-selection 提供了两种方法来获取目标元素,d3.select():返回目标元素的第一个节点,d3.selectAll():返回目标元素的集合,乍一看有点类似原生API 的 querySelector 和 querySelectorAll,但是 d3.select 返回的是一个 selection 对象,querySelector 返回的是一个 NodeList 数组。通过控制台打印的信息,可以看到 selection 下的 groups 存放了所有选择的元素集合,parents 存放了所有选中元素的父节点。
设置属性或者绑定事件: 我们不需要关心 groups 的结构是怎么样的。当调用 selection.attr 或者 selection.style 的时候, selection 中的所有 group 的所有子元素都会被调用,group 存在的唯一影响是: 当我们传参是一个function 的时候,例如 selection.attr(‘attrName’, function(data, i)) 或 selection.on(‘click’, function(data, i)) 时, 传递的 function(data, i) 中, 第二个参数 i 是元素在 group 中的索引而不是在整个 selection 中的索引。
数据绑定: 实际上是给选择的DOM元素的 __data__ 属性赋值,这里提供了3种方式进行数据绑定:
(1)给每一个单独的 DOM 元素调用 selection.datum:d3.select(‘body’).datum(20) 等价于 document.body.__data__ = 20
(2)从父节点中继承来数据, 比如: append , insert , select,子节点会主动继承父节点的数据:
(3) 调用 selection.data() 方法,支持传入装有基础数据类型的数据,也支持传入一个function(parentNode, groupIndex)根据节点索引与数据做映射,data()方法引入了 d3 中非常重要的 join 思想:
绑定 data 到 DOM 元素, 在D3中是通过比较 data 和 DOM 的 key 值来找到对应关系的。 如果我们没有单独设置 key 值,那么默认根据 data 的下标索引来设定,但是当数据顺序发生改变,这个默认下标 key 值 就变得不可靠了,这时我们可以使用 selection.data(data, keyFunction) 中的第二个参数 keyFunction,根据当前的数据返回一个对应的 key 值。通过下面的图例可以看出,不管是有一个还是多个 group(每个group 都是独立的),只要我们保证在任意一个 group 中的 key 值是唯一的,数据一旦发生变化都会反映给对应的 DOM 元素( update 的过程):
上面提到的都是data数据和DOM元素数量相同的情况下的数据绑定,那如果data数据和DOM元素数量不相同时,我们来看看 D3 又是如何进行数据绑定的:现在终于可以来介绍 D3-selecion 模块的核心 Join 思想了,这个思想简单来说就是 “不应该告诉D3去怎么创建元素, 而是告诉D3,.selectAll() 得到的 selecion 集合应该和 .data(data) 绑定的数据要怎么一一对应”。
从上图可以看出,在进行 d3.data(data) 数据绑定的时候,会产生三种状态的选择集:
用 Join 的方式来理解意味着,我们要做的事情仅仅是声明 DOM集合和数据集合之间的关系, 并且通过处理三个不同状态的集合 enter、update 、 exit 来描述这种关系。这种方式可以大大简化我们对DOM元素的操作,我们不需要再用 if 和 for 循环的方式来进行复杂的逻辑判断,来得到我们需要得到的元素集合。并且在处理动态数据的时候,可以通过处理这三种状态,轻松的展示实时数据和添加平滑的动态交互效果。
D3-scale (比列尺) 提供多种不同类型的比例尺。经常和 D3-axis 坐标轴模块一起使用。
D3-scale 提供了多种连续性和非连续性的比例尺,总体可以将他们分为三大类:
常用的一些比例尺:
(1)d3-scaleLinear 线性比例尺(连续性输入和连续性输出)
可以看出,调用d3.scaleLinear()可以生成线性比例尺,domain()是输入域,range()是输出域,相当于将domain中的数据集映射到range的数据集中。
使用示例:
映射关系:
(2)d3-scaleTime 时间比例尺(连续性输入和连续性输出)
时间比例尺与线性比例尺类似,只不过输入域变成了一个时间轴。正常我们使用比例尺都是个正序的过程,但是D3也提供了invert()以及invertExtent()方法,我们可以通过输出域中的具体值得出对应输入域的值。
使用示例:
(3)d3.scaleQuantize 量化比例尺(连续性输入和离散性输出)
量化比例尺是将连续的输入域根据输出域被分割为均匀的片段,所以它的输出域是离散的。
使用示例:
映射关系:
(4)d3. scaleThreshold 阈值比例尺(连续性输入和离散性输出)
阈值比例尺可以为一组连续数据指定分割阈值,阈值比例尺默认的 domain:[0.5] 以及默认的 range:[0, 1] ,因此默认的 d3.scaleThreshold() 等价于 Math.round 函数。 阈值比例尺输入域为 N 的话,输出域必须为 N + 1,否则比例尺对某些值可能会返回 undefined,或者输出域多余的值会被忽略。
使用示例:
存在三种映射关系:
a. 当domain和range的数据是 N : N+1
b. 当domain和range的数据是 N : N + 大于1
c. 当domain和range的数据是 N + 大于0 : N
(5)d3.scaleOrdinal 序数比例尺(离散性输入和离散性输出)
与scaleLinear等连续性比例尺不同,序数比例尺的输出域和输入域都是离散的。
使用示例:
存在三种映射关系:
a.当domain和range的数据是一一对应
b.当domain少于range的数据
c.当domain多于range的数据
通过以上的学习,应该对d3是如何操作DOM以及坐标轴的数据映射为相应的可视化表现有了一定的了解,下面我们来实际运用这两个模块,来实现我们常见的可视化图表:柱状图。
(1)首先添加一个SVG元素。
(2)根据我们上面说到 d3.scale 模块以及 d3.axis 模块绘制坐标轴,d3.scaleBand() 叫做序数分段比例尺,类似我们说的 d3.scaleOrdinal() 序数比例尺,但是它支持连续的数值类型的输出域,离散的输入域可以将连续的范围划分为均匀的分段。这里再讲一个细节,在绘制网格的时候,我们并没有额外添加 line 元素来实现,而是通过 d3.axis 坐标轴模块的 axis.ticks() 方法对坐标轴刻度进行了设置,通过 tickSIze() 设置了刻度线长度,来模拟和图表宽度相等的网格线,并且还可以通过 tickFormat() 对Y轴刻度值进行格式化转换。
(3)坐标轴绘制好了后,我们通过数据绑定来绘制与之对应的矩形(rect)元素了。
(4)这个时候柱状图已经基本绘制好了,我们再丰富内容展示,添加标签、标题等提示信息。
(5)最后我们通过给柱子绑定监听事件,实现tooltips的信息浮层交互。
通过对 d3.selection 、d3.scale 以及 d3.axis等模块的学习,我们已经可以绘制出常用的柱状图等图表,我们也可以通过d3提供的其他模块绘制出更加复杂的可视化效果,例如通过 d3-hierarchy(层级模块) 实现层级树图可视化,d3-geo(地理投影) 实现地图数据可视化等,本文讲解的内容还只是D3库的冰山一角。所以等我们掌握了D3后,限制我们实现可视化的不再是技术而是想象力。
如何使用百度地图API
百度地图API
开始学习百度地图API最简单的方式是看一个简单的示例。以下代码创建了一个520×340大小的地图区域并以天安门作为地图的中心:
1. html
2. head
3. meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ /
4. titleHello, World/title
5. script type=”text/javascript” src=”;v=1.0services=false”/script
6. /head
7. body
8. div style=”width:520px;height:340px;border:1px solid gray” id=”container”/div
9. /body
10. /html
11.
12.
html
head
meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ /
titleHello, World/title
script type=”text/javascript” src=”;v=1.0services=false”/script
/head
body
div style=”width:520px;height:340px;border:1px solid gray” id=”container”/div
/body
/html
1. script type=”text/javascript”
2. var map = new BMap.Map(“container”); // 创建地图实例
3. var point = new BMap.Point(116.404, 39.915); // 创建点坐标
4. map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
5. /script
6.
script type=”text/javascript”
var map = new BMap.Map(“container”); // 创建地图实例
var point = new BMap.Point(116.404, 39.915); // 创建点坐标
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
/script
引用百度地图API文件
当您引用地图API文件时,需要使用自己申请的API密钥。
1. script type=”text/javascript” src=”;v=1.0services=false”/script
script type=”text/javascript” src=”;v=1.0services=false”/script
创建地图容器元素
1. div style=”width:520px;height:340px;border:1px solid #000″ id=”container”/div
div style=”width:520px;height:340px;border:1px solid #000″ id=”container”/div
地图需要一个HTML元素作为容器,这样才能展现到页面上。这里我们创建了一个div元素并制定它的大小。地图会根据容器大小调整自身尺寸。
命名空间
API使用BMap作为命名空间,所有类均在该命名空间之下,比如:BMap.Map、BMap.Control、BMap.Overlay。
创建地图实例
1. var map = new BMap.Map(“container”);
var map = new BMap.Map(“container”);
位于BMap命名空间下的Map类表示地图,通过new操作符可以创建一个地图实例。其参数可以是元素id也可以是元素对象。
注意在调用此构造函数时应确保容器元素已经添加到地图上。
创建点坐标
1. var point = new BMap.Point(116.404, 39.915);
var point = new BMap.Point(116.404, 39.915);
这里我们使用BMap命名空间下的Point类来创建一个坐标点。Point类描述了一个地理坐标点,其中116.404表示经度,39.915表示纬度。
地图初始化
1. map.centerAndZoom(point,15);
map.centerAndZoom(point,15);
在创建地图实例后,我们需要对其进行初始化,BMap.Map.centerAndZoom()方法要求设置中心点坐标和地图级别。
地图必须经过初始化才可以执行其他操作。
地图操作
地图被实例化并完成初始化以后,就可以与其进行交互了。API中的地图对象的外观与行为与百度地图网站上交互的地图非常相似。它支持鼠标拖拽、滚轮缩放、双击放大等交互功能。您也可以修改配置来改变这些功能。
您还可以通过编程的方式与地图交互。Map类提供了若干修改地图状态的方法。例如:setCenter()、panTo()、zoomTo()等等。
下面示例显示一个地图,等待两秒钟后,它会移动到新中心点。panTo()方法将让地图平滑移动至新中心点,如果移动距离超过了当前地图区域大小,则地图会直跳到该点。
1. var map = new BMap.Map(“container”);
2. var point = new BMap.Point(116.404, 39.915);
3. map.centerAndZoom(point, 15);
4. window.setTimeout(function(){
5. map.panTo(new BMap.Point(116.409, 39.918));
6. }, 2000);
var map = new BMap.Map(“container”);
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
window.setTimeout(function(){
map.panTo(new BMap.Point(116.409, 39.918));
}, 2000);
原文:
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/257884.html