YJohn

YJohn 查看完整档案

广州编辑广州大学  |  信息安全 编辑社会主义  |  接班人 编辑 www.404.com 编辑
编辑

404

个人动态

YJohn 回答了问题 · 6月17日

能不能帮我解决下flutter启动项目时遇到的问题呢?试过很多方法了

请问最后解决了,需要怎么处理

关注 7 回答 4

YJohn 收藏了文章 · 2019-02-01

『前端好文整理』2019你值得拥有

年初按照惯例,是应该立下flag的时候了。

把2018年积累的一些碎片化的好文都梳理了一遍,知识体系化后学习会变得更加有目的性,从而提升学习效率(github地址)。

JS篇

数据类型

this

作用域链与闭包

原型与原型链

JS执行底层

ES6/ES7..

除此之外强烈推荐冴羽老师的ES6系列文章,深入骨髓的理解ES6中的核心。

TypeScript

Node

HTML/CSS篇

HTTP

性能&优化篇

Webpack篇

React篇

面试篇

一点感悟

在大前端的时代,要学的知识越来越多,唯有不断的学习不断的积累才能走的更远!本文也会不断的更新下去,希望能帮助到更多的前端爱好者。当然如果你有好文章推荐的话,不妨留言评论,大家一起分享,一起成长。Learn and live!奉上github

查看原文

YJohn 评论了文章 · 2019-02-01

面试篇---1 如何区分深拷贝与浅拷贝

如何区分深拷贝与浅拷贝?


简单来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

浅拷贝例子:

 var a=[0,1,2,3,4],
       b=a;
    console.log(a===b);
    a[0]=1;
    console.log(a,b);  
    

clipboard.png

嗯?明明b复制了a,为啥修改数组a,数组b也跟着变了,这里我不禁陷入了沉思。

那么这里,就得引入基本数据类型与引用数据类型的概念了。

面试常问,基本数据类型有哪些,number,string,boolean,null,undefined五类。

引用数据类型(Object类)有常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。

而这两类数据存储分别是这样的:
a.基本类型--名和值存储在栈内存中,例如let a=1;


clipboard.png

当你b=a复制时,栈内存会新开辟一个内存,例如这样:

clipboard.png

所以当你此时修改a=2,对b并不会造成影响,因为此时的b已自食其力,翅膀硬了,不受a的影响了。虽然b不受a影响,但这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。

b.引用数据类型--名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值,我们以上面浅拷贝的例子画个图:


clipboard.png

当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。

clipboard.png

而当我们a[0]=1时进行数组修改时,由于a与b指向的是同一个地址,所以自然b也受了影响,这就是所谓的浅拷贝了。

clipboard.png

那,要是在堆内存中也开辟一个新的内存专门为b存放值,就像基本类型那样,岂不就达到深拷贝的效果了.

clipboard.png

那么如何实现深拷贝呢?
1、我们可以借用JSON对象的parse和stringify


function deepClone(obj){
        var _obj = JSON.stringify(obj),
            objClone = JSON.parse(_obj);
        return objClone
    }
    var a=[0,1,[2,3],4],
        b=deepClone(a);
    a[0]=1;
    a[2][0]=1;
    console.log(a,b);
    

clipboard.png
现在b完全不受a的影响了。

2、借用JQ的extend方法。


$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

clipboard.png

其实深拷贝也不仅仅是为了应付面试题, 在实际开发中也是非常有用的。 例如后台返回了一堆数据,你需要对这堆数据做操作,
但多人开发情况下,你是没办法明确这堆数据是否有其它功能也需要使用, 直接修改可能会造成隐性问题,深拷贝能帮你更安全安心的去操作数据,
根据实际情况来使用深拷贝,大概就是这个意思。

原文链接https://www.cnblogs.com/echol...

查看原文

YJohn 赞了文章 · 2019-01-16

FIBOS 与 Ethereum 技术对比

共识机制

Ethereum 使用的是 PoW 共识机制,未来几年里将会换成 PoS 共识机制。Ethereum 区块是由矿工计算哈希产生,在 PoW 共识机制中区块需要得到全网络超过51%的节点确认才能够正式被区块链认可。在 Ethereum 网路中,任何人都可以成为矿工。

FIBOS 使用的是 DPoS 共识机制。FIBOS 区块的产生是由21个 BP 轮流出块,产生的区块需要2/3以上的 BP 确认才能够被区块链认可。21个 BP 是由 FO 通证持有者投票选举出。

账户/地址

Ethereum 的用户使用的是地址,一个长达40位的的16进制数。

FIBOS 使用的是账户管理,账户名采用12位数字与字母组合,可自定义,方便用户记忆。

权限

Ethereum 的权限是由地址唯一对应的私钥管理,并且这个私钥是随机生成的,在需要使用的权限的时候用户只能通过私钥授权。

FIBOS 账户默认有2种原生权限: owner、active,一个账户必须“关联” owner、active 权限。

  • owner 拥有超级权限,代表着账户的归属者,因为拥有此权限者可以用于操作其他权限配置,该权限常用事务中(转账、合约 action 等)一般不会使用。
  • active 常用业务的权限,比如:转账、投票等。

另外还可以根据自己需求自定义权限。

手续费/资源

Ethereum gas

在 Ethereum 中使用区块链上的资源需要消耗 gas,消耗的 gas 作为区块打包的费用支付给矿工。

FIBOS 资源

FIBOS的资源分为两种类型:

  • 抵押型资源,包括 CPU 和 NET;
  • 消耗性资源,叫做 RAM,也称存储。

开发者发布一个合约必须拥有足够的资源,包括 RAM、CPU 和 NET。

智能合约

编程语言的区别

Ethereum 上开发智能合约使用的语言为 Solidity,这是一门专为 EVM 而开发的语言,对于一般没有接触过 Ethereum 或智能合约的开发者来说,该语言的研发门槛很高。

Ethereum 合约示例:

pragma solidity ^0.4.0;

contract hello {
    function hello(uint i){

    }
}

FIBOS 使用 JavaScript 编写智能合约,开发成本极低。这让开发智能合约的门槛降低了许多。

FIBOS 合约示例:

exports.hi = user => console.error('in contract:', user);

合约的发布和更新

Ethereum 合约发布成功后会得到一个合约地址。合约地址格式长并且没有规律记忆起来十分困难。Ethereum 合约发布后无法更改。

在 Ethereum 中如果合约发布后发现问题,现有两种解决方案:

  • 一个是在合约中预先设置销毁函数,并设置权限只有合约发布者可以调用,在需要的时候调用销毁函数销毁合约。
  • 另一个方法是在合约中预先设置 delegatecall,由于 delegatecall 保留了函数调用的状态,因此可以更新目标合约的逻辑,并且状态将保留在代理合约中以供更新后的目标合约的逻辑使用。

这两种方法都需要预先的设置,以及发布合约的账号丢失后,也将失去对合约的控制权。

FIBOS 合约账户名就是发布账户的账户名。发布合约时需要发布账号的资源,包括足够的 RAM、CPU 和 NET。

在 FIBOS 中开发者可以使用发布账户随时更新合约代码。相较于以太坊的合约,FIBOS 的合约后期的维护和更新在技术上容易很多,在成本上低了很多。

生态支持

Ethereum:

  1. 开发框架: Truffle 具有以下功能:

    • 内置的智能合约编译,链接,部署和二进制文件的管理。
    • 快速开发下的自动合约测试。
    • 脚本化的,可扩展的部署与发布框架。
    • 部署到公网或私网的网络环境管理功能
    • 使用 EthPM&NPM 提供的包管理,使用 ERC190 标准。
    • 与合约直接通信的直接交互控制台(写完合约就可以命令行里验证了)。
    • 可配的构建流程,支持紧密集成。
    • 在 Truffle 环境里支持执行外部的脚本。

在 Truffle 框架中,可以根据需要编译、部署合约,Truffle 也提供一键启动测试链的工具。

  1. 托管节点: Infura
    Ethereum 的合约可以通过使用 Infura 提供的节点发布合约。

FIBOS:

  1. fibos.js 是 FIBOS 区块链的通用库,具有以下功能:

    • 使用 NPM 提供的包管理。
    • 快速开发下的自动合约测试。
    • 提供合约与客户端交互接口。
    • 提供合约内部所需的 API 接口。
  2. 节点: FIBOS 提供一键脚本发布十分简单易用。
  3. FIBOS-tracker 是一个 FIBOS 区块链数据 API 服务框架,基于 fib-app 框架实现。

    • 提供对 FIBOS 区块数据的 emitter 监听事件。
    • 提供 http 服务,支持 GraphQL 调用。
    • 支持使用 ORM 定制自己的数据模型 model,自定义数据表以及自定义 hook 监听数据。
查看原文

赞 0 收藏 0 评论 0

YJohn 评论了文章 · 2019-01-11

vue 地图可视化 mapbox篇(2)

MapBox

项目中用到MapBox也是偶然的机会,项目中需要采用3D地图,当现有的工具(百度地图)无法满足我们的需求,我们肯定需要更高级开源的地图,无奈谷歌地图无法在国内使用,已是便找到Leafle,一开始惊艳于leafle的开源程度和其与众不同的地图风格,后来顺藤摸瓜,找到一个商业性地图,它便是我们的主角-MapBox
图片描述

作为国外的一款地图,看到其效果时便一发不可收拾

由于项目主要采用3d GL,国内在这方面的文档不多,只能举起社会主义的镰刀和火炬,一遍遍地看它的官方文档
mapbox gl https://www.mapbox.com/mapbox...

  • 项目引入Mapbox

CDN模式
在项目html的<head>中直接插入mapbox

<script data-original='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css' rel='stylesheet' />

module bundler模式
npm install --save mapbox-gl
// cnpm install --save mapbox-gl


  • 初始化地图

这里的思路和之前写的一遍文章[百度地图组件化][2]一样,都是将地图单独抽出来

mapbox.vue

<template>
  <div style="height:100%;width:100%;text-align:left;">
    <div ref="basicMapbox" :style="mapSize"></div>
  </div>
</template>
<script>
import mapboxgl from 'mapbox-gl'
export default {
  props: {
    mapWidth: {
      type: String
    },
    mapHeight: {
      type: String
    }
  },
  data () {
    return {
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    // 初始化
    init () {
      mapboxgl.accessToken = 'your AK'
      const map = new mapboxgl.Map({
        container: this.$refs.basicMapbox,
        style: 'mapbox://styles/mapbox/streets-v9'
      })
      console.log(map)
    }
  },
  computed: {
    mapSize () {
      let styleObj = {
        width: this.mapWidth,
        height: this.mapHeight
      }
      return styleObj
    }
  }
}
</script>
<style>
@import url('https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css');
</style>

因此只需在业务组件中单独引入mapbox.vue就可以加载地图

<mapbox-map mapWidth="100%" mapHeight="600px"></mapbox-map>

效果图:
图片描述


  • mapbox可视化

mapbox原生提供数据可视化的接口,但这并没满足我们的需求
因此我们选用前端经常使用到可视化插件d3.js和echarts,经过横向对比其性能及通用性,最后还是选择了后者
echarts也提供3D绘制的echart-gl,通过利用mapbox强大的地图服务和echaers-gl的可视化渲染,达到我们的前期需求
(3d建模需要消耗大量的GPU运算,项目前期以功能实现为主,后期将着重性能优化)

clipboard.png

效果图:

clipboard.png

mapbox可视化的组件化
1、地图配置:echarts-GL内封装mapbox的配置项,通过options的mapbox可以直接进行简单配置(中心点、等级、摄像机倾斜度、摄像机高度及光源等)



mapbox: {
      center: [113.206456, 23.072519],
      zoom: 6.2,
      pitch: 60,
      bearing: 0,
      style: 'mapbox://styles/mapbox/dark-v9',
      boxHeight: 20,
      light: {
        main: {
          intensity: 1,
          shadow: true,
          shadowQuality: 'high'
        },
        ambient: {
          intensity: 0.2
        }
      }
    }

2、可视化工具:echarts-Gl options的series进行图表设置,通过getModel().getComponent('mapbox3D').getMapbox()获取map对象

series: {
      name: '常驻人口',
      type: 'bar3D',
      shading: 'realistic',
      coordinateSystem: 'mapbox',
      silent: true,
      barSize: 1, // 柱子粗细
      bevelSize: 0.3,
      emphasis: {
        label: {
          show: false
        }
      },
      label: {
        show: true,
        distance: 0,
        formatter: '{b}',
        textStyle: {
          fontSize: 12
        }
      },
      data: []
    }

3、动作及拓展:mapbox通过map API的on属性和mapboxgl进行地图的操作,如修改地图样式、加载图层、添加导航工具等用户交互动作
如:添加导航操作:

    this.nav = new mapboxgl.NavigationControl()
    map.addControl(this.nav)

添加Geojson图层

 map.addSource('states', {
        'type': 'geojson',
        'data': gdData
      })
    map.addLayer({
        'id': 'state-fills',
        'type': 'fill',
        'source': 'states',
        'layout': {},
        'paint': {
          'fill-color': '#627BC1',
          'fill-opacity': 0.1
        }
    })

思路汇总:通过上面三步走的思路,我们可以把组件粗略分成三部分

核心的mapbox.vue是地图视图
可视化图表由echarts-gl组成
动作及拓展对地图视图和图表进行操作

clipboard.png

效果图:

clipboard.png

clipboard.png

待续,文章持续更新修改......


上一篇文章: vue 地图可视化(1) 百度地图篇

完整项目github地址:https://github.com/hty7/vue-d...

有不懂的地方,可以在下方留言,或者私聊。对文章感兴趣的话,点下赞、收藏和github收集小星星,谢谢大家。

查看原文

YJohn 评论了文章 · 2019-01-04

vue 地图可视化 mapbox篇(2)

MapBox

项目中用到MapBox也是偶然的机会,项目中需要采用3D地图,当现有的工具(百度地图)无法满足我们的需求,我们肯定需要更高级开源的地图,无奈谷歌地图无法在国内使用,已是便找到Leafle,一开始惊艳于leafle的开源程度和其与众不同的地图风格,后来顺藤摸瓜,找到一个商业性地图,它便是我们的主角-MapBox
图片描述

作为国外的一款地图,看到其效果时便一发不可收拾

由于项目主要采用3d GL,国内在这方面的文档不多,只能举起社会主义的镰刀和火炬,一遍遍地看它的官方文档
mapbox gl https://www.mapbox.com/mapbox...

  • 项目引入Mapbox

CDN模式
在项目html的<head>中直接插入mapbox

<script data-original='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css' rel='stylesheet' />

module bundler模式
npm install --save mapbox-gl
// cnpm install --save mapbox-gl


  • 初始化地图

这里的思路和之前写的一遍文章[百度地图组件化][2]一样,都是将地图单独抽出来

mapbox.vue

<template>
  <div style="height:100%;width:100%;text-align:left;">
    <div ref="basicMapbox" :style="mapSize"></div>
  </div>
</template>
<script>
import mapboxgl from 'mapbox-gl'
export default {
  props: {
    mapWidth: {
      type: String
    },
    mapHeight: {
      type: String
    }
  },
  data () {
    return {
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    // 初始化
    init () {
      mapboxgl.accessToken = 'your AK'
      const map = new mapboxgl.Map({
        container: this.$refs.basicMapbox,
        style: 'mapbox://styles/mapbox/streets-v9'
      })
      console.log(map)
    }
  },
  computed: {
    mapSize () {
      let styleObj = {
        width: this.mapWidth,
        height: this.mapHeight
      }
      return styleObj
    }
  }
}
</script>
<style>
@import url('https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.2/mapbox-gl.css');
</style>

因此只需在业务组件中单独引入mapbox.vue就可以加载地图

<mapbox-map mapWidth="100%" mapHeight="600px"></mapbox-map>

效果图:
图片描述


  • mapbox可视化

mapbox原生提供数据可视化的接口,但这并没满足我们的需求
因此我们选用前端经常使用到可视化插件d3.js和echarts,经过横向对比其性能及通用性,最后还是选择了后者
echarts也提供3D绘制的echart-gl,通过利用mapbox强大的地图服务和echaers-gl的可视化渲染,达到我们的前期需求
(3d建模需要消耗大量的GPU运算,项目前期以功能实现为主,后期将着重性能优化)

clipboard.png

效果图:

clipboard.png

mapbox可视化的组件化
1、地图配置:echarts-GL内封装mapbox的配置项,通过options的mapbox可以直接进行简单配置(中心点、等级、摄像机倾斜度、摄像机高度及光源等)



mapbox: {
      center: [113.206456, 23.072519],
      zoom: 6.2,
      pitch: 60,
      bearing: 0,
      style: 'mapbox://styles/mapbox/dark-v9',
      boxHeight: 20,
      light: {
        main: {
          intensity: 1,
          shadow: true,
          shadowQuality: 'high'
        },
        ambient: {
          intensity: 0.2
        }
      }
    }

2、可视化工具:echarts-Gl options的series进行图表设置,通过getModel().getComponent('mapbox3D').getMapbox()获取map对象

series: {
      name: '常驻人口',
      type: 'bar3D',
      shading: 'realistic',
      coordinateSystem: 'mapbox',
      silent: true,
      barSize: 1, // 柱子粗细
      bevelSize: 0.3,
      emphasis: {
        label: {
          show: false
        }
      },
      label: {
        show: true,
        distance: 0,
        formatter: '{b}',
        textStyle: {
          fontSize: 12
        }
      },
      data: []
    }

3、动作及拓展:mapbox通过map API的on属性和mapboxgl进行地图的操作,如修改地图样式、加载图层、添加导航工具等用户交互动作
如:添加导航操作:

    this.nav = new mapboxgl.NavigationControl()
    map.addControl(this.nav)

添加Geojson图层

 map.addSource('states', {
        'type': 'geojson',
        'data': gdData
      })
    map.addLayer({
        'id': 'state-fills',
        'type': 'fill',
        'source': 'states',
        'layout': {},
        'paint': {
          'fill-color': '#627BC1',
          'fill-opacity': 0.1
        }
    })

思路汇总:通过上面三步走的思路,我们可以把组件粗略分成三部分

核心的mapbox.vue是地图视图
可视化图表由echarts-gl组成
动作及拓展对地图视图和图表进行操作

clipboard.png

效果图:

clipboard.png

clipboard.png

待续,文章持续更新修改......


上一篇文章: vue 地图可视化(1) 百度地图篇

完整项目github地址:https://github.com/hty7/vue-d...

有不懂的地方,可以在下方留言,或者私聊。对文章感兴趣的话,点下赞、收藏和github收集小星星,谢谢大家。

查看原文

YJohn 提出了问题 · 2018-12-19

如何让父节点绑定onmousedown不影响子孙节点的拖拉事件

现在有这样的需求,如下图蓝色框弹窗通过vue自定义指令绑定了onmousedown(pc)/ontouchstart(移动)事件,实现自由拖拉。

问题:

其子孙节点中又有一个滑块模块,可以拖拉,然鹅前面父节点的onmousedown-onmousemove方法的影响,导致下图红色框内滑块无法拖拉

图片描述

<div class="dialog-box" v-selfDrag="'v-slider__thumb-label primary'">
</div>

drag.js

bind (el, binding, vnode) {
    el.onmousedown = (ev) => {
      if (!ev.target.className || ev.target.className === binding.value) return
      let disX = ev.clientX - el.offsetLeft
      let disY = ev.clientY - el.offsetTop
      document.onmousemove = (ev) => {
        let l = ev.clientX - disX
        let t = ev.clientY - disY
        el.style.left = l + 'px'
        el.style.top = t + 'px'
      }
      document.onmouseup = () => {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
}


勉强的解决方法(前面代码):
(1)提前确定不需要拖拉的节点className;
(2)鼠标绑定onmousedown的节点,绑定其target.className是否为className

这是方法非常愚蠢,有咩更高效的方法?

关注 3 回答 2

YJohn 发布了文章 · 2018-10-31

vue地图可视化 ArcGIS篇(3)

ArcGIS for javascript开发心得

本次实例中采用ArcGIS for javascript3.24版本,由于版本3与4在API等存在较大区别,就不一一列举,详细区别看官方解释
arcgis for js4.7版本能够自动创建layer、graphs等类,而不像3.24版本需要在图形渲染前重新new 新的类。然而,查找大量文件资料,网上有关ArcGIS forjavascript的资料甚少,更不用说通过vueJS+arcGIS开发出一套可视化平台,在不断查看官方文档和实际操作,总结自己的构思和使用心得。

技术采用:vueJS + vuetify + axios + arcGIS3.24 + echarts

clipboard.png

如图所示:可视化界面采用三层三文治结构,从server(后台,非online server)读取数据,vueJS负责数据驱动,ArcGIS与echarts负责数据的图形化。同时引入浏览器的web sql db本地数据库进行海量数据缓存

ArcGIS API for Javascript 是由美国 Esri 公司推出, 基于 dojo框架和 REST 格式的一套编程接口(目前最新版本为 3.3, dojo1.8。 通过 ArcGIS API for Javascript可以对 ArcGIS for Server 进行访问调用,并将 ArcGIS for Server 提供的地图资源和其它资源online加载到Web应用中。

基础知识

Dojo

Dojo 是一个强大的面向对象 Javascript 框架。主要由三大模块组成: Core、 Dijit、 DojoX。 其中 Core提供 Ajax、 events、 packaging、 CSS-based querying、 animations、 JSON 等相关操作 API。 Dijit 是一个可更换皮肤,基于模板的 WEB UI 控件库。 DojoX 包括一些创新/新颖的代码和控件: DateGrid、 charts、离线应用、 跨浏览器矢量绘图等。
Dojo 的特点可从下面几部分诪起:
1、 Dojo 是一个纯 Javascript 库,后台只要提供相应的接口就能够将数据以 Json 的格式输出给前台。
2、 Dojo 自身定了完整的函数库,屏蔽了浏览器的差异。
3、 Dojo 自身定了界面组件库,其组件代码采用了面向对象的思想,便于继承及扩展。
4、 对前端界面联动需求较为复杂的时候,基于 dojo 的页面组件将是首选,因为其可以将界面中
某一个具有共性的区域抽象出来,封装返这一区域的界面行为以及数据,采用模块式的方式完成复杂页面的开发。

热力图

一、实现地图热力图操作
热力图,是以特殊高亮的形式显示访客热衷的页面区域或访客所在的地理区域的图示。常用的热力图统计分成样方计数法(Quadrate Analysis)和核密度法(Kernel Density Estimation)。
核密度法基于密度的点模式分析方法,因此事件之间的相对位置和距离具有决定作用

clipboard.png

样方计数法其事件之间的绝对位置具有决定作用,单位面积的事件、数量在空间上具有比较明确的变化。如:空间对象的平均值/密度。

clipboard.png

例子里,我们采用第二种分析方法来展示区域性的人口密度
然而多次尝试发现,官方给出的热力图基于heatMap并不能满足我们的需求,而且online service的解决方案不符合要求
最后,我们通过esri提供FeatureLayer类创建图层,以坐标绘制图形,权重区分色值来还原热力图

ArcGIS for javascript

效果图

图片描述

clipboard.png

涉及到arcgis 基础地图、geometry、FeatureLayer、graphic等API的使用

模块引入

vue引入arcgis for js模块
Install

npm install --save esri-loader

or

yarn add esri-loader

在文件中引入ersi

import * as esriLoader from 'esri-loader'

加载样式 在加载地图前,需要先加载对应版本的样式表
@import url('https://js.arcgis.com/3.24/es...');
or
esriLoader.loadCss('https://js.arcgis.com/3.24/es...')


到这里我们解决完成vue项目引入arcgis的问题,但在实际开发过程,会发现国内使用arcgis有两个严重不足的问题:
第一个是底图地图服务差,加载慢
第二个是arcgis for js的提供的api接口偶尔出现无法加载的问题
因此,在开发阶段,为优化用户体验,通过切换国内地图服务和本地JS-SDK部署解决上述的问题(后面会介绍这两个方案的解决过程)

加载需要的地图模块
1.通过DOJO loader 加载地图api类
2.通过map加载地图(4.7中将地图渲染分成WebMap和MapView/SceneView视图)

const options = {
    url: 'https://js.arcgis.com/3.24/'
}
esriLoader.loadModules([
    'esri/map',
     'dojo/domReady!'
], options).then(([Map]) => {
    let map = new Map('YouMapDOM', {
        basemap: 'topo',
        center: [113.3209952545166, 23.090055306224895],
        zoom: 15
    })
}).catch (err => {})

到这里我们已经成功加载arcgis地图

map

map:底图,负责底图渲染
Map类创建地图容器和所需的DOM结构,用于添加图层、图形、信息窗口和其他的导航控件

创建地图是arcgis最基本的操作,在3.x中通过map创建地图

new Map(YouMapDOM, option)

地图打点操作,绘制图形范围等覆盖物是地图可视化的基本操作
clipboard.png

属性
map属性是可以自定义配置,如backgroundColor、height、width等

方法
map层作为arcgis最重要的元素,继承了众多的方法,例如
addLayer 地图添加Esri图层
centerAndZoom(mapPoint,levelOrFactor) 居中并缩放地图
destroy() 销毁地图实例
...

map.setBasemap(url)

clipboard.png

事件
我们不单止通过map的方法进行必要层与层间操作,同时也可以在map上绑定事件,官方解释如下

All On Style event listeners receive a single event object.
Additionally, the event object also contains a 'target' property whose
value is the object which fired the event.

常用的如
basemap-change
click
dbl-click
key-down / key-up
load
mouse-down/drag/move
zoom
...
通过监听不同类型的鼠标键盘等事件来触发我们所需的操作,例如通过map绑定click事件,只要我们点击地图,如提示、地点、graphic层等等,都能触发。

map.on('click', (event) => {
    if (event.graphic.symbol && event.graphic.symbol.type === 'simplefillsymbol') {}
    if (event.graphic.symbol && event.graphic.symbol.type === 'textsymbol') {}
    if (event.graphic.symbol && event.graphic.symbol.type === 'simplemarkersymbol') {}
}

ersi官网提供多种默认底图地图样式(如下图),然而引入官方地图国内存在较为严重的稳定性问题,因此后期可以将地图换成国内通用地图,如天地图等

注意:转换地图服务可能存在一定的偏差,具体参考问题3

clipboard.png

this.map.setBasemap(baseMap)

  {
    name: '中国灰色版',
    url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer'
  },
  {
    name: '中国午夜版',
    url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer'
  },
  {
    name: '中国彩色版',
    url: 'https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer'
  },
  {
    name: '中国彩色POI版',
    url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer'
    }
 

clipboard.png

FeatureLayer

FeatureLayer:图形图层,可用于地图服务或地图要素服务中显示单个图层要素。也通过isEditable=true编辑图层要素
FeatureLayer默认从ArcGIS Server中获取图层信息进行渲染,然鹅全文的例子不采用服务器渲染的模式,而是直接本地数据渲染图层
热力图的渲染及操作

      let featureLayers = new FeatureLayer(featureCollection, {
        id: 'flickrLayer',
        outFields: ['*'],
        opacity: 0.5,
        showLabels: true
      })
      map.on('layers-add-result', (results) => {
        loading.close()
        let features = []
        res.forEach(function (item, i) {
          let arrt = {
            title: item.cellId,
            flowCount: item.flowCount,
            groupCount: item.groupCount,
            cellId: item.cellId,
            cityId: item.cityId,
            distId: item.distId
          }
          let geometry = new Polygon(item.rings)
          let graphic = new Graphic(geometry)
          graphic.setAttributes(arrt)
          features.push(graphic)
        })
        featureLayers.applyEdits(features, null, null)
      })
      map.addLayers([featureLayers])

通过featureLayers.applyEdits()类添加网格图层
featureLayer.on()绑定的事件,如click、dbl-click、graphic-add等事件类型进行图层交互,如对图层进行高亮、弹窗

featureLayers.on('click', (event) => {})

graphic

graphic图形绘制

let geometry = new Polygon(rings)
let newGraphic = new Graphic(geometry)
map.graphics.add(newGraphic)

地图上有多样的覆盖物可以采用graphic绘制图形,如高亮网格Polygon、圆形范围Circle、打点point、标志物createSymbol等

let gl = new GraphicsLayer({ id: 'circles2' })
map.addLayer(gl)
let symbol = new SimpleFillSymbol().setColor().outline.setColor([0, 142, 255])
centerPoints.forEach(e => {
   let circleGeometry = new Circle({
       center: e,
       radius: radius,
       geodesic: true
   })
   let circleGraphics = new Graphic(circleGeometry, symbol)
   gl.add(circleGraphics)
})

持续修改更新...

问题

1、4.7中WebMap、MapView的区别
4.0版本由于加入3D元素,Map和Layers不再处理图形的绘制,而是交给Views完成
View视图是4.0版本提出的概念,包括MapView(2D)和SceneView(3D)两个类
在4.X中底图和底图操作层分离的
2、离线部署
(1)国内地图服务
(2)JS-SDK本地部署
考虑到国内的用户会出现地图访问慢甚至无法正常加载的问题,因此ArcGIS for js 的离线部署是非常有必要的
1、注册arcgis开发者账号
2、进入官方api-sdk下载界面选择你需要的版本
https://developers.arcgis.com...

clipboard.png
稍等片刻后
3、需要准备一台可以正常访问的服务器(以Linux-tomcat arcgis_js_api3.2.4为例)
将下载的arcgis_js_api文件复制到tomcat的/usr/local/example/webapps目录下
修改arcgis_js_api/library/3.24/3.24/init.js文件中[HOSTNAME_AND_PATH_TO_JSAPI]为<myserver>/arcgis_js_api/library/3.24/3.24/
修改arcgis_js_api/library/3.24/3.24/dojo/dojo.js 文件中[HOSTNAME_AND_PATH_TO_JSAPI]为<myserver>/arcgis_js_api/library/3.24/3.24/
4、完成上面修改即可正常访问自己服务器上的SDK接口

3、坐标偏差
我们常用的坐标有三种,分别是国际坐标系、火星坐标系、百度坐标系
地球坐标系——WGS84:GCS_WGS_1984,常见于 GPS 设备,Google地图、arcGIS地图等国际标准的坐标体系。
火星坐标系——GCJ-02:中国国内使用的被强制加密后的坐标体系,高德坐标采用这种坐标体系。
百度坐标系——BD-09:百度地图所使用的坐标体系,是在火星坐标系的基础上又进行了一次加密处理。

clipboard.png

坐标偏差依赖于地图底图服务,上面将默认的英文地图转化成国内常用的天地图(默认火星坐标),这里就产生问题。
1、不建议底图选择中存在两种不同坐标体系,如下图坐标存在明显的偏差,火星坐标在采用WGS84坐标系的地图上位置偏上
彩色中国天地图
clipboard.png

全球卫星地图
clipboard.png

2、例如我们使用arcGIS的search类进行查找,返回的数据都是国际坐标,因此必须进行偏差纠正。
我们可以使用高德地图提供的坐标变换AMap.convertFrom()进行坐标转换

AMap.convertFrom(lnglat, type, function (status, result) {
    if (result.info === 'ok') {
        var resLnglat = result.locations[0];
        m = new AMap.Marker({
            position: resLnglat,
        });
        map.add(m);
     }
});

或者也可以自定义转换方法
https://blog.csdn.net/Admin_y...(网上随便搜的参考)

备注:本文中提到的总结可能存在不足和错误,多多包容

查看原文

赞 18 收藏 12 评论 10

YJohn 评论了文章 · 2018-09-14

vue-threeJS数据驱动的三维图形可视化

数据驱动的三维图形可视化

在信息暴涨的2010-2016年间,冷暴力的扁平化确实有效降低用户的信息焦虑感,使有限的精力更高效处理过多的信息流。二维平面化扁平化在苹果等大头引领下,成为大众用户机器交流默认的语言。
然后,随着PC、平板、手机、智能家居等用户持有终端的性能不断提升,大数据末尾差异化处理,用户不再承担过多的信息而带来的压迫感,,用户必然不满足现有界面的设计及交互,因此,多维化虚拟化的用户体验必将得到更多用户的认可。


数据驱动的三维图形可视化涉及三方面得内容,分别是

  • vue数据驱动
  • threeJS对webGL的封装三维可视化
  • 信息处理

文章主要讲解第2、3点,使用vue进行threeJS常用功能的封装组件化和对用户输入源(鼠标、键盘、触摸、摄像头、麦克风等)的信息转化。

threeJS组件化

vue项目中threeJS的简单使用

module bundler模式安装

npm install --save three
npm install --save tween

下面简单写了一个例子,通过创建场景,添加物体及摄像头就可以生成模型

<template>
  <div ref="demo1"></div>
</template>

<script>
import * as THREE from 'three'
import dat from 'dat.gui'
export default {
  data: () => ({
    controls: {
      scene: null,
      camera: null,
      renderer: null,
      rotationSpeed: 0.02
    }
  }),
  created () {
    this.$nextTick(() => {
      this.init()
    })
  },
  methods: {
    init () {
      let {initMesh, controls} = this
      const gui = new dat.GUI() // gui监测器
      gui.add(controls, 'rotationSpeed', 0, 0.5)
      initMesh()
    },
    initMesh () {
      this.scene = new THREE.Scene() // 场景
      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000) // 相机.视场,长宽比,近面,远面
      this.camera.position.x = -20
      this.camera.position.y = 40
      this.camera.position.z = 30
      this.camera.lookAt(this.scene.position)

      this.renderer = new THREE.WebGLRenderer({ antialias: true })// 渲染器
      this.renderer.setSize(window.innerWidth, window.innerHeight - 100)
      this.renderer.shadowMapEnabled = true // 开启阴影

      let axes = new THREE.AxisHelper(20) // 坐标轴

      let planeGeometry = new THREE.PlaneGeometry(60, 20, 10, 10) // 生成平面
      let planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff}) // 材质
      let plane = new THREE.Mesh(planeGeometry, planeMaterial)
      plane.rotation.x = -0.5 * Math.PI
      plane.position.x = 0
      plane.position.y = 0
      plane.position.z = 0
      plane.receiveShadow = true

      let cubeGeometry = new THREE.CubeGeometry(10, 10, 10)
      let cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000})
      this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
      this.cube.position.x = -4
      this.cube.position.y = 3
      this.cube.position.z = 0
      this.cube.castShadow = true

      let spotLight = new THREE.SpotLight(0xffffff)
      spotLight.position.set(-40, 60, -10)
      spotLight.castShadow = true

      this.scene.add(axes) // 场景添加坐标轴
      this.scene.add(plane) // 向该场景中添加物体
      this.scene.add(this.cube)
      this.scene.add(spotLight)

      this.$refs.demo1.append(this.renderer.domElement)
      this.renderScene()
    },
    renderScene () {
      let {controls, cube, scene, camera, renderer} = this
      cube.rotation.x += controls.rotationSpeed
      cube.rotation.y += controls.rotationSpeed
      cube.rotation.z += controls.rotationSpeed
      requestAnimationFrame(this.renderScene)
      renderer.render(scene, camera)
    }
  }
}
</script>

效果图:
图片描述

然而我们的目标是建立可复用的图形组件,并具有灵活的数据输入及高效的图形输出
图片描述

threeJS基础

在进行进一步的three组装前,我们必须掌握threeJS的基本知识及原理
传统三维图像制作中,开发人员需要使用OpenGL(Open Graphics Library)图形程序接口进行开发,从而在 PC、工作站、超级计算机等硬件设备上实现高性能、极具冲击力的高视觉表现力图形处理软件的开发。openGL并不适合直接在浏览器端运行,因此在OpenGL基础上,webGL通过统一的、标准的、跨平台的OpenGL接口,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,webGL可以为HTML5 Canvas提供硬件三维加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示三维场景和模型了,还能创建复杂的导航和数据视觉化。

threeJS是一个webgl为基础的库,对webGL的3D渲染工具方法与渲染循环封装的js库,省去与繁琐底层接口的交互,通过threeJS就可以快速生成三维模型
图片描述

在threeJS中,作者是这样说的:

  • To actually be able to display anything with three.js, we need three
    things: scene, camera and renderer, so that we can render the scene
    with camera.

因此,要创建模型,我们需要场景(scene)、相机(camera)和渲染器(renderer)三样东西,他们是图形渲染得重要部分


场景
场景作为实体代入必要的背景,它是承载所有模型的容器,它允许渲染模型和位置

new THREE.Scene()


相机
作为场景中人眼的角色,决定场景中模型的远近、高度角度等参数

threeJS提供正投影相机、透视相机、立体相机等多种相机模式,现实常用的为前两种
正投影相机(OrthographicCamera)

new THREE.OrthographicCamera( left, right, top, bottom, near, far )

分别设置相机的左边界,右边界,上边界,下边界,远面,近面
左/右边界:左右边界渲染范围,超出部分不做渲染处理
上/下边界:上下边界渲染范围,超出部分不做渲染处理
近面:基于相机所在位置开始渲染
远面:基于相机位置,一直渲染场景到远面,后面的部分不做渲染处理

图片描述


透视相机(PerspectiveCamera)

new THREE.PerspectiveCamera( fov, aspect, near, far )

分别设置相机的视场角度,长宽比,近面,远面
视场:从相机位置看到的部分场景,就如人类有180度视场,某些昆虫却拥有360度视场。
长宽比:水平视场和垂直视场之间的比例
近面:从距离相机多远的距离开始渲染场景(近面越小,离相机越近)
远面:相机可以看到最远的距离(过低只看到部分场景,过高则影响模型渲染)

图片描述


渲染器
渲染器决定了渲染的结果应该画在页面的什么元素上面,并且以怎样的方式来绘制

物体
相机的主要渲染对象,threeJS自带的最基本的物体有球体,平面,坐标轴,方块等

renderer.render(scene, camera)

待续...

查看原文

YJohn 收藏了文章 · 2018-09-03

2018前端面试准备

前端面试常见问题按知识点分类整理

前端面试常考问题整理,按模块知识点分类,持续完善中... Front-end-Developer-Questions by Modules and knowledge

前端面试经典问题:CSS 中居中的几种方式

面试中经常遇到的面试题之一,居中布局,特来总结

几个让我印象深刻的面试题 (一)

分享几个我遇到的认为不错的面试题

27款优质简洁的个人简历打包下载

优质简洁的个人简历打包

前端开发面试题总结之——JAVASCRIPT(一)

前端面试系列之 JavaScript,还有两篇

44 个 JavaScript 变态题解析

读者可以先去做一下感受感受. 当初笔者的成绩是 21/44...

当初笔者做这套题的时候不仅怀疑智商, 连人生都开始怀疑了....

不过, 对于基础知识的理解是深入编程的前提. 让我们一起来看看这些变态题到底变态不变态吧!

技术 | 前端面试题(二):自定义事件

我和阿里巴巴的同事守雌将为大家带来一个系列专题:前端面试题解析,一周更新两篇,本篇主要讲如何实现自定义事件。

前端开发面试题总结之——JAVASCRIPT(二)

前端开发面试题总结之—JavaScript,一共三篇

前端开发面试题总结之——HTML

前端开发面试题,本文主要讲述的是 HTML 相关的面试题。面试相关的我整理成收藏集欢迎关注。

收集 JavaScript 各种疑难杂症的问题集锦

关于 JavaScript,工作和学习过程中遇到过许多问题,也解答过许多别人的问题。这篇文章记录了一些有价值的问题。

一道 JS 面试题所引发的 "血案",透过现象寻本质,再从本质看现象

由一道面试题想到拓展的,分析问题的方法

CSS 面试题解答

什么是 CSS reset?CSS 性能优化?浮动的原理和工作方式,会产生什么影响呢,要怎么处理?CSS 权重?

Excuse me?这个前端面试在搞事!

金三银四搞事季,前端这个近年的热门领域,搞事气氛特别强烈,我朋友小伟最近就在疯狂面试,遇到了许多有趣的面试官,有趣的面试题,我来帮这个搞事 boy 转述一下。

前端开发面试题总结之——JAVASCRIPT(三)

前端开发面试题总结之 JavaScript,一共三篇

1月前端面试记

背景 我于16.12.18辞职,之前有过一年左右的前端工作经验。从12月26号开始到1月9号先后面试了微信,百度,阿里巴巴uc,唯品会以及深圳腾讯等几家公司,特此总结与各位共勉。 微信 由于我已经毕业工作过,所以去微信面试是走的社招。微信社招极其严格,共八轮面试,总体来说我基本…

一道面试题引发的对 javascript 类型转换的思考

通过一道面试题,详细描述了 javascript 类型转换的相关内容,对 javascript 进阶有所帮助。

献给前端求职路上的你们(上)

我是一名前端开发,从2016年6月毕业到如今步入工作,期间也面试了一些公司,参考过一些面试文档,学习了一些面试宝典,掌握了一些面试、笔试技巧和经验,所以就总结了一些优质的前端面试题以及面试要点,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习,透彻学习,才能形成自己的知识链,以不变应万变,万不可投机取巧,只求面试过关哦!

征服 JavaScript 面试:什么是闭包

征服 JavaScript 面试:什么是闭包

一个普通本科在校生的前端学习之路

今天我分享的内容主要是关于前端初学者的学习路线和一些建议,还有自己在准备校招过程中的一点经验。

CSS 并不简单 -- 一道微信面试题的实践

本系列会持续分享本人学习到的 CSS 知识点、技巧和效果展示。如有错误,希望您能指出。

从培训班出来之后找工作的经历,教会了我这五件事

这是 Medium 上的一篇文章(已有 5900 个赞),讲的是国外一个培训出来的程序员,用三个月时间,找到了一份年薪 12 万美元的工作,并从中得到的五个忠告的故事。 我觉得他总结得很好,尤其是心态和方法,非常值得学习。对正在找工作的同学非常有用。 想收到更多最新、最专业的前…

最近遇到的前端面试题 (2017.02.23 更新版)

最近整理的前端面试题,希望能对大家有帮助。转载自:http://www.jianshu.com/p/3944...

17 年 2 月面试经验 | _striveg blog

个人面试几家的面试题和一点小感悟

面试 -- 网络 HTTP

现在面试门槛越来越高,很多开发者对于网络知识这块了解的不是很多,遇到这些面试题会手足无措。本篇文章知识主要集中在 HTTP 这块。文中知识来自 《图解 HTTP》与维基百科,若有错误请大家指出。文章会持续更新。 面试 -- 网络 TCP/IP 了解 Web 及网络基础 对端传输…

从一道面试题,到 “我可能看了假源码”

今天想谈谈一道前端面试题

技术 | 前端面试题(一):递归解析

我和阿里巴巴的同事守雌将为大家带来一个系列专题:前端面试题解析,一周更新两篇,也许答案可能不是最优的,但是也可以给你提供解决问题的思路。

谈谈面试与面试题

Winter 对于前端面试的一些看法。

查看原文

认证与成就

  • 获得 101 次点赞
  • 获得 5 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2018-04-08
个人主页被 1.8k 人浏览