<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>arcgis结合three js 之光标标记(带字体)</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.js"></script>
<link rel="stylesheet" href="https://js.arcgis.com/4.17/esri/themes/light/main.css"/>
<script src="https://js.arcgis.com/4.17/"></script>
<style>
html, body, #mapContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="mapContainer"></div>
</body>
<script>
require([
"esri/Map",
"esri/views/SceneView",
"esri/views/3d/externalRenderers",
'esri/geometry/support/webMercatorUtils',
"esri/geometry/SpatialReference",
"esri/geometry/Extent",
'esri/layers/GraphicsLayer',
'esri/Graphic',
], function (Map, SceneView, externalRenderers, webMercatorUtils, SpatialReference, Extent, GraphicsLayer, Graphic) {
let pointList = [
[117.23852198201362, 31.86098581806428],
[117.30175059354593, 31.866926290825337],
[117.28071356588781, 31.831107798543204]
];
var map = new Map({
basemap: {
portalItem: {
id: "8d91bd39e873417ea21673e0fee87604"
}
},
ground: 'world-elevation'
});
var view = new SceneView({
container: "mapContainer",
map: map,
viewingMode: "local",
camera: {
position: [117.27870319392615, 31.738730506030283, 9547.106932271272],
fov: 55,
heading: 359.99613521961805,
tilt: 55.00000000000099
}
});
view.on('click', function (evt) {
console.log(evt.mapPoint);
})
//加几个点标一下位置
pointList.forEach((item) => {
view.graphics.add(new Graphic({
geometry: {
type: 'point',
longitude: item[0],
latitude: item[1]
},
symbol: {
type: "point-3d",
symbolLayers: [{
type: "icon",
size: 8,
resource: {primitive: "circle"},
material: {color: "red"}
}]
}
}))
})
//引入three js
const myRenderer = {
view: view,
renderer: null, // three js 渲染器
camera: null, //three js 相机
scene: null, //three js 场景
height: 0,
angle: 0,
uniforms: null,
group: null,
setup: function (context) {
this.renderer = new THREE.WebGLRenderer({
context: context.gl,
premultipliedAlpha: false, //renderer 是否假设颜色有 premaultiplied alpha 默认为true
});
this.renderer.setPixelRatio(window.devicePixelRatio); //设置设备像素比。通常用于避免HiDPI设备上绘图模糊
this.renderer.setViewport(0, 0, view.width, view.height);//视图大小设置
//防止three.js 清除Arcgis JS API 提供的缓冲区
this.renderer.autoClearDepth = false; // 定义renderer是否清除深度缓存
this.renderer.autoClearStencil = false; // 定义renderer是否清除模板缓存
this.renderer.autoClearColor = false; // 定义renderer是否清除颜色缓存
// ArcGIS JS API渲染自定义离屏缓冲区,而不是默认的帧缓冲区。
// 我们必须将这段代码注入到three.js运行时中,以便绑定这些缓冲区而不是默认的缓冲区。
const originalSetRenderTarget = this.renderer.setRenderTarget.bind(
this.renderer
);
this.renderer.setRenderTarget = function (target) {
originalSetRenderTarget(target);
if (target == null) {
// 绑定外部渲染器应该渲染到的颜色和深度缓冲区
context.bindRenderTarget();
}
};
this.scene = new THREE.Scene();//场景
this.camera = new THREE.PerspectiveCamera();//相机
//添加坐标轴辅助工具
const axesHelper = new THREE.AxesHelper(10000000);
this.scene.add(axesHelper);
//创建几何体
let geometry = new THREE.CylinderBufferGeometry(0, 6.4, 11, 4, 1, false, 0, 6.3);
geometry.scale(10, 10, 10);
geometry.computeBoundingSphere();
this.uniforms = {
dtPyramidTexture: {
value: new THREE.TextureLoader().load('./img/saom.png')
},
time: {
value: 0.0
},
uColor: {
value: new THREE.Color('#f28000')
}
}
let uniforms = this.uniforms;
let material = new THREE.ShaderMaterial({
uniforms,
vertexShader: 'varying vec2 vUv;\n' +
'void main(){\n' +
'vUv = uv;\n' +
'gl_Position = projectionMatrix*viewMatrix*modelMatrix*vec4( position, 1.0 );\n' +
'}\n',
fragmentShader: 'uniform float time;\n' +
'varying vec2 vUv;\n' +
'uniform sampler2D dtPyramidTexture;\n' +
'uniform vec3 uColor;\n' +
'void main() {\n' +
' vec2 st = vUv;\n' +
' vec4 colorImage = texture2D(dtPyramidTexture, vec2(vUv.x,fract(vUv.y-time)));\n' +
'vec3 diffuse =(1.0-colorImage.a)*vec3(0.8,1.0,0.0)+colorImage.rgb*vec3(0.8,1.0,0);\n' +
'gl_FragColor = vec4(diffuse,0.7);\n' +
'}\n',
});
//确定几何体位置
this.group = new THREE.Group();
pointList.forEach((item) => {
let mesh = new THREE.Mesh(geometry, material);
var renderPos = [0, 0, 0];
externalRenderers.toRenderCoordinates(this.view, [item[0], item[1], 250], 0, SpatialReference.WGS84, renderPos, 0, 1);
mesh.position.set(renderPos[0], renderPos[1], renderPos[2]);
mesh.rotation.x = Math.PI / 2;
mesh.rotation.z = Math.PI;
mesh.scale.set(5, 5, 5);
//文字标签
var renderPos1 = [0, 0, 0];
externalRenderers.toRenderCoordinates(this.view, [item[0], item[1], 500], 0, SpatialReference.WGS84, renderPos1, 0, 1);
let sprite = makeTextSprite(" 这是我的文本标签!!!",
{
fontsize: 25,
borderColor: {r: 255, g: 0, b: 0, a: 0.4},/* 边框黑色 */
backgroundColor: {r: 255, g: 255, b: 255, a: 0.9}/* 背景颜色 */
});
sprite.position.set(renderPos1[0], renderPos1[1], renderPos1[2]);
this.group.add(sprite);
this.group.add(mesh);
})
this.
评论2