地图对象实体
MapViewEntity 继承于 MeshEntity, 里面包含 MapView 地图对象。
常用方法
MapViewEntity 是由 实体MeshEntity 派生而来。具体 MeshEntity 的所有属性和方法。同时可通过属性map访问 MapView 对象所有相关方法
| 方法 | 描述 |
|---|---|
| mapToLocal | 地图坐标转局部世界坐标 |
| localToMap | 局部世界坐标转地图坐标 |
| mapToWorld | 地图坐标转世界坐标 |
| worldToMap | 世界坐标转地图坐标 |
| lngLatToLocal | 经纬度转局部世界坐标 |
| localToLngLat | 局部世界坐标转经纬度 |
| lngLatToWorld | 经纬度转世界坐标 |
| worldToLngLat | 世界坐标转经纬度 |
| lngLatToNormalize | 经纬度转归一化的坐标 |
| getMapBounds | 获取地图范围 |
| worldResolution | 世界坐标中一个单位代表多少地图单位(= 地图范围宽度 ÷ 对应世界距离):互联网底图下是墨卡托米,CAD 底图下是 CAD 图形单位(不一定是米) |
| isWebBaseMap | 是否为互联网地图底图 (选项中设置了mapBounds的为cad底图,没设置mapBounds的为互联网底图) |
| setProvider | 设置地图数据提供者 |
| setHeightProvider | 设置地图地形高度数据提供者 |
| clear | 清空 |
| minZoom | 最小缩放级别 |
| maxZoom | 最大缩放级别 |
提示
调用 MapViewEntity 中的方法 等同于 调用 MapViewEntity.map 中的方法
如 MapViewEntity.mapToLocal 等价于 MapViewEntity.map.mapToLocal
构造函数第二参数与多张图
new vjmap3d.MapViewEntity(mapOptions, entityOptions?) 的第二参数除 MeshEntity 选项外还有:
autoSetAppCurrentMapView(默认true):加入 app 时把自己设为app.mapViewEntity;disableRayQuery(默认true):给地图网格打userData.disableRayQuery标记(实体射线查询会跳过带此标记的对象)。
vjmap3d.toWorld / fromWorld / toDist / fromDist 缺省使用 app.mapViewEntity——同一场景加多张图时最后加入的那张生效,需显式传 mapView 参数(toWorld/fromWorld 第 3 参、toDist/fromDist 第 4 参,如 vjmap3d.toWorld([x, y], app, mapviewEnt2)),或直接用 mapviewEnt2.mapToWorld(...)。
mapToWorld / lngLatToWorld 依赖地图节点的 matrixWorld,请在 addTo(app) 之后再调用(之前得到的是未经 baseScale 缩放的局部坐标)。
加载全世界地图
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
let provider = new vjmap3d.MapProvider(
[
{
url: tdtImgUrl,
},
{
url: tdtAnnoUrl
}
]
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: 100,
});
mapviewEnt.addTo(app);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtVecUrl =
"https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
let provider = new vjmap3d.MapProvider(
[
{
url: tdtImgUrl,
},
{
url: tdtAnnoUrl
}
]
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: 100,
});
mapviewEnt.addTo(app);
//
let lngLat = [116.3912, 39.9073];
let worldPoint = mapviewEnt.lngLatToWorld(lngLat);
let marker2d = new vjmap3d.Marker2D({
color: '#f00'
});
marker2d.setPosition(worldPoint);
marker2d.addTo(app);
加载瓦片调试图层
{
fetchTile: (zoom, x, y) => vjmap3d.MapUtils.fetchDebugTile(zoom, x, y, "#16417C", "#39107B")
}
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
let provider = new vjmap3d.MapProvider(
[
{
fetchTile: (zoom, x, y) => vjmap3d.MapUtils.fetchDebugTile(zoom, x, y, "#16417C", "#39107B")
},
{
url: tdtImgUrl,
opacity: 0.5
},
{
url: tdtAnnoUrl
}
]
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: 100,
});
mapviewEnt.addTo(app);
加载局部地图
通过指定 rootTile 根节点下为哪个瓦片来加载局部地图。
{
rootTile: [7, 105, 48] // 根节点下瓦片z,x,y 具体数字可通过调试瓦片得到
}
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtVecUrl =
"https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
let provider = new vjmap3d.MapProvider(
[
{
url: tdtVecUrl
},
{
url: tdtAnnoUrl
}
],
{
rootTile: [7, 105, 48]
}
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: 100,
});
mapviewEnt.addTo(app);
//
let lngLat = [116.3912, 39.9073];
let worldPoint = mapviewEnt.lngLatToWorld(lngLat);
let marker2d = new vjmap3d.Marker2D({
color: '#f00'
});
marker2d.setPosition(worldPoint);
marker2d.addTo(app);
//
let isRoadWayLayer = true; // 当前是否为道路图层
let control = new vjmap3d.ButtonGroupControl({
buttons: [
{
id: "grid",
html: "影像图层",
title: "影像图层",
style: {
width: "100px"
},
onclick: async () => {
if (!isRoadWayLayer) return;
isRoadWayLayer = false;
let provider = new vjmap3d.MapProvider([
{
url: tdtImgUrl
},
{
url: tdtAnnoUrl
}
],
{
rootTile: [7, 105, 48]
});
mapviewEnt.setProvider(provider);
}
},
{
id: "grid",
html: "道路图层",
title: "道路图层",
style: {
width: "100px"
},
onclick: async () => {
if (isRoadWayLayer) return;
isRoadWayLayer = true;
let provider = new vjmap3d.MapProvider([
{
url: tdtVecUrl
},
{
url: tdtAnnoUrl
}
],
{
rootTile: [7, 105, 48]
});
mapviewEnt.setProvider(provider);
}
},
{
id: "grid",
html: "调试图层",
title: "调试图层",
style: {
width: "100px"
},
onclick: async () => {
let provider = new vjmap3d.MapProvider([
{
fetchTile: (zoom, x, y) => vjmap3d.MapUtils.fetchDebugTile(zoom, x, y, "#16417C", "#39107B")
},
{
url: isRoadWayLayer ? tdtVecUrl : tdtImgUrl,
opacity: 0.5
},
{
url: tdtAnnoUrl
}
],
{
rootTile: [7, 105, 48]
});
mapviewEnt.setProvider(provider);
}
}
]
});
app.addControl(control, "top-right");
加载地形数据
通过指定 heightProvider 指定高度地形数据
// 地形高度数据
let heightProvider = new vjmap3d.MapProvider(
[
{
url: terrainHeightUrl
}
],
{
rootTile: [3, 6, 3]
}
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
heightProvider,
baseScale: 100,
});
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtVecUrl =
"https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
const terrainHeightUrl =
"https://your-terrain-server/{z}/{x}/{y}.png"; // 替换为 Terrain-RGB 编码的高程瓦片服务
let provider = new vjmap3d.MapProvider(
[
{
url: tdtImgUrl
},
{
url: tdtAnnoUrl
}
],
{
rootTile: [3, 6, 3]
}
);
// 地形高度数据
let heightProvider = new vjmap3d.MapProvider(
[
{
url: terrainHeightUrl
}
],
{
rootTile: [3, 6, 3]
}
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
heightProvider,
baseScale: 100,
});
mapviewEnt.addTo(app);
裁剪地图
通过 clipPolygon来设置裁剪多边形的范围
let clipRegion = [[117.210024,40.082262],[117.105315,40.074479],[117.344299,40.13443],[117.210024,40.082262]];
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: 100,
clipPolygon: clipRegion
});
数组形式只支持单个外环(不支持多多边形/挖洞)。需要挖洞时改传 THREE.Shape(在其 holes 中加洞),且 Shape 坐标是归一化的 0–1 地图坐标(不是经纬度/CAD 坐标),如下面的示例将生成一个圆环的裁剪地图
const circleRadius = 0.4;
const circleShape = new THREE.Shape().ellipse(
0.5,
0.5,
circleRadius,
circleRadius,
0,
Math.PI * 2,
true,
0
);
const holePath = new THREE.Path().ellipse(
0.5,
0.5,
circleRadius / 2,
circleRadius / 2,
0,
Math.PI * 2,
true,
0
);
circleShape.holes.push(holePath);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider: provider,
baseScale: 100,
clipPolygon: circleShape
});
mapviewEnt.addTo(app);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtVecUrl =
"https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
const terrainHeightUrl =
"https://your-terrain-server/{z}/{x}/{y}.png"; // 替换为 Terrain-RGB 编码的高程瓦片服务
let provider = new vjmap3d.MapProvider(
[
{
url: tdtImgUrl
},
{
url: tdtAnnoUrl
}
],
{
rootTile: [7, 105, 48]
}
);
// 地形高度数据
let heightProvider = new vjmap3d.MapProvider(
[
{
url: terrainHeightUrl
}
],
{
rootTile: [7, 105, 48]
}
);
let beijingRegion = [[117.210024,40.082262],[117.105315,40.074479],[117.105315,40.074479],[117.102851,40.073563],[117.102235,40.073105],[117.102235,40.073105],[117.102851,40.073563],[116.999989,40.030053],[116.927924,40.054788],[116.783794,40.035093],[116.757925,39.968176],[116.786874,39.886963],[116.926076,39.835524],[116.949482,39.778529],[116.902055,39.763813],[116.90575,39.687883],[116.812128,39.616018],[116.717273,39.603572],[116.717273,39.603572],[116.720969,39.599884],[116.720969,39.599884],[116.726512,39.595274],[116.726512,39.595274],[116.703106,39.588819],[116.703106,39.588819],[116.607636,39.619705],[116.524484,39.596657],[116.440716,39.527466],[116.433325,39.44296],[116.332927,39.457744],[116.245464,39.515466],[116.204196,39.588819],[116.10195,39.576368],[116.10195,39.576368],[115.957204,39.561147],[115.910393,39.600345],[115.910393,39.600345],[115.855574,39.554689],[115.855574,39.554689],[115.846951,39.550999],[115.846951,39.550999],[115.821081,39.517312],[115.821081,39.517312],[115.752712,39.512696],[115.752712,39.512696],[115.738545,39.539464],[115.738545,39.539925],[115.738545,39.539464],[115.738545,39.539925],[115.737314,39.544078],[115.737314,39.544078],[115.723763,39.544539],[115.723763,39.544539],[115.721299,39.543617],[115.721299,39.543617],[115.721299,39.55146],[115.721299,39.55146],[115.716988,39.560225],[115.716988,39.560225],[115.699125,39.577751],[115.698509,39.577751],[115.698509,39.577751],[115.699125,39.577751],[115.698509,39.577751],[115.69543,39.579135],[115.69543,39.579135],[115.586408,39.58928],[115.478619,39.650578],[115.478619,39.650578],[115.498945,39.69617],[115.498945,39.69617],[115.443511,39.785426],[115.443511,39.785426],[115.567314,39.816224],[115.514344,39.837821],[115.522967,39.898898],[115.426264,39.95029],[115.454597,40.029595],[115.599343,40.11979],[115.73485,40.129398],[115.773038,40.176044],[115.85311,40.148609],[115.89869,40.234536],[115.968907,40.264219],[115.9184,40.354103],[115.861733,40.364589],[115.861733,40.364589],[115.779197,40.442501],[115.755792,40.540333],[115.907929,40.617133],[116.005247,40.58397],[116.088399,40.62667],[116.22021,40.744181],[116.247311,40.791762],[116.464738,40.771827],[116.334159,40.90446],[116.473977,40.895867],[116.455499,40.98084],[116.519557,40.981292],[116.519557,40.981292],[116.599013,40.974516],[116.615643,41.053072],[116.688324,41.044499],[116.677853,40.970902],[116.730208,40.897676],[116.858323,40.833423],[116.964881,40.70972],[117.110858,40.70836],[117.286401,40.660719],[117.386799,40.684317],[117.49582,40.674334],[117.389879,40.5617],[117.344299,40.582152],[117.213104,40.512136],[117.225423,40.369148],[117.309191,40.279284],[117.309807,40.279284],[117.309191,40.279284],[117.309807,40.279284],[117.389879,40.228141],[117.367089,40.172387],[117.367089,40.172844],[117.367089,40.173301],[117.367089,40.173301],[117.367089,40.172844],[117.367089,40.172387],[117.344299,40.13443],[117.210024,40.082262]];
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
heightProvider,
baseScale: 100,
clipPolygon: beijingRegion
});
mapviewEnt.addTo(app);
// 根据给定的经纬度置为默认地图中心点
let world = mapviewEnt.lngLatToWorld([116.3912, 39.9073]);
app.cameraControl.moveTo(world.x, 0, world.z)
加载CAD图
通过指定 mapBounds 传入CAD地图范围
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
let res = await app.svc.openMap({
mapid: env.exampleMapId, // 地图ID,(请确保此ID已存在,可上传新图形新建ID)
mapopenway: vjmap3d.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap3d.openMapDarkStyle()
});
if (res.error) {
showError(res.error);
return;
}
// 获取当前地图的可视范围
let provider = new vjmap3d.MapProvider(
[
{
url: app.svc.rasterTileUrl()
}
],
{
transparent: true
}
);
let mapBounds = vjmap3d.GeoBounds.fromString(res.bounds)
let scale = 100;
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: scale,
mapBounds: mapBounds.toArray()
});
mapviewEnt.addTo(app);
// 根据cad图上的一个点用marker标记出来,看是否正确
let point = mapBounds.center().toArray();
//let local = mapview.mapToLocal(point);
let world = mapviewEnt.mapToWorld(point);
let marker2d = new vjmap3d.Marker2D({
color: '#f00'
});
marker2d.setPosition(world);
marker2d.addTo(app);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
let res = await app.svc.openMap({
mapid: env.exampleMapId, // 地图ID,(请确保此ID已存在,可上传新图形新建ID)
mapopenway: vjmap3d.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap3d.openMapDarkStyle()
});
if (res.error) {
showError(res.error);
return;
}
let provider = new vjmap3d.MapProvider(
[
{
url: app.svc.rasterTileUrl()
}
],
{
transparent: true
}
);
let mapBounds = vjmap3d.GeoBounds.fromString(res.bounds)
let scale = 100;
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: scale,
mapBounds: mapBounds.toArray()
});
mapviewEnt.addTo(app);
// 根据cad图上的一个点用marker标记出来,看是否正确
let point = mapBounds.center().toArray();
//let local = mapview.mapToLocal(point);
let world = mapviewEnt.mapToWorld(point);
let marker2d = new vjmap3d.Marker2D({
color: '#f00'
});
marker2d.setPosition(world);
marker2d.addTo(app);
同时创建加载多个CAD图
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
const createMap = async (mapId) => {
let res = await app.svc.openMap({
mapid: mapId, // 地图ID,(请确保此ID已存在,可上传新图形新建ID)
mapopenway: vjmap3d.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap3d.openMapDarkStyle()
});
if (res.error) {
showError(res.error);
return;
}
let provider = new vjmap3d.MapProvider(
[
{
url: app.svc.rasterTileUrl()
}
],
{
transparent: true
}
);
let mapBounds = vjmap3d.GeoBounds.fromString(res.bounds)
let scale = 100;
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: scale,
mapBounds: mapBounds.toArray()
});
mapviewEnt.addTo(app);
// 根据cad图上的一个点用marker标记出来,看是否正确
let point = mapBounds.center().toArray();
// 转成地图的局部坐标,再把这个marker加进地图实体中,做为一个子节点。这样地图实体位置变化,他也会相应变化
let local = mapviewEnt.mapToLocal(point);
let marker2d = new vjmap3d.Marker2D({
color: vjmap3d.randHtmlColor()
});
marker2d.setPosition(local);
marker2d.addTo(mapviewEnt);
return mapviewEnt;
}
let mapviewEnt1 = await createMap(env.exampleMapId);
let mapviewEnt2 = await createMap("sys_world");
mapviewEnt2.position.set(10, 5, 0);
拾取CAD图上的对象
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
let res = await app.svc.openMap({
mapid: env.exampleMapId, // 地图ID,(请确保此ID已存在,可上传新图形新建ID)
mapopenway: vjmap3d.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap3d.openMapDarkStyle()
});
if (res.error) {
showError(res.error);
return;
}
let provider = new vjmap3d.MapProvider(
[
{
url: app.svc.rasterTileUrl()
}
],
{
transparent: true
}
);
let mapBounds = vjmap3d.GeoBounds.fromString(res.bounds)
let scale = 100;
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: scale,
mapBounds: mapBounds.toArray()
});
mapviewEnt.addTo(app);
const pickMapObject = async () => {
let result = await app.pickPoint({
unprojectOpts: { include: [mapviewEnt.node], exclude: [] } // 直接传数组会被忽略、退化为全场景求交
});
if (!result.point) return;
console.log(result);
let mapPoint = mapviewEnt.worldToMap(result.point);
// @ts-ignore
let px = result.event.originalEvent.clientX, // unproject 用浏览器视口 client 坐标(内部减去容器 left/top)
// @ts-ignore
py = result.event.originalEvent.clientY;
// 获取一个像素多少地图长度
let worldPointNextPoint = app.unproject(px, py + 1, { include: [mapviewEnt.node], exclude: [] });
if (!worldPointNextPoint) return;
let mapNextPoint = mapviewEnt.worldToMap(worldPointNextPoint);
let onePixelDist = Math.max(
Math.abs(mapPoint[0] - mapNextPoint[0]),
Math.abs(mapPoint[1] - mapNextPoint[1])
);
// @ts-ignore
let queryResult = await svc.pointQueryFeature({
x: mapPoint[0],
y: mapPoint[1],
pixelsize: 5,
pixelToGeoLength: onePixelDist
});
if (queryResult.result?.length > 0) {
app.logInfo(`拾取的objectid是: ${queryResult.result[0].objectid}`, "success")
} else {
app.logInfo(`没有拾取到`, "warn")
}
}
let control = new vjmap3d.ButtonGroupControl({
buttons: [
{
id: "grid",
html: "拾取地图上的对象",
title: "拾取地图上的对象",
style: {
width: "130px"
},
onclick: async () => {
await pickMapObject()
}
}
]
});
app.addControl(control, "top-right");
CAD图与互联网地图叠加显示
const tdtImgUrl =
"https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=YOUR_TK";
const tdtAnnoUrl = `https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=YOUR_TK`;
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
stat: { show: true, left: "0" },
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
},
control: { leftButtonPan: true } // 设置为左键用于平移 (同时右键将用于旋转) 和地图2d使用习惯一样
})
let mapId = "sys_cadcesium";
let res = await svc.openMap({
mapid: mapId, // 地图ID
mapopenway: vjmap3d.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: vjmap3d.openMapDarkStyle() // div为深色背景颜色时,这里也传深色背景样式
});
if (res.error) {
// 如果打开出错
showError(res.error);
return;
}
let layer = res.layer; //图层样式名
let cadEpsg = "EPSG:4544"; // cad图的espg代号
// 增加cad的wms图层
let wmsUrl = svc.wmsTileUrl({
mapid: mapId, // 地图id
layers: layer, // 图层名称
bbox: "", // bbox这里不需要
srs: "EPSG:3857", //
crs: cadEpsg
});
wmsUrl += "&bbox={BBOX}";
let provider = new vjmap3d.MapProvider(
[
{
url: tdtImgUrl
},
{
url: tdtAnnoUrl
},
{
url: wmsUrl
}
],
{
rootTile: [8, 203, 106]
}
);
let mapviewEnt = new vjmap3d.MapViewEntity({
provider,
baseScale: 100,
});
mapviewEnt.addTo(app);
// 相机切换至CAD图所在的位置
app.cameraControl.loadState({
cameraTarget: new THREE.Vector3(6.585799392027572,-1.9140336121623333e-18, -39.579426677122015),
cameraPosition: new THREE.Vector3(6.585799392027572,19.84534552753801, -38.00315388879424),
})
地图加载3dtiles瓦片
地图加载3dtiles瓦片 需加载3dtiles插件,具体示例可参考 加载3D瓦片