AMap + echarts、google map + d3.js分别实现数据可视化中的飞线图(迁徙图)

2023-11-07

首先肯定是给出demo啦:
演示demo

直接到左侧选择框中选择View taxi flow里面随便选个日期

总体介绍

最近由于工作室项目需要做一个数据可视化平台,这个平台最终是交由国外人使用的。而国内的高德地图在国外是访问很慢,所以只能使用Google map进行实现(尝试过用AMap去实现,后面改回来)
回归主题:今天要讲的是迁徙图分别用两个平台进行实现

  • AMap + eCharts.js 实现迁徙图
  • Google map + D3.js 实现迁徙图

首先先来谈一下为什么都是在map上面进行数据可视化,但是实现迁徙图的技术不同(一个用eCharts、一个用d3)?!先来讲一下高德地图(AMap)和谷歌地图实现的技术区别吧(Google map)。
在这里插入图片描述
上面是高德地图,高德地图的实现是基于canvas进行实现的,显示效果都在这个画板上显示。接下来我们看一下谷歌地图是怎么实现的?
在这里插入图片描述

可以发现谷歌地图是由一张张图片拼接而成的,两者之间谁优谁劣不说,但是实现方式不同。正由于二者实现方式不同,所以飞线图实现方式也会有不同。

在github上面仅有开发echarts-amap中间插件(当然还有百度地图的echarts-bmap),并没有一个项目作为echarts和google map的中间件。这个项目给我的时间仅仅只有5天,所以不可能也没有能力去写这个插件。所以只能另外找资料实现google map + d3.js 飞线。


一、用echarts + amap 实现飞线,首先看一下效果图

在这里插入图片描述
这里有1000+条飞线数据,这是我随机找广州景区互相生成的假数据。因为既然今天讲到了两种技术实现飞线,那么顺带展示一下两个技术的性能区别,以1000条为例子。这个是怎么实现的呢?!我大概分成以下几步来进行分析:

  • 引入echarts-amap插件,如果是非vue框架的,去找一下echarts-amap插件(我没有用,所以无法提供)。如果是vue框架的话,npm i echarts-amap --save-dev进行安装,然后在项目中require(‘eharts-amap’)就行了。
  • 找到飞线所需的echarts配置
  • 初始化echarts,然后进行设置series,就和普通的echarts图标的流程一样,以下我给出例子。

下面是整个流程需要的代码,拿走就可以了。

let mychart = this.$echarts.init($('#' + id)[0]), // 初始化echarts到目标块中
	mychart.serOption({
     amap: {
        zoom: 10,
        zooms: [3, 20],
        mapStyle: 'amap://styles/darkblue', //地图主题
        center: [113.25, 23.1], //中心点
        lang: 'en',
        resizeEnable: true
      },
      animation: false,
      series: []
	});
// 以下对象的一个例子
FlyLineOption: {
	name: 'name',
	lineColor: '#fff',
	fromName: 'fromName',
	toName: 'toName',
	fromLngLat: [123, 23],
	toLngLat: [123, 23],
	value: 1,
	symbolColor: '#000'
}

// 以下是echartsoption配置对象
{
      name: FlyLineOption.name,
      coordinateSystem: "amap",
      type: "lines",
      zlevel: 1,
      effect: {
        show: true,
        period: 6,
        trailLength: 0.7,
        color: "#fff",
        symbolSize: 3
      },
      lineStyle: {
        normal: {
          color: FlyLineOption.lineColor,
          width: 0,
          curveness: 0.2
        }
      },
      data: [
        {
          fromName: FlyLineOption.fromName,
          toName: FlyLineOption.toName,
          coords: [FlyLineOption.fromLngLat, FlyLineOption.toLngLat],
          value: FlyLineOption.value
        }
      ]
    },
    {
      name: FlyLineOption.name,
      coordinateSystem: "amap",
      type: "lines",
      zlevel: 2,
      symbol: ["none", "arrow"],
      symbolSize: 10,
      lineStyle: {
        normal: {
          color: FlyLineOption.lineColor,
          width: 1,
          opacity: 0.6,
          curveness: 0.2
        }
      },
      data: [
        {
          fromName: FlyLineOption.fromName,
          toName: FlyLineOption.toName,
          coords: [FlyLineOption.fromLngLat, FlyLineOption.toLngLat],
          value: FlyLineOption.value
        }
      ]
    },
    {
      name: FlyLineOption.name,
      type: "effectScatter",
      coordinateSystem: "amap",
      zlevel: 2,
      rippleEffect: {
        brushType: "stroke"
      },
      label: {
        normal: {
          show: true,
          position: "bottom",
          formatter: "{b}"
        }
      },
      itemStyle: {
        normal: {
          color: FlyLineOption.symbolColor
        }
      },
      data: [
        {
          name: FlyLineOption.toName,
          value: [...FlyLineOption.toLngLat, FlyLineOption.value]
        }
      ]
    }

这样即可绘制飞线图。echarts这个插件其实蛮好用的,很多图都有,也比较齐全。它里面的飞线是二次贝塞尔曲线,会自动帮你绘制这条贝塞尔曲线。
但是换成google map并不会像国内的地图有这么好的生态了。可能国外会有一些插件去支持它,但是目前来看我是找不到。那么我是怎么去实现的呢?

二、Google map + D3.js 实现飞线

先讲一下总体的思路:

  1. 添加谷歌地图图层,进行绘制svg标签
  2. 利用d3在谷歌地图图层进行绘制svg图
  3. 首先将gps化为谷歌坐标,求出两点之间的贝塞尔曲线(需要自己寻找控制点),并且绘制出来(利用path标签自带的贝塞尔曲线绘制方法)

Google map 初始化

首先,你要有一个Google map 的ID,这个百度查询如何使用,然后最好是引用国内镜像,毕竟VPN来直接访问还是有点慢。

<script src="http://ditu.google.cn/maps/api/js?&key=&language=en"></script>

接来下进行地图的初始化,同样上代码

let map = new google.maps.Map(document.getElementById(this.id), {
    zoom: 8,
    center: {
    lat: 23.1,
    lng: 113.25
  },
  disableDefaultUI: true,               //取消默认的试图
  navigationControl: false,              //true表示显示控件
  mapTypeControl: false,                //false表示不显示控件
  scaleControl: false
 });

Google map 渲染技术简单介绍

初始化完毕后,我先给大家简单介绍一下google map api提供地图的技术吧。

  1. google map如何渲染?
    google map分成20左右的zoom层数,即放大层数,每个层数都有固定的地图的图片,将这些地图的图片进行拼装,就会出现整个世界地图的模型。
    在这里插入图片描述
    还是老样子直接上图,在进行渲染、拖拽、缩放的时候,系统会识别当前显示的区域,进行请求显示区域所需要的图片,请求完毕后进行渲染。
  2. 如何在google map 上添加自定义的图层呢?
    在以canvas为基础的地图中,我们可以用两个canvas重叠后来进行渲染,即地图canvas在下面,echarts的canvas在上面,从而实现飞线效果。
    但是google map并不行,它不是这种技术实现,但是它也可以进行添加自定义图层,创建一个对象,new google.maps.OverlayView();这个对象返回一个创建的图层。它有add、draw两个属性比较重要,在本项目中会用到。
    特别地,在google map上绘画东西是需要坐标的,即横坐标和纵坐标进行绘制。这个正是google map渲染时候的技术决定的(很多图片组成,图片间是紧挨着的,这个是通过创建元素构成的。也就是需要有一个特别大的容器装下这些图片。绘制的时候只能用坐标来进行绘制)。

Google map 图层的建立

那么下面就来给大家手把手教大家如何建立图层。google map官网有一个例子进行比较正规方法的,它是通过新建一个OverlayView对象实例,对实例对象的原型进行修改add、draw方法,然后以这个实例对象为原型,进行原型链继承。那个方法太麻烦了,我这边就直接来个简单的。

let overlay = new google.maps.OverlayView();
overlay.onAdd = () => {
	// 这个函数式图层加载完毕后就执行一遍时候的事件监听函数(可以这么理解)
}
overlay.draw = () => {
	// 这个是地图每一次绘画完毕后进行的事件监听执行函数(绘画地图包括左右移动和缩放)
}

现在大家已经会进行图层的建立了,那么如何在图层上进行绘制呢?首先要得到绘制的坐标。google map有一个方法将经纬度转为地图做标。

let project = overlay.getProjection();
let latLng = new google.maps.LatLng(23, 123)
let axios = projection.fromLatLngToDivPixel(latLng);
axios.x, axios.y //这两个属性就是x值和y值

上面得到的坐标是全局绝对坐标,可能会很大。但是有显示的图层只有在屏幕范围内,所以要进行坐标的转换。如何理解呢,我画了以下的图。
在这里插入图片描述
我们需要将目标点坐标减去视图层的左上角的坐标,就能得到相对坐标了。

前面的代码已经将想要描述的点通过经纬度转为坐标了,那么现在就要进行绘制了,首先要获取overlay定义的图层,这个图层在overlay添加完毕后可以使用,代码如下:

overlay.onAdd = () => {
	let layer = overlay.getPanes().overlayLayer;  // 获取绘制容器
	// 然后通过appendChild进行绘制,使用绝对定位,设置left和right进行绘制,这样就可以了。
	// 这个是涉及到d3的一些操作,可以去了解以下d3的操作。
	
	// 下面是我的一些代码,可以拿去当做参考
	let layer = d3.select(overlay.getPanes().overlayLayer).append('svg')
	              .attr('class', 'fly-layer');  // 创建svg标签
	
	 let defs = layer.append('defs');	// 添加defs属性列表
	 defs.append('marker')				// 添加marker标签(svg标签的)这个是添加箭头的样式,因为svg标签只需要一个,所以在创建svg标签的时候就创建了
	   .attr('id', 'markerArrow')
	   .attr('markerWidth', '13')
	   .attr('markerHeight', '13')
	   .attr('refX', '2')
	   .attr('refY', '6')
	   .attr('orient', 'auto')
	   .append('path')
	   .attr('d', 'M2,2 L2,11 L10,6 L2,2')
	   .attr('fill', '#FF0000');

		// 下面是对data进行批量添加数据,此时并没有绘制path路径,而是添加flyLine类名而已,这个是方便后面进行获取容器
	   layer.selectAll('.flyLine').data(data, (d) => d.id).enter().append('path').attr('class', 'flyLines')
	   let projection = overlay.getProjection();
}

d3可以去它的官网查看文档怎么使用
https://d3js.org/
但是,你想看懂d3的操作,首先要知道svg矢量图是什么,怎么用的。我曾经做过一个用svg矢量图实现的流动效果的网页作为我们团队的招新网:
http://47.102.136.151:4000/dist/index.html
如果弄懂了里面svg图的变化,基本上是可以上手任何svg矢量图了。
把话题拉回来了,上面是获取绘制图层块并且在里面进行添加svg标签,并且添加一个通用的箭头效果。那么接下来来谈谈这个overlay图层怎么添加draw方法。

// draw方法是地图在缩放或者鼠标拖动的时候会触发的事件,所以在短时间会触发很多次,这个要注意到
overlay.draw = () => {
	let bounds = this.map.getBounds();
    let ne = bounds.getNorthEast(),  // 获取当前显示区域右上角的对象(可通过访问获取右上角坐标)
         sw = bounds.getSouthWest(),	// 获取当前显示区域左下角的对象
         center = bounds.getCenter();		// 获取中心点坐标
    layer.selectAll('.flyLines')
              .data(data)   // 进行更新数据
              .each(transform)  // 对每个数据渲染的对象进行修改,将transform的返回值作为这个each的参数
     // 这里为了方便我把下面两个函数就直接贴在这里
     // 这个函数计算出两个坐标点贝塞尔曲线控制点相对于两个坐标点中点的位置,isContract是为了让绘制结果更好看
     function getCosFromTan(d1, d2, isContract) {
          let value, rad;
          if (d2.x == d1.x) {
            value = 0;
            rad = Math.PI / 2;
          } else {
            value = (d2.y - d1.y) / (d2.x - d1.x),
            rad = Math.atan(Math.abs(value));
          }
          
          let length = Math.pow(Math.pow(d2.y - d1.y, 2) + Math.pow(d2.x - d1.x, 2), 1 / 2),
              paramX, paramY;

          if (value < 0) {
            paramX = 1;
            paramY = 1;
          } else {
            paramX = 1;
            paramY = -1;
          }

          return isContract ? {
            x: paramX * length * Math.sin(rad),
            y: paramY * length * Math.cos(rad)
          } : {
            x: -(paramX * length * Math.sin(rad)),
            y: -(paramY * length * Math.cos(rad))
          }
        }

        function transform(flyObj) {
          // 将原生的gps坐标改为谷歌地图坐标
          let fromLngLat = new google.maps.LatLng(flyObj.fromLnglat[1], flyObj.fromLnglat[0]);
          let toLngLat = new google.maps.LatLng(flyObj.toLnglat[1], flyObj.toLnglat[0]);
          // 将右上角的坐标转为谷歌地图坐标
          let neLngLat = new google.maps.LatLng(ne.lat(), ne.lng())
          // 将左下角的坐标转为谷歌地图坐标
          let swLngLat = new google.maps.LatLng(sw.lat(), sw.lng())
          // 将gps坐标转为平面直角坐标系的坐标
          fromLngLat = projection.fromLatLngToDivPixel(fromLngLat );
          toLngLat = projection.fromLatLngToDivPixel(toLngLat);
          let bashX = projection.fromLatLngToDivPixel(neLngLat).x;  // 获取可视区域左边的坐标
          let bashY = projection.fromLatLngToDivPixel(swLngLat).y	// 获取可是区域上边的坐标
          let res = getCosFromTan(fromLngLat, toLngLat , isContract);	// 获取二次贝塞尔曲线的控制点的相对于两点的坐标

          if (isContract == true) {
            isContract = false;
          } else {
            isContract = true;
          }
          randomBash =  (randomBash + 1) % 10;
          // 获取贝塞尔曲线的控制点坐标
          res.x = bashX + res.x * (randomBash / 10) + (toLngLat .x + fromLngLat.x) / 2;  
          res.y = bashY + res.y * (randomBash / 10) + (toLngLat .y + fromLngLat.y) / 2;
          let color = that.getValeColor(flyObj.value, rankUnit)

          return d3.select(this)
          			// 绘制贝塞尔曲线
                  .attr('d', 'M ' + (bashX + fromLngLat.x) + ',' + (bashY + fromLngLat.y) + ' Q ' + res.x + ',' + res.y + ' ' + (bashX + toLngLat .x) + ',' + (bashY + toLngLat .y))
                  .attr('stroke', color)
                  .attr('stroke-width', '1')
                  .attr('fill', 'none')
                  .attr('marker-end', 'url(#markerArrow)');
        }
}

这里留下一个分割线来解释一下那个求控制点方法的函数。。。


  • 首先,先创建当前谷歌地图的layer,这个新建的对象回去监听地图的重绘和图层的添加完毕事件,但是这个事件的回调函数需要我们去定义。
  • 当layer创建完毕的时候,进行初始化svg标签,以后的图都要在这个svg标签上面绘制东西,最好是给这个svg添加一个类,然后将svg调整为宽度是100vw,100vh大小,并且要讲这个svg图完全显示到可视区域上(使用以下css样式)。
// 这个图层是固定在可视区域的(也正是这样,需要在draw方法中每次重新绘制飞线)。并且是从页面的中点开始绘制的,所以需要将其调整一下。
{
  width: 100vw;
  height: 100vh;
  position: absolute;
  top: -50vh;
  left: -50%;
}
  • 在draw回调函数中利用数据添加飞线
  • 为什么top和left要进行设置-50%?这是因为svg的画板的横纵坐标是从可视区域的中点开始画起的。我们要的是可视区域都是svg的画板,所以需要尽心设置偏移。
    明天再回来补充、先睡了

补充,之前还没有讲完,现在进行补充完毕


利用数据进行添加飞线。需要用到d3数据可视化库的一个selectAll选择已经渲染后的节点,并且进行遍历数据进行渲染。我们在draw代码中提取对数据进行更新的代码。

layer.selectAll('.flyLines')
              .data(data)   // 进行遍历数据(数据要以一个数组的形式)
              .each(transform)  // 这个是数据的遍历,这里transform是对每个数据的回调

上面的each的用法类似于JavaScript中对于数组的遍历的用法(针对于被遍历的数组每个数据进行设置针对于google map的操作)。
我先说transfrom的作用:不加这个方法的话,所有的线都是执行,所以没有那种弯曲的感觉,transform的作用就是将线条变成飞线。

接下来我们顺藤摸瓜找到了transform方法,如下代码。

function transform(flyObj) {
              // 将原生的gps坐标改为谷歌地图坐标
              let fromLngLat = new google.maps.LatLng(flyObj.fromLnglat[1], flyObj.fromLnglat[0]);
              let toLngLat = new google.maps.LatLng(flyObj.toLnglat[1], flyObj.toLnglat[0]);
              // 将右上角的坐标转为谷歌地图坐标
              let neLngLat = new google.maps.LatLng(ne.lat(), ne.lng())
              // 将左下角的坐标转为谷歌地图坐标
              let swLngLat = new google.maps.LatLng(sw.lat(), sw.lng())
              // 将gps坐标转为平面直角坐标系的坐标
              fromLngLat = projection.fromLatLngToDivPixel(fromLngLat );
              toLngLat = projection.fromLatLngToDivPixel(toLngLat);
              let bashX = projection.fromLatLngToDivPixel(neLngLat).x;  // 获取可视区域左边的坐标
              let bashY = projection.fromLatLngToDivPixel(swLngLat).y	// 获取可是区域上边的坐标
              let res = getCosFromTan(fromLngLat, toLngLat , isContract);	// 获取二次贝塞尔曲线的控制点的相对于两点的坐标

              if (isContract == true) {
                isContract = false;
              } else {
                isContract = true;
              }
              randomBash =  (randomBash + 1) % 10;
              // 获取贝塞尔曲线的控制点坐标
              res.x = bashX + res.x * (randomBash / 10) + (toLngLat .x + fromLngLat.x) / 2;  
              res.y = bashY + res.y * (randomBash / 10) + (toLngLat .y + fromLngLat.y) / 2;
              let color = that.getValeColor(flyObj.value, rankUnit)

              return d3.select(this)
              // 绘制贝塞尔曲线
                      .attr('d', 'M ' + (bashX + fromLngLat.x) + ',' + (bashY + fromLngLat.y) + ' Q ' + res.x + ',' + res.y + ' ' + (bashX + toLngLat .x) + ',' + (bashY + toLngLat .y))
                      .attr('stroke', color)
                      .attr('stroke-width', '1')
                      .attr('fill', 'none')
                      .attr('marker-end', 'url(#markerArrow)');
            }

首先要明确我们要干什么?

  • 得到可是区域左上角在谷歌的DivPixel坐标作为基础的坐标(相对于谷歌的平面坐标系的坐标)
  • 得到出发点的坐标以及终止点的坐标(仅仅是相对于svg画板的左上角的坐标)
  • 根据出发点和终点求出贝塞尔曲线控制点的坐标(仅仅是相对于svg画板左上角的坐标)
  • 将控制点、起点、终点都加上基础坐标

这样就可以进行确定我们所要显示的坐标在画布上的位置(包括起点、终点、控制点),接下来就可以通过svg矢量图来进行绘制贝塞尔曲线了。接下来我就直接晒出用d3来画的成果吧。我这里就不给出项目地址了。
在这里插入图片描述
这个是显示所有的飞线的效果图。大概就几万条,如果用canvas来进行绘制的话,可能会因为现实内容过多将浏览器卡死。
而用svg矢量图的话,它是作为dom节点会知道html上面的,会比canvas性能好一点。但也不会好到哪里去(因为放大或者缩小、移动地图的时候,svg里面的标签需要重新渲染(因为画布永永远是跟随着用户的,并且只有屏幕大小,只会渲染屏幕现实的内容,所以移动一次交渲染一次))。
如果是dom标签的渲染的话,就回到了我们的舒适圈了。进行优化的话我这里就不列出代码了,提供几个思路。

  1. 减少渲染的次数,比如说按住地图进行拖动的时候,不是一移动屏幕就重新渲染,而是等到用户停止移动的时候才会进行渲染。(默认是只要用户一移动屏幕,就会重新渲染)
  2. 如果听说过线程池的概念的话,就很好理解了。渲染dom节点花费的性能很贵的,那么我们就造一个dom节点池来进行优化。
    最后的最后,我还是人性化一点,贴几张能看的google map + d3的飞线效果图吧。

在这里插入图片描述

最后如果想要我的源码的话,请到

Github: MapDemo

如果觉得可以的话,请点个赞并且Star一下谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AMap + echarts、google map + d3.js分别实现数据可视化中的飞线图(迁徙图) 的相关文章

  • 使用StarRocks导入大数据:详细教程及示例代码

    使用StarRocks导入大数据 详细教程及示例代码 StarRocks是一个快速 可扩展的大数据分析引擎 它提供了高性能的数据导入功能 在本文中 我们将介绍如何使用StarRocks导入大数据 并提供相应的示例代码 步骤1 准备工作 在开

随机推荐

  • 云计算平台常用命令

    云计算IAAS篇 mysql篇 mysql uroot p000000 使用root账号登录mysql use mysql 切换到mysql层 show tables 查询mysql数据库列表 select from mysq
  • linux高性能服务器开发之TCP/IP协议族(1)

    TCP IP协议族体系结构以及主要协议 每层协议完成不一样的功能 上层协议得借助下层协议提供的服务 计网 数据链物层 数据链物层实现网卡接口的网络驱动程序 网络驱动程序隐藏一些 物理层不同电气特性 为上层提供一个统一的接口 常用的协议ARR
  • 【中兴ZXV10 B860A1.1】

    这里写自定义目录标题 开启adb 开启adb 部分盒子的ADB调试位置 在设置页面中可以有开启开发者选项 地区界面不同 位置不同有的在设置里 如果找不到 直接按住遥控器 返回 不放 5秒后 快速不停按 左键 点击 打开ADB调试 这时侯让你
  • 2021-08-04 读书笔记:Python 学习手册(2)

    读书笔记 Python 学习手册 2 结于2021 08 04 OREILY的书籍 可读性很强 入门类 而且这本书很厚 第三部分 语句和语法 第四部分 函数 第三部分 语句和语法 第10章 Python语句简介 Python是面向过程的 基
  • 程序或-内存区域分配(五个段)--终于搞明白了

    一 在学习之前我们先看看ELF文件 ELF分为三种类型 o 可重定位文件 relocalble file 可执行文件以及共享库 shared library 三种格式基本上从结构上是一样的 只是具体到每一个结构不同 下面我们就从整体上看看这
  • DC系列漏洞靶场-渗透测试学习复现(DC-1)

    最近闲着冲浪玩发现了DC系列漏洞靶场 下载了8个靶场 DC 1到DC 8 从信息收集到最后拿到超级管理员权限 可以说几乎贯穿了渗透测试的每一步 寻找一个个flag 通过flag中的指引内容 帮助我们拿到最后的root身份 过程还是挺有趣的
  • Jvm之垃圾回收机制

    判断一个对象是否可被回收 1 引用计数算法 给对象添加一个引用计数器 当对象增加一个引用时计数器加 1 引用失效时计数器减 1 引用计数为 0 的对象可被回收 两个对象出现循环引用的情况下 此时引用计数器永远不为 0 导致无法对它们进行回收
  • vue中使用闭包(例如防抖和节流)失效问题(直接调用)

    文章目录 1 出现问题 2 问题原因 3 解决办法 4 防抖节流函数 1 出现问题 防抖 节流使用无效 例如防抖 按钮点击多次依旧执行多次 gt 查看是闭包无效 定义的局部变量依旧为初值 gt 没有相应清除定时器
  • Ubuntu安装MonoDevelop

    安装步骤 在ubuntu终端执行下面步骤代码 第一步 安装源 根据自己的版本在Ubuntu上安装Mono 运行下面代码授权注册repo源并更新软件列表 Ubuntu 18 04 sudo apt install apt transport
  • Vue3之Vuex

    1 Vuex的基本使用 2 Module 2 1 vuex中模块化的基本使用 2 2 在命名空间中访问全局内容 3 vuex的typescript用法 3 1 不使用模块化 3 2 使用模块化 1 Vuex的基本使用 vuex的安装 npm
  • python利用selenium(webdriver chrome)模拟登陆获取cookie

    我是在windows下进行实验的 准备工作 1 安装python环境 2 python安装selenium插件 执行以下命令就行 pip install selenium 3 Windows下配置webdriver chrome 如果以上准
  • 天气预报小程序 微信小程序期末大作业(含文档)

    天气预报微信小程序 运行正常无错误 下载链接在文末 详情如下图 点我下载资源 https download csdn net download weixin 43474701 58813129
  • golang中的TLS

    HTTP和 HTTPS https和http都属于应用层 基于TCP 以及UDP 协议 但是不同的是 HTTP 缺省工作在TCP协议80端口 HTTPS缺省工作在TCP协议443端口 HTTPS服务不同于HTTP服务 HTTPS是HTTP
  • 数字IC,三大核心代码架构之计数器(verilo实列)

    简介 计数器设计是数字IC设计 的核心 也是最常用的代码片段 通过记录时钟周期个数 可以控制电路的时序 通过计数器可以实现测量 计数 状态控制 分频 计数器有触发器和逻辑门共同构成 计数器设计要素 1 初始值是多少 这里要考虑的是复位信号和
  • Swagger统一Authorization认证

    Swagger统一Authorization认证 1 Swagger Authorization 2 Code 3 Awakening 摘自 https blog csdn net qq 23035335 article details 1
  • python离线安装wheel_使用 pip wheel 实现 Python 依赖包的离线安装

    pip python 依赖 安装 有时候 需要部署 Python 应用的服务器没有网络连接 这时候 你就要把整个 Python 应用做成离线安装包 借助 wheel 很容易就可以实现 首先 你的开发机器上要安装 wheel pip inst
  • vlunhub系列之Momentum2

    靶机Momentum2 如果主机发现发现不了ip地址请看这里 https hackergu com vulnhub ip arp scan主机发现nmap端口扫描 端口扫描 发现并没有可以利用的内容 我们使用dirb nikto 以及dir
  • 发html邮件乱码 java,Java发送邮件时标题和发件人乱码

    Java发送邮件时标题和发件人乱码 最近碰到一个问题 Java发送邮件时 查看邮箱结果 发件人及邮件标题正文全部乱码 通过翻阅资料 原因及解决方法如下 Set Subject 头字段 message setSubject MimeUtili
  • 基于 Web 实现 m3u8 视频播放的简单应用示例

    实现思路 将视频 MP4 等 转换为 M3U8 视频的服务 可以按照以下步骤进行操作 将视频 MP4 等 转换为 M3U8 在服务中 使用适当的工具 如 FFmpeg 将接收到的视频 MP4 等 转换为 M3U8 格式 这将生成一个包含视频
  • AMap + echarts、google map + d3.js分别实现数据可视化中的飞线图(迁徙图)

    首先肯定是给出demo啦 演示demo 直接到左侧选择框中选择View taxi flow里面随便选个日期 总体介绍 最近由于工作室项目需要做一个数据可视化平台 这个平台最终是交由国外人使用的 而国内的高德地图在国外是访问很慢 所以只能使用