baidu
本文回答:百度地图的特殊坐标系 BD09、WMS 叠加透明色坑与 GeoJSON 叠加备用方案。
一、坐标系
百度地图使用独立的 BD09 坐标系(GCJ02 上再加一层偏移),且其瓦片投影为 百度墨卡托(非 EPSG:3857)。
因此:
- 不能直接通过 vjmap 标准栅格源显示百度地图(投影不同)。
- 只能在 百度 JSAPI GL 里叠加 CAD WMS。
二、在百度地图 SDK 中叠加 CAD WMS(有坐标系)
const map = new BMapGL.Map("allmap");
map.centerAndZoom(new BMapGL.Point(116.49, 39.97), 15);
const svc = new vjmap.Service(URL, TOKEN);
const mapId = "sys_cad2000";
const res = await svc.openMap({ mapid: mapId, mapopenway: vjmap.MapOpenWay.GeomRender });
if (res.error) throw new Error(res.error);
const wmsUrl = svc.wmsTileUrl({
mapid: mapId,
layers: res.layer,
srs: "EPSG:3857", // 百度 WMS 支持 EPSG:3857
crs: "EPSG:4548", // CAD EPSG(sys_cad2000 = CGCS2000 3° 带 117°E;4544 是 105°E 带)
bbox: "" // ⚠️ 必填:清空默认的 {bbox-epsg-3857} 占位,否则该字面量会发到服务端
// 不用填 webMapType:默认 WGS84 的 WMS 服务就能用(百度 JSAPI 自己做了加偏)
});
const wmsLayer = BMapGL.XYZLayer({
tileUrlTemplate: wmsUrl + "&BBOX=[b]", // 百度 XYZLayer 的 BBOX 占位符(官方示例同款写法)
useThumbData: false
});
map.addTileLayer(wmsLayer);
三、无坐标系 CAD:四参数校准
// 在 CAD 上取 2 个及以上控制点
const cadPoints = [
vjmap.geoPoint([587464448.84, 3104003685.21]),
vjmap.geoPoint([587761927.72, 3104005967.66]),
vjmap.geoPoint([587463688.03, 3103796743.38]),
vjmap.geoPoint([587760406.09, 3103793700.12])
];
// 对应点:在百度地图上点取(BD09 坐标)
const webPoints = [
vjmap.geoPoint([116.497386, 39.969244]),
vjmap.geoPoint([116.500002, 39.967539]),
vjmap.geoPoint([116.498440, 39.966136]),
vjmap.geoPoint([116.495814, 39.967791])
];
// BD09 → EPSG:3857
const mercPoints = webPoints.map(w =>
vjmap.geoPoint(vjmap.transform.convert(w, vjmap.transform.CRSTypes.BD09, vjmap.transform.CRSTypes.EPSG3857))
);
// 求四参数(考虑旋转)
const p = vjmap.coordTransfromGetFourParamter(mercPoints, cadPoints, false);
const fourparam = [p.dx, p.dy, p.scale, p.rotate];
const wmsUrl = svc.wmsTileUrl({
mapid: mapId, layers: res.layer,
srs: "EPSG:3857",
bbox: "", // ⚠️ 清空默认占位,BBOX 由百度 [b] 提供
fourParameter: fourparam,
transparent: true
});
map.addTileLayer(BMapGL.XYZLayer({ tileUrlTemplate: wmsUrl + "&BBOX=[b]" }));
四、百度 WMS 透明色坑
现象:透明 WMS 叠到百度地图上,CAD 颜色发生变化(偏蓝 / 偏灰)。
原因:百度 JSAPI 对透明 tile 的 blend 方式与其他底图不同,暂无公开解法。
解法 A:关闭透明度,改用纯色背景。
const wmsUrl = svc.wmsTileUrl({
...,
transparent: false,
backgroundColor: "rgba(240,255,255)" // 固定背景,颜色正常
});
代价:看不到 CAD 覆盖区域的百度地图。
解法 B:换 GeoJSON 方式展示 CAD(见下节)。
五、GeoJSON 方式叠加 CAD(替代 WMS)
// 1) 查询 CAD 所有几何
async function queryData() {
const res = await svc.conditionQueryFeature({
condition: "",
fields: "",
includegeom: true,
realgeom: true,
limit: 100000
}, pt => {
// 坐标回调:CAD → WGS84 经纬度(下面 GeoJSONLayer 的 reference 是 "WGS84",由百度自己加偏;
// 这里若返回 BD09 会被再加偏一次)
const cadPt = cadPrj.fromMercator(pt);
return cadToWgs84(cadPt); // 如 proj4(cadEpsg, "EPSG:4326", cadPt.toArray())
});
const features = [];
for (const ent of res.result) {
if (!ent.geom?.geometries) continue;
const clr = vjmap.entColorToHtmlColor(ent.color);
ent.geom.geometries.forEach((g, i) => {
features.push({
type: "Feature",
id: ent.id,
properties: { objectid: ent.objectid + "_" + i, color: clr },
geometry: g
});
});
}
return { type: "FeatureCollection", features };
}
// 2) 加载到百度
const layer = new BMapGL.GeoJSONLayer("cad-child", {
reference: "WGS84",
dataSource: await queryData(),
level: -10,
polygonStyle: p => ({ fillColor: p.color }),
polylineStyle: p => ({ strokeColor: p.color })
});
bmap.addGeoJSONLayer(layer, { maxZoom: 24 });
优点:透明度正常、可交互(hover / click)。 缺点:GeoJSON 体量大,前端渲染慢;大图不适合。
六、常见坑
- 直接当标准墨卡托底图加载百度瓦片 → 投影不同,图片完全错位。
- BD09 和 GCJ02 混淆 → 坐标计算链中
convert参数错,常见多一次/少一次加偏,结果差 500~2000 米。 useThumbData: true→ 百度缓存缩略图;WMS 动态数据要关掉。- WMS URL 里带
&:百度tileUrlTemplate要自己加&BBOX=[b]占位符;&可能被 encode。