常见图层
绘图图层
let data = {
"type": "FeatureCollection",
"features": [
{
"id": "1",
"type": "Feature",
"properties": {
"name": "point1",
"color": "#00ffff",
"icon": "icon1"
},
"geometry": {
"coordinates": [
6971.5378667085715,
14385.014943907285
],
"type": "Point"
}
},
{
"id": "2",
"type": "Feature",
"properties": {
"name": "polyline1",
"color": "#00ffff"
},
"geometry": {
"coordinates": [
[
3006.0952985307595,
15198.972934052355
],
[
12606.64046359223,
9285.59366571666
],
[
4745.324495099878,
3720.060236694666
],
[
3006.0952985307595,
15198.972934052355
]
],
"type": "LineString"
}
},
{
"id": "3",
"type": "Feature",
"properties": {
"name": "polygon1",
"color": "#ff00ff"
},
"geometry": {
"coordinates": [
[
[
19841.833921319492,
13807.589576796912
],
[
19841.833921319492,
4207.0444117340885
],
[
26172.62819683108,
4207.0444117340885
],
[
26172.62819683108,
13807.589576796912
],
[
19841.833921319492,
13807.589576796912
]
]
],
"type": "Polygon"
}
}
]
}
map.getDrawLayer().set(map.toLngLat(data));
在沙箱中运行,调用唯杰地图公共演示服务
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: "sys_hello", // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapLightStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
showError(res.error)
return;
}
// 获取地图范围
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapBounds);
//
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapBounds.center()), // 设置地图中心点
zoom: 1, // 设置地图缩放级别
pitch: 0,
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
await map.onLoad();
let data = {
"type": "FeatureCollection",
"features": [
{
"id": "1",
"type": "Feature",
"properties": {
"name": "point1",
"color": "#00ffff",
"icon": "icon1"
},
"geometry": {
"coordinates": [
6971.5378667085715,
14385.014943907285
],
"type": "Point"
}
},
{
"id": "2",
"type": "Feature",
"properties": {
"name": "polyline1",
"color": "#00ffff"
},
"geometry": {
"coordinates": [
[
3006.0952985307595,
15198.972934052355
],
[
12606.64046359223,
9285.59366571666
],
[
4745.324495099878,
3720.060236694666
],
[
3006.0952985307595,
15198.972934052355
]
],
"type": "LineString"
}
},
{
"id": "3",
"type": "Feature",
"properties": {
"name": "polygon1",
"color": "#ff00ff"
},
"geometry": {
"coordinates": [
[
[
19841.833921319492,
13807.589576796912
],
[
19841.833921319492,
4207.0444117340885
],
[
26172.62819683108,
4207.0444117340885
],
[
26172.62819683108,
13807.589576796912
],
[
19841.833921319492,
13807.589576796912
]
]
],
"type": "Polygon"
}
}
]
}
map.getDrawLayer().set(map.toLngLat(data));热力图层
let heatmapLayer = new vjmap.Heatmap({
data: geoDatas,
// heatmapWeight:表示一个点对热力图权重的贡献,在贡献越大的地方热力图显示应该越明显
heatmapWeight: [
'interpolate',
['linear'],
['get', 'value'],
0, // 因为上面用了0,100,最小和最大值,把这两个最小和最大值归化到0,1区间
0,
100,
1
],
// heatmapRadius:热力图的一个点计算权重的时候计算的点的半径,单位为像素,默认为30
heatmapRadius: [
'interpolate',
['linear'],
['zoom'],
0, //0级别
10, //半径10
9, // 9级别 (其余级别,线性插值)
50 // 半径50
],
// heatmapColor:热力图的颜色,设置在各个热力图的数值上是什么颜色
heatmapColor: [
'interpolate',
['linear'],
['heatmap-density'],
0,
'rgba(33,102,172,0)',
0.2,
'rgb(103,169,207)',
0.4,
'rgb(209,229,240)',
0.6,
'rgb(253,219,199)',
0.8,
'rgb(239,138,98)',
1,
'rgb(178,24,43)'
],
//heatmapIntensity:热力图强度,有点类似于heatmapWeight属性,但是该属性是设置整体上热力图的强度
heatmapIntensity: [
'interpolate',
['linear'],
['zoom'],
0,
1,
9,
3
],
//heatmapOpacity:热力图的透明度
heatmapOpacity: [
'interpolate',
['linear'],
['zoom'],
7,
1,
9,
0
]
});
heatmapLayer.addTo(map);
在沙箱中运行,调用唯杰地图公共演示服务
// --热力图层--
// 地图服务对象
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: 'sys_zp', // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
message.error(res.error)
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapExtent.center()), // 设置地图中心点
zoom: 2, // 设置地图缩放级别
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
map.fitMapBounds();
await map.onLoad();
const mapBounds = map.getGeoBounds(0.6);
let geoDatas = []
for(let i = 0; i < 1000; i++) {
const pt = mapBounds.randomPoint();
const data = {
point: map.toLngLat(pt),
properties: {
value: vjmap.randInt(0, 100)
}
}
geoDatas.push(data)
}
let heatmapLayer = new vjmap.Heatmap({
data: geoDatas,
// heatmapWeight:表示一个点对热力图权重的贡献,在贡献越大的地方热力图显示应该越明显
heatmapWeight: [
'interpolate',
['linear'],
['get', 'value'],
0, // 因为上面用了0,100,最小和最大值,把这两个最小和最大值归化到0,1区间
0,
100,
1
],
// heatmapRadius:热力图的一个点计算权重的时候计算的点的半径,单位为像素,默认为30
heatmapRadius: [
'interpolate',
['linear'],
['zoom'],
0, //0级别
10, //半径10
9, // 9级别 (其余级别,线性插值)
50 // 半径50
],
// heatmapColor:热力图的颜色,设置在各个热力图的数值上是什么颜色
heatmapColor: [
'interpolate',
['linear'],
['heatmap-density'],
0,
'rgba(33,102,172,0)',
0.2,
'rgb(103,169,207)',
0.4,
'rgb(209,229,240)',
0.6,
'rgb(253,219,199)',
0.8,
'rgb(239,138,98)',
1,
'rgb(178,24,43)'
],
//heatmapIntensity:热力图强度,有点类似于heatmapWeight属性,但是该属性是设置整体上热力图的强度
heatmapIntensity: [
'interpolate',
['linear'],
['zoom'],
0,
1,
9,
3
],
//heatmapOpacity:热力图的透明度
heatmapOpacity: [
'interpolate',
['linear'],
['zoom'],
7,
1,
9,
0
]
});
heatmapLayer.addTo(map);
// 点击查询热力图层
map.on('click', heatmapLayer.layerId, (e) => {
map.logInfo(`影响此点热力值的要素有: ${e.features.length} 个`);
});背景遮盖层
const background = new vjmap.BackgroundLayer({
backgroundColor: "yellow",
backgroundOpacity: 0.4
}
)
background.addTo(map);
在沙箱中运行,调用唯杰地图公共演示服务
// 地图服务对象
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: 'sys_zp', // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
message.error(res.error)
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapExtent.center()), // 设置地图中心点
zoom: 2, // 设置地图缩放级别
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
map.fitMapBounds();
await map.onLoad();
const background = new vjmap.BackgroundLayer({
backgroundColor: "yellow",
backgroundOpacity: 0.4
}
)
background.addTo(map);自定义水印背景层
// 注意图片大小必须为2的指数倍,如(2, 4, 8, ..., 512)
await map.loadImageEx(`testwatermark`, `https://vjmap.com/static/assets/images/testwatermark.png`);
let layers = map.getStyle().layers
const background = new vjmap.BackgroundLayer({
backgroundPattern: "testwatermark",
backgroundOpacity: 0.3
})
background.addTo(map);
// 把这个图层放至所有图层的最下面
map.moveLayer(background.layerId, layers[0].id)
在沙箱中运行,调用唯杰地图公共演示服务
// 地图服务对象
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: 'sys_zp', // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
message.error(res.error)
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapExtent.center()), // 设置地图中心点
zoom: 2, // 设置地图缩放级别
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
map.fitMapBounds();
await map.onLoad();
// 注意图片大小必须为2的指数倍,如(2, 4, 8, ..., 512)
await map.loadImageEx(`testwatermark`, `https://vjmap.com/static/assets/images/testwatermark.png`);
let layers = map.getStyle().layers
const background = new vjmap.BackgroundLayer({
backgroundPattern: "testwatermark",
backgroundOpacity: 0.3
})
background.addTo(map);
// 把这个图层放至所有图层的最下面
map.moveLayer(background.layerId, layers[0].id)栅格图像图层
const mapBounds = map.getGeoBounds(0.001);
const coords = map.toLngLat(mapBounds.toPointArray());
map.addImageSource("park", {
url: "https://vjmap.com/static/assets/images/park.jpg",
coordinates: coords
})
map.addRasterLayer("parkLayer", "park", {
rasterOpacity: 0.8,
minzoom: 7,
maxzoom: 20
})
在沙箱中运行,调用唯杰地图公共演示服务
// --热力图层--
// 地图服务对象
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: 'sys_zp', // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
message.error(res.error)
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapExtent.center()), // 设置地图中心点
zoom: 9, // 设置地图缩放级别
pitch: 40, // 倾斜角度
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
await map.onLoad();
const mapBounds = map.getGeoBounds(0.001);
const coords = map.toLngLat(mapBounds.toPointArray());
map.addImageSource("park", {
url: "https://vjmap.com/static/assets/images/park.jpg",
coordinates: coords
})
map.addRasterLayer("parkLayer", "park", {
rasterOpacity: 0.8,
minzoom: 7,
maxzoom: 20
})
// 增加四个覆盖物用来调节位置
const colors = ["#FF0000", "#00FF00", "#0000FF", "#FFFF00"];
const markers = []
for(let c = 0; c < colors.length; c++) {
const marker = new vjmap.Marker({
color: colors[c],
draggable: true
});
marker.setLngLat(coords[c]).addTo(map);
marker.on('drag', e => {
updateBounds();
});
markers.push(marker);
}
const updateBounds = () => {
// 更新位置
map.getSource("park").setCoordinates(markers.map(m => {
let lngLat = m.getLngLat();
return [lngLat.lng,lngLat.lat]
}));
}天空图层
const sky = new vjmap.SkyLayer({
skyType: 'gradient',
skyGradient: [
'interpolate',
['linear'],
['sky-radial-progress'],
0.8,
'rgba(135, 206, 235, 1.0)',
1,
'rgba(0,0,0,0.1)'
],
skyGradientCenter: [0, 0],
skyGradientRadius: 90,
skyOpacity: [
'interpolate',
['exponential', 0.1],
['zoom'],
0,
0.3,
22,
1
]
}
)
sky.addTo(map);
在沙箱中运行,调用唯杰地图公共演示服务
// --热力图层--
// 地图服务对象
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: 'sys_zp', // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
message.error(res.error)
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapExtent.center()), // 设置地图中心点
zoom: 2, // 设置地图缩放级别,
pitch: 80, // 倾斜角度
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
map.fitMapBounds();
await map.onLoad();
const sky = new vjmap.SkyLayer({
skyType: 'gradient',
skyGradient: [
'interpolate',
['linear'],
['sky-radial-progress'],
0.8,
'rgba(135, 206, 235, 1.0)',
1,
'rgba(0,0,0,0.1)'
],
skyGradientCenter: [0, 0],
skyGradientRadius: 90,
skyOpacity: [
'interpolate',
['exponential', 0.1],
['zoom'],
0,
0.3,
22,
1
]
}
)
sky.addTo(map);唯杰地图三维图层
在沙箱中运行,调用唯杰地图公共演示服务
// --唯杰2D地图效果--唯杰2D地图为底图,vjmap3d做为一个3D图层叠加在上面
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: env.exampleMapId, // 地图ID
// @ts-ignore
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapLightStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
showError(res.error)
return;
}
// 获取地图范围
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapBounds);
let rasterStyle = svc.rasterStyle()
// @ts-ignore
rasterStyle.layers[0].paint = {
// 自定义地图样式,用深色来代替默认的样式
"raster-inverse": 1, // 0不反色 1 反色
"raster-monochrome": "#4586b6", // // 修改地图样式,用纯色代替
"raster-saturation": 0, // 饱和度 取值 -1 到 1
"raster-contrast": 0, // 对比度 取值 -1 到 1
}
//
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: rasterStyle, // 样式,这里是栅格样式
center: prj.toLngLat(mapBounds.center()), // 设置地图中心点
zoom: 1, // 设置地图缩放级别
pitch: 45,
antialias: true, // 反锯齿
renderWorldCopies: false // 不显示多屏地图
});
//
// 关联服务对象和投影对象
map.attach(svc, prj);
await map.onLoad();
//
// 创建3d图层
let mapLayer = new vjmap3d.MapThreeLayer(map, {
stat: {
show: true,
left: "0"
}
});
map.addLayer(new vjmap.ThreeLayer({ context: mapLayer }))
let app = mapLayer.app;
// 创建一个四棱锥
const createConeMesh = (co /*[number, number, number] | THREE.Vector3*/, opts /*{
size?: number;
height?: number;
color?: THREE.ColorRepresentation;
rotation?: boolean;
rotationAxis?: THREE.Vector3;
rotationSpeed?: number;
jumpHeightScale?: number;
jumpDuration?: number;
}*/, app) => {
opts ??= {};
let size = opts.size || 0.5;
let height = opts.height || size * 4; //棱锥高度
// 圆锥体几何体API(ConeGeometry)圆周方向四等分实现四棱锥效果
let geometry = new THREE.ConeGeometry(size, height, 4);
// 可以根据需要旋转到特定角度
// geometry.rotateX(Math.PI);
app ??= vjmap3d.Store.app;
if (app.isMapMode) {
geometry.rotateX(-Math.PI / 2);
geometry.translate(0, 0, height / 2);
} else {
geometry.rotateX(Math.PI);
geometry.translate(0, height / 2, 0);
}
// MeshBasicMaterial MeshLambertMaterial
let material = new THREE.MeshLambertMaterial({
color: opts.color || 0xffcc00,
});
let mesh = new THREE.Mesh(geometry, material);
// // 棱锥上在叠加一个棱锥
let mesh2 = mesh.clone();
if (app.isMapMode) {
//2维地图模式
mesh2.scale.z = 0.5;
mesh2.position.z = height * (1 + mesh2.scale.z);
} else {
//3维模式
mesh2.scale.y = 0.5;
mesh2.position.y = height * (1 + mesh2.scale.y);
}
mesh2.rotateX(Math.PI);
mesh.add(mesh2);
let entity = vjmap3d.Entity.fromObject3d(mesh);
let pt = vjmap3d.toVector3(co);
entity.position.copy(pt);
entity.addTo(app);
// 旋转
let mod = entity.addModule(vjmap3d.BehaviorModule);
let rotateId = "";
const startRotation = () => {
// 开始旋转
stopRotation();
rotateId = mod.addBehavior(vjmap3d.RotationBehavior.fromJSON({
axis: opts.rotationAxis ?? (app.isMapMode ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(0, 1, 0)),
speed: opts.rotationSpeed ?? 2,
resetWhenFinalize: true // 结束时复位成原来角度
}))
}
const stopRotation = () => {
// 停止旋转
if (rotateId) {
mod.removeBehaviorById(rotateId);
rotateId = ""
}
}
if (opts.rotation !== false) {
startRotation()
}
// 跳动
opts.jumpHeightScale ??= 0.6;
let jumpHeight = height * opts.jumpHeightScale;
let anim;
const startJump = () => {
if (anim) {
stopJump()
}
// 开始跳动
anim = vjmap3d.animation({
//from: mesh.position,
//to: new THREE.Vector3(mesh.position.x, mesh.position.y + dumpHeight, mesh.position.z),
duration: opts.jumpDuration ?? 1000,
onProgress(target, key, start, end, alpha, reversed) {
if (app.isMapMode) {
mesh.position.z = pt.z + alpha * jumpHeight
} else {
mesh.position.y = pt.y + alpha * jumpHeight
}
},
yoyoForever: true
})
}
const stopJump = () => {
// 停止跳动
if (!anim) return;
app.tweenManager.stopById(anim.id)
anim = null;
mesh.position.copy(pt);
}
if (jumpHeight != 0) {
startJump()
}
return {
entity,
startRotation,
stopRotation,
startJump,
stopJump
};
}
// 创建立体光墙
const createWall = (pts /*[number, number][]*/, opts /*{
height?: number;
flyline?: boolean;
texture1?: string;
repeatX?: number;
repeatY?: number;
color1?: THREE.ColorRepresentation;
offsetX?: number;
offsetY?: number;
texture2?: string;
color2?: THREE.ColorRepresentation;
opacity?: number
}*/, app /*vjmap3d.App*/) => {
opts ??= {};
let model = new THREE.Group(); //声明一个组对象,用来添加加载成功的三维场景
let c = [...pts];
let geometry = new THREE.BufferGeometry(); //声明一个空几何体对象
let posArr = [];
let uvrr = [];
let h = opts.height || 1; // 围墙拉伸高度
app ??= vjmap3d.Store.app;
for (let i = 0; i < c.length - 1; i++) {
if (app.isMapMode) {
// 二维地图模式
posArr.push(c[i][0], c[i][1], 0, c[i + 1][0], c[i + 1][1], 0, c[i + 1][0], c[i + 1][1], h);
posArr.push(c[i][0], c[i][1], 0, c[i + 1][0], c[i + 1][1], h, c[i][0], c[i][1], h);
} else {
posArr.push(c[i][0], 0, c[i][1], c[i + 1][0], 0, c[i + 1][1], c[i + 1][0], h, c[i + 1][1]);
posArr.push(c[i][0], 0, c[i][1], c[i + 1][0], h, c[i + 1][1], c[i][0], h, c[i][1]);
}
// 所有点展开 x方向从零到1 所有点生成的矩形铺满一张纹理贴图
uvrr.push(i / c.length, 0, i / c.length + 2 / c.length, 0, i / c.length + 2 / c.length, 1);
uvrr.push(i / c.length, 0, i / c.length + 2 / c.length, 1, i / c.length, 1);
}
// 设置几何体attributes属性的位置position属性
geometry.attributes.position = new THREE.BufferAttribute(new Float32Array(posArr), 3);
// 设置几何体attributes属性的位置uv属性
geometry.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvrr), 2);
geometry.computeVertexNormals();
if (opts.flyline !== false) {
let texture = vjmap3d.ResManager.loadTexture(opts.texture1 ?? env.assetsPath + "textures/wall1.png");
// 设置阵列模式为 RepeatWrapping
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.x = opts.repeatX || 3;// x方向阵列
texture.repeat.y = opts.repeatY || 3;// y方向阵列
let material = new vjmap3d.FlowMaterial({
color: new THREE.Color(opts.color1 || 0xffff00),
uvOffset: new THREE.Vector2(opts.offsetX || -1, opts.offsetY || 0),
uvScale: new THREE.Vector2(texture.repeat.x, texture.repeat.y), // repeat
map: texture,
side: THREE.DoubleSide, //两面可见
transparent: true, //需要开启透明度计算,否则着色器透明度设置无效
}, {time: app.commonUniforms.time});
let mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
model.add(mesh);
}
let texture2 = vjmap3d.ResManager.loadTexture(opts.texture2 ?? env.assetsPath + "textures/wall2.png");
let material2 = new THREE.MeshLambertMaterial({
color: opts.color2 || 0x00ffff,
map: texture2,
side: THREE.DoubleSide, //两面可见
transparent: true, //需要开启透明度计算,否则着色器透明度设置无效
opacity: opts.opacity || 0.5,//整体改变透明度
depthTest: false,
});
let mesh2 = new THREE.Mesh(geometry, material2); //网格模型对象Mesh
model.add(mesh2);
let entity = vjmap3d.Entity.fromObject3d(model);
entity.addTo(app);
return entity
}
// 创建波动光墙
const createWaveWall = (pt /*[number, number, number] | THREE.Vector3*/, opts /* {
size?: number;
height?: number;
}*/, app /*vjmap3d.App*/) => {
opts ??= {};
app ??= vjmap3d.Store.app;
let model = new THREE.Group(); //声明一个组对象
// 矩形平面网格模型设置背景透明的png贴图
let len = opts.size ?? 10;
let height = opts.height ?? len / 10;
const geometry = new THREE.CylinderGeometry(len, len, height, 32, 1, true);
geometry.translate(0, height / 2, 0);
if (app.isMapMode) {
// 二维地图模式
geometry.rotateX(Math.PI / 2.0);
}
let texture = vjmap3d.ResManager.loadTexture(opts.texture ?? env.assetsPath + "textures/wavewall.png")
let material = new THREE.MeshLambertMaterial({
color: opts.color || 0x00ffff,
map: texture,
side: THREE.DoubleSide, //两面可见
transparent: true, //需要开启透明度计算,否则着色器透明度设置无效
opacity: opts.opacity || 0.5,//整体改变透明度
depthTest: false,
});
let mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
model.add(mesh); //网格模型添加到model中
model.position.copy(vjmap3d.toVector3(pt));
let entity = vjmap3d.Entity.fromObject3d(model);
entity.addTo(app);
entity.addAnimationAction({
duration: 2000,
repeatForever: true
}, ({ alpha}) => {
model.scale.set(alpha, alpha, alpha)
})
return entity
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 查询要绘制的光墙线坐标
let query = await svc.conditionQueryFeature({
condition: `objectid='9BE'`, // 只需要写sql语句where后面的条件内容,字段内容请参考文档"服务端条件查询和表达式查询"
// 查询所有文字(包括单行文本,多行文本、块注记文字,属性文字) 具体类型数字参考文档"服务端条件查询和表达式查询-支持的cad实体类型"
// condition: `name='12' or name='13' or name='26' or name='27'`,
fields: ""
})
let linePoints = [];
if (query.error) {
showError(query.error)
return
} else {
if (query.recordCount > 0) {
let points = query.result[0].points; // 得到点坐标序列
linePoints = points.split(";").map(p => vjmap.GeoPoint.fromString(p));
// 闭合
linePoints.push(linePoints[0]);
linePoints = linePoints.map(p => vjmap3d.toWorld(p).toArray())
createWall(linePoints, {
height: vjmap3d.toDist(mapExtent.width() / 20)
}, app)
}
}
let c = mapExtent.center();
linePoints[0] = vjmap3d.toWorld(c).toArray();
for(let i = 0; i < linePoints.length; i++) {
if (i != 0) {
// 增加从中点至坐标点的飞线
vjmap3d.createFlyline({
source: [linePoints[0][0], linePoints[0][1], 0],
target: [linePoints[i][0], linePoints[i][1], 0],
count: 1000,
range: 200,
height: vjmap3d.toDist(mapExtent.width() / 5),
color: vjmap.randomColor(),
color2: vjmap.randomColor(),
size: 5000
}, app);
}
let pt = linePoints[i];
pt.z = 1000;
// 创建一个四棱锥
createConeMesh(pt, {
size: 10240,
color: vjmap.randomColor()
}, app);
}
// 创建一个波动光圈
createWaveWall(linePoints[0], {
color: "#ffff00",
size: vjmap3d.toDist(mapExtent.width() / 10),
height: vjmap3d.toDist(mapExtent.width() / 20),
}, app);
// 增加烟花背景
for(let i = 0; i < 20; i++) {
let pt = vjmap3d.toWorld(mapExtent.randomPoint().toArray());
vjmap3d.createFlyline({
source: [pt.x, pt.y, 0],
target: [pt.x, pt.y, vjmap3d.toDist(mapExtent.width() / 10)],
count: 1000,
range: 500,
height: 0,
color: vjmap.randomColor(),
color2: vjmap.randomColor(),
speed: 1,
size: 3,
opacity: 1.0,
}, app);
}视频图层
map.addSource("butterfly_src", {
type: 'video',
urls: ["https://vjmap.com/static/assets/video/butterfly.mp4"],
coordinates: map.toLngLat(mapBounds.toPointArray())
});
map.addLayer({
'id': 'video_layer',
'type': 'raster',
'source': 'butterfly_src'
});
let video = map.getSource('butterfly_src');
// 播放
// video.play();
// 暂停
// video.pause();
在沙箱中运行,调用唯杰地图公共演示服务
// --热力图层--
// 地图服务对象
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
mapid: 'sys_zp', // 地图ID
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
})
if (res.error) {
// 如果打开出错
message.error(res.error)
}
// 获取地图范围
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(mapExtent);
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: svc.rasterStyle(), // 样式,这里是栅格样式
center: prj.toLngLat(mapExtent.center()), // 设置地图中心点
zoom: 4, // 设置地图缩放级别
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
map.fitMapBounds();
await map.onLoad();
const mapBounds = map.getGeoBounds(0.1);
map.addSource("butterfly_src", {
type: 'video',
urls: ["https://vjmap.com/static/assets/video/butterfly.mp4"],
coordinates: map.toLngLat(mapBounds.toPointArray())
});
map.addLayer({
'id': 'video_layer',
'type': 'raster',
'source': 'butterfly_src'
});
let video = map.getSource('butterfly_src');
// 播放
// video.play();
// 暂停
// video.pause();这篇文档有帮助吗?感谢反馈!