---
title: 常见问题
source: https://vjmap.com/guide/faq.html
---

# 常见问题

## 怎么查看文档和示例
- 快速入门 [https://vjmap.com/guide/quickstart.html](https://vjmap.com/guide/quickstart.html)
- 简单开发示例(vue,react,html) [https://vjmap.com/guide/downloaddemo.html](https://vjmap.com/guide/downloaddemo.html)
- 工程化开发封装复杂交互参考源码 [https://vjmap.com/app/cloud](https://vjmap.com/app/cloud)
- 各种应用场景和效果demo看 [https://vjmap.com/demo](https://vjmap.com/demo)
- [唯杰地图3d](https://vjmap.com/map3d/)


## 唯杰地图系统架构
唯杰地图系统架构为BS架构。

服务端主要核心功能如解析打开DWG文件、保存成空间数据、生成栅格矢量瓦片渲染数据等功能都在于服务端；

服务端可跨平台私有化部署(推荐linux系统docker部署），支持内网无网络环境部署；

官网的免费试用版本功能与正式版本一样，但有水印；如需去水印，用于商用私有化部署请联系客服; 

和地图有关的服务端功能一般无需用户二次开发；用户自定义的数据获取和保存功能，用户可用任意语言开发自己的服务端功能。

前端sdk库，可直接在html中引入样式` <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>` ；或安装npm包 `npm install vjmap`来进行开发。前端需要用户利用sdk库开发自己的功能融合进自己的系统中。可原生js开发，或React、vue开发(示例：[点击下载](https://vjmap.com/download/vjmap_demo.zip) )。支持移动端，如果是原生开发，请用webview基于h5开发。

## 唯杰地图是免费的吗？
唯杰地图是可以`免费试用`的，但试用版本`有水印`，上传文件`大小有限制`，上传的数据会`不定时清空`，功能与正式版一致。如需`去水印`，私有化`部署到自己服务器上面`是`收费`的(支持内网无网络环境部署)。具体费用请联系客服;

客服微信: ![wx](https://vjmap.com/wx.png)

## 怎么打开CAD图形

打开CAD图形有以下四种方式 

- 1. 通过sdk的`Service`的`uploadMap`方法上传dwg图形；[示例](https://vjmap.com/demo/#/demo/map/service/06uploadmap)

- 2. 通过一个能访问的http网址路径直接打开图形；[示例](https://vjmap.com/demo/#/demo/map/service/05openMapFromHttp)

- 3. 如果CAD与服务在同一个服务器，可直接通过本地路径来打开CAD图形；[示例](https://vjmap.com/demo/#/demo/map/service/05openMapFromLocal)

- 4. 如果是新建图形，可以传入新建图形的json数据来创建图形；[示例](https://vjmap.com/demo/#/demo/map/service/05newmap)

## 支持移动端吗？

唯杰地图完全兼容移动端查看。在每个示例中和云平台管理中都增加了手机扫一扫的功能，可直接扫描二维码在手机端查看效果。

<div align="left">
  <img :src="$withBase('/assets/images/qrcode.png')" style="transform:scale(1.0)"/>
</div>

## 是否支持第三方开源的GIS前端库进行开发？
唯杰地图全面支持用`openlayers`、`leaflet`、`maptalks`来加载CAD图
- 用`openlayers`开发，请参考示例 [https://vjmap.com/demo/#/demo/map/openlayers/01olraster](https://vjmap.com/demo/#/demo/map/openlayers/01olraster)
- 用`leaflet`开发，请参考示例 [https://vjmap.com/demo/#/demo/map/leaflet/01leafletraster](https://vjmap.com/demo/#/demo/map/leaflet/01leafletraster)
- 用`maptalks`开发，请参考示例 [https://vjmap.com/demo/#/demo/map/maptalks/01maptalksraster](https://vjmap.com/demo/#/demo/map/maptalks/01maptalksraster)

## 是否支持对CAD图的编辑？
唯杰地图支持对CAD图的编辑，不过唯杰地图主要是对CAD图GIS展示和效果为主，编辑功能相对较弱。

完整的能在cad图上进行删除、修改，新增，导出CAD图的示例源码。可参考 [https://vjmap.com/app/visual/#/draw?mapid=p5ff2aa38c0f&version=v1&mapopenway=GeomRender&vector=true&theme=dark](https://vjmap.com/app/visual/#/draw?mapid=p5ff2aa38c0f&version=v1&mapopenway=GeomRender&vector=true&theme=dark)

[https://vjmap.com/demo/#/demo/map/comprehensive/05drawcadedit](https://vjmap.com/demo/#/demo/map/comprehensive/05drawcadedit)

实现对CAD图的编辑，原理如下:

- 对cad原图进行修改。可对CAD图中的实体进行新增、修改、删除等操作。修改保存后，后台会新成一个新的版本号。示例 [https://vjmap.com/demo/#/demo/map/service/05zfrommap](https://vjmap.com/demo/#/demo/map/service/05zfrommap)

- 利用修改样式对cad图的显示进行修改，不会修改原图数据，只会改前端显示结果。性能高些。示例代码 [https://vjmap.com/demo/#/demo/map/service/05zgmodifymap](https://vjmap.com/demo/#/demo/map/service/05zgmodifymap)
  
`利用修改样式对cad图的显示进行修改`主要原理是：
  
（1）后台通过样式去控制绘制。可利用我们的表达式语法，对指定的图层，实体等进行显示或隐藏，和颜色的修改等。这样会在后台创建一个新的样式名称。服务后台打开图的时候指定此样式名称即可，这样生成的瓦片数据就是您个性化后的数据。
  
（2）前端可以加一个绘制图层，可以绘制点，线，面等名种形状。
  通过后台样式控制和前端的绘制来达到您想要的修改后的效果。



如果是自已上传的图形，可以在`唯杰地图云平台中`打开,点击上面`工具栏`中的`更多绘图功能`进入。


## 如何让不同的用户或用户组只能看到自己或自己所有组的图？
  首先唯杰地图只是一个地图开发平台,只会提供了和地图有关的服务，不会对业务中的用户和密码进行封装。和地图服务有关的权限配置请参考博文 [唯杰地图之前端CAD图GIS数据访问权限配置](https://www.cnblogs.com/vjmap/p/16720980.html)。

  实现`让不同的用户或用户组只能看到自己或自己所有组的图`需要在您`自己的业务系统`中与`唯杰地图`进行融合。

   具体思路为：

  - (1) 在业务系统中进行用户登录
  - (2) 登录成功后，此用户上传的图名称与此用户及用户组相关联。
    
        举例如下：
    
        用户组 `admin` 中的用户 `user1` 上传了 图名称为 `ns_map1`, `ns_map2`的CAD图。

        用户组 `admin` 中的用户 `user2` 上传了 图名称为 `ns_cad3`, `ns_cad4`的CAD图。
    
        那在业务数据库中可以用一个表记录下如下信息
    
    表结构如下 (上传时间、上传文件名、缩略图地址、打开方式可通过上传打开完成后接口获取)

|图id|所属用户组|上传用户|上传时间|上传文件名|缩略图地址|打开方式|
|:---|:---|:---|:---|:---|:---|:---|
|ns_map1|admin|user1|
|ns_map1|admin|user1|
|ns_cad3|admin|user2|
|ns_cad4|admin|user2|

- (3) 通过上面的关联关系, 当 用户 `user1` 查看图纸时，在业务系统的后台表中，查询出 `user1` 有  `ns_map1`, `ns_map2`的CAD图，这时候只显示出这两张图即可。 
  
- (4) 如果 `允许此用户看此用户组下面的所有图` 的话，可以知道此用户组为`admin`，在业务系统的后台表中，查询出 `admin`用户组 有  `ns_map1`, `ns_map2`, `ns_cad3`, `ns_cad4` 的CAD图，这时候只显示出这四张图即可。

- (5) 如`防止`用户通过在`唯杰地图管理平台`或通过`vjmap.Service.listMaps`获取到不是此用户的图，还需要把用户上传的图设置为`隐藏`，这样通过唯杰的默认接口查询时，不会查询到此图。设置图形`隐藏`的方法为，图名称为`ns_`开头即可。如果要自定义隐藏图形名称的前缀，需要在后台`config.json`的`map`配置下， 加上`map_list_exclude_prefix`设置，允许多个时以分号隔开，如设置为`map_list_exclude_prefix`为 `ts_;ns_;test_`表示以`ts_`、`ns_`、`test_`开头的图名称都将自动隐藏。

- (6) 可直接通过 `vjmap.Service.openMap` 传入图名称打开图即可, 图形设置了隐藏的也是一样的打开方式。图设置为了隐藏与不隐藏的唯一区别就是通过`vjmap.Service.listMaps`获取所有图时，不能获取到隐藏了的图形id。

::: tip 提示
 如果只是需要不同用户组的数据之间隔离，可以利用工作区的机制。不同的用户组，创建不同的工作区。工作区之间数据是隔离的。工作区示例 [https://vjmap.com/demo/#/demo/map/service/07mapWorkspace](https://vjmap.com/demo/#/demo/map/service/07mapWorkspace)
:::

## CAD图中自定义字体会不会显示乱码或问号？
唯杰地图后台服务会安装一些常用的字体， 如果用户CAD图中自定义字体不在这些常用的字体中，我们会用默认字体替代这些字体，这样就不会显示问号或乱码了。但有时候显示可能会与原字体显示有差别，如宽高大小不一样。要想显示完全一样，需要把自定义的字体拷贝到唯杰地图后台服务字体目录`data/fonts`即可。如果需要在线替换字体，可采用以下步骤:
- (1) 在cad中打开有问号字体的图形，查看字体样式中有问号的字体样式名称是什么字体，例如为"tssdeng.shx"
- (2) 在唯杰中打开有问号字体的图形，在openMap返回的字段findFonts为系统查找的字体替换规则，例如为 {"tssdeng.shx_1":"tssdeng.shx"}
- (3) 删除之前上传的图形，在 云端管理平台上传页面重新上传之前的图形 
- (4) 上传完后，在更多设置中 `字体替换规则` 中输入要替换的字体规则，如{"tssdeng.shx_1": "_default_.ttc"}
- (5) 为了防止缓存，可以对图形id重命名下，打开图形即可。

如遇乱码上述方法操作麻烦的情况下，万能解决办法，打开图形的时候，在更多设置里`字体替换规则` 中输入 `{"*":"_default_.ttc"}` , 这表示将图中的所有字体都用默认字体来代替(缺点是图中所有字体都是同一个字体了)。

### 在服务端怎么上传和打开图形
在服务端，可以通过调用唯杰Restful的请求来上传和打开图形。具体请求接口的参数，可以在前端F12打开调试控制台网络请求中可以查看。
下面为node.js为例，实现服务端怎么上传和打开图形的demo
```js
// app.js
const fs = require('fs')
const FormData = require('form-data')
const axios = require('axios')
const prompt = require('prompt');

(async ()=>{
    const defaultServiceUrl = 'https://vjmap.com/server/api/v1';
    const defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MiwiVXNlcm5hbWUiOiJhZG1pbjEiLCJOaWNrTmFtZSI6ImFkbWluMSIsIkF1dGhvcml0eUlkIjoiYWRtaW4iLCJCdWZmZXJUaW1lIjo4NjQwMCwiZXhwIjo0ODEzMjY3NjM3LCJpc3MiOiJ2am1hcCIsIm5iZiI6MTY1OTY2NjYzN30.cDXCH2ElTzU2sQU36SNHWoTYTAc4wEkVIXmBAIzWh6M';

    let formData = new FormData();
    let { filepath } =  await prompt.get('filepath'); // 请输入要上传的文件路径
    if (!filepath) return;
    let file = fs.createReadStream(filepath)   
    formData.append('fileToUpload', file);
    
    let len = await new Promise((resolve, reject) => {
      return formData.getLength((err, length) => (err ? reject(err) : resolve(length)));
    });
    let res = await axios({
        url: `${defaultServiceUrl}/map/uploads?token=${defaultAccessToken}`,
        method: 'POST',
        data: formData,
        headers: {
          ...formData.getHeaders(),
          'Content-Length': len,  
        },
    });
    /*
    {
        fileid: 'c036d8ca23eb',
        mapid: 'c036d8ca23eb', // mapid是建议的mapid，如果之前上传打开过，则为之前的mapid
        uploadname: 'base1.dwg'
    }
    */
    console.log(res.data);

    // 上传只是把图上传到了服务器， 您新建地图的时候的，第一次的时候openMap要传上传的fileid，然后给新建的图取个mapid打开就可以了,以后就可以直接通过mapid打开图了
    let { mapid } =  await prompt.get('mapid'); // 请输入要上传的文件路径
    if (!mapid) {
        // 如果没有输入mapid，则用上传的时候返回的默认mapid
        mapid = res.data.mapid;
    }
    let result = await axios({
        url: `${defaultServiceUrl}/map/openmap/${res.data.mapid}?version=&layer=&geom=true&fileid=${res.data.fileid}&uploadname=${res.data.uploadname}&mapfrom=&mapdependencies=&subfrom=&subdependencies=&stylename=&layeron=&layeroff=&clipbounds=&bkcolor=0&lineweight=&expression=`,
        method: 'GET',
        headers: {
          token: defaultAccessToken,  
        },
    });
    console.log(result)
    
    // 如要判断图上传已创建处理完成，可用定时器如3s轮询判断处理状态
    let result2 = await axios({
        url: `${defaultServiceUrl}/map/cmd/listmaps/${result.data.mapid}/${result.data.version},
        method: 'GET',
        headers: {
            token: defaultAccessToken,
        },
    });
    console.log(result2)
    // result2.status "working" 正在处理;   "error" 表示有错误;  "finish" 处理完成
})();
```

## 图形打开显示一个小点的解决办法
### 在唯杰云端管理平台处理办法
- 1. 进入唯杰云端管理平台 https://vjmap.com/app/cloud
- 2. 打开显示小点的地图后，进入上面工具栏中的“更多功能”-> "选择裁剪范围生成新的图形"
- 3. 拉框选择要显示的区域，然后在新打开的页面中，给新的图形重命名即可。
- 4. 可以删除以前的图形.(可选)

### 在CAD里面处理办法
- 1.在CAD双击鼠标中键,使CAD图全图显示
- 2.如果这时候发现全图显示后，只看见几个小点，说明图其他区域很远处有一些其他东西，需要删除掉。
- 3.这时候再按 Ctrl+A全选所有图形。按住Shift拉框，把真正要显示的图选中，排除到选择集中，按delete键，删除多余的图形。（如果无法删除，可能是图层冻结或锁定了，需把无法删除的图层取消冻结或锁定）
- 4.再 双击鼠标中键,使CAD图全图显示，这时候就正常了。再保存图形


## 如何把另外一个坐标系的数据叠加到当前CAD图上
- 如果另外一个坐标系和当前CAD图是同一个坐标系，那数据无需转换直接用就可以的
- 如果不是同一个坐标系，如果不知道这两个坐标系对应关系的话，可以通过四参数来对应解决(误差由给定的公共点决定。公共点越准确，误差越小)。示例代码如:
```js
// cad上面的点坐标
let cadPoints = [
    vjmap.geoPoint([39760.07407, 237424.52134]),
    vjmap.geoPoint([39006.60468, 237808.49494749]),
    vjmap.geoPoint([38823.92918, 235003.98994]),
    vjmap.geoPoint([37885.55424, 235452.80893])
];

// 另外坐标系上拾取的与上面的点一一对应的坐标
let otherPoints = [
    vjmap.geoPoint([113.292983, 23.206979]),
    vjmap.geoPoint([113.285631, 23.210304]),
    vjmap.geoPoint([113.283897, 23.185047]),
    vjmap.geoPoint([113.274716, 23.188962])
]

// 通过坐标参数求出四参数
let fourparam = vjmap.coordTransfromGetFourParamter(otherPoints, cadPoints, false);

// 把另外的坐标系上面的公共点转成cad坐标,与原始cad坐标比较，看得到的四参数误差有多大，如果误差比较小，说明公共点是可以用的
for(let i = 0; i< otherPoints.length; i++) {
    const cadpt = vjmap.coordTransfromByFourParamter(otherPoints[i], fourparam);
    console.log("原始点：" + cadPoints[i], "计算结果：" + cadpt, "误差：" +cadPoints[i].distanceTo(cadpt))
}

// 例如把另外坐标系的点[113.292983, 23.206979] 转成cad坐标
const cadpt = vjmap.coordTransfromByFourParamter(vjmap.geoPoint([113.292983, 23.206979]), fourparam);
console.log(cadpt)
// {x: 39792.49478817663, y: 237432.04509891104}

// 通过cad的点反算出另外坐标系的点
const otherpt = vjmap.coordTransfromByInvFourParamter(cadpt, fourparam); // 通过四参数反算
console.log(otherpt)
// {x: 113.29298300000002, y: 23.206979


// 注：四参数只用应用于有平移旋转缩放的情况， 如有水平或垂直翻转请先转换完再用四参数。
```

