互联网地图应用
唯杰地图 vjmap做为一款地图引擎, 不仅能加载CAD地图瓦片,也可以直接加载互联网地图瓦片,同时也支持CAD图和互联网地图叠加显示。
直接加载互联网地图
通过给定互联网地图WMTS的瓦片地址加载互联网地图。
在沙箱中运行,调用唯杰地图公共演示服务
// --天地图地图--
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 根据地图范围建立经纬度投影坐标系
let prj = new vjmap.LnglatProjection();
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: {
version: svc.styleVersion(),
glyphs: svc.glyphsUrl(),
sources: {
tdt1: {
type: 'raster',
// 影像
// tiles: ["https://t3.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=7baeffb96bf61861b302d0f963cfda66"],
// 道路
tiles: ["https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=7baeffb96bf61861b302d0f963cfda66"]
},
tdt2: {
type: 'raster',
tiles: ["https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=7baeffb96bf61861b302d0f963cfda66"],
}
},
layers: [{
id: 'tdt1',
type: 'raster',
source: 'tdt1',
},{
id: 'tdt2',
type: 'raster',
source: 'tdt2',
}]
},
center: prj.toLngLat([116.3912, 39.9073]),
zoom: 8,
pitch: 0,
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
//map.fitMapBounds();
await map.onLoad();
const co = prj.toLngLat([116.3912, 39.9073])
const marker = new vjmap.Marker({color: "red"})
marker.setLngLat(co).addTo(map)
// 地形
// map.addSource('dem', {
// type: 'raster-dem',
// tiles: ["https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=pk.eyJ1IjoiZnJhemllcm1hcmsiLCJhIjoiY2wzOTBhZzJiMDFwejNqbzJyMGs0YmZ5NCJ9.2VB9C63HoxzjCpCmbhga9A"],
// })
// map.setTerrain({ source: 'dem', exaggeration: 1})提示
唯杰地图不提供互联网地图瓦片数据,如需离线部署互联网地图服务, 请自行下载互联网地图离线瓦片数据或通过第三方工具下载。
互联网地图与CAD图叠加(为互联网地图为底图)
此场景是以互联网地图为底图(以互联网地图为坐标系),通用调用唯杰地图CAD图的 WMS 服务适配互联网地图来进行叠加显示。
如果CAD图有地理坐标系,如本身是2000坐标系的图,则可以自动叠加。
如果CAD图本身没有坐标系,只能通过人为指定三个以上的公共点进行校准,计算出四参数(平移xy、旋转、缩放)来进行叠加。
具体原理可查看 坐标转换 文档。
此场景适合于业务数据大部分是互联网地图数据,CAD图只是叠加查看效果。
在沙箱中运行,调用唯杰地图公共演示服务
// --天地图与CAD图叠加[天地图为底图]--天地图与CAD图叠加,以天地图为坐标系
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 根据地图范围建立经纬度投影坐标系
let prj = new vjmap.LnglatProjection();
// 地图对象
let map = new vjmap.Map({
container: 'map', // DIV容器ID
style: {
version: svc.styleVersion(),
sources: {
tdt1: {
type: 'raster',
tiles: ["https://t3.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=7baeffb96bf61861b302d0f963cfda66"],
// 要使用影像请用这个地址
// tiles: ["https://t3.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=7baeffb96bf61861b302d0f963cfda66"]
},
tdt2: {
type: 'raster',
tiles: ["https://t3.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=7baeffb96bf61861b302d0f963cfda66"],
}
},
layers: [{
id: 'tdt1',
type: 'raster',
source: 'tdt1',
},{
id: 'tdt2',
type: 'raster',
source: 'tdt2',
}]
},
center: prj.toLngLat([117.21242940465396, 39.196783504641644]),
zoom: 15,
pitch: 0,
renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 根据地图本身范围缩放地图至全图显示
//map.fitMapBounds();
await map.onLoad();
// 先获取地图元数据来获取图层样式
let cadMapId = "sys_cad2000"
let style = await svc.createStyle({
backcolor: 0xFFFFFF // 浅色主题
}, cadMapId)
let wmsurl = svc.wmsTileUrl({
mapid: cadMapId,
version:"v1",
layers: style.stylename,
srs: "EPSG:3857", // 底图是天地图坐标系
crs: "EPSG:4548", // cad图是2000坐标 可通过前两位获取 vjmap.transform.getEpsgParam(vjmap.transform.EpsgCrsTypes.CGCS2000, 39).epsg
// fourParameter: "-39000000,0,1,0"// 此图坐标前面没有加带系,需要加上带系的偏移量,用四参数调节位置
})
map.addSource('wms-test-source', {
'type': 'raster',
'tiles': [
wmsurl
],
'tileSize': 256
});
map.addLayer({
'id': 'wms-test-layer',
'type': 'raster',
'source': 'wms-test-source',
'paint': { "raster-opacity": 1 }
}
);
map.addControl(new vjmap.MousePositionControl({showZoom: true}));CAD图与互联网地图叠加(为CAD图为底图)
此场景是以CAD为底图(以CAD图为坐标系),通用调用唯杰地图提供的互联网地图的WMS服务来适配CAD地图来进行叠加显示。
如果CAD图有地理坐标系,如本身是2000坐标系的图,则可以自动叠加。
如果CAD图本身没有坐标系,只能通过人为指定三个以上的公共点进行校准,计算出四参数(平移xy、旋转、缩放)来进行叠加。
具体原理可查看 坐标转换 文档。
此场景适合于业务数据大部分是CAD图数据,互联网地图只是叠加查看效果。
在沙箱中运行,调用唯杰地图公共演示服务
// --CAD图与互联网图叠加--CAD图与互联网图叠加显示,以CAD图为坐标系
// 假设我们希望CAD全图显示是对应级别为8级,这样地图缩小后,互联网地图还会显示
let initZoom = 8;
let style = {
backcolor: 0, // div为深色背景颜色时,这里也传深色背景样式
clipbounds: Math.pow(2, initZoom) // 只传值,不传范围,表示之前的范围放大多少倍
}
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
let res = await svc.openMap({
mapid: "sys_cad2000",
mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
style: style
})
if (res.error) {
consoloe.error(res.error)
}
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
let prj = new vjmap.GeoProjection(mapExtent);
let center = mapExtent.center();
let map = new vjmap.Map({
container: 'map', // container ID
style: svc.rasterStyle(),
center: prj.toLngLat(center),
zoom: 10,
renderWorldCopies: false
});
map.attach(svc, prj);
await map.onLoad();
map.addControl(new vjmap.NavigationControl());
map.addControl(new vjmap.MousePositionControl({showZoom: true}));
// 如果x是8位,可通过前两位获取 如 vjmap.transform.getEpsgParam(vjmap.transform.EpsgCrsTypes.CGCS2000, 39).epsg
// 如果x是6位,是通过下面此工具 https://vjmap.com/demo/#/demo/map/web/03webzgetepsg,把地图移动至cad图位置的省市,点击获取当前地图中心经纬度, 计算EPSG,找一个与 CAD图距离相近的EPSG
let epsg = "EPSG:4509" // cad图的epsg
// 增加高德地图底图
const addGaodeMap = async (isRoadway) => {
const tileUrl = svc.webMapUrl({
tileCrs: "gcj02",
tileUrl: isRoadway ? [
"https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
] :
/* 如果用影像 */
[
"https://webst0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=6&x={x}&y={y}&z={z}",
"https://webst0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
],
tileSize: 256,
tileRetina: 1,
tileMaxZoom: 18,
tileShards: "1,2,3,4",
tileToken: "",
tileFlipY: false,
mapbounds: res.bounds,
srs: epsg
})
map.addSource('web-gaode-source', {
'type': 'raster',
'tiles': [
tileUrl
],
'tileSize': 256
});
map.addLayer({
'id': 'web-gaode-layer',
'type': 'raster',
'source': 'web-gaode-source',
'paint': { "raster-opacity": 1 }
}
);
let layers = map.getStyle().layers
// 把这个图层放至所有图层的最下面
map.moveLayer('web-gaode-layer', layers[0].id)
// cad坐标与高德坐标相互转换示例
let webCo = await cad2webCoordinate(center, false); // cad转高德
let cadCo = await web2cadCoordinate(webCo, false); // 高德转cad
console.log(center, webCo, cadCo)
}
// 增加天地图图底图
const addTiandituMap = async (isRoadway) => {
const tileUrl = svc.webMapUrl({
tileCrs: "wgs84",
tileUrl: [
isRoadway ? "https://t{s}.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk={t}" :
/* 如果用影像 */"https://t{s}.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk={t}",
"https://t{s}.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk={t}"
],
tileSize: 256,
tileRetina: 1,
tileMaxZoom: 18,
tileShards: "1,2,3,4,5,6",
tileToken: [
"6d53378dc5f7dbef8d84ffdd2b54139b", // 有可能有一个token会导致请求过多而返回失败,可以多写几个,失败时会尝试后面的token
"69eb2fa0de3b2a668f1ef603a3f8bc73"
],
tileFlipY: false,
mapbounds: res.bounds,
srs: epsg
})
map.addSource('web-tdt-source', {
'type': 'raster',
'tiles': [
tileUrl
],
'tileSize': 256
});
map.addLayer({
'id': 'web-tdt-layer',
'type': 'raster',
'source': 'web-tdt-source',
'paint': { "raster-opacity": 1 }
}
);
let layers = map.getStyle().layers
// 把这个图层放至所有图层的最下面
map.moveLayer('web-tdt-layer', layers[0].id)
// cad坐标与天地图坐标相互转换示例
let webCo = await cad2webCoordinate(center, true); // cad转天地图
let cadCo = await web2cadCoordinate(webCo, true); // 天地图转cad
console.log(center, webCo, cadCo)
}
const removeMapLayer = ()=> {
// 删除source及source下面的所有图层
map.removeSourceEx(['web-gaode-source', 'web-tdt-source'])
}
// cad转web坐标,isWgs84是否为wgs84 4326坐标,如天地图;否的话为gcj02火星坐标,如高德地图
const cad2webCoordinate = async (pt, isWgs84) => {
// 通过坐标转换把转成wgs84 4326坐标
let res = await svc.cmdTransform(epsg,"EPSG:4326",pt); // 如果不想调服务转,也可以在前端用proj4库
// 如果为火星坐标,还需要从4326转火星
let webPt = res[0];// 返回的第1条结果
if (isWgs84 === false) {
webPt = vjmap.transform.convert(webPt, vjmap.transform.CRSTypes.EPSG4326, vjmap.transform.CRSTypes.AMap)
}
return webPt;
}
// web转cad坐标,isWgs84是否为wgs84 4326坐标,如天地图;否的话为gcj02火星坐标,如高德地图
const web2cadCoordinate = async (pt, isWgs84) => {
// (上面计算过程的逆过程), 如果为火星坐标,还需要从火星转4326,再通过坐标转换把wgs84 4326转成cad图坐标
if (isWgs84 === false) {
pt = vjmap.transform.convert(pt, vjmap.transform.CRSTypes.AMap, vjmap.transform.CRSTypes.EPSG4326);
}
// 通过坐标转换把cad epsg转成wgs84 4326坐标
let res = await svc.cmdTransform("EPSG:4326",epsg,vjmap.geoPoint(pt)); // 如果不想调服务转,也可以在前端用proj4库
let cadPt = res[0];// 返回的第1条结果
return cadPt
}
map.on("zoomend", async ()=> {
let center = map.fromLngLat(map.getCenter());// 得到cad地图地理中心坐标点
let gcj02Web = await cad2webCoordinate(center, false);// 转高德坐标
let wgs84Web = await cad2webCoordinate(center, true);// 转天地图坐标
let content = `当前地图中心点坐标: CAD坐标:${center.x.toFixed(4)},${center.y.toFixed(4)}; 高德坐标:${gcj02Web[0].toFixed(4)},${gcj02Web[1].toFixed(4)}; 天地图坐标:${wgs84Web[0].toFixed(4)},${wgs84Web[1].toFixed(4)}`;
console.log({ content, key: "info", duration: 3});
})
addGaodeMap(true);提示
更多互联网地图叠加显示的介绍请查看 互联网地图 文档。
这篇文档有帮助吗?感谢反馈!