---
title: 快速入手
source: https://vjmap.com/guide/quickstart.html
---

# 快速入手

## 视频教程
[唯杰地图VJMAP整体介绍视频教程](https://www.bilibili.com/video/BV11M4y19788/?share_source=copy_web&vd_source=8da0f3e60fa8d1449934f8be7b675a52)  　　        
[唯杰地图管理平台介绍](https://www.bilibili.com/video/BV1dv4y167Cu/?vd_source=606b3092bb2ff9d13b249fdab0633fdb)  
[唯杰地图示例介绍](https://www.bilibili.com/video/BV1gT411C75t/?vd_source=606b3092bb2ff9d13b249fdab0633fdb)


## 上传图形

- 通过 [唯杰地图云端图纸管理平台](https://vjmap.com/app/cloud) 提供的[上传图形](https://vjmap.com/demo/#/demo/map/service/06uploadmap) 功能(推荐)  或者 演示示例中[上传图形](https://vjmap.com/demo/#/demo/map/service/06uploadmap) 功能上传图形, 或者参考代码自己通过官方提供的SDK来自己实现上传图形。

![image-20220306184355126](https://vjmap.com/blogimages/image-20220306184355126.png)

上传成功后，取个图名称ID

![image-20220306184730008](https://vjmap.com/blogimages/image-20220306184730008.png)


::: tip 提示
如果选择存储后渲染栅格或矢量，第一次打开时由于需要保存几何数据，需耐心等待一段时间。下次打开时会很快打开图形。
:::

- 上传时给图取一个唯一的图名称mapid,在以后的开发中会用这个mapid来显示图形

  ![image-20220217090623700](https://vjmap.com/blogimages/image-20220217090623700.png)

- 如果需要工程化开发，请参考 html、Vue、React应用[示例代码下载](https://vjmap.com/download/vjmap_demo.zip)

  工程化开发时，可通过`npm install vjmap`安装sdk
```js
  import 'vjmap/dist/vjmap.min.css' // 样式一定要引用！！！
  import vjmap from 'vjmap'; 
```

::: tip 提示
免费试用版不提供私有化部署，直接连官网的服务进行试用，有水印，上传文件大小有限制，上传数据会不定时清空，功能与正式版一致。如果需要正式版本私有化部署，请联系客服。
:::

## 通过服务打开地图

通过`Service`对象的`openMap`方法可打开服务器上面已存在的地图，或者通过`fileid`传入`http`网络路径或服务器本地路径打开一幅`DWG`格式的`CAD图形`.

```js
// 新建地图服务对象，传入服务地址和token
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
    mapid: "sys_world", // 地图ID (上传图形时，取的图名称)
    mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
    // 第一次打开此图时，必须传fileid,以后打开不需要再传了
    // fileid: ”通过uploadMap上传图，得到一个fileid，或 一个dwg文件http地址 或 一个服务器固定目录下面的本地文件名称 或 或者新建图的json数据 
    style: vjmap.openMapDarkStyle() // 服务器渲染样式
})
if (res.error) {
    message.error(res.error)
}
```

::: tip 提示
打开一个新图:

第一次openMap时：
取个图名称唯一的mapid

第一次打开此图时，必须传fileid,以后打开不需要再传了

fileid可以是以下几个方式

(1) 通过uploadMap上传图，得到一个fileid

(2) 一个dwg文件http地址

(3) 一个服务器固定目录下面的本地文件名称

(4) 或者新建图的json数据

以后直接通过 mapid打开此图形，不需要再传fileid
:::

## 建立地图对象

获取上面打开地图返回的`地理范围`建立`坐标系`，然后创建`地图对象`

```js
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(res.bounds);

// 地图对象
let map = new vjmap.Map({
    container: 'map', // DIV容器ID
    style: svc.vectorStyle(), // 样式，这里是矢量瓦片样式
    center: prj.toLngLat(prj.getMapExtent().center()), // 设置地图中心点
    zoom: 2, // 设置地图缩放级别
    pitch: 60, // 倾斜角度
    renderWorldCopies: false // 不显示多屏地图
});

// 关联服务对象和投影对象
map.attach(svc, prj);
```

::: tip 提示
唯杰地图也支持用openlayers、leaflet、maptalks来加载CAD图

如果需要用openlayers来开发，请参考示例 https://vjmap.com/demo/#/demo/map/openlayers/01olraster

如果需要用leaflet来开发，请参考示例 https://vjmap.com/demo/#/demo/map/leaflet/01leafletraster

如果需要用maptalks来开发，请参考示例 https://vjmap.com/demo/#/demo/map/maptalks/01maptalksraster
:::
## 获取地图范围
![image-20230625112656838](https://vjmap.com/blogimages/image-20230625112656838.png)
- 整个地图范围 map.getGeoBounds(1.0) // 正方形
- CAD图实际范围(整个地图范围的0.4倍) map.getGeoBounds(0.4) // 正方形
- CAD图的可视范围（有图的部分的范围)
 
  方法1： 范围准确，速度稍慢 let dataBounds = await svc.cmdGetDrawBounds(); // 获取地图有数据的范围区域

  方法2： 范围大致准确，速度快 svc.currentMapParam().drawBounds

## 地图交互

当鼠标在地图的某个实体上面时，需要高亮显示或者点击查看，在`矢量瓦片`模式下可调用 `enableVectorLayerHoverHighlight`；在`栅格瓦片`下，可调用 `enableLayerClickHighlight`

```js
// 获取所有图层
const layers = svc.getMapLayers();
// 实体类型ID和名称映射
const { entTypeIdMap } = await svc.getConstData();

// 有高亮状态（鼠标在地图元素上时，会高亮)
map.enableVectorLayerHoverHighlight((event, feature, layer) => {
    // 点击高亮实体回调事件
    const prop = feature.properties;
    let content = `event: ${event}; feature: ${feature.id}; layer: ${layers[prop.layer].name}; type: ${entTypeIdMap[prop.type]}`
    message.info({ content, key: "info", duration: 5});
})
```

## 增加覆盖物或其它图层

地图提供了在地图之上绘制覆盖物的能力，比如点标记、纯文本标记、折线、圆、多边形、矩形等图形，在绘制中可以对点标记进行标题、图标等进行设置，对折线可以进行颜色、宽度等属性进行设置，对于面（圆、多边形、矩形）同样可以进行填充色、边框色、宽度等很多自定义属性进行设置。

增加一个marker覆盖物
```js
const mapBounds = map.getGeoBounds(0.6); // 获取地图地理范围，并进行比例缩放
let position = mapBounds.randomPoint(); // 在此地理范围内生成一个随机点坐标
let latLng = map.toLngLat(position); // 地理坐标转经纬度
let marker = new vjmap.Marker(); // 新建一个Marker
marker.setLngLat(latLng).addTo(map); // 设置坐标并加入地图
```

创建很多正方形拉伸图层
```js
let lengthMin = mapBounds.width() / 200; // 随机生成正方形边长的最小长度
let lengthMax = mapBounds.width() / 100; // 随机生成正方形边长的最大长度
let geoDatas = []; // 数据
for(let i = 0; i < 100; i++) {
    const pts = [];
    const len = vjmap.randInt(lengthMin, lengthMax); // 在两个范围内随机生成一个长度
    const p1 = mapBounds.randomPoint(); // 在此范围内随机生成一个点，做为正方形的右下角的点
    const p2 = vjmap.geoPoint([p1.x, p1.y + len]);
    const p3 = vjmap.geoPoint([p1.x + len, p1.y + len]);
    const p4 = vjmap.geoPoint([p1.x + len, p1.y]);
    pts.push(p1, p2, p3, p4); // 正方形的四个点坐标
    geoDatas.push({
        points: map.toLngLat(pts), // 需要把地理坐标转化成经纬度去绘制
        properties: {
            name: "square" + (i + 1),
            color:  vjmap.randomColor(),
            type: "square",
            baseHeight: 0,
            height: prj.toMeter(vjmap.randInt(lengthMin * 10, lengthMax * 10)) // 高度，这里根据上面设置的最小和最大长度的十倍随机生成一个高度值
        }
    })
}

// 创建拉伸对象图层
let fillExtrusions = new vjmap.FillExtrusion({
    data: geoDatas, // 数据
    // 如果是hover状态时，用红色，非hover状态时，取属性中的'color'做为颜色值
    fillExtrusionColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']],
    fillExtrusionOpacity: 0.8, // 透明度
    fillExtrusionHeight:['get', 'height'], // 高度值
    fillExtrusionBase: ['get', 'baseHeight'], // 基点高度，如需悬空，可改变此值
    isHoverPointer: true, // 鼠标在上面时会改变鼠标形状
    isHoverFeatureState: true // 鼠标在上面时会改变状态值，从而有高亮效果
});
fillExtrusions.addTo(map); // 增加至地图
// 点击事件
fillExtrusions.clickLayer(e => message.info(`您点击了第 ${e.features[0].id} 个，名称为 ${e.features[0].properties.name}，颜色为 ${e.features[0].properties.color} 的 ${e.features[0].properties.type}`))
// 悬浮事件
fillExtrusions.hoverPopup(f => `<h3>ID: ${f.properties.name}</h3>Color: ${f.properties.color}`, { anchor: 'bottom' });
```

<mapFrameEx>
<pre>
// 新建地图服务对象，传入服务地址和token
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打开地图
let res = await svc.openMap({
	mapid: "sys_zp", // 地图ID (每一次打开此地图ID时，会根据fileid去获取dwg路径打开，之后会读取缓存打开)
	mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
	style: vjmap.openMapDarkStyle() // 服务器渲染样式
})
if (res.error) {
	console.error(res.error)
}
// 根据地图范围建立几何投影坐标系
let prj = new vjmap.GeoProjection(res.bounds);
// 地图对象
let map = new vjmap.Map({
	container: 'map', // DIV容器ID
	style: svc.vectorStyle(), // 样式，这里是矢量瓦片样式
	center: prj.toLngLat(prj.getMapExtent().center()), // 设置地图中心点
	zoom: 2, // 设置地图缩放级别
	pitch: 60, // 倾斜角度
	renderWorldCopies: false // 不显示多屏地图
});
// 关联服务对象和投影对象
map.attach(svc, prj);
// 获取所有图层
const layers = svc.getMapLayers();
// 实体类型ID和名称映射
const { entTypeIdMap } = await svc.getConstData();
// 有高亮状态（鼠标在地图元素上时，会高亮)
map.enableVectorLayerHoverHighlight((event, feature, layer) => {
	// 点击高亮实体回调事件
	const prop = feature.properties;
	let content = `event: ${event}; feature: ${feature.id}; layer: ${layers[prop.layer].name}; type: ${entTypeIdMap[prop.type]}`
	map.logInfo(content)
})
// 等待地图加载完成才能增加下面的其他图层
await map.onLoad();
// 增加一个marker覆盖物
const mapBounds = map.getGeoBounds(0.6); // 获取地图地理范围，并进行比例缩放
let position = mapBounds.randomPoint(); // 在此地理范围内生成一个随机点坐标
let latLng = map.toLngLat(position); // 地理坐标转经纬度
let marker = new vjmap.Marker(); // 新建一个Marker
marker.setLngLat(latLng).addTo(map); // 设置坐标并加入地图
// 创建很多正方形拉伸图层
let lengthMin = mapBounds.width() / 200; // 随机生成正方形边长的最小长度
let lengthMax = mapBounds.width() / 100; // 随机生成正方形边长的最大长度
let geoDatas = []; // 数据
for(let i = 0; i < 100; i++) {
	const pts = [];
	const len = vjmap.randInt(lengthMin, lengthMax); // 在两个范围内随机生成一个长度
	const p1 = mapBounds.randomPoint(); // 在此范围内随机生成一个点，做为正方形的右下角的点
	const p2 = vjmap.geoPoint([p1.x, p1.y + len]);
	const p3 = vjmap.geoPoint([p1.x + len, p1.y + len]);
	const p4 = vjmap.geoPoint([p1.x + len, p1.y]);
	pts.push(p1, p2, p3, p4); // 正方形的四个点坐标
	geoDatas.push({
		points: map.toLngLat(pts), // 需要把地理坐标转化成经纬度去绘制
		properties: {
			name: "square" + (i + 1),
			color:  vjmap.randomColor(),
			type: "square",
			baseHeight: 0,
			height: prj.toMeter(vjmap.randInt(lengthMin * 10, lengthMax * 10)) // 高度，这里根据上面设置的最小和最大长度的十倍随机生成一个高度值
		}
	})
}
// 创建拉伸对象图层
let fillExtrusions = new vjmap.FillExtrusion({
	data: geoDatas, // 数据
	// 如果是hover状态时，用红色，非hover状态时，取属性中的'color'做为颜色值
	fillExtrusionColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']],
	fillExtrusionOpacity: 0.8, // 透明度
	fillExtrusionHeight:['get', 'height'], // 高度值
	fillExtrusionBase: ['get', 'baseHeight'], // 基点高度，如需悬空，可改变此值
	isHoverPointer: true, // 鼠标在上面时会改变鼠标形状
	isHoverFeatureState: true // 鼠标在上面时会改变状态值，从而有高亮效果
});
fillExtrusions.addTo(map); // 增加至地图
// 点击事件
fillExtrusions.clickLayer(e => map.logInfo(`您点击了第 ${e.features[0].id} 个，名称为 ${e.features[0].properties.name}，颜色为 ${e.features[0].properties.color} 的 ${e.features[0].properties.type}`))
// 悬浮事件
fillExtrusions.hoverPopup(f =>`&lt;h3>ID: ${f.properties.name}&lt;/h3>Color: ${f.properties.color}`, { anchor: 'bottom' });
</pre>
</mapFrameEx>

<br/>
<br/>



## 全部代码

```js
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vjmap demo</title>
    <link rel="stylesheet" type="text/css" href="https://vjmap.com/demo/js/vjmap/vjmap.min.css">
    <script type="text/javascript" src="https://vjmap.com/demo/js/vjmap/vjmap.min.js"></script>
</head>
<body style=" margin: 0;overflow: hidden;background-color:white;font-size: 16px">
<div id="map" style="left:0;right:0;top:0;bottom:0;position: absolute;z-index: 0;"></div>
</body>
<script>
    window.onload = async () => {
        document.body.style.background = "#022B4F"; // 背景色改为深色
        const env = {
            serviceUrl: "https://vjmap.com/server/api/v1",
            accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MiwiVXNlcm5hbWUiOiJhZG1pbjEiLCJOaWNrTmFtZSI6ImFkbWluMSIsIkF1dGhvcml0eUlkIjoiYWRtaW4iLCJCdWZmZXJUaW1lIjo4NjQwMCwiZXhwIjoxOTQyMzg5NTc0LCJpc3MiOiJ2am1hcCIsIm5iZiI6MTYyNzAyODU3NH0.VQchVXxgjl5aCp3j3Uf5U2Mpk1NJNirH62Ys-8XOfnY",
            exampleMapId: "sys_zp"
        };
        try {
            // 新建地图服务对象，传入服务地址和token
			let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
			// 打开地图
			let res = await svc.openMap({
				mapid: "helloVjmap", // 地图ID (每一次打开此地图ID时，会根据fileid去获取dwg路径打开，之后会读取缓存打开)
				fileid: "mapfiles/ccf12a1f8711.dwg", // 必须是相对路径，路径相于服务器程序安装目录data下面
				mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
				style: vjmap.openMapDarkStyle() // 服务器渲染样式
			})
			if (res.error) {
				console.error(res.error)
			}
			// 根据地图范围建立几何投影坐标系
			let prj = new vjmap.GeoProjection(res.bounds);

			// 地图对象
			let map = new vjmap.Map({
				container: 'map', // DIV容器ID
				style: svc.vectorStyle(), // 样式，这里是矢量瓦片样式
				center: prj.toLngLat(prj.getMapExtent().center()), // 设置地图中心点
				zoom: 2, // 设置地图缩放级别
				pitch: 60, // 倾斜角度
				renderWorldCopies: false // 不显示多屏地图
			});

			// 关联服务对象和投影对象
			map.attach(svc, prj);

			// 获取所有图层
			const layers = svc.getMapLayers();
			// 实体类型ID和名称映射
			const { entTypeIdMap } = await svc.getConstData();

			// 有高亮状态（鼠标在地图元素上时，会高亮)
			map.enableVectorLayerHoverHighlight((event, feature, layer) => {
				// 点击高亮实体回调事件
				const prop = feature.properties;
				let content = `event: ${event}; feature: ${feature.id}; layer: ${layers[prop.layer].name}; type: ${entTypeIdMap[prop.type]}`
				map.logInfo(content)
			})

			// 等待地图加载完成才能增加下面的其他图层
			await map.onLoad();

			// 增加一个marker覆盖物
			const mapBounds = map.getGeoBounds(0.6); // 获取地图地理范围，并进行比例缩放
			let position = mapBounds.randomPoint(); // 在此地理范围内生成一个随机点坐标
			let latLng = map.toLngLat(position); // 地理坐标转经纬度
			let marker = new vjmap.Marker(); // 新建一个Marker
			marker.setLngLat(latLng).addTo(map); // 设置坐标并加入地图

			// 创建很多正方形拉伸图层
			let lengthMin = mapBounds.width() / 200; // 随机生成正方形边长的最小长度
			let lengthMax = mapBounds.width() / 100; // 随机生成正方形边长的最大长度
			let geoDatas = []; // 数据
			for(let i = 0; i < 100; i++) {
				const pts = [];
				const len = vjmap.randInt(lengthMin, lengthMax); // 在两个范围内随机生成一个长度
				const p1 = mapBounds.randomPoint(); // 在此范围内随机生成一个点，做为正方形的右下角的点
				const p2 = vjmap.geoPoint([p1.x, p1.y + len]);
				const p3 = vjmap.geoPoint([p1.x + len, p1.y + len]);
				const p4 = vjmap.geoPoint([p1.x + len, p1.y]);
				pts.push(p1, p2, p3, p4); // 正方形的四个点坐标
				geoDatas.push({
					points: map.toLngLat(pts), // 需要把地理坐标转化成经纬度去绘制
					properties: {
						name: "square" + (i + 1),
						color:  vjmap.randomColor(),
						type: "square",
						baseHeight: 0,
						height: prj.toMeter(vjmap.randInt(lengthMin * 10, lengthMax * 10)) // 高度，这里根据上面设置的最小和最大长度的十倍随机生成一个高度值
					}
				})
			}

			// 创建拉伸对象图层
			let fillExtrusions = new vjmap.FillExtrusion({
				data: geoDatas, // 数据
				// 如果是hover状态时，用红色，非hover状态时，取属性中的'color'做为颜色值
				fillExtrusionColor: ['case', ['to-boolean', ['feature-state', 'hover']], 'red', ['get', 'color']],
				fillExtrusionOpacity: 0.8, // 透明度
				fillExtrusionHeight:['get', 'height'], // 高度值
				fillExtrusionBase: ['get', 'baseHeight'], // 基点高度，如需悬空，可改变此值
				isHoverPointer: true, // 鼠标在上面时会改变鼠标形状
				isHoverFeatureState: true // 鼠标在上面时会改变状态值，从而有高亮效果
			});
			fillExtrusions.addTo(map); // 增加至地图
			// 点击事件
			fillExtrusions.clickLayer(e => map.logInfo(`您点击了第 ${e.features[0].id} 个，名称为 ${e.features[0].properties.name}，颜色为 ${e.features[0].properties.color} 的 ${e.features[0].properties.type}`))
			// 悬浮事件
			fillExtrusions.hoverPopup(f => `<h3>ID: ${f.properties.name}</h3>Color: ${f.properties.color}`, { anchor: 'bottom' });

        }
        catch (e) {
            console.error(e);
        }
    };
</script>
</html>
```
