---
title: 互联网地图应用
source: https://vjmap.com/guide/webmapapp.html
---

# 互联网地图应用

`唯杰地图` `vjmap`做为一款地图引擎, 不仅能加载CAD地图瓦片，也可以直接加载互联网地图瓦片，同时也支持CAD图和互联网地图叠加显示。

## 直接加载互联网地图

通过给定互联网地图`WMTS`的瓦片地址加载互联网地图。

<mapFrameEx>
<pre>
// --天地图地图--
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})
</pre>
</mapFrameEx>



::: warning 提示
唯杰地图不提供互联网地图瓦片数据，如需离线部署互联网地图服务， 请自行下载互联网地图离线瓦片数据或通过第三方工具下载。
:::


## 互联网地图与CAD图叠加(为互联网地图为底图)

此场景是以互联网地图为底图（以互联网地图为坐标系），通用调用唯杰地图CAD图的 `WMS` 服务适配互联网地图来进行叠加显示。

如果CAD图有地理坐标系，如本身是2000坐标系的图，则可以自动叠加。

如果CAD图本身没有坐标系，只能通过人为指定三个以上的公共点进行校准，计算出四参数（平移xy、旋转、缩放)来进行叠加。

具体原理可查看 [坐标转换](/guide/coordtransform.html) 文档。


此场景适合于业务数据大部分是互联网地图数据，CAD图只是叠加查看效果。

<mapFrameEx>
<pre>
// --天地图与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}));
</pre>
</mapFrameEx>


## CAD图与互联网地图叠加(为CAD图为底图)

此场景是以CAD为底图（以CAD图为坐标系），通用调用唯杰地图提供的互联网地图的`WMS`服务来适配CAD地图来进行叠加显示。

如果CAD图有地理坐标系，如本身是2000坐标系的图，则可以自动叠加。

如果CAD图本身没有坐标系，只能通过人为指定三个以上的公共点进行校准，计算出四参数（平移xy、旋转、缩放)来进行叠加。

具体原理可查看 [坐标转换](/guide/coordtransform.html) 文档。


此场景适合于业务数据大部分是CAD图数据，互联网地图只是叠加查看效果。


<mapFrameEx>
<pre>
// --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);
</pre>
</mapFrameEx>


::: tip 提示
更多互联网地图叠加显示的介绍请查看 [互联网地图](/guide/webmap.html) 文档。
:::


