Skip to content

Commit d4e526c

Browse files
[fix]视频地图支持叠加矢量要素
AI-GEN: 70% Cursor
1 parent 0127971 commit d4e526c

17 files changed

Lines changed: 7387 additions & 5207 deletions

dist/mapboxgl/iclient-mapboxgl.css

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/mapboxgl/iclient-mapboxgl.js

Lines changed: 6163 additions & 5081 deletions
Large diffs are not rendered by default.

dist/mapboxgl/iclient-mapboxgl.min.css

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/mapboxgl/iclient-mapboxgl.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/locales/en-US/resources.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ window.examplesResources = {
739739
"title_chartService": "Chart",
740740
"title_videoLayer":"Video Layer",
741741
"title_videoMap":"Video Map",
742+
"title_videoMapWithTime":"Dynamic Video Map",
743+
"title_videoMapWithTime_qingdao":"Dynamic Video Map - Qingdao",
744+
"title_videoMapWithTime_huainan":"Dynamic Video Map - Huainan",
742745
"title_uavVideo":"Uav Video",
743746
"title_knowledgeGraphMap": "KnowledgeGraph",
744747
"title_l7_grid_map": "Grid Map",

examples/locales/zh-CN/resources.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,9 @@ window.examplesResources = {
714714
"text_selectEndNode": "捕捉结束节点",
715715
"title_videoLayer":"视频图层",
716716
"title_videoMap":"视频地图",
717+
"title_videoMapWithTime":"动态视频地图",
718+
"title_videoMapWithTime_qingdao":"动态视频地图 - 青岛",
719+
"title_videoMapWithTime_huainan":"动态视频地图 - 淮南",
717720
"title_uavVideo":"无人机视频",
718721
"title_knowledgeGraphMap": "知识图谱",
719722
"title_l7_grid_map": "网格地图",

examples/mapboxgl/config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,20 @@ var exampleConfig = {
18821882
version: '11.2.0',
18831883
thumbnail: 'videoLayerWithTime.png',
18841884
fileName: 'videoLayerWithTime'
1885+
},
1886+
{
1887+
name: '动态视频地图',
1888+
name_en: 'Dynamic Video Map',
1889+
version: '12.1.1',
1890+
thumbnail: 'videoMap.png',
1891+
fileName: 'videoMapWithTime'
1892+
},
1893+
{
1894+
name: '动态视频地图 - 淮南',
1895+
name_en: 'Dynamic Video Map - Huainan',
1896+
version: '12.1.1',
1897+
thumbnail: 'videoMap.png',
1898+
fileName: 'videoMapWithTime_huainan'
18851899
}
18861900
]
18871901
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<!--********************************************************************
2+
* Copyright© 2000 - 2026 SuperMap Software Co.Ltd. All rights reserved.
3+
*********************************************************************-->
4+
<!--********************************************************************
5+
* 该示例需要引入
6+
* mapbox-gl-enhance (https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.1-12/mapbox-gl-enhance.js)
7+
* Turf (https://github.com/Turfjs/turf/)
8+
* proj4js (https://github.com/proj4js/proj4js)
9+
* video.js (https://github.com/videojs/video.js)
10+
* opencv (https://github.com/opencv/opencv)
11+
*********************************************************************-->
12+
<!DOCTYPE html>
13+
<html>
14+
15+
<head>
16+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
17+
<title data-i18n="resources.title_uavVideo"></title>
18+
<style type="text/css">
19+
body {
20+
margin: 0;
21+
padding: 0;
22+
}
23+
24+
#map {
25+
position: absolute;
26+
top: 0;
27+
bottom: 0;
28+
width: 100%;
29+
}
30+
</style>
31+
</head>
32+
33+
<body>
34+
<div id="map"></div>
35+
<script type="text/javascript" include="bootstrap" src="../js/include-web.js"></script>
36+
<script type="text/javascript" include="mapbox-gl-enhance,proj4,turf,videojs,opencv"
37+
src="../../dist/mapboxgl/include-mapboxgl.js"></script>
38+
<script type="text/javascript">
39+
var map, videoLayer;
40+
var attribution =
41+
"<a href='https://www.mapbox.com/about/maps/' target='_blank'>© Mapbox </a>" +
42+
" with <span>© <a href='https://iclient.supermap.io' target='_blank'>SuperMap iClient</a> | </span>" +
43+
" Map Data <span>© <a href='http://support.supermap.com.cn/product/iServer.aspx' target='_blank'>SuperMap iServer</a></span> ";
44+
var dataUrl = 'http://172.16.14.44:8090/iserver/services/data-qingdao/rest/data';
45+
var datasourceName = 'qingdao';
46+
var datasetName = 'video';
47+
var map = new mapboxgl.Map({
48+
container: 'map',
49+
renderWorldCopies: false,
50+
style: {
51+
version: 8,
52+
sources: {
53+
'raster-tiles': {
54+
type: 'raster',
55+
tileSize: 256,
56+
tiles: [
57+
'https://t4.tianditu.gov.cn/img_w/wmts?service=WMTS&request=GetTile&version=1.0.0&style=default&tilematrixSet=w&format=tiles&width=256&height=256&layer=img&tilematrix={z}&tilerow={y}&tilecol={x}&tk=1d109683f4d84198e37a38c442d68311'
58+
]
59+
}
60+
},
61+
layers: [
62+
{
63+
id: 'simple-tiles',
64+
type: 'raster',
65+
source: 'raster-tiles',
66+
minzoom: 0,
67+
maxzoom: 22
68+
}
69+
]
70+
},
71+
center: [
72+
120.1602827751941, 35.94287657808641],
73+
zoom: 16.98
74+
});
75+
map.addControl(new mapboxgl.NavigationControl(), 'top-left');
76+
map.addControl(new mapboxgl.supermap.LogoControl({ link: 'https://iclient.supermap.io' }), 'bottom-right');
77+
function query() {
78+
var sqlParam = new mapboxgl.supermap.GetFeaturesBySQLParameters({
79+
queryParameter: {
80+
name: datasetName + '@' + datasourceName,
81+
attributeFilter: 'SMID > 0'
82+
},
83+
datasetNames: [datasourceName + ':' + datasetName]
84+
});
85+
86+
new mapboxgl.supermap.FeatureService(dataUrl).getFeaturesBySQL(sqlParam).then(function (serviceResult) {
87+
const timeData = [];
88+
serviceResult.result.features.features[0].properties.videoParameters.videoParameterList.forEach((param) => {
89+
let coordinates1 = [];
90+
param.extent.points.forEach((coord) => {
91+
const res = proj4('EPSG:3857', 'EPSG:4326', coord);
92+
coordinates1.push(res);
93+
});
94+
let cameraLocation = param.calibrationModel.cameraLocation;
95+
let calibrationModel = param.calibrationModel;
96+
timeData.push({
97+
time: param.time,
98+
extent: [coordinates1[3], coordinates1[2], coordinates1[1], coordinates1[0]],
99+
fovX: calibrationModel.fovX,
100+
fovY: calibrationModel.fovY,
101+
centerX: calibrationModel.centerX,
102+
centerY: calibrationModel.centerY,
103+
pitch: cameraLocation.cameraPitch,
104+
roll: cameraLocation.cameraRoll,
105+
yaw: cameraLocation.cameraYaw,
106+
x: cameraLocation.cameraX,
107+
y: cameraLocation.cameraY,
108+
z: cameraLocation.cameraZ
109+
});
110+
});
111+
let coordinates = [];
112+
turf.featureEach(serviceResult.result.features, function (currentFeature, featureIndex) {
113+
currentFeature.geometry.coordinates[0][0].forEach((coord) => {
114+
const res = proj4('EPSG:3857', 'EPSG:4326', coord);
115+
coordinates.push(res);
116+
});
117+
});
118+
var url = serviceResult.result.features.features[0].properties.address;
119+
var cameraLocation = serviceResult.result.features.features[0].properties.cameraLocation;
120+
var calibrationModel =
121+
serviceResult.result.features.features[0].properties.videoParameters.videoParameterList[0].calibrationModel;
122+
var clipRegionPoints =
123+
serviceResult.result.features.features[0].properties.videoParameters.videoParameterList[0].clipRegion
124+
.points;
125+
videoLayer = new mapboxgl.supermap.VideoLayer({
126+
url,
127+
videoParameters: timeData,
128+
interval: 0.033,
129+
clipRegion: [
130+
[clipRegionPoints[0].x, clipRegionPoints[0].y],
131+
[clipRegionPoints[1].x, clipRegionPoints[1].y],
132+
[clipRegionPoints[2].x, clipRegionPoints[2].y],
133+
[clipRegionPoints[3].x, clipRegionPoints[3].y]
134+
]
135+
});
136+
map.addLayer(videoLayer);
137+
});
138+
}
139+
map.on('load', function () {
140+
query();
141+
});
142+
map.on('click', function (event) {
143+
console.log('vectorupdate:', map.getZoom(), event);
144+
});
145+
</script>
146+
</body>
147+
148+
</html>
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<!--********************************************************************
2+
* Copyright© 2000 - 2026 SuperMap Software Co.Ltd. All rights reserved.
3+
*********************************************************************-->
4+
<!DOCTYPE html>
5+
<html>
6+
<head>
7+
<meta charset="utf-8" />
8+
<title data-i18n="resources.title_videoMapWithTime"></title>
9+
<style>
10+
body { margin: 0; padding: 0; }
11+
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
12+
</style>
13+
</head>
14+
<body>
15+
<div id="map"></div>
16+
<script type="text/javascript" include="bootstrap" src="../js/include-web.js"></script>
17+
<script type="text/javascript" include="mapbox-gl-enhance,proj4,turf,videojs,opencv" src="../../dist/mapboxgl/include-mapboxgl.js"></script>
18+
<script type="text/javascript">
19+
var dataUrl = 'http://172.16.14.44:8090/iserver/services/data-video/rest/data';
20+
var videoMap;
21+
var count = 0;
22+
var activePopups = [];
23+
24+
function queryFeatures(datasetName, dataSourceName) {
25+
var sqlParam = new mapboxgl.supermap.GetFeaturesBySQLParameters({
26+
queryParameter: {
27+
name: datasetName + '@' + dataSourceName,
28+
attributeFilter: 'SMID > 0'
29+
},
30+
targetEpsgCode: '4326',
31+
datasetNames: [dataSourceName + ':' + datasetName]
32+
});
33+
return new mapboxgl.supermap.FeatureService(dataUrl).getFeaturesBySQL(sqlParam);
34+
}
35+
36+
function addVectorDataset(datasetName) {
37+
queryFeatures(datasetName, 'TFxinqu').then(function (serviceResult) {
38+
var features = serviceResult.result.features;
39+
var sourceId = 'dynamic-source-' + count;
40+
var layerId = 'dynamic-layer-' + count;
41+
count++;
42+
videoMap.addSource(sourceId, { type: 'geojson', data: features });
43+
var type = features.features[0].geometry.type;
44+
var layer = {
45+
id: layerId,
46+
type: type === 'Point' ? 'circle' : type === 'LineString' ? 'line' : 'fill',
47+
source: sourceId,
48+
paint: type === 'Point'
49+
? { 'circle-radius': 5, 'circle-color': '#ff5a36', 'circle-stroke-width': 1, 'circle-stroke-color': '#ffffff' }
50+
: type === 'LineString'
51+
? { 'line-width': 4, 'line-color': '#ff9f1c' }
52+
: { 'fill-color': '#48cae4', 'fill-opacity': 0.55 }
53+
};
54+
videoMap.addLayer(layer);
55+
videoMap.map.on('click', layerId, function (e) {
56+
var feature = e.features[0];
57+
var properties = feature.properties;
58+
var html =
59+
'<div style="max-height:300px;overflow:auto;min-width:160px;">' +
60+
'<h4 style="margin:0 0 8px;font-size:13px;">' + datasetName + '</h4>' +
61+
'<table style="border-collapse:collapse;font-size:12px;">';
62+
Object.keys(properties).forEach(function (key) {
63+
html +=
64+
'<tr>' +
65+
'<td style="padding:2px 12px 2px 0;color:#888;vertical-align:top;">' + key + '</td>' +
66+
'<td style="padding:2px 0;vertical-align:top;">' + properties[key] + '</td>' +
67+
'</tr>';
68+
});
69+
html += '</table></div>';
70+
var spatialPoint = videoMap.toSpatialCoordinate(e.lngLat);
71+
var popup = new mapboxgl.Popup({ closeButton: true, closeOnClick: true })
72+
.setLngLat(e.lngLat)
73+
.setHTML(html)
74+
.addTo(videoMap.map);
75+
activePopups.push({ popup: popup, spatialPoint: spatialPoint });
76+
popup.on('close', function () {
77+
activePopups = activePopups.filter(function (item) {
78+
return item.popup !== popup;
79+
});
80+
});
81+
});
82+
videoMap.map.on('mouseenter', layerId, function () {
83+
videoMap.map.getCanvas().style.cursor = 'pointer';
84+
});
85+
videoMap.map.on('mouseleave', layerId, function () {
86+
videoMap.map.getCanvas().style.cursor = '';
87+
});
88+
});
89+
}
90+
91+
function createVideoMap() {
92+
queryFeatures('DJI_09304', 'VideoData').then(function (serviceResult) {
93+
var feature = serviceResult.result.features.features[0];
94+
var parameters = feature.properties.videoParameters.videoParameterList.map(function (item) {
95+
var calibration = item.calibrationModel;
96+
var camera = calibration.cameraLocation;
97+
return {
98+
time: item.time,
99+
fovX: calibration.fovX,
100+
fovY: calibration.fovY,
101+
centerX: calibration.centerX,
102+
centerY: calibration.centerY,
103+
pitch: camera.cameraPitch,
104+
roll: camera.cameraRoll,
105+
yaw: camera.cameraYaw,
106+
x: camera.cameraX,
107+
y: camera.cameraY,
108+
z: camera.cameraZ
109+
};
110+
});
111+
videoMap = new mapboxgl.supermap.VideoMap({
112+
url: feature.properties.address,
113+
videoParameters: parameters,
114+
interval: 0.1,
115+
vectorUpdateInterval: 0.1,
116+
styleOptions: {
117+
sprite: 'https://iclient.supermap.io/web/styles/street/sprite',
118+
glyphs: 'https://iserver.supermap.io/iserver/services/map-beijing/rest/maps/beijingMap/tileFeature/sdffonts/{fontstack}/{range}.pbf'
119+
}
120+
});
121+
videoMap.on('load', function () {
122+
['trafficGuideLine', 'road', 'building', 'landuse'].forEach(addVectorDataset);
123+
});
124+
videoMap.on('vectorupdate', function () {
125+
activePopups.forEach(function (item) {
126+
if (!item.spatialPoint) {
127+
return;
128+
}
129+
var lngLat = videoMap.toVideoMapCoordinate(item.spatialPoint);
130+
if (lngLat) {
131+
item.popup.setLngLat(lngLat);
132+
}
133+
});
134+
});
135+
});
136+
}
137+
138+
createVideoMap();
139+
</script>
140+
</body>
141+
</html>

0 commit comments

Comments
 (0)