Cesium测量工具,距离测量、面积测量、高度测量

前言

测量工具几乎是每个GIS系统都具备的基础工具,Cesium没有自带测量工具,只能我们自己封装。

实现效果



实现思路

测距测高在Cesium中有相关的接口用来计算,但是测面没有计算方法,这里是通过turf.js来计算,所以计算的是平面面积

关键代码

测量距离

//距离测量类
export default class MeasureDistance {constructor(viewer) {this.viewer = viewer;this.initEvents();this.positions = [];this.tempPositions = [];this.vertexEntities = [];this.labelEntity = undefined;this.measureDistance = 0; //测量结果}//初始化事件initEvents() {this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);this.MeasureStartEvent = new Cesium.Event(); //开始事件this.MeasureEndEvent = new Cesium.Event(); //结束事件        }//激活activate() {this.deactivate();this.registerEvents(); //注册鼠标事件  //设置鼠标状态 this.viewer.enableCursorStyle = false;this.viewer._element.style.cursor = 'default';this.isMeasure = true;this.measureDistance = 0;}//禁用deactivate() {if (!this.isMeasure) return;this.unRegisterEvents();this.viewer._element.style.cursor = 'pointer';this.viewer.enableCursorStyle = true;this.isMeasure = false;this.tempPositions = [];this.positions = [];}//清空绘制clear() {//清除线对象this.viewer.entities.remove(this.lineEntity);this.lineEntity = undefined;//清除节点this.vertexEntities.forEach(item => {this.viewer.entities.remove(item);});this.vertexEntities = [];}//创建线对象createLineEntity() {this.lineEntity = this.viewer.entities.add({polyline: {positions: new Cesium.CallbackProperty(e => {return this.tempPositions;}, false),width: 2,material: Cesium.Color.YELLOW,depthFailMaterial: Cesium.Color.YELLOW}})}//创建线节点createVertex() {let vertexEntity = this.viewer.entities.add({position: this.positions[this.positions.length - 1],id: "MeasureDistanceVertex" + this.positions[this.positions.length - 1],type: "MeasureDistanceVertex",label: {text: spaceDistance(this.positions) + "米",scale: 0.5,font: 'normal 24px MicroSoft YaHei',distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),verticalOrigin: Cesium.VerticalOrigin.BOTTOM,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, -30),outlineWidth: 9,outlineColor: Cesium.Color.WHITE},point: {color: Cesium.Color.FUCHSIA,pixelSize: 8,disableDepthTestDistance: 500,},});this.vertexEntities.push(vertexEntity);}//创建起点createStartEntity() {let vertexEntity = this.viewer.entities.add({position: this.positions[0],type: "MeasureDistanceVertex",billboard: {image: "../../static/images/start.png",scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4), //设置随图缩放距离和比例distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), //设置可见距离 10000米可见verticalOrigin: Cesium.VerticalOrigin.BOTTOM},point: {color: Cesium.Color.FUCHSIA,pixelSize: 6,},});this.vertexEntities.push(vertexEntity);}//创建终点节点createEndEntity() {//结束时删除最后一个节点的距离标识let lastLabel = this.viewer.entities.getById("MeasureDistanceVertex" + this.positions[this.positions.length - 1]);this.viewer.entities.remove(lastLabel);this.viewer.entities.remove(this.moveVertexEntity);let vertexEntity = this.viewer.entities.add({position: this.positions[this.positions.length - 1],type: "MeasureDistanceVertex",label: {text: "总距离:" + spaceDistance(this.positions) + "米",scale: 0.5,font: 'normal 26px MicroSoft YaHei',distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),verticalOrigin: Cesium.VerticalOrigin.BOTTOM,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, -50),outlineWidth: 9,outlineColor: Cesium.Color.WHITE,eyeOffset: new Cesium.Cartesian3(0, 0, -10)},billboard: {image: "../../static/images/end.png",scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4), //设置随图缩放距离和比例distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000), //设置可见距离 10000米可见verticalOrigin: Cesium.VerticalOrigin.BOTTOM},point: {color: Cesium.Color.FUCHSIA,pixelSize: 6,},});this.vertexEntities.push(vertexEntity);}//注册鼠标事件registerEvents() {this.leftClickEvent();this.rightClickEvent();this.mouseMoveEvent();}//左键点击事件leftClickEvent() {//单击鼠标左键画点点击事件this.handler.setInputAction(e => {this.viewer._element.style.cursor = 'default';let position = this.viewer.scene.pickPosition(e.position);if (!position) {const ellipsoid = this.viewer.scene.globe.ellipsoid;position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);}if (!position) return;this.positions.push(position);if (this.positions.length == 1) { //首次点击  this.createLineEntity();this.createStartEntity();return;}this.createVertex();}, Cesium.ScreenSpaceEventType.LEFT_CLICK);}//鼠标移动事件mouseMoveEvent() {this.handler.setInputAction(e => {if (!this.isMeasure) return;this.viewer._element.style.cursor = 'default';let position = this.viewer.scene.pickPosition(e.endPosition);if (!position) {position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);}if (!position) return;this.handleMoveEvent(position);}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);}//处理鼠标移动handleMoveEvent(position) {if (this.positions.length < 1) return;this.tempPositions = this.positions.concat(position);}//右键事件rightClickEvent() {this.handler.setInputAction(e => {if (!this.isMeasure || this.positions.length < 1) {this.deactivate();this.clear();} else {this.createEndEntity();this.lineEntity.polyline = {positions: this.positions,width: 2,material: Cesium.Color.YELLOW,depthFailMaterial: Cesium.Color.YELLOW};this.measureEnd();}}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);}//测量结束measureEnd() {this.deactivate();this.MeasureEndEvent.raiseEvent(this.measureDistance); //触发结束事件 传入结果}//解除鼠标事件unRegisterEvents() {this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);}
}

测量高度

//高度测量类
export default class MeasureHeight {constructor(viewer) {this.viewer = viewer;this.initEvents();this.positions = [];this.vertexEntities = [];this.labelEntity = undefined;this.measureHeight = 0; //测量结果}//初始化事件initEvents() {this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);this.MeasureStartEvent = new Cesium.Event(); //开始事件this.MeasureEndEvent = new Cesium.Event(); //结束事件        }//激活activate() {this.deactivate();this.registerEvents(); //注册鼠标事件  //设置鼠标状态 this.viewer.enableCursorStyle = false;this.viewer._element.style.cursor = 'default';this.isMeasure = true;this.circleRadius = 0.1;this.measureHeight = 0;this.positions = [];}//禁用deactivate() {if (!this.isMeasure) return;this.unRegisterEvents();this.viewer._element.style.cursor = 'pointer';this.viewer.enableCursorStyle = true;this.isMeasure = false;}//清空绘制clear() {//清除线对象this.viewer.entities.remove(this.lineEntity);this.lineEntity = undefined;//清除文本this.viewer.entities.remove(this.labelEntity);this.labelEntity = undefined;//移除圆this.removeCircleEntity();//清除节点this.vertexEntities.forEach(item => {this.viewer.entities.remove(item);});this.vertexEntities = [];}//创建线对象createLineEntity() {this.lineEntity = this.viewer.entities.add({polyline: {positions: new Cesium.CallbackProperty(e => {return this.positions;}, false),width: 2,material: Cesium.Color.YELLOW,depthFailMaterial: new Cesium.PolylineDashMaterialProperty({color: Cesium.Color.RED,}),}})}//创建结果文本标签createLabel() {this.labelEntity = this.viewer.entities.add({position: new Cesium.CallbackProperty(e => {return this.positions[this.positions.length - 1]; //返回最后一个点}, false),label: {text: "",scale: 0.5,font: 'normal 40px MicroSoft YaHei',distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),scaleByDistance: new Cesium.NearFarScalar(500, 1, 1500, 0.4),verticalOrigin: Cesium.VerticalOrigin.BOTTOM,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, -30),outlineWidth: 9,outlineColor: Cesium.Color.WHITE}})}//创建线节点createVertex(index) {let vertexEntity = this.viewer.entities.add({position: new Cesium.CallbackProperty(e => {return this.positions[index];}, false),type: "MeasureHeightVertex",point: {color: Cesium.Color.FUCHSIA,pixelSize: 6,// disableDepthTestDistance: 2000,},});this.vertexEntities.push(vertexEntity);}//创建圆 这样方便看出水平面的高低createCircleEntitiy() {this.circleEntity = this.viewer.entities.add({position: new Cesium.CallbackProperty(e => {return this.positions[this.positions.length - 1]; //返回最后一个点}, false),ellipse: {height: new Cesium.CallbackProperty(e => {return positionHeight(this.positions[this.positions.length - 1]);}, false),semiMinorAxis: new Cesium.CallbackProperty(e => {return this.circleRadius;}, false),semiMajorAxis: new Cesium.CallbackProperty(e => {return this.circleRadius;}, false),material: Cesium.Color.YELLOW.withAlpha(0.5),},});}//删除圆removeCircleEntity() {this.viewer.entities.remove(this.circleEntity);this.circleEntity = undefined;}//注册鼠标事件registerEvents() {this.leftClickEvent();this.rightClickEvent();this.mouseMoveEvent();}//左键点击事件leftClickEvent() {//单击鼠标左键画点点击事件this.handler.setInputAction(e => {this.viewer._element.style.cursor = 'default';let position = this.viewer.scene.pickPosition(e.position);if (!position) {const ellipsoid = this.viewer.scene.globe.ellipsoid;position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);}if (!position) return;if (this.positions.length == 0) { //首次点击this.positions.push(position);this.createVertex(0);this.createLineEntity();this.createCircleEntitiy();this.createLabel();} else { //第二次点击结束测量this.measureEnd();}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);}//鼠标移动事件mouseMoveEvent() {this.handler.setInputAction(e => {if (!this.isMeasure) return;this.viewer._element.style.cursor = 'default';let position = this.viewer.scene.pickPosition(e.endPosition);if (!position) {position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);}if (!position) return;this.handleMoveEvent(position);}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);}//处理鼠标移动handleMoveEvent(position) {if (this.positions.length < 1) return;let firstPoint = cartesian3Point3(this.positions[0]); //第一个点let movePoint = cartesian3Point3(position); //鼠标移动点const h = movePoint[2] - firstPoint[2];firstPoint[2] = movePoint[2];const twoPosition = Cesium.Cartesian3.fromDegrees(firstPoint[0], firstPoint[1], movePoint[2]);if (this.positions.length < 2) {this.positions.push(twoPosition);this.createVertex(1);} else {this.positions[1] = twoPosition;this.measureHeight = h.toFixed(3);this.labelEntity.label.text = "高度:" + this.measureHeight + " 米"}//计算圆的半径   this.circleRadius = getDistanceH(this.positions[0], position);}//右键事件rightClickEvent() {this.handler.setInputAction(e => {if (this.isMeasure) {this.deactivate();this.clear();}}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);}//测量结束measureEnd() {this.deactivate();this.MeasureEndEvent.raiseEvent(this.measureHeight); //触发结束事件 传入结果}//解除鼠标事件unRegisterEvents() {this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);}
}

测量面积

//面积测量类
export default class MeasureDistance {constructor(viewer) {this.viewer = viewer;this.initEvents();this.positions = [];this.tempPositions = [];this.vertexEntities = [];this.labelEntity = undefined;this.measureArea = 0; //测量结果}//初始化事件initEvents() {this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);this.MeasureStartEvent = new Cesium.Event(); //开始事件this.MeasureEndEvent = new Cesium.Event(); //结束事件        }//激活activate() {this.deactivate();this.registerEvents(); //注册鼠标事件  //设置鼠标状态 this.viewer.enableCursorStyle = false;this.viewer._element.style.cursor = 'default';this.isMeasure = true;this.measureArea = 0;}//禁用deactivate() {if (!this.isMeasure) return;this.unRegisterEvents();this.viewer._element.style.cursor = 'pointer';this.viewer.enableCursorStyle = true;this.isMeasure = false;this.tempPositions = [];this.positions = [];this.height = undefined;}//清空绘制clear() {//清除线面对象this.viewer.entities.remove(this.polygonEntity);this.polygonEntity = undefined;//清除节点this.vertexEntities.forEach(item => {this.viewer.entities.remove(item);});this.vertexEntities = [];this.viewer.entities.remove(this.mesureResultEntity);this.mesureResultEntity = undefined;this.height = undefined;}//创建面对象createPolygonEntity() {this.polygonEntity = this.viewer.entities.add({polygon: {hierarchy: new Cesium.CallbackProperty(e => {return new Cesium.PolygonHierarchy(this.tempPositions);//使用最新1.72的时候 必须返回PolygonHierarchy类型 Cannot read property 'length' of undefined//低版本好像都可以}, false),material: Cesium.Color.RED.withAlpha(0.4),perPositionHeight: true, //  },polyline: {positions: new Cesium.CallbackProperty(e => {return this.tempPositions.concat(this.tempPositions[0]);}, false),width: 1,material: new Cesium.PolylineDashMaterialProperty({color: Cesium.Color.YELLOW,}),depthFailMaterial: new Cesium.PolylineDashMaterialProperty({color: Cesium.Color.YELLOW,}),}})}//创建节点createVertex() {let vertexEntity = this.viewer.entities.add({position: this.positions[this.positions.length - 1],type: "MeasureAreaVertex",point: {color: Cesium.Color.FUCHSIA,pixelSize: 8,disableDepthTestDistance: 500,},});this.vertexEntities.push(vertexEntity);}//测量结果标签createResultLabel() {this.mesureResultEntity = this.viewer.entities.add({position: new Cesium.CallbackProperty(e => {return this.getCenterPosition()}, false),type: "MeasureAreaResult",label: {text: new Cesium.CallbackProperty(e => {return "面积" + computeArea(this.tempPositions) + "平方米";}, false),scale: 0.5,font: 'normal 28px MicroSoft YaHei',distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),verticalOrigin: Cesium.VerticalOrigin.BOTTOM,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, -30),outlineWidth: 9,outlineColor: Cesium.Color.YELLOW},});}//获取节点的中心点getCenterPosition() {let points = [];if (this.tempPositions.length < 3) return this.tempPositions[0];this.tempPositions.forEach(position => {const point3d = this.cartesian3ToPoint3D(position);points.push([point3d.x, point3d.y]);})//构建turf.js  lineStringlet geo = turf.lineString(points);let bbox = turf.bbox(geo);let bboxPolygon = turf.bboxPolygon(bbox);let pointOnFeature = turf.center(bboxPolygon);let lonLat = pointOnFeature.geometry.coordinates;return Cesium.Cartesian3.fromDegrees(lonLat[0], lonLat[1], this.height + 0.3);}//注册鼠标事件registerEvents() {this.leftClickEvent();this.rightClickEvent();this.mouseMoveEvent();}//左键点击事件leftClickEvent() {//单击鼠标左键画点点击事件this.handler.setInputAction(e => {this.viewer._element.style.cursor = 'default';let position = this.viewer.scene.pickPosition(e.position);if (!position) {const ellipsoid = this.viewer.scene.globe.ellipsoid;position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);}if (!position) return;this.positions.push(position);this.height = this.unifiedHeight(this.positions, this.height);if (this.positions.length == 1) { //首次点击  this.createPolygonEntity();}this.createVertex();}, Cesium.ScreenSpaceEventType.LEFT_CLICK);}//鼠标移动事件mouseMoveEvent() {this.handler.setInputAction(e => {if (!this.isMeasure) return;this.viewer._element.style.cursor = 'default';let position = this.viewer.scene.pickPosition(e.endPosition);if (!position) {position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);}if (!position) return;this.handleMoveEvent(position);}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);}//处理鼠标移动handleMoveEvent(position) {if (this.positions.length < 1) return;this.height = this.unifiedHeight(this.positions, this.height);this.tempPositions = this.positions.concat(position);if (this.tempPositions.length >= 3 && !this.mesureResultEntity) {this.createResultLabel();}}//统一节点的高度unifiedHeight(positions, height) {if (!height) height = this.getPositionHeight(positions[0]); //如果没有指定高度 就用第一个的高度let point3d;for (let i = 0; i < positions.length; i++) {const element = positions[i];point3d = this.cartesian3ToPoint3D(element);positions[i] = Cesium.Cartesian3.fromDegrees(point3d.x, point3d.y, height)}return height;}//获取某个点的高度getPositionHeight(position) {const cartographic = Cesium.Cartographic.fromCartesian(position);return cartographic.height;}cartesian3ToPoint3D(position) {const cartographic = Cesium.Cartographic.fromCartesian(position);const lon = Cesium.Math.toDegrees(cartographic.longitude);const lat = Cesium.Math.toDegrees(cartographic.latitude);return { x: lon, y: lat, z: cartographic.height };}//右键事件rightClickEvent() {this.handler.setInputAction(e => {if (!this.isMeasure || this.positions.length < 3) {this.deactivate();this.clear();} else {this.tempPositions = [...this.positions];this.polygonEntity.polyline = {positions: this.positions.concat(this.positions[0]),width: 2,material: Cesium.Color.YELLOW,depthFailMaterial: new Cesium.PolylineDashMaterialProperty({color: Cesium.Color.YELLOW,}),};this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(this.tempPositions);this.mesureResultEntity.position = this.getCenterPosition();this.mesureResultEntity.label.text = "总面积" + computeArea(this.positions) + "平方米"this.measureEnd();}}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);}//测量结束measureEnd() {this.deactivate();this.MeasureEndEvent.raiseEvent(this.measureArea); //触发结束事件 传入结果}//解除鼠标事件unRegisterEvents() {this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);}
}

详情参见 Cesium实战专栏

Cesium测量工具,距离测量、面积测量、高度测量相关推荐

  1. 基于数据融合和串级PID的小型四旋翼无人机高度测量与控制系统

    作者:Tomy 摘要:简单介绍了一种基于 Mahony 算法无人机姿态解算算法,并在这个的基础上设计了一 种融合惯导加速度计和气压计的小型无人机高度测量系统, 同时利用该高度测量系统设计了 基于串级 ...

  2. ScrollView高度测量原理

    在使用Lint扫描工程时,看到这个提示. Google推荐将ScrollView的子View高度设置为wrap_content,  但实际业务开发时可能根节点是LinearLayout(layout_ ...

  3. cesium进行模型高度测量的代码片段

    主要参考 https://sandcastle.cesium.com/index.html?src=Picking.html export function monitorMove() {const ...

  4. cesium面积计算_Cesium面积测量之思路解析加源码

    如果你看过我的距离量测文章,那么我相信,面积也是你需要测量的吧,那就看看吧. 一.实现思路 首先我们需要用到的鼠标移动事件.单击事件和双击事件,具体功能如下: 1,鼠标移动事件:判断是否开始进行测量操 ...

  5. 像素测量工具_结构光测量—工程质量管理的潜力股

    计算机视觉技术与图像处理技术的发展促进了三维测量技术的进步,基于计算机视觉的三维信息获取技术已成为了当前三维测量的主流技术方案,光学测量迅速成为了三维测量技术的热门研究内容.本文将介绍工程应用上三维测 ...

  6. Cesium geojson 区域拉伸高度

    geojson文件地址:http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=30.332329214580188&am ...

  7. 像素测量工具_一键式测量仪在手,磁性元件尺寸测量无忧

    智能手机元年已经迈入了折叠屏时代,厂商们都在公布自己在相关领域的突破,无论是内折还是外折,每一种都让消费者欣喜若狂.其中有一个功能,各厂商都实现了意见统一,那就是闭合功能需要使用磁铁佢支持.当前所发布 ...

  8. 什么软件能测试gps高度,‎App Store: GPS海拔测量仪-实时高度测量海拔表

    GPS海拔仪能准确实时的获取到当前位置的的海拔.GPS位置.气压.经纬度坐标信息,并且还带有指南针.天气等功能,进行户外活动的绝佳应用 [特色功能] 1. 海拔高度表:实时测量海拔,可以准确测量所在地 ...

  9. java网络流量测量工具_使用Indy测量网络流量

    我正在使用TIdTCPCmdServer来处理与客户端应用程序的所有通信. 我希望我的服务器记录所有类型的东西,包括网络流量. 有没有简单或聪明的方法来查看TCPCmdServer实际收到和发送了多少 ...

最新文章

  1. python中如何对复杂的json数据快速查找key对应的value值(使用JsonSearch包)
  2. Vagrant搭建Ubuntu-JavaEE开发环境——Tomcat+JDK+MySQL+dubbo+测试
  3. 1ke android逆向助手_android: 使用android逆向助手反编译APK
  4. 【转】内存耗用:VSS/RSS/PSS/USS
  5. Devops-运维效率之数据迁移自动化
  6. Open cup #2
  7. git提交报异常,fatal: The remote end hung up unexpectedly
  8. 预处理、const、static与sizeof-static全局变量与普通的全局变量有什么区别
  9. [WebApp开发]基础教程-Web App开发入门
  10. 网评计算机学校好,网评十大最痛苦专业:计算机、数学上榜
  11. c语言sobel边缘检测,C/C++ OpenCV之Sobel边缘检测
  12. 微信小程序map组件 markers 展示当前位置修改标记点图标
  13. 人工智能学习:CS188
  14. 解决fatal: unable to access‘‘:GnuTLS recv error
  15. GPRS远程开关 1 综述
  16. 利用Winhex,OllyDbg和W32Dasm破解USB监控器
  17. 一个关于计算分批进货按照先进先出规则的商品成本统计算法(js版本)
  18. epub 电子书的制作
  19. 维度表,实体表,事实表之间的关系
  20. 从设计哲学对比波卡与Cosmos

热门文章

  1. Django邮件应用--QQ邮箱、网易邮箱(二)
  2. 基于java毕业设计的汽车销售进销存
  3. [css选择器] 后代选择器
  4. 星城,你准备好了么?Greenplum走进长沙技术研讨会
  5. 《软件测试》第二章 软件开发的过程
  6. 02 - 语义网络,语义网,链接数据和知识图谱
  7. 15. 计算几何:圆的表示 点、直线、线段与圆的关系
  8. 智慧公厕,让厕所也成为城市文明的一部分
  9. 【DeepLearning笔记】python规范书写
  10. excel 2010 删除重复行(按某一列重复)