![]() |
跑龙套的松树 · 林則徐紀念館--網上導航--中國共產黨新聞網· 3 月前 · |
![]() |
痴情的数据线 · 东阳光:与中际旭创成立合资公司,强强联合剑指 ...· 5 月前 · |
![]() |
一身肌肉的眼镜 · 前列腺癌- 诊断与治疗- 妙佑医疗国际· 9 月前 · |
![]() |
老实的鸵鸟 · 2021年11月23日药品收据邮寄详情单· 1 年前 · |
![]() |
玩滑板的绿茶 · 高合HiPhi ...· 1 年前 · |
良久没有写过博客了,最近忙的焦头烂额,忽略了博客,罪过罪过。今天补充一篇,前一段时间研究过的技术,使用React+Three.js 封装一个三维地球,支持鼠标的交互行为。其实也实现了对有坐标的json数据展示在地球上的功能,以后会有补充。
https://github.com/zrysmt/react-threejs-app
整体做完之后的效果图:
废话少说,直接上环境
使用facebook给出的脚手架工具 create-react-app .
1 |
npm install -g create-react-app |
执行
1 |
npm start |
浏览器会自动打开
localhost:3000
。
如果不是很了解WebGL技术也没有关系,不妨现在先看看Three.js创建模型的整体过程。
安装需要的库,
three
是Three.js的库,
three-orbitcontrols
用来支持鼠标的交互行为的库。
1 |
npm i three three-orbitcontrols --save |
ThreeMap
在
ThreeMap.js
定义组件
ThreeMap
,并且创建改组件的样式
ThreeMap.css
。css定义三维地球的容器的宽度和高度。
1 |
#WebGL-output{ |
并且该组件在
App.js
引用。
1 |
import './ThreeMap.css'; |
1 |
componentDidMount(){ |
要渲染的虚拟DOM设定好
1 |
render(){ |
1 |
let scene; |
1 |
let group; |
1 |
camera = new THREE.PerspectiveCamera( 60, width / height, 1, 2000 ); |
Orbitcontrols
的参数,支持鼠标交互
1 |
let orbitControls = new Orbitcontrols(camera); |
1 |
let ambi = new THREE.AmbientLight(0x686868); //环境光 |
1 |
let loader = new THREE.TextureLoader(); |
1 |
let renderer; |
1 |
stats = new Stats(); |
将以上封装到
init
函数中
1 |
function animate() {
|
调用的顺序是:
1 |
init(); |
大功告成,一个可交互的三维地球就可以使用了。
ThreeMap.js
整体代码
1 |
import './ThreeMap.css'; |
参考阅读:
deck.gl是由uber开发并开源出来的基于WebGL的大数据量可视化框架。它具有提供不同类型可视化图层,GPU渲染的高性能,React和Mapbox GL集成,结合地理信息数据(GPS)的特点。下面我们就举两个例子探索一下这个神奇的库。
npm 下载,在项目根目录下
1 |
npm install |
(友情提醒,如果npm下载速度比较慢,可以使用淘宝镜像,详细请自行搜索)
下面我们来到例子中,和上不一样在
example
文件夹下下载安装
1 |
npm install |
安装成功之后,要申请mapbox的一个key。方法如下:
在
mapbox
网站注册后进入
https://www.mapbox.com/studio/account/tokens/
,我们便可以在
Default Public Token
找到我们需要的
mapbox key
。
在例子文件夹下命令行下输入
1 |
export MAPBOX_ACCESS_TOKEN=<上面申请到的key> |
注意:cmd会不认export,可以使用git命令行,或者直接在代码中加入
1 |
//const MAPBOX_TOKEN = process.env.MAPBOX_ACCESS_TOKEN; //改为 |
然后执行
1 |
npm run start |
浏览器会自动打开,地址为
localhost:3030
。
第一例子
3d-heatmap
,我们看到
对应官网上的例子
http://uber.github.io/deck.gl/#/examples/core-layers/hexagon-layer
这是一个
HexagonLayer
的例子。
第二个例子是利用
geojson
对应官网上的例子
http://uber.github.io/deck.gl/#/examples/core-layers/geojson-layer
源码路径 。
https://github.com/uber/deck.gl/tree/master/examples/3d-heatmap
deck.gl 是基于地理信息数据的,所以可视化很多都会分层两层,一层是地图数据底图,一层是可视化的数据。这个观念我们要记住,带进去看整个例子。对于这个例子组件
MapGL
是地里数据底图,组件
DeckGLOverlay
是可视化成的数据。
基本结构很见简单。
由于是使用React框架搭建,html很简单
1 |
<!doctype html> |
首先引入React和deckgl。
1 |
import React, {Component} from 'react'; |
几个变量先放出来,光线设置(LIGHT_SETTINGS),颜色范围设置(colorRange),高度显示范围(elevationScale),一些默认的属性(defaultProps)。
1 |
const LIGHT_SETTINGS = { |
我们建立叫
DeckGLOverlay
的组件
1 |
export default class DeckGLOverlay extends Component { |
组件中提供了两个静态的属性,静态属性可以使用[类名].[方法名]调用,例如:
DeckGLOverlay.defaultColorRange
。
1 |
static get defaultColorRange() {//默认的颜色范围 |
constructor
是构造函数,主要看的是
_animateHeight
对组件state的设置,这个是用来控制高度的
1 |
constructor(props) { |
render
渲染方法,layers是可视化渲染的图层定义变量。
1 |
render() { |
引入:
1 |
import React, {Component} from 'react'; |
mapbox key:
1 |
const MAPBOX_TOKEN = process.env.MAPBOX_ACCESS_TOKEN; |
组件
Root
:
在构造函数中,我们将两个关键的变量viewport和data均放入到state中。这里的
MapGL
组件就是地理底图。
1 |
class Root extends Component { |
渲染:
1 |
render(<Root />, document.body.appendChild(document.createElement('div'))); |
MapGL组件我们来修改下
mapStyle
来重新生成一张图。
1 |
mapStyle="mapbox://styles/mapbox/satellite-v9" |
来看下显示效果,地图就变成了卫星影像。
mapbox
提供了几款基础的样式,我们还可以自定义样式使用。
参考阅读:
https://github.com/zrysmt/leaflet-viz
leaflet 是一个开源的前端地图交互类库,比较轻量级,支持移动端。而且有丰富的 插件资源 可供我们使用。
Echarts 是百度开源的前端可视化类库,提供丰富的前端可视化图表,平台中重要的一部分是我们要将leaflet和Echarts结合在一起。
该平台是基于leaflet及其插件搭建的一个方便可用的可视化平台。详细参见[示例Demo]。( https://zrysmt.github.io/demo/leaflet-demo/ )
1 |
npm install |
debug模式
1 |
npm run dev |
1 |
npm run build |
示例地址:
https://zrysmt.github.io/demo/leaflet-demo/
示例包含最基本的GIS功能和可视化Demo
引入:
1 |
import '../common/leaflet-plugin/HeatLayer.js'; |
使用:
1 |
var heat = L.heatLayer([ |
效果图
:
1 |
let overlay = new L.echartsLayer3(map, echarts); |
迁徙图
(选择了高德卫星底图)
散点图
(选择了Geoq午夜蓝底图)
这个方案不太适合大数据量的渲染。
我写了两个简单的功能函数,一个用来渲染可视化图(echartsIcon),一个专门用来渲染图例(echartsLegend)。
效果图
(底图选择了为google底图)
1 |
import echartsIcon from '../common/plugin/echartsIcon.js'; //echartsLegend |
1 |
let option = { |
leaflet-dvf
是一个基于leaflet的数据可视化框架,提供有比较多的可视化图形。
1 |
import "../common/leaflet-plugin/Leaflet.dvf/css/dvf.css"; |
地震图:
收入水平图:
需要的数据
1 |
import earthquakesData from '../data/earthquakes.json'; |
地震图代码:
1 |
let lastLayer; |
收入水平图代码:
1 |
let incomeLevelTypes = ['OEC', 'NOC', 'UMC', 'MIC', 'LMC', 'LIC', 'HPC']; |
假设我们需要自己做个地图,然后加载到平台中。这个时候可以使用我们提供了编辑栏,编辑后会得到坐标,把坐标转成GeoJSON数据存到数据库中,下次加载的时候解析即可。
还可以使用GIS工具,做成GeoJSON的数据,然后使用下面的方法加载,详细说明的
传送门
在这,当然这包括MapServer的东西,我们将在第六部分有简要说明。
示例图:
引入数据:
1 |
import { json_china } from '../data/china.js'; |
1 |
function pop_0(feature, layer) {//部分有省略 |
再进一步,如果我们想要自己的地图服务器,这个时候就需要使用到了MapServer,具体的说明见 传送门
有个示例在
test
文件夹下:
leaflet-mapserver.html
。注意这个是需要配置好服务器的,在这里直接预览是不能成功的。
示例得到我们的世界地图的地图服务器。
其实leaflet和D3等开源库结合起来,能得到很多丰富多彩的可视化图,姑且留下点神秘,这里就不再探究两者结合的神奇魅力了。
快要秋招找工作了,预约的暑期实习面试,也是为了秋招攒点经验。约的时间是15:15 - 16:00,焦急又必须有耐心的等待后,终于在下午四点左右接通了视频,紧张ing。
首先面试官介绍了自己的花名,心里紧张没记下来,现在想想挺后悔的。但是谁让我紧张了呢?
然后是我的自我介绍,简单的介绍了一下我的基本情况,把技能和项目都介绍了介绍。
面试官态度挺好的,平易近人的感觉,慢慢的也就不紧张了,后面面试官一路45度仰天扣鼻子,也是让我乐了,心态更加轻松随意了。
面试的前端工程师,当然最重要的技术问题。上来就是让我共享屏幕,然后打开IDE写个排序,尼玛宝宝好怕,虽然简单,但是全部写下来运行太痛苦了。
原生实现 sort函数,倒是很快就写出来了,然后随时就让我用不是原生的方法实现
1 |
var arr = [1,6,8,34,20,10]; |
快排 我记得模棱两可,没写出来啊,心痛啊。现在把正确的贴在这里。
1 |
function quickSort(arr) { |
还好冒泡还记得,又用冒泡写的,马马虎虎能运行了。
1 |
function bubbleSort(arr) { |
问我在项目中使用的ES6都有哪些?我说 Promoise 挺优雅的,然后让我写写,然后我就写了个XmlHttpServer,啊悲了个催了的,我的编辑器没有智能提示(论一个智能提醒的IDE有多重要),然后我手写的ajax请求,忘记了很多细节,怎么写啊,写了部分,面试官看不下去了吧(心伤),说他明白我的意思,你不用全部写下来,把过程大概写好就行了。然后我就写了怎么调用,我是理解了Promise,不知道这个问题面试官给打多少分,所以说坑都是自己挖的。
其实介绍了几次我使用了React+react router,估计阿里内部使用的是Weex,Kissy这样的自己的框架,面试官估计没有太接触React,所以一直没问我这方面的问题。
然后问我做了其他的有什么最深的体会。
所以我立刻就说了使用 React的项目(终于可以介绍了),然后我就说主要分了两个模块,一个是基础的显示模块,一个是地图模块,使用Openlayers api的组件化,还和github上的有个OpenLayer封装的做了个对比,我说有一个开源的使用React封装的Openlayers不方便,而且源码不全,我就自己封装了,面试官再次表现出了不太了解React,所以就没有继续追问下去。
总之问我理解,我又给出的印象是我的理解不深,痛心了。
然后给了个更大的题目,对可视化的理解,这题目呢,怎么说啊。我只能说大数据可视化和canvas,然后举了举例子,ECharts,datav,mapv等,然后说我对这方面挺有兴趣的,忘了面试官说什么了,好像的意思也只是你对这感兴趣,有个方向,没有深耕下去。
这可以说是我第一次真正意义上的面试,第一次视频面试,还是阿里的。总之感觉是这次我没戏了,哪怕是个实习面试。看来是要多刷刷面试经验的。
离远方还是有很多路要走啊,还有两三个月时间,继续加油吧,一定要告诫自己不要气馁,坚持就是胜利。
简单体会,写至此处,感怀万千。,坚持就是胜利。 简单体会,写至此处,感怀万千。
上一篇我们介绍了使用WebGL的基础,包括顶点着色器、片元着色器、初始化WebGL,初始化着色器以及变换、动画、颜色、纹理等,这一部分的内容我们就来进入三维的世界。和上一篇文章一样,我们的这篇只做个大概的介绍,详细的内容部分请参阅《WebGL编程指南》一书。
https://github.com/zrysmt/data-viz/tree/master/webgl/demo
首先我们来绘制一个三维的实例。
示例程序:
https://zrysmt.github.io/demo/webgl-demo/demo/10-HelloCube.html
.
实例的源码程序:
https://github.com/zrysmt/data-viz/blob/master/webgl/demo/HelloCube.js
其实这里我们应该注意到示例和源码的结构对应,下面的一些我可能只给出一个url地址。
1 |
function main() {
|
1 |
var VSHADER_SOURCE = |
关于
attribute uniform varying
attribute:
只能是全局的,只能出现在顶点着色器,标识逐顶点信息;
uniform:
只能是全局的,可以在顶点着色器和片元着色器上,如果两个地方均定义,那么这变量被两个着色器共享了;
varying:
只能是全局的,负责从顶点着色器向片元着色器传输数据。
1 |
var mvpMatrix = new Matrix4(); |
投影的作用就是使得距离近的看的比较大,距离远的看的比较小
示例
1 |
projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100); |
三角形与可视空间的位置
其实投影矩阵的核心就是两种变换,1)按比例缩放;2)平移
1 |
gl.enable(gl.DEPTH_TEST); |
清除颜色和深度buffer
1 |
// Clear color and depth buffer |
1 |
<投影矩阵> X <视图矩阵> X <模型矩阵> X <顶点坐标> |
1 |
function initVertexBuffers(gl) { |
立方体的结构
1 |
v6----- v5 |
首先顶点坐标和顶点坐标的颜色存储在
verticesColors
矩阵中。
而WebGL的绘制是按照三角形的形式一个一个绘制的,那么意味着一个立方体的一个面有两个三角形,一个立方体总共需要2
6 = 12个三角形,一个三角形需要3个顶点,那么一共需要绘制 3
12 = 36个顶点。我们知道一个立方体只需要8个顶点就可以了。为此我们在这里使用了
索引矩阵
(indices),索引矩阵也要写入缓存中。
这样我们就能完成绘制了
1 |
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); |
注意这里的
n = indices.length
。
物理表面 反射光线: 分为漫反射和环境反射
1 |
<环境反射光颜色> = <入射光颜色> X <表面基底色> |
1 |
<漫反射光颜色> = <入射光颜色> X <表面基底色> X cosθ |
即:
1 |
<漫反射光颜色> = <入射光颜色> X <表面基底色> X (<光线方向> · <法线方向>) |
我们只用漫反射的效果的时候
示例
由于只考虑漫反射,右边的部分几乎是黑色了,这时候我们来考虑下环境光。
环境反射下的表面的反射光颜色
1 |
<表面的反射光颜色> = <漫反射颜色> + <环境反射光颜色> |
示例
我们来看下着色器源码
1 |
var VSHADER_SOURCE = |
对于变化后的物体,物体的法向量也会改变
示例
1 |
<变换后的法向量> = <法向量> X <变化矩阵的逆转置矩阵> |
1 |
normalMatrix.setInverseOf(modelMatrix); |
在顶点着色器中变化原法向量
1 |
vec3 normal = normalize(vec3(u_NormalMatrix * a_Normal)) |
最后我们来看下最终的
漫反射光颜色
的公式
1 |
<漫反射光颜色> = <入射光颜色> X <表面基底色> X (<光线方向> ·(<模型矩阵逆转置矩阵> X <法线方向>)) |
1 |
光线方向 = 归一化(点光源方向 - 顶点坐标) |
1 |
// 顶点处的光线方向 = 点光源的光坐标 - 顶点坐标 |
有的物体的运动会带动别的物体,如上臂的运动会带动下臂和手掌的运动。
示例:
https://zrysmt.github.io/demo/webgl-demo/ch09/JointModel.html
示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch09/JointModel.js
下边的(Arm1)会带动上边的(Arm2)运动,而上边的运动不会带动下边的。
思路:共用一个变换的模型矩阵:
g_modelMatrix
,Arm1变化
g_modelMatrix
也会变化,那么Arm2也会使用这个模型。谁能控制谁,关键是谁先写上去,谁后写上去,先写上去的控制后写上去的。
1 |
// Arm1 |
我也是个初学WebGL的人,这部分的内容是我在看完《WebGL编程指南》一书后的精简教程。看完之后我对三维世界重建了一些观念,这篇文章是尽量在有限的内容中,一下介绍几个重要的基本的概念,后面我会分几篇再详细介绍几个重要的概念。
WebGL是利用HTML5的canvas绘制和渲染三维图形,再现代的浏览器中均支持。WebGL是从OpenGL ES中继承过来的。
代码存储在我的 GitHub 中。
https://github.com/zrysmt/data-viz/tree/master/webgl/demo
首先我们来绘制一个二维的实例,点击的时候绘制一个点。
示例程序:
https://zrysmt.github.io/demo/webgl-demo/demo/0-simple.html
.
注意WebGL canvas的坐标(右,z轴垂直屏幕向外)和二维canvas(左)不一样。
html片段很简单,我们使用就是canvas元素。
1 |
<body onload="main()"> |
1 |
function main() {
|
1 |
var VSHADER_SOURCE = |
是一种类似C的语言。a_Position是一个attribute变量,vec4表示有四个浮点数组成的矢量。
1 |
var FSHADER_SOURCE = |
这部分的代码也是通用的,流程如下,具体代码我们在我的github中查看
1 |
* 1.创建着色器对象(gl.createShader()) |
1 |
canvas.onmousedown = function(ev) { |
注意要转化为WebGL的坐标。
1 |
function click(ev, gl, canvas, a_Position) { |
1 |
gl.drawArrays(gl.POINTS, 0, 1); |
指定第一个参数可以绘制线或三角形,具体的这几个有什么意义,可以查看
github
中示例的源码。
一次性的将全部的点传给顶点着色器,这个时候就需要用到了
缓冲对象
。
我们以绘制个三角形为例(一次性至少传入三个点),示例程序:
https://zrysmt.github.io/demo/webgl-demo/ch03/HelloTriangle.html
。
效果如下所示:
对应的源码位置:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch03/HelloTriangle.js
1 |
function initVertexBuffers(gl) { |
学过线性代数的都知道矢量的变化是可以通过矩阵(4 X 4的,可以容纳下三种变化)完成的。
我们来看顶点着色器代码
1 |
var VSHADER_SOURCE = |
u_xformMatrix就是变化的矩阵。
旋转示例:
https://zrysmt.github.io/demo/webgl-demo/ch03/RotatedTriangle_Matrix.html
旋转示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch03/RotatedTriangle_Matrix.js
缩放示例:
https://zrysmt.github.io/demo/webgl-demo/ch03/ScaledTriangle_Matrix.html
缩放示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch03/ScaledTriangle_Matrix.js
平移示例:
https://zrysmt.github.io/demo/webgl-demo/ch03/TranslatedTriangle.html
平移示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch03/TranslatedTriangle.js
注意:
以后关于矩阵的运算我们使用源码提供的库。旋转使用
setRotate
,
rotate
;平移使用
setTranslate
,
translate
;缩放使用
setScale
,
scale
.
这部分的使用
1 |
var formatMatrix = new Matrix4(); |
第一个都要是带z的方法,后面的都不带即可。
https://github.com/zrysmt/data-viz/blob/master/webgl/lib/cuon-matrix.js
动画的原理是使用HTML5 requestAnimationFrame()方法重绘WebGL图形。
示例:
https://zrysmt.github.io/demo/webgl-demo/ch04/RotatingTriangle_withButtons.html
示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch04/RotatingTriangle_withButtons.js
示例:
https://zrysmt.github.io/demo/webgl-demo/ch05/ColoredTriangle.html
示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch05/ColoredTriangle.js
大概流程
是这样的:
顶点坐标==>图形装配==>光栅化==>执行片元着色器
1 |
var verticesColors = new Float32Array([ |
initVertexBuffers函数对整个矩阵的处理,位置和颜色分别分配给a_Position和a_Color
1 |
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0); |
1 |
function initVertexBuffers(gl) { |
示例:
https://zrysmt.github.io/demo/webgl-demo/ch05/TexturedQuad.html
示例源码:
https://github.com/zrysmt/data-viz/blob/master/webgl/ch05/TexturedQuad.js
1 |
var image = new Image(); // Create the image object |
逻辑函数
1 |
function loadTexture(gl, n, texture, u_Sampler, image) { |
三维单独写一篇介绍。
参考阅读:
最近尝试了很多次,看到网上的很多教程都是版本比较老旧,会出现很多问题。经过数天的实践,现在可以调用成功,遂将步骤记录在此。
为避免以后使用的软件不兼容,首先给出基于window 10的软件版本:
http://www.qgis.org/en/site/forusers/download.html
所有配置和示例我都放在了github仓库中 mapserver-leaflet-openlayers 。
https://github.com/zrysmt/mapserver-leaflet-openlayers
Windows平台MapServer (MS4W)安装 Windows平台MapServer (MS4W)安装
http://blog.csdn.net/u010924834/article/details/53434322
http://mapserver.org/de/introduction.html
MapServer的安装包(ms4w.zip,解压到根目录下)里内置了 Apache ,不过因为IIS占用了80的端口,所以需要设置下端口 (在\ms4w\Apache\conf\ httpd.conf中,将Listen 80改为Listen 8081)
因为刚开始值安装了Destop桌面端,后来出了问题,无奈废了很大的劲又卸载了重新安装的。这里建议全部安装,选择
Advanced Install
点击选择全部安装即可。
导出后会打开一个网页,我们需要的是data文件夹下的js,里面有geoJson数据
2.RT Mapfile Export
这是我们发布地图服务的重要的插件
使用插件的时候注意先设置好,打开
Manager and Install Plugin
对话框,注意在设置中勾选住实验性的插件一项,再搜索插件并进行安装。
MapFile
在发布服务方面,MapServer有一个和mxd(ArcGIS)类似的map文件来描述地图的图层及样式,不同的是,在使用地图服务的时候,调用的url中需要知道map文件的位置,而ArcGIS则不需要
关于MapFile,这里就不单独介绍太多,Mapfile的作用如下图所示。
基本介绍:
http://blog.csdn.net/qingyafan/article/details/46500127
MapServer 快速入门文档:
http://live.osgeo.org/zh/quickstart/mapserver_quickstart.html
发布过程
因为我把发布的服务器端口改为8000了,所以
Online resource url
地址是
http://127.0.0.1:8000/cgi-bin/mapserv.exe
1.
2.
3.
【确定】即可生成mapfile文件,在本文末尾会给出.
mapfile文件地址在
E:\ms4w\apps\worldmap
中。
我们在浏览器中输入地址
http://127.0.0.1:8000/cgi-bin/mapserv.exe?MAP=E:/ms4w/apps/worldmap/world3857.map&LAYERS=World_region&MODE=MAP
注意:
在使用类库调用该WMS服务的时候一定要去掉
&MODE=MAP
,否则不能成功。
1 |
<!DOCTYPE html> |
访问示例如下:
openlayers示例如下:
1 |
<!DOCTYPE html> |
访问示例如下:
1 |
MAP |
所有配置和示例我都放在了github仓库中 mapserver-leaflet-openlayers 。
https://github.com/zrysmt/mapserver-leaflet-openlayers
我们直接来看两个例子,一个是hash结构的,这是在Html5 的history api出现之前的解决方案;一个是基于history api实现的。
1 |
http://10.0.0.1/ |
1 |
http://10.0.0.1/ |
前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的。
关键是监控两个事件,一个是页面加载进来的时候触发
load
,一个是hash改变的时候触发
hashchange
。
1 |
<!DOCTYPE html> |
html5 增加了两个方法,分别是
pushState
,
replaceState
.
两个方法均有三个参数:一个状态对象、一个标题(现在会被忽略),一个可选的URL地址
状态对象(state object)
— 一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
任何可序列化的对象都可以被当做状态对象。因为FireFox浏览器会把状态对象保存到用户的硬盘,这样它们就能在用户重启浏览器之后被还原,我们强行限制状态对象的大小为640k。如果你向pushState()方法传递了一个超过该限额的状态对象,该方法会抛出异常。如果你需要存储很大的数据,建议使用sessionStorage或localStorage。
pushState 用于向 history 添加当前页面的记录,而 replaceState 和 pushState 的用法完全一样,唯一的区别就是它用于修改当前页面在 history 中的记录。
两者的一个表现的区别是 :在浏览器上点击后退键的时候,使用pushState的会正常按照点击的顺序依次返回,而使用replaceState的只是替换,不会返回,会直接返回到pushState的记录。
index.html
1 |
<!DOCTYPE html> |
simple-history.js
1 |
(function(window, undefined) { |
参考阅读:
调用这三个商业地图服务,我们使用的都是切片(Tile)地图服务,关于切片地图的含义这里做简单的介绍:
切片地图就是指将显示的地图切成一块一块的(256 * 256)分别显示加载。openlayers 3中有这样图层加载类,
ol.layer.Tile
,对应的source类有
ol.source.TileImage
,
ol.source.XYZ
,这两者的关系通过源码可以看到
ol.inherits(ol.source.XYZ, ol.source.TileImage);
,
ol.source.TileImage
是父类。
对于天地图,我们访问
天地图
地图主页服务,打开控制台->
Network
,我们可以看到请求的一些地址如下:
1 |
http://t2.tianditu.com/DataServer?T=vec_w&x=53&y=24&l=6' |
其中重要的信息是x,y,z分别表示x坐标,y坐标和zoomLevel,
其实在openlayers 3源码中有Bing地图和OSM地图的扩展了,我们可以仿照它们进行一些扩展。
1 |
var ol = require('openlayers'); |
1 |
var tianMapSat = new ol.layer.Tile({ |
1 |
baiduMercator.forward(bd09.fromWGS84(point)) |
反过来的转化为
1 |
bd09.toWGS84(baiduMercator.inverse(point)) |
https://github.com/tschaub/projzh
1 |
var ol = require('openlayers'); |
调用
1 |
var baiduMapSat = new ol.layer.Tile({ |
1 |
var ol = require('openlayers'); |
调用
1 |
var aMapSat = new ol.layer.Tile({ |
最后推荐一个
github仓库
,Openlayers 3 使用React 组件化+wepack+ES6实践,
包括扩展在其中的具体使用方法
https://github.com/zrysmt/openlayers3-react
本博文不作深入研究内容,只用来记录使用React 组件化+wepack+ES6技术操作Openlayers 3 实践中遇到的问题,本博文作为开篇,所以只是简单的demo案例说明。后面还会有其他的一些博文分享我在项目中遇到的问题和总结的经验。
大约一年前我写过一个系列的Openlayers 3的简单的源码结构的分析,代码以及说明在我的 github 中有,需要的同学出门右转。
Openlayers 3的简单的源码结构的分析 https://github.com/zrysmt/openlayers-3
我在github上看到一些人将openlayers彻底组件化,属性通过props传入进来,例如:
1 |
<layer.Tile> |
这样做的好处是高度组件化,看起来很和谐。但是这样无形中增加了学习成本和时间成本,我们要看到ol3的API,然后再考虑到转化为组件化的书写的对应形式,导致了多走一步。
本博文的思想很简单,就是外壳用react组件封装,内部的源码实现使用ol3的API完全没有改变,这样就简单清晰而且避免多走一步。具体例子见下面给出的Demo。
我还将我写的一些组件,比如基础地图,工具栏和绘制栏用React写的组件单独从项目中拿出来,提供给使用和学习者一些方便,下面给出 地址 ,欢迎fork,star,不定期更新,有错误请指出:
https://github.com/zrysmt/openlayers3-react
1 |
Failed at the [email protected] postinstall script 'node ./bin/closure-util.js update' |
解决方案:
1 |
首先 npm i closure-util --save |
1 |
WARNING in ./~/openlayers/dist/ol.js` |
修改webpack.config.js
1 |
module: {// ... |
1 |
import React from 'react'; |
olbasemap.scss
1 |
#map{ |
1 |
/** |
此时有个问题,假设我们要把
map
变量传出去,供其他的组件使用,子类和父类之间的传值可以通过props和回调函数完成;现在我们做的组件其实是兄弟关系,怎么将
map
做成通用呢,经过考虑我们决定使用
发布-订阅模式
,涉及到各个组件的变量的都在组件内部定义,然后通过
发布-订阅模式
将一些事件集中管理起来。此外我们还组织将变量放到构造函数中。
于是我们可以这样修改
1 |
/** |
在兄弟模块中该调用的模块中调用下面的关键代码即可
1 |
Eventful.dispatch('zoomtoall'); |
最后列下来
发布-订阅模式
的代码
Eventful.js
1 |
/** |
![]() |
跑龙套的松树 · 林則徐紀念館--網上導航--中國共產黨新聞網 3 月前 |
![]() |
一身肌肉的眼镜 · 前列腺癌- 诊断与治疗- 妙佑医疗国际 9 月前 |
![]() |
老实的鸵鸟 · 2021年11月23日药品收据邮寄详情单 1 年前 |