接入互联网地图
大约 3 分钟
接入互联网地图
vjmapext 不仅可以用于 CAD 图纸,也能直接叠加在天地图、高德等互联网栅格底图之上。本节介绍推荐写法。
核心思路
- 内部坐标系统一用 Web Mercator 米(EPSG:3857)。
- 投影用
vjmap.GeoProjection+ 整个地球的 Mercator 范围[-EQ, -EQ, EQ, EQ],其中EQ = vjmap.Projection.EQUATORIAL_SEMIPERIMETER。 - 业务侧经纬度 → Mercator 米 后,作为实体坐标传入
MapCadLayer。
const EQ = vjmap.Projection.EQUATORIAL_SEMIPERIMETER;
const prj = new vjmap.GeoProjection(vjmap.GeoBounds.fromArray([-EQ, -EQ, EQ, EQ]));
// 经纬度 → 内部坐标 (Mercator 米)
const xy = vjmap.Projection.lngLat2Mercator([lng, lat]);天地图接入
const { MapCadLayer, CircleEnt, TextEnt } = vjmapext;
const svc = new vjmap.Service(env.serviceUrl, env.accessToken);
const EQ = vjmap.Projection.EQUATORIAL_SEMIPERIMETER;
const prj = new vjmap.GeoProjection(vjmap.GeoBounds.fromArray([-EQ, -EQ, EQ, EQ]));
const map = new vjmap.Map({
container: 'map',
style: {
version: svc.styleVersion(),
glyphs: svc.glyphsUrl(),
sources: {
tdtVec: {
type: 'raster',
tiles: ['https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=<你的token>']
},
tdtCva: {
type: 'raster',
tiles: ['https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=<你的token>']
}
},
layers: [
{ id: 'tdtVec', type: 'raster', source: 'tdtVec' },
{ id: 'tdtCva', type: 'raster', source: 'tdtCva' }
]
},
center: [116.3912, 39.9073],
zoom: 13,
renderWorldCopies: false
});
map.attach(svc, prj);
await map.onLoad();
// 浅色底图下,给工具默认色一个深色,避免预览线看不清
const mapcadLayer = new MapCadLayer({
defaultColor: 0x1f4e79,
drawingDefaults: {
color: 0x1f4e79,
fillColor: 0x1f4e79,
fillOpacity: 0.15
}
});
map.addControl(mapcadLayer);
mapcadLayer.createUI({ theme: 'light' });
// 添加实体:经纬度先转 Mercator 米
const p = vjmap.Projection.lngLat2Mercator([116.3912, 39.9073]);
const c = new CircleEnt([p[0], p[1]], 120);
c.color = 0xc0392b;
c.fillColor = 0xc0392b;
c.fillOpacity = 0.35;
mapcadLayer.addEntity(c);瓦片类型
vec_w:矢量路网img_w:影像cva_w:中文注记(通常和vec_w/img_w叠加使用)
高德地图接入(GCJ02 纠偏)
高德瓦片使用 GCJ02 火星坐标系,业务中常见的 WGS84(GPS)经纬度需要先纠偏到 GCJ02,再转 Mercator 米。vjmap 内置了转换函数:
// WGS84 经纬度 → 高德内部坐标 → Mercator 米
function wgsToXY(lng, lat) {
const gcj = vjmap.transform.convert(
[lng, lat],
vjmap.transform.CRSTypes.WGS84,
vjmap.transform.CRSTypes.GCJ02
);
return vjmap.Projection.lngLat2Mercator(gcj);
}完整示例:
const svc = new vjmap.Service(env.serviceUrl, env.accessToken);
const EQ = vjmap.Projection.EQUATORIAL_SEMIPERIMETER;
const prj = new vjmap.GeoProjection(vjmap.GeoBounds.fromArray([-EQ, -EQ, EQ, EQ]));
// 地图 center 用 WGS84 原始值时,也要先转 GCJ02 传给 Vjmap
const centerGcj = vjmap.transform.convert(
[116.3912, 39.9073],
vjmap.transform.CRSTypes.WGS84,
vjmap.transform.CRSTypes.GCJ02
);
const map = new vjmap.Map({
container: 'map',
style: {
version: svc.styleVersion(),
glyphs: svc.glyphsUrl(),
sources: {
gaode: {
type: 'raster',
tiles: ['https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}']
}
},
layers: [{ id: 'gaode', type: 'raster', source: 'gaode' }]
},
center: centerGcj,
zoom: 13,
renderWorldCopies: false
});
map.attach(svc, prj);
await map.onLoad();
const mapcadLayer = new MapCadLayer({
defaultColor: 0x1f4e79,
drawingDefaults: { color: 0x1f4e79, fillColor: 0x1f4e79, fillOpacity: 0.15 }
});
map.addControl(mapcadLayer);
mapcadLayer.createUI({ theme: 'light' });
// 业务坐标全部用 WGS84,wgsToXY 统一换算
const xy = wgsToXY(116.3912, 39.9073);注意
- vjmap 看到的始终是底图自己坐标系下的经纬度,所以
center也要传转换后的值。 - 如果坐标不纠偏,画的实体会偏移几十到上百米。
浅色底图下的视觉配置
互联网底图多为浅色。为了保证 UI 和绘图工具预览都可见:
UI 主题 选
light:mapcadLayer.createUI({ theme: 'light' });绘图默认色 设为深色(影响绘圆/椭圆等工具的实时预览,以及新建实体的默认颜色):
new MapCadLayer({ defaultColor: 0x1f4e79, drawingDefaults: { color: 0x1f4e79, fillColor: 0x1f4e79, fillOpacity: 0.15 } });body 背景色 建议设为与底图协调的浅灰色(demo runner 默认是深蓝,需要覆盖):
document.body.style.background = '#f5f7fa';
在线示例
| 示例 | 说明 |
|---|---|
| web/01webTianditu.js | 天地图道路底图 + CAD 实体叠加 |
| web/02webGaode.js | 高德地图(WGS84 → GCJ02 纠偏) |
| basic/04locale.js | 中英文 + 浅色/深色主题切换 |