cesium 经纬度绘制点_Cesium 绘制点、线、面和测距

本文基于ES6,采用React+Cesium的Webgis前端开发框架,目前threejs和cesium的结合正在研究中。此段代码采用原生javascript,可能过程中用到了es6的扁平化语法,如()=>{},list.map方法。

废话不多说了,直接上代码。

import Cesium from 'cesium/Source/Cesium';

import monitor from '../style/images/monitor.jpeg';

const ECesium = {

version: '0.1',

description: '自定义cesium组件',

copyright: '2018-enbo'

};

ECesium.Tools = function (viewer, callback) {

this.viewer = viewer;

this.init();

};

ECesium.Tools.prototype.init = function (back) {

//初始化事件

const viewer = this.viewer;

const scene = viewer.scene;

this.drawingMode = null;

this.measureMode = null;

this.geodesic = new Cesium.EllipsoidGeodesic();

this.handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);

this.dataSource = new Cesium.CustomDataSource('test1');

viewer.dataSources.add(this.dataSource);

console.log(viewer.dataSources.indexOf(this.dataSource));

};

ECesium.Tools.prototype.draw = function (type) {

if (!this.viewer) return console.error('this.viewer 未定义');

this.deactivate();

this.drawingMode = type;

switch (type) {

case this.DRAW_TYPE.Point:

this.DrawPoint();

break;

case this.DRAW_TYPE.PolyLine:

case this.DRAW_TYPE.Polygon:

this.DrawGraphics();

break;

default:

break;

}

};

ECesium.Tools.prototype.DrawPoint = function (callback) {

const viewer = this.viewer;

const this_ = this;

this.drawingMode = "point";

this.handler.setInputAction(function (evt) {

const ray = viewer.camera.getPickRay(evt.position);

const mapPosition = this_.getMapPoint(ray);

if (!mapPosition) return;

this_.dataSource.entities.add({

id: '云台' + Math.random(),

name: '林火监测点',

position: Cesium.Cartesian3.fromDegrees(mapPosition.x, mapPosition.y, mapPosition.z),

point: new Cesium.PointGraphics({

color: Cesium.Color.SKYBLUE,

pixelSize: 10,

outlineColor: Cesium.Color.YELLOW,

outlineWidth: 3,

heightReference: Cesium.HeightReference.CLAMP_TO_GROUND

}),

description: ``

});

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

};

ECesium.Tools.prototype.DrawGraphics = function (callback) {

const viewer = this.viewer;

const this_ = this;

let activeShapePoints = [];

let activeShape, floatingPoint;

this.handler.setInputAction(function (event) {

if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {

return console.log('This browser does not support polylines on terrain.');

}

const ray = viewer.camera.getPickRay(event.position);

const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);

if (Cesium.defined(earthPosition)) {

if (activeShapePoints.length === 0) {

floatingPoint = this_.createPoint(earthPosition);

activeShapePoints.push(earthPosition);

const dynamicPositions = new Cesium.CallbackProperty(function () {

return activeShapePoints;

}, false);

activeShape = this_.drawShape(dynamicPositions);

}

activeShapePoints.push(earthPosition);

this_.createPoint(earthPosition);

}

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

this.handler.setInputAction(function (event) {

if (Cesium.defined(floatingPoint)) {

const ray = viewer.camera.getPickRay(event.endPosition);

const newPosition = viewer.scene.globe.pick(ray, viewer.scene);

if (Cesium.defined(newPosition)) {

floatingPoint.position.setValue(newPosition);

activeShapePoints.pop();

activeShapePoints.push(newPosition);

}

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

this.handler.setInputAction(function () {

terminateShape();

}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

function terminateShape() {

activeShapePoints.pop();

this_.drawShape(activeShapePoints);

this.dataSource.entities.remove(floatingPoint);

this.dataSource.entities.remove(activeShape);

floatingPoint = undefined;

activeShape = undefined;

activeShapePoints = [];

}

};

ECesium.Tools.prototype.getMapPoint = function (ray) {

const viewer = this.viewer;

const cartesian = viewer.scene.globe.pick(ray, viewer.scene);

if (!cartesian) {

return null;

}

const cartographic = Cesium.Cartographic.fromCartesian(cartesian);

const lng = Cesium.Math.toDegrees(cartographic.longitude);//经度值

const lat = Cesium.Math.toDegrees(cartographic.latitude);//纬度值

//cartographic.height的值为地形高度。

return {x: lng, y: lat, z: cartographic.height};

};

ECesium.Tools.prototype.createPoint = function (worldPosition) {

return this.dataSource.entities.add({

position: worldPosition,

point: {

color: Cesium.Color.WHITE,

pixelSize: 5,

heightReference: Cesium.HeightReference.CLAMP_TO_GROUND

}

});

};

ECesium.Tools.prototype.drawShape = function (positionData) {

switch (this.drawingMode) {

case this.DRAW_TYPE.PolyLine:

return this.dataSource.entities.add({

polyline: {

positions: positionData,

clampToGround: true,

width: 3

}

});

case this.DRAW_TYPE.Polygon:

return this.dataSource.entities.add({

polygon: {

hierarchy: positionData,

material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7))

}

});

default:

return;

}

};

ECesium.Tools.prototype.measure = function (type) {

this.deactivate();

this.measureMode = type;

this.DrawMeasureGraphics();

};

ECesium.Tools.prototype.DrawMeasureGraphics = function () {

const viewer = this.viewer;

const this_ = this;

let activeShapePoints = [];

let activeShape, floatingPoint;

let measureDistance = 0, floatDistance = 0;

this.handler.setInputAction(function (event) {

if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {

return console.log('This browser does not support polylines on terrain.');

}

const ray = viewer.camera.getPickRay(event.position);

const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);

if (Cesium.defined(earthPosition)) {

if (activeShapePoints.length === 0) {

floatingPoint = this_.createMeasurePoint(earthPosition);

if (this_.measureMode === this_.MEASURE_TYPE.MEASURE_DISTANCE) {

floatingPoint.label = {

text: new Cesium.CallbackProperty(function (time) {

let distance = floatDistance = this_.getLatestLength(activeShapePoints);

return ((distance + measureDistance) / 1000).toFixed(2) + ' km';

}, false),

showBackground: true,

backgroundColor: new Cesium.Color(0, 0, 0, 0.5),

backgroundPadding: new Cesium.Cartesian2(7, 5),

font: '16px sans-serif',

};

this_.createLabel(earthPosition, '起点')

}

activeShapePoints.push(earthPosition);

const dynamicPositions = new Cesium.CallbackProperty(function () {

return activeShapePoints;

}, false);

activeShape = this_.drawMeasureShape(dynamicPositions);

}

if (activeShapePoints.length > 1 && this_.measureMode === this_.MEASURE_TYPE.MEASURE_DISTANCE) {

measureDistance += floatDistance;

this_.createLabel(earthPosition, (measureDistance / 1000).toFixed(2) + ' km');

}

activeShapePoints.push(earthPosition);

this_.createMeasurePoint(earthPosition);

}

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

this.handler.setInputAction(function (event) {

if (Cesium.defined(floatingPoint)) {

const ray = viewer.camera.getPickRay(event.endPosition);

const newPosition = viewer.scene.globe.pick(ray, viewer.scene);

if (Cesium.defined(newPosition)) {

floatingPoint.position.setValue(newPosition);

activeShapePoints.pop();

activeShapePoints.push(newPosition);

}

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

this.handler.setInputAction(function () {

terminateShape();

}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

function terminateShape() {

activeShapePoints.pop();

this_.drawMeasureShape(activeShapePoints);

this_.dataSource.entities.remove(floatingPoint);

this_.dataSource.entities.remove(activeShape);

floatingPoint = undefined;

activeShape = undefined;

activeShapePoints = [];

measureDistance = 0;

}

};

ECesium.Tools.prototype.drawMeasureShape = function (positionData, callback) {

console.log("draw shape");

switch (this.measureMode) {

case this.MEASURE_TYPE.MEASURE_DISTANCE:

return this.dataSource.entities.add({

polyline: {

positions: positionData,

clampToGround: true,

width: 3

}

});

case this.MEASURE_TYPE.MEASURE_AREA:

return this.dataSource.entities.add({

polygon: {

hierarchy: positionData,

material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7))

}

});

default:

return;

}

};

ECesium.Tools.prototype.getLatestLength = function (activeShapePoints) {

const length = activeShapePoints.length;

const endPoint = activeShapePoints[length - 1];

const startPoint = activeShapePoints[length - 2];

const startCartographic = Cesium.Cartographic.fromCartesian(startPoint);

const endCartographic = Cesium.Cartographic.fromCartesian(endPoint);

this.geodesic.setEndPoints(startCartographic, endCartographic);

return Math.round(this.geodesic.surfaceDistance);

};

ECesium.Tools.prototype.createMeasurePoint = function (worldPosition, callback) {

return this.dataSource.entities.add({

position: worldPosition,

point: {

color: Cesium.Color.WHITE,

pixelSize: 8,

outlineColor: Cesium.Color.RED,

outlineWidth: 3,

heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,

scaleByDistance: new Cesium.NearFarScalar(0, 0, 1, 1)

}

});

};

ECesium.Tools.prototype.createLabel = function (worldPosition, text) {

return this.dataSource.entities.add({

position: worldPosition,

label: {

text: text,

showBackground: true,

backgroundColor: new Cesium.Color(1, 1, 1, 0.7),

backgroundPadding: new Cesium.Cartesian2(7, 5),

font: '16px sans-serif',

fillColor: Cesium.Color.BLACK,

outlineColor: Cesium.Color.BLACK,

pixelOffset: new Cesium.Cartesian2(-15, -15)

}

});

};

ECesium.Tools.prototype.deactivate = function () {

if (this.handler) {

this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);

}

this.drawingMode = null;

};

ECesium.Tools.prototype.DRAW_TYPE = {

Point: 'Point',

PolyLine: 'PolyLine',

Polygon: 'Polygon'

};

ECesium.Tools.prototype.MEASURE_TYPE = {

MEASURE_DISTANCE: 'MeasureTerrainDistance',

MEASURE_AREA: 'MeasureTerrainArea'

};

export default ECesium;

使用时直接实例化ECesium

this.tool = new ECesium.Tools(this.viewer);

绘制图形

this.tool.draw('Point/PolyLine/Polygon');

测距

this.tool.measure(MeasureTerrainDistance);

Tips*面积测量没有添加计算方法,后期会加上。

你可能感兴趣的:(cesium,经纬度绘制点)