Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

Cesium卫星地图和高程数据切片经验总结

发表于 2018-06-13 | 更新于 2023-03-19

最近研究在Cesium中调用自定义的图像和地形,不借助任何GIS系统(如Arcgis、天地图等),方便在网络不好或离线的情况下使用。下面对整个过程进行总结。

基础知识

地图服务提供方法

目前互联网地图服务商提供的地图服务分成两种[3]:

  • 图像瓦片地图服务
    这种方法目前最常见,其提供的是图片格式的瓦片,在客户端将拼接成真正的地图。
  • 矢量瓦片地图服务
    这种方法正在发展,其提供矢量的瓦片数据,然后在客户端进行渲染,是今后的发展方向。

地图服务在使用过程中需要获取特定经纬度所在区域的瓦片和获取瓦片上像素点对应的经纬度,因此需要进行经纬度坐标与瓦片坐标、像素坐标的相互转换。

经纬度与瓦片编号互换

互联网地图的经纬度坐标与瓦片坐标相互转换只与该地图商的墨卡托投影和瓦片编号的定义有关,跟地图商采用的大地坐标系标准无关。

经纬度与瓦片像素互换

转换方式与地图商采用的大地坐标系有关。国际标准的经纬度坐标是WGS84。Open Street Map、外国版的Google Map都是采用WGS84;高德地图使用的坐标系是GCJ-02;百度地图使用的坐标系是BD-09。

地图投影

地图投影,是指按照一定的数学法则将地球椭球面上的经纬网转换到平面上,使地面的地理坐标与平面直角坐标建立起函数关系。这是绘制地图的数学基础之一。由于地球是一个不可展的球体,使用物理方法将其展平会引起褶皱、拉伸和断裂,因此要使用地图投影实现由曲面向平面的转化。

麦卡托投影法

麦卡托投影法 (Mercator projection),又称麦卡托投影法、正轴等角圆柱投影,是一种等角的圆柱形地图投影法。本投影法得名于法兰德斯出身的地理学家杰拉杜斯·麦卡托,他于1569年发表长202公分、宽124公分以此方式绘制的世界地图。在以此投影法绘制的地图上,经纬线于任何位置皆垂直相交,使世界地图可以绘制在一个长方形上。由于可显示任两点间的正确方位,航海用途的海图、航路图大都以此方式绘制。在该投影中线型比例尺在图中任意一点周围都保持不变,从而可以保持大陆轮廓投影后的角度和形状不变(即等角);但麦卡托投影会使面积产生变形,极点的比例甚至达到了无穷大。

墨卡托投影示意图

图1 墨卡托投影示意图
各大地图服务商大都采用了Web Mercator进行投影,瓦片坐标系的不同主要是投影截取的地球范围不同、瓦片坐标起点不同[3]。

瓦片切割和瓦片坐标

对于经过墨卡托投影为平面的世界地图,在不同的地图分辨率(整个世界地图的像素大小)下,通过切割的方式将世界地图划分为像素为256px/256px的地图单元,划分成的每一块地图单元称为地图瓦片。其特定如下:

  • 具有唯一的瓦片等级(Level)和瓦片坐标编号(tileX, tileY)。
  • 瓦片分辨率为256*256。
  • 最小的地图等级是0,此时世界地图只由一张瓦片组成。
  • 瓦片等级越高,组成世界地图的瓦片数越多,可以展示的地图越详细。
  • 某一瓦片等级地图的瓦片是由低一级的各瓦片切割成的4个瓦片组成,形成了瓦片金字塔。

瓦片金字塔

过程总结

将自定义图像和地形以Web形式发布后,在cesium中调用自定义图像和地形很简单,代码如下,关键是图像和地形的获取和处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var tmsImageryProvider=Cesium.createTileMapServiceImageryProvider({
url:'http://localhost:8080/test_tms_tiles'
});

var terrainProvider=new Cesium.CesiumTerrainProvider({
url:'http://localhost:8080/terrain_tiles'
});
var viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider : tmsImageryProvider,
terrainProvider: terrainProvider,
baseLayerPicker: false,
geocoder: false,
shadows: false,
shouldAnimate: true
})
// 摄像头使用默认姿态在指定高度指向指定位置
viewer.camera.setView({
destination : Cesium.Cartesian3.fromDegrees(108.60, 34.15, 6000.0)
});

卫星图像的获取和处理

卫星图像获取可以使用一些相关软件,如水经注、LocaSpaceViewer、SXearth等。其原理通常是从一些地图服务商下载地图瓦片后重新拼接,再分割成对应格式的瓦片。拼接的图像最好输出为tif格式,因为tif格式可以在头部包含一些信息,例如地理坐标等信息,以方便后续的瓦片切割,以及被GIS系统直接识别导入。为使切割后的瓦片能够被Cesium直接调用,应采用标准TMS方式。

通常卫星图像下载软件提供多种瓦片分割方式,如果能直接进行标准TMS瓦片分割最好不过,如果不可以进行标准TMS分割,则可使用GDAL。

GDAL是地理空间数据抽象库的简称,是一个地理空间数据的格式转换及处理工具。文章最后将详细介绍其安装使用方法。使用GDAL进行卫星图像瓦片分割主要使用gdal2tiles.py工具。具体步骤如下:

  1. 选取之前下载拼接的最大分辨率的tif卫星图像
  2. 使用如下命令切割卫星图片,将自动生成瓦片金字塔。
    1
    gdal2tiles.py <image> <tilesdir>

或者参考瓦片底图:TIF影像金字塔切片处理及加载。

卫星图像蓝边的处理

卫星图像在浏览的过程中有可能会出现蓝边,其原因是瓦片下载过程中的边界没有处理好。解决思路是严格按照瓦片的经纬度设定边界。可通过google-maps-coordinates-tile-bounds-projection查询特定级别瓦片的各个顶点的经纬度。

地形的获取和处理

Cesium支持多种地形provider来接收地形数据瓦片[8]:

  1. Cesium Terrain Server——高分辨率的全球地形数据,支持地形光照和水流效果。地形瓦片提交给客户端的数据的格式用的是quantized-mesh v1.0。
  2. Esri ArcGIS Image Server——从Esri影像服务里的高度图中产生地形数据集。详情见Cesium里的ArcGisImageServerTerrainProvider.
  3. VR-TheWorld Server——从一个VR-TheWorld服务里的高度图中产生地形数据。它们的托管服务器有全球90米的数据,包括深度测量。
  4. Ellipsoid——是Cesium默认的地形provider,是一个光滑的椭球面,没有现实的地形,地形高度为0。

常用的CesiumTerrainProvider支持两种格式的地形:一种是quantized-mesh格式的地形数据,另一种是基于高度图技术的DEM。前一种技术是Cesium独有不开放,因此将使用DEM数据在Cesium中渲染地形。

DEM数据是数字高程模型,是描述每个点位的高程数据,没有其他附加信息[9]。DEM数据在ArcGIS中打开只能看到是灰度图。通过相关软件可直接下载各大地图服务商的高程数据,但没有在Cesium中加载成功。下面介绍一种经过验证可在Cesium中成功加载地形的方法:

  1. 下载地形数据。可以从地理空间数据云下载地形数据。注册登录后,在首页选择“DEM 数字高程数据”,在选择“GDEMV2 30M 分辨率数字高程数据”。
  2. 合并地形数据。使用GDAL下的gdal_merge.py工具将下载的地形数据合并成一个Tif文件。
    1
    gdal_merge.py -o out.tif input1.tif input2.tif
  3. 切割地形数据。使用牛人制作的gdal2srtmtiles.py脚本分割地形数据。编辑gdal2srtmtiles.py,在最后设置高程文件和输出目录。参考链接工具gdal2srtmtiles的安装使用。或者参考地形数据:TIF地形转terrain格式。
  4. 发布地形服务。把terrain_tiles直接放到与 Cesium同端口的Tomcat或IIS站点。
    下(不能跨域),即可发布服务。 需要在Web Server中增加配置 .terrain文件的 Content-Type设为 application/octet-stream,同时拷贝“覆盖至生成tiles结果”目录中的 layer.json文件和0文件夹至生成结果目录下,比如我当前是 terrain_tiles目录下。

注意:地形切片至少要到14级,地形分辨率太低将导致卫星影像失真。

GDAL的安装使用

GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。该项目由Frank Warmerdam教授于1998年发起。 它利用抽象数据模型来表达所支持的各种文件格式。 它还有一系列命令行工具来进行数据转换和处理。 OGR(OpenGIS Simple Features Reference Implementation)是GDAL项目的一个子项目, 提供对矢量数据的支持。 一般把这两个库合称为GDAL/OGR,或者简称为GDAL。

GDAL安装方法之一

GDAL不推荐从源码编译安装,建议从gisinternals下载gdal-203-1911-x64-core.msi、GDAL-2.3.0.win-amd64-py2.7.msi直接二进制安装。安装步骤如下:

  1. 安装python2.7。安装完成后配置环境变量,在path中添加 C:\Python27;
  2. 安装gdal-203-1911-x64-core.msi。安装完成后,设置环境变量GDAL_DATA,值为C:\Program Files\GDAL\gdal-data\,修改环境变量PATH,增加C:\Program Files\GDAL;
  3. pip install numpy。这是为了使用地形切割的脚本gdal2srtmtiles.py。
  4. 安装GDAL-2.3.0.win-amd64-py2.7.msi。

注意:当瓦片过多时,会报“OverflowError: range() result has too many items”的错误,而且python2已不再维护,因此不建议采用该方法安装GDAL。

GDAL安装方法之二

OSGeo4W是用于开源GIS项目的Windows安装程序。 开源的本质意味着许多项目/程序相互依赖才能实现功能。 GDAL就是一个很好的例子。 几乎所有的开源GIS项目都在某种程度上使用GDAL来读写数据。 但是因为Windows是一个封闭的平台,所以它没有像基于Unix的操作系统那样开发软件包管理器。 因此,如果使用GRASS和QGIS的独立安装程序安装它们,则最终会进行2次GDAL安装。 添加3或4个以上的开源安装,最终您将获得十几个GDAL安装,此外还有一个仅用于GDAL的安装。

这就是OSGeo4W的用处。它可以跟踪开源GIS软件包的共享需求,因此QGIS和GRASS可以共享一次GDAL安装。 它还跟踪版本,因此您可以简单地升级程序。

从官网GDAL2Tiles Project找到 OSGeo4W 的下载链接,下载OSGeo4W并安装即可。

参考链接

  1. Imagery-Layers-Tutorial, by cesiumjs
  2. Terrain-Tutorial, by cesiumjs
  3. 国内主要地图瓦片坐标系定义及计算原理, by CntChen
  4. 地图投影, by wikipedia
  5. Hexo博客搭建之在文章中插入图片, by Yan Yinhong
  6. 用ArcMap给遥感影像(tif格式)加入地理坐标,by wbz810.
  7. GDAL,by gdal
  8. Cesium之地形(1), by Super洛伽
  9. Cesium中地形数据的加载,by CrazyGIS
  10. OpenLayers之多源数据加载二:瓦片地图原理,by giser.
  11. cesium加载离线tms切片,by nygfcn.
  12. TIFF,by wikipedia.
  13. Tile_Map_Service_Specification,by osgeo.
  14. TIFF图像文件格式详解(1),by xdyang.
  15. TIFF图像文件格式分析,by windcsn.
  16. 1. 地理数据处理软件包GDAL简介,by osgeo.cn.
  17. google-maps-coordinates-tile-bounds-projection,by maptiler.
  18. geopy,by theonegis.
  19. 工具gdal2srtmtiles的安装使用,by 四域公子.
  20. 地形数据:TIF地形转terrain格式,by mars3d.
  21. 瓦片底图:TIF影像金字塔切片处理及加载,by mars3d.

Cesium中飞行器姿态控制

发表于 2018-06-10 | 更新于 2020-11-29

问题提出

最近研究开源虚拟地球Cesium,遇到一个问题:在获取飞行器经度纬度高度偏航俯仰滚转六个参数的前提下,如何在Cesium中用CZML文件表示,从而完美实现飞行器姿态轨迹的复现。在CZML的position属性中使用cartographicDegrees表示飞行器的经度纬度高度,可以很好复现飞行器的轨迹。然而在CZML的orientation属性中使用unitQuaternion表示飞机自身姿态时,飞机姿态总是不对。

问题分析

基本知识

在Cesium中存在两种常用坐标系:

  1. 世界坐标系
    世界坐标系统是以椭球中心为原点的笛卡尔空间直角坐标系。
  2. 地理坐标系
    地理坐标系即人们常用的使用经度、纬度、高度表示位置的坐标系。
  3. 站心坐标系
    又称为Earth-fixed coordinate system(站点坐标系、东-北-天坐标系ENU)。可分为站心直角坐标系和站心极坐标系。
    常用的站心直角坐标系定义为:以站心(如GPS接收天线中心)为坐标系原点O,Z轴与椭球法线重合,向上为正(天向),y与椭球短半轴重合(北向),x轴与地球椭球的长半轴重合(东向)所构成的直角坐标系,称为当地东北天坐标系(ENU)。
    飞行器的偏航、俯仰、滚转即是以站心直角坐标系为参考。
  4. 模型坐标系
    模型坐标系以物体的中心为坐标原点,物体旋转、平移等操作都是围绕局部坐标系进行的。这时当物体模型进行旋转、平移等操作时,局部坐标系也执行相应的旋转、平移等操作。
    局部坐标系是一个假想的坐标系,该坐标系与物体的相对位置至始至终是不变的,假想出这个坐标系的目的主要是为了正向理解对三维场景中物体执行的平移和旋转操作。使用局部坐标系理解模型变换时,所有的变换操作直接作用与局部坐标系,由于局部坐标系与物体的相对位置不变,因此对局部坐标系进行平移、旋转和缩放时,物体在场景中位置和形状也会发生相应的变化。

在Cesium中存在两种世界坐标系和地理坐标系之间坐标转换的方法:

1
2
3
4
5
6
7
8
9
# 经纬度转换为世界坐标
Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result)
# 世界坐标转换为经纬度
var ellipsoid=viewer.scene.globe.ellipsoid;
var cartesian3=new Cesium.cartesian3(x,y,z);
var cartographic=ellipsoid.cartesianToCartographic(cartesian3);
var lat=Cesium.Math.toDegrees(cartograhphic.latitude);
var lng=Cesium.Math.toDegrees(cartograhpinc.longitude);
var alt=cartographic.height;

CZML分析

CZML是一种用来描述动态场景的JSON架构的语言,主要用于Cesium在浏览器中的展示。它可以用来描述点、线、布告板、模型以及其他的图元,同时定义他们是怎样随时间变化的[3]。

CZML可使用model属性直接加载3D模型,由position属性决定模型在世界坐标系内的位置,由orientation决定模型在世界坐标系内的姿态,并最终由orientation的unitQuaternion表示。

unitQuaternion即单位四元数,可与偏航俯仰滚转相互转换,并避免偏航俯仰滚转的万向节锁定问题,但其本质上都是一个旋转矩阵,可决定模型在世界坐标系内的姿态。

获取正确的飞行器姿态

首先计算飞行器模型坐标系对站点直角坐标系的旋转矩阵(在制作飞行器3D模型时,应使其中心在本地坐标系原点,机头机翼与轴平行,方便计算在站点直角坐标系内的旋转角度),再乘以由飞行器偏航俯仰滚转得到的旋转矩阵,再乘以站点直角坐标系对世界坐标系的旋转矩阵。将最终得到旋转矩阵转换为单位四元数,即得到正确的飞行器姿态。

小技巧:飞机3D模型的中心设置在本地坐标系原点,机头机翼与轴平行后,可能在Cesium中渲染时姿态还是不对。原因是绕Z轴旋转的角度还是不对。可以在HeadingPitchRoll示例中使用自己的飞机3D模型,参照Cesium给的运输机模型,比较它们之间绕Z轴旋转的差异,然后调整飞机3D模型绕Z轴旋转的角度。

解决方法

参考代码如下:

1
2
3
4
5
6
var lon=113,lat=34;//模型的站心经纬度
var h1=0,p1=0,r1=0;//模型坐标系对站点坐标系的旋转角度
var h2=0,p2=0,r2=0;//模型在站点坐标系的姿态
var center = Cesium.Cartesian3.fromDegrees(lon, lat)
var hpr = new Cesium.HeadingPitchRoll(h1+h2, p1+p2, r1+r2)
var q1 = Cesium.Transforms.headingPitchRollQuaternion(center, hpr)

参考链接

  1. CESIUM : How to animate an aircraft from pitch, roll, heading?, by stackoverflow.
  2. Cesium中的几种坐标和相互转换, by finalLi.
  3. Cesium Language (CZML) 入门1 — CZML Structure(CZML的结构), by laixiangran.
  4. CZML Structure, by AnalyticalGraphicsInc.
  5. 3D坐标系, by S_H_C.
  6. 3D空间的坐标系, by trojanpizza.
  7. cesium获取某个位置垂直于当前地表的垂直坐标系,by 暮志未晚Webgl.
  8. Cesium控制模型旋转2019-11-15,by _____xyz.

春江花月夜

发表于 2018-06-09
作者:张若虚 春江潮水连海平,海上明月共潮生。 滟滟随波千万里,何处春江无月明? 江流宛转绕芳甸,月照花林皆似霰。 空里流霜不觉飞,汀上白沙看不见。 江天一色无纤尘,皎皎空中孤月轮。 江畔何人初见月,江月何年初照人? 人生代代无穷已,江月年年祇相似。 不知江月待何人?但见长江送流水。 白云一片去悠悠,青枫浦上不胜愁。 谁家今夜扁舟子,何处相思明月楼? 可怜楼上月徘徊,应照离人妆镜台。 玉户帘中卷不去,捣衣砧上拂还来。 此时相望不相闻,愿逐月华流照君。 鸿雁长飞光不度,鱼龙潜跃水成文。 昨夜闲潭梦落花,可怜春半不还家。 江水流春去欲尽,江潭落月复西斜。 斜月沉沉藏海雾,碣石潇湘无限路。 不知乘月几人归,落月摇情满江树。

Cesium小部件animation和timeline的系统时间显示

发表于 2018-06-09 | 更新于 2019-12-26

Cesium的小部件animation和timeline显示UTC系统时间,需要将其改为本地系统时间。修改方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
this.viewer.animation.viewModel.dateFormatter = localeDateTimeFormatter
this.viewer.animation.viewModel.timeFormatter = localeTimeFormatter
this.viewer.timeline.makeLabel = function (time) { return localeDateTimeFormatter(time) }

// Date formatting to a global form
function localeDateTimeFormatter(datetime, viewModel, ignoredate) {
var julianDT = new Cesium.JulianDate();
Cesium.JulianDate.addHours(datetime,8,julianDT)
var gregorianDT= Cesium.JulianDate.toGregorianDate(julianDT)
var objDT;
if (ignoredate)
objDT = '';
else {
objDT = new Date(gregorianDT.year, gregorianDT.month - 1, gregorianDT.day);
objDT = gregorianDT.year + '年' +objDT.toLocaleString("zh-cn", { month: "short" })+ gregorianDT.day + '日' ;
if (viewModel || gregorianDT.hour + gregorianDT.minute === 0)
return objDT;
objDT += ' ';
}
return objDT + Cesium.sprintf("%02d:%02d:%02d", gregorianDT.hour, gregorianDT.minute, gregorianDT.second);
}

function localeTimeFormatter(time, viewModel) {
return localeDateTimeFormatter(time, viewModel, true);
}

上述代码还存在一个问题,当timeline小部件不活动时,其仍然显示UTC标准系统时间。

Cesium的credit十分碍眼,采用如下方法去掉:

1
2
//去除版权信息
viewer._cesiumWidget._creditContainer.style.display = "none";

参考链接

  1. EST,CST,PST,GMT,UTC,EDT等等时间缩写, by chienchia.
  2. Change UTC timezone to SGT timezone in Cesiumjs, by stackoverflow.
  3. Cesium去掉logo,by 跃然实验室.

Matplotlib蜡烛图绘制教程

发表于 2018-06-03 | 更新于 2020-01-01

股票分析离不开各种图表的绘制,尤其是最常用的蜡烛图。下面介绍python中使用matplotlib绘制蜡烛图的过程。

环境及配置

使用的环境如下:

1
2
3
4
5
6
7
8
9
10
11
12
$ python3 --version
Python 3.6.5rc1
$ ipython3
In [1]: import matplotlib
In [2]: matplotlib.__version__
Out[2]: '2.2.2'
In [3]: import tushare as ts
In [4]: ts.__version__
Out[4]: '1.1.9'
In [5]: import talib
In [6]: talib.__version__
Out[6]: '0.4.17'

绘制蜡烛图通常使用matplotlib.finance库,但这个库在matplotlib 2.0后已经被废弃,并被移到一个名叫mpl_finance的库中。可使用如下命令安装mpl_finance。

1
pip3 install https://github.com/matplotlib/mpl_finance/archive/master.zip

mpl_finance使用雅虎接口获取股票数据,但是不稳定,因此推荐使用tushare库获取股票数据。另外使用talib计算股票各种技术分析指标,例如常用的均线数据。需要注意的是通过pip3按照的talib库是对C/C++版talib的包装,因此需先安装C/C++版talib。

蜡烛图绘制

蜡烛图绘制函数简介

mpl_finance库中蜡烛图的绘制主要有以下四个函数:

1
2
3
4
candlestick2_ochl(ax, opens, closes, highs, lows, width=4, colorup='k', colordown='r', alpha=0.75)
candlestick2_ohlc(ax, opens, highs, lows, closes, width=4, colorup='k', colordown='r', alpha=0.75)
candlestick_ochl(ax, quotes, width=0.2, colorup='k', colordown='r', alpha=1.0)
candlestick_ohlc(ax, quotes, width=0.2, colorup='k', colordown='r', alpha=1.0)

在这四个函数的使用过程中需要注意的是:

  • candlestick2_ohlc函数假定opens, highs, lows, closes中任意一个值不存在,则其他值也不存在。

  • candlestick_ochl和candlestick_ohlc的输入参数quotes是(time, open, close, high, low, …)元组序列,其中time必须是浮点日期格式,具体参见date2num。

蜡烛图绘制函数存在日线图的时间间隔问题(非交易日无法跳过,导致图像断裂)。常用解决方法是建议重新调整横坐标,被动地过滤掉非交易时间段[2]。例如:

1
2
ax.set_xticks(range(0, len(data['date']), 10))
ax.set_xticklabels(data['date'][::10])

蜡烛图的简单绘制

蜡烛图的简单例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import talib
import tushare as ts
import matplotlib.pyplot as plt
import mpl_finance as mpf

data = ts.get_k_data('002320')
sma_10 = talib.SMA(np.array(data['close']), 10)
sma_30 = talib.SMA(np.array(data['close']), 30)
fig = plt.figure(figsize=(24, 8))
ax = fig.add_subplot(1, 1, 1)
ax.set_xticks(range(0, len(data['date']), 50))
ax.set_xticklabels(data['date'][::50])
ax.plot(sma_10, label='10 日均线')
ax.plot(sma_30, label='30 日均线')
ax.legend(loc='upper left')
mpf.candlestick2_ochl(ax, data['open'], data['close'], data['high'], data['low'],width=0.5, colorup='r', colordown='green',alpha=0.6)
plt.grid()
plt.show()

参考链接

  1. finance api, by matplotlib

matplotlib用法笔记

发表于 2018-05-26 | 更新于 2020-01-05

matplotlib 是Python编程语言及其数值数学扩展包 NumPy的可视化操作界面。它为利用通用的图形用户界面工具包,如Tkinter, wxPython, Qt或GTK+向应用程序嵌入式绘图提供了应用程序接口(API)。此外,matplotlib还有一个基于图像处理库(如开放图形库OpenGL)的pylab接口,其设计与MATLAB非常类似–尽管并不怎么好用。SciPy就是用matplotlib进行图形绘制。

绘图结构

matplotlib API包含有三层:

  • backend_bases.FigureCanvas : 图表的绘制领域
  • backend_bases.Renderer : 知道如何在FigureCanvas上如何绘图
  • artist.Artist : 知道如何使用Renderer在FigureCanvas上绘图

FigureCanvas和Renderer需要处理底层的绘图操作,例如使用wxPython在界面上绘图,或者使用PostScript绘制PDF。Artist则处理所有的高层结构,例如处理图表、文字和曲线等的绘制和布局。通常我们只和Artist打交道,而不需要关心底层的绘制细节。

Artists分为简单类型和容器类型两种。简单类型的Artists为标准的绘图元件,例如Line2D、 Rectangle、 Text、AxesImage 等等。而容器类型则可以包含许多简单类型的Artists,使它们组织成一个整体,例如Axis、 Axes、Figure等。

matplotlib pyplot绘图结构

图1 matplotlib pyplot绘图结构

基本用法

使用plt.figure定义一个图像窗口。

1
2
3
4
5
6
7
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-1, 1, 50)
y = 2*x + 1
plt.figure()
plt.plot(x, y)
plt.show()

设置标题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 导入matplotlib库
import matplotlib
import matplotlib.pyplot as plt
# %matplotlib inline 显示图表
# 使用'ggplot'风格美化显示的图表
plt.style.use('ggplot')

# 设置使用的字体(需要显示中文的时候使用)
font = {'family':'SimHei'}
matplotlib.rc('font',**font)

# 当坐标轴有负号的时候可以显示负号
matplotlib.rcParams['axes.unicode_minus']=False

# 设置标题
plt.title('正弦函数',fontsize=20) 设置子图表标题和标题字体的大小

设置坐标轴

使用plt.xlim设置x坐标轴范围:(-1, 2); 使用plt.ylim设置y坐标轴范围:(-2, 3);
使用plt.xlabel设置x坐标轴名称:’I am x’; 使用plt.ylabel设置y坐标轴名称:’I am y’;

1
2
3
4
plt.xlim((-1, 2))
plt.ylim((-2, 3))
plt.xlabel('I am x')
plt.ylabel('I am y')

使用np.linspace定义范围以及个数:范围是(-1,2);个数是5. 使用print打印出新定义的范围. 使用plt.xticks设置x轴刻度:范围是(-1,2);个数是5.

1
2
3
new_ticks = np.linspace(-1, 2, 5)
print(new_ticks)
plt.xticks(new_ticks)

使用plt.yticks设置y轴刻度以及名称:刻度为[-2, -1.8, -1, 1.22, 3];对应刻度的名称为[‘really bad’,’bad’,’normal’,’good’, ‘really good’]. 使用plt.show显示图像.

1
2
plt.yticks([-2, -1.8, -1, 1.22, 3],[r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])
plt.show()

使用plt.gca获取当前坐标轴信息. 使用.spines设置边框:右侧边框;使用.set_color设置边框颜色:默认白色; 使用.spines设置边框:上边框;使用.set_color设置边框颜色:默认白色;

1
2
3
4
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()

调整坐标轴

使用.xaxis.set_ticks_position设置x坐标刻度数字或名称的位置:bottom.(所有位置:top,bottom,both,default,none)

1
ax.xaxis.set_ticks_position('bottom')

使用.spines设置边框:x轴;使用.set_position设置边框位置:y=0的位置;(位置所有属性:outward,axes,data)
使用.yaxis.set_ticks_position设置y坐标刻度数字或名称的位置:left.(所有位置:left,right,both,default,none)
使用.spines设置边框:y轴;使用.set_position设置边框位置:x=0的位置;(位置所有属性:outward,axes,data) 使用plt.show显示图像.

1
2
3
4
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
plt.show()

legend图例

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = 2*x + 1
y2 = x**2

plt.figure()
#set x limits
plt.xlim((-1, 2))
plt.ylim((-2, 3))

# set new sticks
new_sticks = np.linspace(-1, 2, 5)
plt.xticks(new_sticks)
# set tick labels
plt.yticks([-2, -1.8, -1, 1.22, 3],
[r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])

# set line syles
l1, = plt.plot(x, y1, label='linear line')
l2, = plt.plot(x, y2, color='red', linewidth=1.0, linestyle='--', label='square line')

plt.legend(loc='upper right')

调整位置和名称

1
plt.legend(handles=[l1, l2], labels=['up', 'down'],  loc='best')

其中’loc’参数有多种,’best’表示自动分配最佳位置。

1
2
3
4
5
6
7
8
9
10
11
'best' : 0,          
'upper right' : 1,
'upper left' : 2,
'lower left' : 3,
'lower right' : 4,
'right' : 5,
'center left' : 6,
'center right' : 7,
'lower center' : 8,
'upper center' : 9,
'center' : 10,

子图

使用plt.subplot来创建小图。 plt.subplot(2,2,1)表示将整个图像窗口分为2行2列, 当前位置为1。 使用plt.plot([0,1],[0,1])在第1个位置创建一个小图。

1
2
3
4
import matplotlib.pyplot as plt
fig=plt.figure()
ax = fig.add_subplot(2, 2, 1, projection='3d')
ax.plot([0,1,1],[0,1,1])

plt.subplot(222)表示将整个图像窗口分为2行2列, 当前位置为2. 使用plt.plot([0,1],[0,2])在第2个位置创建一个小图.

1
2
plt.subplot(222)
plt.plot([0,1],[0,2])

动画

Matplotlib使用FuncAnimation函数生成动画。参数说明:

  • fig 进行动画绘制的figure
  • func 自定义动画函数,即传入刚定义的函数animate
  • frames 动画长度,一次循环包含的帧数
  • init_func 自定义开始帧,即传入刚定义的函数init
  • interval 更新频率,以ms计
  • blit 选择更新所有点,还是仅更新产生变化的点。应选择True,但mac用户请选择False,否则无法显示动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np

fig, ax = plt.subplots()

x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))

def animate(i):
line.set_ydata(np.sin(x + i/10.0))
return line,

def init():
line.set_ydata(np.sin(x))
return line,
//注意此处FuncAnimation必须有返回值
ani = animation.FuncAnimation(fig=fig,
func=animate,
frames=100,
init_func=init,
interval=20,
blit=False)

plt.show()

参考链接

  1. matplotlib, by wikipedia
  2. 莫烦Python, by morvanzhou
  3. API Overview,by matplotlib.
  4. Python matplotlib高级绘图详解,by 微岩.
  5. 用Matplotlib制作动画,by 段丞博.
  6. Plot inline or a separate window using Matplotlib in Spyder IDE,by stackoverflow.
  7. Python之matplotlib的使用汇总,by 探索数据之美.

python3与python2的区别与兼容

发表于 2018-05-26 | 更新于 2018-10-09

Python是一种广泛使用的高级编程语言,属于通用型编程语言,由吉多·范罗苏姆创造,第一版发布于1991年。可以视之为一种改良(加入一些其他编程语言的优点,如面向对象)的LISP。作为一种解释型语言,Python的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进划分代码块,而非使用大括号或者关键词)。相比于C++或Java,Python让开发者能够用更少的代码表达想法。不管是小型还是大型程序,该语言都试图让程序的结构清晰明了。

与Scheme、Ruby、Perl、Tcl等动态类型编程语言一样,Python拥有动态类型系统和垃圾回收功能,能够自动管理内存使用,并且支持多种编程范式,包括面向对象、命令式、函数式和过程式编程。其本身拥有一个巨大而广泛的标准库。

Python 解释器本身几乎可以在所有的操作系统中运行。Python的正式解释器CPython是用C语言编写的、是一个由社区驱动的自由软件,目前由Python软件基金会管理。

python3与python2区别

print函数

Python 2 的 print 声明在Python 3中已经被 print() 函数取代

1
2
3
4
5
#!/usr/bin/python2
print 'Hello, World!'

#!/usr/bin/python3
print('Hello, World!')

整除

/是精确除法,//是向下取整除法,%是求模。

//和%运算符在2和3版本中一样,但是运算符/不一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python2
>>> 3 / 2
1
>>> 3 // 2
1
>>> 3 / 2.0
1.5
>>> 3 // 2.0
1.0

#!/usr/bin/python3
>>> 3 / 2
1.5
>>> 3 // 2
1
>>> 3 / 2.0
1.5
>>> 3 // 2.0
1.0

Unicode

由于历史遗留问题,Python 2.x版本虽然支持Unicode,但在语法上需要’xxx’和u’xxx’两种字符串表示方式。

在Python 3.x版本中,把’xxx’和u’xxx’统一成Unicode编码,即写不写前缀u都是一样的,而以字节形式表示的字符串则必须加上b前缀:b’xxx’。

1
2
3
4
5
6
#!/usr/bin/python2

#!/usr/bin/python3
>>> 中国 = 'china'
>>> print(中国)
china

xrange模块

在 Python 2 中 xrange() 创建迭代对象的用法是非常流行的。比如: for 循环或者是列表/集合/字典推导式。

在 Python 3 中,range() 是像 xrange() 那样实现以至于一个专门的 xrange() 函数都不再存在(在 Python 3 中 xrange() 会抛出命名异常)。

不等运算符

Python 2.x中不等于有两种写法 != 和 <>

Python 3.x中去掉了<>, 只有!=一种写法

数据类型

  • Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
  • 新增了bytes类型,对应于2.X版本的八位串
  • dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),用 in替代它吧 。

异常

  • 在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用 as 作为关键词。
  • 捕获异常的语法由 except exc, var 改为 except exc as var。
    使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。 Python 2.6已经支持这两种语法。

解析用户的输入

  • 在python2.x中raw_input()和input(),两个函数都存在,其中区别为

    raw_input()—将所有输入作为字符串看待,返回字符串类型

    input()—–只能接收“数字”的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float)

  • 在python3.x中raw_input()和input()进行了整合,去除了raw_input(),仅保留了input()函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。

返回可迭代对象,而不是列表

如果在 xrange 章节看到的,现在在 Python 3 中一些方法和函数返回迭代对象 — 代替 Python 2 中的列表。

因为我们通常那些遍历只有一次,我认为这个改变对节约内存很有意义。尽管如此,它也是可能的,相对于生成器 —- 如需要遍历多次。它是不那么高效的。

而对于那些情况下,我们真正需要的是列表对象,我们可以通过 list() 函数简单的把迭代对象转换成一个列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/python2
>>> print range(3)
[0, 1, 2]
>>> print type(range(3))
<type 'list'>

#!/usr/bin/python3
>>> print(range(3))
range(0, 3)
>>> print(type(range(3)))
<class 'range'>
>>> print(list(range(3)))
[0, 1, 2]

For循环变量和全局命名空间泄漏

在 Python 3.x 中 for 循环变量不会再导致命名空间泄漏。

在 Python 3.x 中做了一个改变,在 What’s New In Python 3.0 中有如下描述:
“列表推导不再支持 [… for var in item1, item2, …] 这样的语法。使用 [… for var in (item1, item2, …)] 代替。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python2
>>> i = 1
>>> print 'before: i =', i
before: i = 1
>>> print 'comprehension: ', [i for i in range(5)]
comprehension: [0, 1, 2, 3, 4]
>>> print 'after: i =', i
after: i = 4

#!/usr/bin/python3
>>> i = 1
>>> print('before: i =', i)
before: i = 1
>>> print('comprehension:', [i for i in range(5)])
comprehension: [0, 1, 2, 3, 4]
>>> print('after: i =', i)
after: i = 1

兼容python3与python2

当前python3的普及还不尽人意,因此编写的python程序能同时兼容python2与python3是十分必要的。下面介绍同时支持python2与python3的方法。

  • 放弃python 2.6之前的python版本
  • 使用 2to3 工具对代码检查
  • 使用python -3执行python程序
  • from future import
    “from future import”后即可使使用python的未来特性了。python的完整future特性可见 future 。python3中所有字符都变成了unicode。在python2中unicode字符在定义时需要在字符前面加 u,但在3中则不需要家u,而且在加u后程序会无法编译通过。为了解决该问题可以 “from future import unicode_literals” ,这样python2中字符的行为将和python3中保持一致,python2中定义普通字符将自动识别为unicode。
  • import问题
    python3中“少”了很多python2的包,在大多情况下这些包之是改了个名字而已。我们可以在import的时候对这些问题进行处理。
    1
    2
    3
    4
    5
    6
    7
    try:#python2
    from UserDict import UserDict
    #建议按照python3的名字进行import
    from UserDict import DictMixin as MutableMapping
    except ImportError:#python3
    from collections import UserDict
    from collections import MutableMapping
  • 使用python3的方式写程序
  • 检查当前运行的python版本
    1
    2
    3
    4
    5
    import sys
    if sys.version > '3':
    PY3 = True
    else:
    PY3 = False
  • six
    不推荐使用six。

参考链接

  1. https://zh.wikipedia.org/wiki/Python, by wikipedia
  2. https://www.jianshu.com/p/85583e032eb8, by EarthChen
  3. http://python.jobbole.com/83987/, by 天地一沙鸥

Git用法总结

发表于 2018-05-24 | 更新于 2025-02-27

git是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计[1]。

git结构

新建代码库

1
2
3
4
5
6
7
8
# 在当前目录新建一个Git代码库
$ git init

# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]

# 下载一个项目和它的整个代码历史
$ git clone [url]

配置

Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

1
2
3
4
5
6
7
8
9
# 显示当前的Git配置
$ git config --list

# 编辑Git配置文件
$ git config -e [--global]

# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"

代码提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 提交暂存区到仓库区
$ git commit -m [message]

# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]

# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a

# 提交时显示所有diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]

# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...

查看信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 显示有变更的文件
$ git status

# 显示当前分支的版本历史
$ git log

# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat

# 搜索提交历史,根据关键词
$ git log -S [keyword]

# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s

# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature

# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]

# 显示指定文件相关的每一次diff
$ git log -p [file]

# 显示过去5次提交
$ git log -5 --pretty --oneline

# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn

# 显示指定文件是什么人在什么时间修改过
$ git blame [file]

# 显示暂存区和工作区的差异
$ git diff

# 显示暂存区和上一个commit的差异
$ git diff --cached [file]

# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD

# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]

# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"

# 显示某次提交的元数据和内容变化
$ git show [commit]

# 显示某次提交发生变化的文件
$ git show --name-only [commit]

# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]

# 显示当前分支的最近几次提交
$ git reflog

Git 工具 - 子模块

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。

Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

1
2
3
4
5
6
7
$ git submodule add https://github.com/chaconinc/DbConnector
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.

默认情况下,子模块会将子项目放到一个与仓库同名的目录中,本例中是 “DbConnector”。 如果你想要放到其他地方,那么可以在命令结尾添加一个不同的路径。

Git代理设置

1
2
3
4
5
6
7
8
9
10
git config --global https.proxy http://127.0.0.1:1080

git config --global https.proxy https://127.0.0.1:1080

git config --global --unset http.proxy

git config --global --unset https.proxy


npm config delete proxy

不常用操作

  • 查看代码仓库中标签

    1
    git tag
  • 检出指定标签代码

    1
    git checkout tag_name
  • 丢弃本地修改

    1
    git checkout .
  • 打包导出仓库代码

    1
    git archive --format zip --output ..\emsdk\zips\1.38.8.zip HEAD

参考链接

  1. Git, by wikipedia
  2. git 如何获取指定 tag 代码, by 一介布衣
  3. 常用 Git 命令清单,by 阮一峰.
  4. 7.11 Git 工具 - 子模块,by git.
  5. Git submodule用法,by jinlei_123.

Vue.js集成three.js

发表于 2018-05-13 | 更新于 2023-03-23

Three.js是一个跨浏览器的脚本,使用JavaScript函数库或API来在网页浏览器中创建和展示动画的三维计算机图形。Three.js使用WebGL。源代码托管在GitHub。

下面介绍在Vue.js中集成three.js的步骤。

  1. 安装vue-cli脚手架
  2. 安装three.js
    1
    npm install --save three
  3. 编写使用three.js创建3D场景的Vuejs组件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    <template>
    <div id="container"></div>
    </template>
    <script>
    import * as Three from 'three'

    export default {
    name: 'Home',
    data () {
    return {
    camera: null,
    scene: null,
    renderer: null,
    mesh: null
    }
    },
    methods: {
    init: function () {
    var container = document.getElementById('container')

    this.camera = new Three.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 10)
    this.camera.position.z = 1

    this.scene = new Three.Scene()

    var geometry = new Three.BoxGeometry(0.2, 0.2, 0.2)
    var material = new Three.MeshNormalMaterial()

    this.mesh = new Three.Mesh(geometry, material)
    this.scene.add(this.mesh)

    this.renderer = new Three.WebGLRenderer({ antialias: true })
    this.renderer.setSize(container.clientWidth, container.clientHeight)
    container.appendChild(this.renderer.domElement)
    },
    animate: function () {
    requestAnimationFrame(this.animate)
    this.mesh.rotation.x += 0.01
    this.mesh.rotation.y += 0.02
    this.renderer.render(this.scene, this.camera)
    }
    },
    mounted () {
    this.init()
    this.animate()
    }
    }

    </script>
    <style rel="stylesheet/scss" lang="scss" scoped>
    #container {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    }

    </style>

参考链接

  1. Three.js, by Wikipedia
  2. Import and use three.js library in vue component, by Stackoverlflow

Windows批处理编程语法解析

发表于 2018-05-13 | 更新于 2024-03-04

批处理文件(BAT文件)是DOS,OS/2和Microsoft Windows中的一种脚本文件[1]。 它由命令行解释器执行的一系列命令组成,存储在纯文本文件中,通常以BAT为扩展名。批处理文件可以包含解释器交互接受的任何命令,并使用在批处理文件中启用条件分支和循环的构造,如IF,FOR和GOTO标签。在Windows平台自动化部署或处理日常重复性工作时,常使用Windows批处理文件。

批处理命令简介

下面简单介绍Windows BAT文件的语法。

变量操作

  • 设置变量

格式:set 变量名=变量值
详细:被设定的变量以%变量名%引用

  • 取消变量
    格式:set 变量名=
    详细:取消后的变量若被引用%变量名%将为空

  • 展示变量
    格式:set 变量名
    详细:展示以变量名开头的所有变量的值

  • 列出所有可用的变量
    格式:set

常用命令

  • @

让执行窗口中不显示它后面这一行的命令本身。

1
2
// 使用@将不显示后面的echo off命令
@ echo off
  • echo

echo即回显或反馈的意思。它由两种状态:打开和关闭。

1
2
3
4
// 将不显示后续的命令
@ echo off
// 将显示后续的命令
@ echo on
  • ::

注释命令。在批处理文件中与rem命令等效

  • call

call命令用来从一个批处理文件调用另一个批处理文件。只有当被调用的批处理文件执行完成时,才返回。

1
call pm2-startup install
  • start

启动单独的“命令提示符”窗口来运行指定程序或命令。如果在没有参数的情况下使用,start 将打开第二个命令提示符窗口。

  • pause

暂停命令。方便用户查看信息,查看完毕后可继续执行。

  • explorer

在 cmd 下输入explorer可打开文件夹图形界面,例如:

1
2
// 在图形界面中打开当前文件夹
explorer .
  • %i

for循环在cmd命令行中的固定用法for %i in (set) do (…),循环变量格式为%i

1
for %i in (1,2,3,5,8) do echo %i
  • %%i

for循环在bat处理程序中的固定用法for %%i in (set) do (…),循环变量格式为%%i

  • &

顺序执行多条命令,而不管命令是否执行成功

  • &&

顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令

  • ||

顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令(即:只有前面命令执行错误时才执行后面命令)

  • |

管道命令 前一个命令的执行结果输出到后一个命令 如:help|more

清除文件中原有的内容后再写入

追加内容到文件末尾,而不会清除原有的内容主要将本来显示在屏幕上的内容输出到指定文件中指定文件如果不存在,则自动生成该文件。

1
certutil -hashfile user-history.db md5 >> hash.txt
  • cd /d %~dp0
1
2
3
4
5
6
/d 表示直接切换到对应分区
%0代表批处理本身 d:\qq\a.bat
~dp是变量扩充
d既是扩充到分区号 d:
p就是扩充到路径 \qq
dp就是扩充到分区号路径 d:\qq

批处理脚本示例

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
set PATH=E:\Simulation\x64\Release\;%PATH%;
E:
cd E:\Simulation\x64\Release\
cd BlueSimu
start FlightSimServer.exe
cd ../RedSimu
start FlightSimServer.exe
cd ..
start Simulation.exe
start Simulation.exe
pause

示例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
:: 定义变量
set dataset=j:\tensorflow\dataset\LSOTB-TIR\Training Dataset
set imagedir=%dataset%\LSOTB-TIR_TrainingData\TrainingData\TIR_training_004\bird_001
set xmldir=%dataset%\LSOTB-TIR_TrainingData\Annotations\TIR_training_004\bird_001
set labelpath=j:\tensorflow\workspace\training_demo\annotations\label_map.pbtxt
set outputdir=j:\tensorflow\workspace\training_demo\annotations\infrared_train_bird_004_001
set process_script=j:\tensorflow\scripts\preprocessing\generate_pascal_tfrecord.py

:: 调用tfrecord脚本程序, for循环,字符串截取,字符串拼接,路径空格处理
for /L %%i in (1,1,7) do python %process_script% -i "%imagedir:~0,-1%%%i" -x "%xmldir:~0,-1%%%i" -l %labelpath% -o %outputdir:~0,-1%%%i.record
:: for /L %%i in (10,1,16) do python %process_script% -i "%imagedir:~0,-2%%%i" -x "%xmldir:~0,-2%%%i" -l %labelpath% -o %outputdir:~0,-2%%%i.record

pause

参考链接

  1. Batch file,by Wikipedia.
  2. 批处理最完整人性化教程(.bat文件语法), by s1ihome.
  3. 批处理命令之Start的详细用法,by QiaoZhi.
  4. windows批处理set命令,by 鹤唳九天.
  5. windows批处理——变量,命令换行,by undefined.
  6. Batch批处理字符串操作、for循环学习记录,by blingbling_110.
  7. .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别,by AlbertS.
  8. Bat命令学习-批处理中的&、&&、|、||、>、>>符号,by iloli.
  9. Windows certutil.exe 命令 简单举例 计算MD5与SHA1/256,by ldq_sd.
  10. cmd: cd /D %~dp0 的含义,by Nemo_XP.
  11. CMD获取当前目录的绝对路径 (当前盘符和路径:%~dp0),by 亟待!.
上一页1…505152下一页

Jack Huang

519 日志
66 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse