Common Layers
Drawing Layer
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));
Runs in a sandbox against the VJMAP public demo service
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: "sys_hello", // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapLightStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
showError(res.error)
return;
}
// Get map bounds
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapBounds);
//
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapBounds.center()), // Set map center
zoom: 1, // Set map zoom level
pitch: 0,
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
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));Heatmap Layer
let heatmapLayer = new vjmap.Heatmap({
data: geoDatas,
// heatmapWeight: contribution of a point to heatmap weight, heatmap should be more visible where contribution is greater
heatmapWeight: [
'interpolate',
['linear'],
['get', 'value'],
0, // Because 0,100 min and max above, normalize these to 0,1 range
0,
100,
1
],
// heatmapRadius: radius in pixels when calculating point weight for heatmap, default 30
heatmapRadius: [
'interpolate',
['linear'],
['zoom'],
0, // level 0
10, // radius 10
9, // level 9 (other levels, linear interpolation)
50 // radius 50
],
// heatmapColor: heatmap color, set color at each heatmap value
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: heatmap intensity, similar to heatmapWeight but sets overall heatmap intensity
heatmapIntensity: [
'interpolate',
['linear'],
['zoom'],
0,
1,
9,
3
],
// heatmapOpacity: heatmap transparency
heatmapOpacity: [
'interpolate',
['linear'],
['zoom'],
7,
1,
9,
0
]
});
heatmapLayer.addTo(map);
Runs in a sandbox against the VJMAP public demo service
// --Heatmap Layer--
// Map service object
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: 'sys_zp', // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapDarkStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
message.error(res.error)
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapExtent);
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapExtent.center()), // Set map center
zoom: 2, // Set map zoom level
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
map.attach(svc, prj);
// Fit map to full extent based on map bounds
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: contribution of a point to heatmap weight, heatmap should be more visible where contribution is greater
heatmapWeight: [
'interpolate',
['linear'],
['get', 'value'],
0, // Because 0,100 min and max above, normalize these to 0,1 range
0,
100,
1
],
// heatmapRadius: radius in pixels when calculating point weight for heatmap, default 30
heatmapRadius: [
'interpolate',
['linear'],
['zoom'],
0, // level 0
10, // radius 10
9, // level 9 (other levels, linear interpolation)
50 // radius 50
],
// heatmapColor: heatmap color, set color at each heatmap value
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: heatmap intensity, similar to heatmapWeight but sets overall heatmap intensity
heatmapIntensity: [
'interpolate',
['linear'],
['zoom'],
0,
1,
9,
3
],
// heatmapOpacity: heatmap transparency
heatmapOpacity: [
'interpolate',
['linear'],
['zoom'],
7,
1,
9,
0
]
});
heatmapLayer.addTo(map);
// Click to query heatmap layer
map.on('click', heatmapLayer.layerId, (e) => {
map.logInfo(`Features affecting heat value at this point: ${e.features.length}`);
});Background Overlay Layer
const background = new vjmap.BackgroundLayer({
backgroundColor: "yellow",
backgroundOpacity: 0.4
}
)
background.addTo(map);
Runs in a sandbox against the VJMAP public demo service
// Map service object
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: 'sys_zp', // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapDarkStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
message.error(res.error)
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapExtent);
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapExtent.center()), // Set map center
zoom: 2, // Set map zoom level
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
map.attach(svc, prj);
// Fit map to full extent based on map bounds
map.fitMapBounds();
await map.onLoad();
const background = new vjmap.BackgroundLayer({
backgroundColor: "yellow",
backgroundOpacity: 0.4
}
)
background.addTo(map);Custom Watermark Background Layer
// Note: image size must be power of 2, e.g. (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);
// Move this layer to the bottom of all layers
map.moveLayer(background.layerId, layers[0].id)
Runs in a sandbox against the VJMAP public demo service
// Map service object
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: 'sys_zp', // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapDarkStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
message.error(res.error)
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapExtent);
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapExtent.center()), // Set map center
zoom: 2, // Set map zoom level
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
map.attach(svc, prj);
// Fit map to full extent based on map bounds
map.fitMapBounds();
await map.onLoad();
// Note: image size must be power of 2, e.g. (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);
// Move this layer to the bottom of all layers
map.moveLayer(background.layerId, layers[0].id)Raster Image Layer
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
})
Runs in a sandbox against the VJMAP public demo service
// --Raster Image Layer--
// Map service object
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: 'sys_zp', // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapDarkStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
message.error(res.error)
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapExtent);
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapExtent.center()), // Set map center
zoom: 9, // Set map zoom level
pitch: 40, // Tilt angle
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
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
})
// Add four markers for position adjustment
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 = () => {
// Update position
map.getSource("park").setCoordinates(markers.map(m => {
let lngLat = m.getLngLat();
return [lngLat.lng,lngLat.lat]
}));
}Sky Layer
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);
Runs in a sandbox against the VJMAP public demo service
// --Sky Layer--
// Map service object
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: 'sys_zp', // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapDarkStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
message.error(res.error)
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapExtent);
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapExtent.center()), // Set map center
zoom: 2, // Set map zoom level,
pitch: 80, // Tilt angle
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
map.attach(svc, prj);
// Fit map to full extent based on map bounds
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);VJMap 3D Layer
Runs in a sandbox against the VJMAP public demo service
// --VJMap 2D map effect--VJMap 2D map as base, vjmap3d as 3D layer overlay
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: env.exampleMapId, // Map ID
// @ts-ignore
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapLightStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
showError(res.error)
return;
}
// Get map bounds
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapBounds);
let rasterStyle = svc.rasterStyle()
// @ts-ignore
rasterStyle.layers[0].paint = {
// Custom map style, use dark color instead of default
"raster-inverse": 1, // 0 no inverse 1 inverse
"raster-monochrome": "#4586b6", // Modify map style, use solid color instead
"raster-saturation": 0, // Saturation -1 to 1
"raster-contrast": 0, // Contrast -1 to 1
}
//
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: rasterStyle, // Style, raster style here
center: prj.toLngLat(mapBounds.center()), // Set map center
zoom: 1, // Set map zoom level
pitch: 45,
antialias: true, // Anti-aliasing
renderWorldCopies: false // Do not display multi-screen map
});
//
// Associate service object and projection object
map.attach(svc, prj);
await map.onLoad();
//
// Create 3D layer
let mapLayer = new vjmap3d.MapThreeLayer(map, {
stat: {
show: true,
left: "0"
}
});
map.addLayer(new vjmap.ThreeLayer({ context: mapLayer }))
let app = mapLayer.app;
// Create a pyramid
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; // Pyramid height
// ConeGeometry with 4 divisions for pyramid effect
let geometry = new THREE.ConeGeometry(size, height, 4);
// Can rotate to specific angle as needed
// 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);
// Stack another pyramid on top
let mesh2 = mesh.clone();
if (app.isMapMode) {
// 2D map mode
mesh2.scale.z = 0.5;
mesh2.position.z = height * (1 + mesh2.scale.z);
} else {
// 3D mode
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);
// Rotation
let mod = entity.addModule(vjmap3d.BehaviorModule);
let rotateId = "";
const startRotation = () => {
// Start rotation
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 // Reset to original angle when finished
}))
}
const stopRotation = () => {
// Stop rotation
if (rotateId) {
mod.removeBehaviorById(rotateId);
rotateId = ""
}
}
if (opts.rotation !== false) {
startRotation()
}
// Jump
opts.jumpHeightScale ??= 0.6;
let jumpHeight = height * opts.jumpHeightScale;
let anim;
const startJump = () => {
if (anim) {
stopJump()
}
// Start jump
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 = () => {
// Stop jump
if (!anim) return;
app.tweenManager.stopById(anim.id)
anim = null;
mesh.position.copy(pt);
}
if (jumpHeight != 0) {
startJump()
}
return {
entity,
startRotation,
stopRotation,
startJump,
stopJump
};
}
// Create light wall
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(); // Group object for loaded 3D scene
let c = [...pts];
let geometry = new THREE.BufferGeometry(); // Empty geometry object
let posArr = [];
let uvrr = [];
let h = opts.height || 1; // Wall extrusion height
app ??= vjmap3d.Store.app;
for (let i = 0; i < c.length - 1; i++) {
if (app.isMapMode) {
// 2D map mode
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]);
}
// All points expanded, x from 0 to 1, rectangles fill texture
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);
}
// Set geometry position attribute
geometry.attributes.position = new THREE.BufferAttribute(new Float32Array(posArr), 3);
// Set geometry uv attribute
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");
// Set wrap mode to RepeatWrapping
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.x = opts.repeatX || 3;// x direction repeat
texture.repeat.y = opts.repeatY || 3;// y direction repeat
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, // Both sides visible
transparent: true, // Enable transparency for shader
}, {time: app.commonUniforms.time});
let mesh = new THREE.Mesh(geometry, material); // Mesh object
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, // Both sides visible
transparent: true, // Enable transparency for shader
opacity: opts.opacity || 0.5,// Overall opacity
depthTest: false,
});
let mesh2 = new THREE.Mesh(geometry, material2); // Mesh object
model.add(mesh2);
let entity = vjmap3d.Entity.fromObject3d(model);
entity.addTo(app);
return entity
}
// Create wave light wall
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(); // Group object
// Rectangle plane with transparent PNG texture
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) {
// 2D map mode
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, // Both sides visible
transparent: true, // Enable transparency for shader
opacity: opts.opacity || 0.5,// Overall opacity
depthTest: false,
});
let mesh = new THREE.Mesh(geometry, material); // Mesh object
model.add(mesh); // Add mesh to 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
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Query light wall line coordinates
let query = await svc.conditionQueryFeature({
condition: `objectid='9BE'`, // Only write SQL condition after where, see "Server condition query and expression query" doc
// Query all text (single-line, multi-line, block annotation, attribute text)
// 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; // Get point sequence
linePoints = points.split(";").map(p => vjmap.GeoPoint.fromString(p));
// Close
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) {
// Add flyline from center to point
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;
// Create a pyramid
createConeMesh(pt, {
size: 10240,
color: vjmap.randomColor()
}, app);
}
// Create wave ring
createWaveWall(linePoints[0], {
color: "#ffff00",
size: vjmap3d.toDist(mapExtent.width() / 10),
height: vjmap3d.toDist(mapExtent.width() / 20),
}, app);
// Add fireworks background
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);
}Video Layer
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');
// Play
// video.play();
// Pause
// video.pause();
Runs in a sandbox against the VJMAP public demo service
// --Video Layer--
// Map service object
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// Open map
let res = await svc.openMap({
mapid: 'sys_zp', // Map ID
mapopenway: vjmap.MapOpenWay.GeomRender, // Open with geometry render mode
style: vjmap.openMapDarkStyle() // When div has dark background, pass dark background style here
})
if (res.error) {
// If open fails
message.error(res.error)
}
// Get map bounds
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
// Create geometric projection coordinate system based on map bounds
let prj = new vjmap.GeoProjection(mapExtent);
// Map object
let map = new vjmap.Map({
container: 'map', // DIV container ID
style: svc.rasterStyle(), // Style, raster style here
center: prj.toLngLat(mapExtent.center()), // Set map center
zoom: 4, // Set map zoom level
renderWorldCopies: false // Do not display multi-screen map
});
// Associate service object and projection object
map.attach(svc, prj);
// Fit map to full extent based on map bounds
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');
// Play
// video.play();
// Pause
// video.pause();Was this page helpful?Thanks for the feedback!