# 地图服务Rest接口

# 介绍

地图服务采用的是Rest的服务接口,前端开发可采用封装好的vjmap js sdk中的Service来调用相关服务。如获取一个地图的元数据,可采用以下代码

let svc = new vjmap.Service(env.serviceUrl, env.accessToken);
let res = await svc.metadata("sys_zp" /*地图id*/, "v1" /*地图版本号,为空表示最新版本*/);
console.log(res)
1
2
3

上面代码在浏览器中执行时,F12在网络请求中,可以看到,是给地图服务发送了一个http请求.

image-20230524140958184

所以在后端如果调用相同的功能,只需发送同样的http请求即可。

下面在PostMan中进行测试下 image-20230524141331530

测试发现,通过PostMan中调用地图服务的rest接口,返回了正确的结果。

需要注意的是:所有的服务调用要需指定是application/json,同时要在请求头里面带上Token字段 或者 如果是Get请求,则加上token=xxxx的查询参数,用于鉴权, 如需打开有密码保护的图同时不提示输入密码,请在请求头中加入secretKeyaccessKey。(下面的所有示例中将不在重复这条,实际中记得加Token)

# 常用服务接口

(为简便起见,下面的服务地址只写相对地址。如https://vjmap.com/server/api/v1/map/cmd/metadata/sys_zp/v1将简写为/api/v1/map/cmd/metadata/sys_zp/v1

# 上传图形

服务地址 /api/v1/map/uploads
请求类型 Post
请求参数 参数说明 参数示例
fileToUpload 文件二进制内容

# 创建或打开图形

服务地址 /api/v1/map/openmap/{mapid}
请求类型 Get或Post
请求参数 参数说明 参数示例
version 文件二进制内容
layer 样式
geom 以几何渲染方式打开 true
fileid 文件唯一ID. 地图ID第一次打开时,需传递fileid cfbe8dc085fb
imageLeft 图像左上角坐标x 第一次打开图像类型时有效 undefined
imageTop 图像左上角坐标y 第一次打开图像类型时有效
imageResolution 图像分辨率 第一次打开图像类型时有效
uploadname 上传时的文件名 zp.dwg
mapfrom 地图来源参数(协同图形有效)
mapdependencies 地图依赖项(协同图形有效)
subfrom 地图来源参数(子项的设置)(协同图形有效)
subdependencies 地图依赖项(子项的设置)(协同图形有效)
stylename 样式图层名称
layeron 要开的图层索引列表,格式如[0,1,3]
layeroff 要关的图层索引列表,格式如[2,4]
clipbounds 地图裁剪范围,范围如[x1,y1,x2,y2]
bkcolor 背景颜色 0
lineweight 线宽,格式如[1,1,1,1,0]
expression 样式表达式
secretKey 如第一次创建图时要对图加密可设置此key
accessKey 如图设置了密码需访问key

注:第一次上传图形时,如需设置密码,需设置secretKey值。计算方式为对密码明文四次md5加密,取加密后的字符串前16位。

如用 nodejs 在后台上传图形并创建打开图示例


// 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 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=`;
    // 如需设置密码,如密码是123456
    //  md5四次加密 strMd5是字符串md5值计算方法,请自行实现
    // let secretKey =  strMd5(strMd5(strMd5(strMd5("123456")))).substr(0, 16);
    // url += "&secretKey=" + secretKey
    let result = await axios({
        url: url,
        method: 'GET',
        headers: {
          token: defaultAccessToken,  
        },
    });
    console.log(result)
})();


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

如果是需要在后台根据参数创建图形,则需要把创建的实体对象生成一个json对象,同时对json序列化成字符串转成base64编码,做为fileid传入 用nodejs在后台参数创建图形代码如下:

const axios = require("axios");


(async () => {
  const defaultServiceUrl = "https://vjmap.com/server/api/v1";
  const defaultAccessToken =
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MiwiVXNlcm5hbWUiOiJhZG1pbjEiLCJOaWNrTmFtZSI6ImFkbWluMSIsIkF1dGhvcml0eUlkIjoiYWRtaW4iLCJCdWZmZXJUaW1lIjo4NjQwMCwiZXhwIjo0ODEzMjY3NjM3LCJpc3MiOiJ2am1hcCIsIm5iZiI6MTY1OTY2NjYzN30.cDXCH2ElTzU2sQU36SNHWoTYTAc4wEkVIXmBAIzWh6M";

  let doc = {};
  let entitys = [];
  // 具体的参数请查看官网文档 https://vjmap.com/doc/Class_DbDocument.html
  entitys.push({
    typename: "DbLine",
    start: [14, 0],
    end: [14, 15],
    colorIndex: 1,
  });
  entitys.push({
    typename: "DbCircle",
    center: [14, 7.5],
    radius: 1.83,
    color: 0xff0000,
  });
  entitys.push({
    typename: "DbText",
    position: [14, 16],
    contents: "篮球场示意图",
    colorIndex: 1,
    horizontalMode: 4,
    height: 1,
  });
  doc.entitys = entitys;

  // 转base64的方法也可以,但不推荐了,直接转json字符就可以了
  //var bytes = new Buffer(JSON.stringify(doc));
  //var base64 = "data:application/dwg;base64," + bytes.toString('base64')// let fileid = base64;

    let fileid = JSON.stringify(doc);
  // 上传只是把图上传到了服务器, 您新建地图的时候的,第一次的时候openMap要传上传的fileid,然后给新建的图取个mapid打开就可以了,以后就可以直接通过mapid打开图了
  let mapid = "mybackendmap"
  let url = `${defaultServiceUrl}/map/updatemap/${mapid}`;
  let data = {
    fileid: fileid,
    clipbounds: '',
    bkcolor: 0,
    geom: true,
    uploadname: ""
  }
  // 如需设置密码,如密码是123456
  //  md5四次加密 strMd5是字符串md5值计算方法,请自行实现
  // let secretKey =  strMd5(strMd5(strMd5(strMd5("123456")))).substr(0, 16);
  // url += "&secretKey=" + secretKey
  let result = await axios({
    url: url,
    method: "POST",
    headers: {
      token: defaultAccessToken,
    },
    data
  });
  console.log(result);
})();


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

执行结果如下:

image-20230524172844505

# 检查文件是否上传过

服务地址 api/v1/map/mapfile
请求类型 Get
服务说明 此方法是在文件上传时用来检测后台是否有相同的文件,如果有则不再上传直接返回fileid,提高效率。实际中也可省去此步骤
请求参数 参数说明 参数示例
md5 文件md5值 fbe8dc085fbcdac502c640cf2dd8065c

获取文件md5值的方法node实现为(其他后端也可以参考同样实现)

import SparkMD5 = require("spark-md5");
/**
     * 获取文件的Md5值
     * @param file
     * @return {Promise<any>}
     */
    function fileMd5(file: File): Promise<any> {
        return new Promise((resolve, reject) => {
            const blobSlice =
                // @ts-ignore
                File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
            const chunkSize = 2097152; // Read in chunks of 2MB
            const chunks = Math.ceil(file.size / chunkSize);
            let currentChunk = 0;
            const spark = new SparkMD5.ArrayBuffer();
            const fileReader = new FileReader();

            fileReader.onload = function(e) {
                // @ts-ignore
                spark.append(e.target.result); // Append array buffer
                currentChunk++;

                if (currentChunk < chunks) {
                    loadNext();
                } else {
                    var md5 = spark.end();
                    resolve(md5);
                }
            };

            fileReader.onerror = function() {
                reject("file reader error");
            };

            function loadNext() {
                var start = currentChunk * chunkSize;
                var end = start + chunkSize >= file.size ? file.size : start + chunkSize;
                fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
            }

            loadNext();
        });
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 更新图形

服务地址 /api/v1/map/updatemap/{mapid}
请求类型 Get或Post

参数同创建或打开图形

# 栅格瓦片地址

服务地址 api/v1/map/tile/{mapid}/{version}/{stylename}/{zoom}/{x}/{y}
请求类型 Get
服务说明 mapid地图id;version版本号; stylename当前样式名;zoom当前级别;xy当前瓦片行列
请求参数 参数说明 参数示例
tag fileid

# 矢量瓦片地址

服务地址 api/v1/map/tile/{mapid}/{version}/{stylename}/{zoom}/{x}/{y}.mvt
请求类型 Get
服务说明 mapid地图id;version版本号; stylename当前样式名;zoom当前级别;xy当前瓦片行列
请求参数 参数说明 参数示例
tag fileid

# 执行地图命令

服务地址 api/v1/map/cmd/${cmdname}/${mapid}/${version}
请求类型 Get 或 Post
服务说明 cmdname命令名mapid地图id;version版本号;
请求参数 参数说明 参数示例
不同的命名名称参数不一样

# 获取地图元数据

服务地址 api/v1/map/cmd/metadata/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
geom 是否是几何渲染

# 修改地图元数据

服务地址 api/v1/map/cmd/updateMetadata/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
元数据key值 元数据key对应的value值

# 主动关闭打开的地图

服务地址 api/v1/map/cmd/closemap/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
元数据key值 元数据key对应的value值

# 获取地图列表

服务地址 api/v1/map/cmd/listmaps/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;为空,则获取所有的;如果传入的是地图ID数组,则获取指定的地图ID数组的信息。如果不想一次性获取,可通过传入分页对象获取,如{curPage: 1, pageCount: 10} ; version版本号,为空,则获取最新的; * 则获取所有的版本
请求参数 参数说明 参数示例
mapIds mapid为空时,可指定地图id数组查询

# 查询实体

服务地址 api/v1/map/cmd/queryFeatures/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号
请求参数 参数说明 参数示例
querytype 查询类型,支持条件查询"condition",矩形范围查询"rect",点查询"point", 表达式查询"expresion" condition
beginpos 记录开始位置 0
bounds 范围 ""
condition 查询条件 layerindex = 0
fields 是返回的字段列表,多个之是用逗号,分开,如. "name,objectid"
geom 是否为几何图形查询 true
includegeom 是否返回几何数据,为了性能问题,realgeom为false时,如果返回条数大于1.只会返回每个实体的外包矩形,如果条数为1的话,会返回此实体的真实geojson;realgeom为true时每条都会返回实体的geojson true
isContains 是否为包含关系, true为包含关系,false为相交关系,默认false. (传入了bounds进行范围查询时有效) false
layername 样式名称 必填项,可通过createMapStyle接口返回的stylename,如api/v1/map/cmd/createMapStyle/yourMapid/v1?geom=true&token=xxx
maxReturnCount 返回最多的记录条数 50000
realgeom 是否返回真实实体几何geojson.与 includegeom参数,结合使用。参考includegeom的用法 true
expr 表达式
x 点查询x坐标
y 点查询y坐标
pixelsize 点查询像素大小
zoom 当前级别 1
toMapCoordinate 查询返回的坐标默认为墨卡托坐标,返回会程序会自动转化为cad坐标,如果要直接返回cad地图坐标,需要把toMapCoordinate设置为true.

js中sdk查询相关源码如下


/**
 * 查询实体参数
 */
export interface IQueryBaseFeatures {
    /** 当前级别. */
    zoom?: number;
    /** 地图ID(为空时采用当前打开的mapid). */
    mapid?: string;
    /** 地图版本(为空时采用当前打开的地图版本). */
    version?: string;
    /** 图层名称(为空时采用当前打开的地图图层名称). */
    layer?: string;
    /** 返回最多的记录条数. */
    limit?: number;
    /** 是返回的字段列表,多个之是用逗号,分开,如. "name,objectid" */
    fields?: string;
    /** 是否为几何图形查询. */
    geom?: boolean;
    /** GeoJSON几何数据简化墨托卡距离,默认为零,不简化。例如允许10级别以上一个像素级别的误差,可用 map.pixelToGeoLength(1, 10) * vjmap.Projection.EQUATORIAL_SEMIPERIMETER * 2 / map.getGeoBounds(1.0).width() */
    simplifyTolerance?: boolean;
    /** 启动cache(内存打开的图形有效). */
    useCache?: boolean;
    /** 查询返回的坐标默认为墨卡托坐标,返回会程序会自动转化为cad坐标,如果要直接返回cad地图坐标,需要把toMapCoordinate设置为true. */
    toMapCoordinate?: boolean;
}

/**
 * 点查询实体参数
 */
export interface IPointQueryFeatures extends IQueryBaseFeatures {
    /** 查询的坐标X. */
    x: number;
    /** 查询的坐标Y. */
    y: number;
    /** 像素大小. */
    pixelsize?: number;
    /** 条件. */
    condition?: string;
    /** 返回最大的几何字节数. */
    maxGeomBytesSize?: number;
    /** 当前一个像素表示多少几何长度,如果输入了此值,则为此值为主,否则,根据输入的zoom值后台自动计算. */
    pixelToGeoLength?: number;
}

/**
 * 矩形查询实体参数
 */
export interface IRectQueryFeatures extends IQueryBaseFeatures {
    /** 查询的坐标X1. (如果x1,y1,x2,y2同时不输的话,表示是查询整个图的范围 */
    x1?: number;
    /** 查询的坐标Y1. */
    y1?: number;
    /** 查询的坐标X2. */
    x2?: number;
    /** 查询的坐标Y2. */
    y2?: number;
    /** 条件. */
    condition?: string;
    /** 返回最大的几何字节数. */
    maxGeomBytesSize?: number;
}

/**
 * 表达式查询实体参数
 */
export interface IExprQueryFeatures extends IQueryBaseFeatures {
    /** 表达式. */
    expr: string;
    /** 记录开始位置. */
    beginpos?: number;
}

/**
 * 条件查询实体参数
 */
export interface IConditionQueryFeatures extends IQueryBaseFeatures {
    /** 条件. */
    condition: string;
    /** 范围. */
    bounds?: [number,number,number,number];
    /** 记录开始位置. */
    beginpos?: number;
    /** 是否返回几何数据,为了性能问题,realgeom为false时,如果返回条数大于1.只会返回每个实体的外包矩形,如果条数为1的话,会返回此实体的真实geojson;realgeom为true时每条都会返回实体的geojson */
    includegeom?: boolean;
    /** 是否返回真实实体几何geojson.与 includegeom参数,结合使用。参考includegeom的用法*/
    realgeom?: boolean;
    /** 是否为包含关系, true为包含关系,false为相交关系,默认false. (传入了bounds进行范围查询时有效)*/
    isContains?: boolean;
}
/**
     * 点查询实体
     * @param param 参数
     * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
     */
    async pointQueryFeature(param: IPointQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any> {
        const res = await this.execCommand(
            "queryFeatures",
            {
                querytype: "point",
                zoom: param.zoom ?? 1,
                pixelToGeoLength: param.pixelToGeoLength ?? undefined,
                layername: param?.layer ?? this._cur_map_param?.layer,
                x: param.x,
                y: param.y,
                pixelsize: param.pixelsize ?? 5,
                condition: param.condition ?? undefined,
                maxReturnCount: param.limit ?? undefined,
                maxGeomBytesSize: param.maxGeomBytesSize ?? undefined,
                fields: param.fields ?? "",
                geom: param.geom ?? undefined,
                simplifyTolerance: param.simplifyTolerance ?? undefined,
                useCache: param.useCache,
                toMapCoordinate: param.toMapCoordinate,
            },
            param.mapid,
            param.version
        );
        return this._processQueryResult(res, cb);
    }

    /**
     * 矩形查询实体
     * @param param 参数
     * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
     */
    async rectQueryFeature(param: IRectQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any> {
        const res = await this.execCommand(
            "queryFeatures",
            {
                querytype: "rect",
                zoom: param.zoom ?? 1,
                layername: param?.layer ?? this._cur_map_param?.layer,
                x1: param.x1,
                y1: param.y1,
                x2: param.x2,
                y2: param.y2,
                condition: param.condition ?? undefined,
                maxReturnCount: param.limit ?? undefined,
                maxGeomBytesSize: param.maxGeomBytesSize ?? undefined,
                fields: param.fields ?? "",
                geom: param.geom ?? undefined,
                simplifyTolerance: param.simplifyTolerance ?? undefined,
                useCache: param.useCache,
                toMapCoordinate: param.toMapCoordinate,
            },
            param.mapid,
            param.version
        );
        return this._processQueryResult(res, cb);
    }

    /**
     * 表达式查询实体
     * @param param 参数
     * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
     */
    async exprQueryFeature(param: IExprQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any> {
        const res = await this.execCommand(
            "queryFeatures",
            {
                querytype: "expresion",
                zoom: param.zoom ?? 1,
                layername: param?.layer ?? this._cur_map_param?.layer,
                expr: param.expr,
                beginpos: param.beginpos,
                maxReturnCount: param.limit ?? undefined,
                limit: param.limit ?? undefined,
                fields: param.fields ?? "",
                useCache: param.useCache ?? false,
                geom: param.geom ?? undefined,
                simplifyTolerance: param.simplifyTolerance ?? undefined,
                toMapCoordinate: param.toMapCoordinate,
            },
            param.mapid,
            param.version
        );
        return this._processQueryResult(res, cb);
    }

    /**
     * 条件查询实体
     * @param param 参数
     * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
     */
    async conditionQueryFeature(param: IConditionQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any> {
        const res = await this.execCommand(
            "queryFeatures",
            {
                querytype: "condition",
                zoom: param.zoom ?? 1,
                layername: param?.layer ?? this._cur_map_param?.layer,
                condition: param.condition,
                beginpos: param.beginpos,
                maxReturnCount: param.limit ?? undefined,
                limit: param.limit ?? undefined,
                includegeom: param.includegeom ?? undefined,
                realgeom: param.realgeom ?? undefined,
                isContains: param.isContains ?? undefined,
                fields: param.fields ?? "",
                bounds: param.bounds ? JSON.stringify(param.bounds) : "",
                geom: param.geom ?? undefined,
                simplifyTolerance: param.simplifyTolerance ?? undefined,
                useCache: param.useCache,
                toMapCoordinate: param.toMapCoordinate,
            },
            param.mapid,
            param.version
        );
        return this._processQueryResult(res, cb);
    }

// _processQueryResult函数是将返回的墨卡托坐标转cad坐标了。如果后端调用查询请求直接返回cad坐标,请将参数toMapCoordinate设置为true即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

同时也可通过图形界面来看请求的参数

https://vjmap.com/app/visual/#/query?mapid=sys_zp&version=v1&mapopenway=GeomRender&theme=dark (opens new window) (sys_zp改成自己的mapid)

image-20230524160509120

在postMan中测试下。记得把参数toMapCoordinate设置为true,让直接返回cad坐标

image-20230524160843420

# 切换图层

服务地址 api/v1/map/cmd/switchlayer/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
visibleLayers 让可见的图层列表数组
darkMode 是否是深色主题

# 获取样式图层名

服务地址 api/v1/map/cmd/createMapStyle/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
geom 是否是几何渲染
name 样式名称
layeron 要开的图层索引列表,格式如[0,1,3]
layeroff 要关的图层索引列表,格式如[2,4]. layeron与layeroff只要输入一个即可
clipbounds 地图裁剪范围,范围如[x1,y1,x2,y2].如果只需入了数值的话,表示是缩放倍数
backcolor 背景颜色
lineweight 线宽,格式如[1,1,1,1,0].表式第1,2,3,4级线宽开,第5级线宽关,大于第5级的,以最后设置的级别状态为主,所以也是关。如为空,则和原图线宽显示状态相同
expression 表达式

# 获取图形中有数据的范围区域

服务地址 api/v1/map/cmd/getDataBounds/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例

# 获取图的缩略图

服务地址 api/v1/map/cmd/thumbnail/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
width 像素高
height 像素高
darkTheme 是否是深色主题,是的话,图片将反色(黑色变白色)

# WMS瓦片地址

服务地址 api/v1/map/cmd/wms/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;
请求参数 参数说明 参数示例
layers 图层名称(为空时采用当前打开的地图图层名称).
bbox 范围,缺省{bbox-epsg-3857}. (如果要获取地图cad一个范围的wms数据无需任何坐标转换,将此范围填cad范围,srs,crs,mapbounds填为空).
srs 当前坐标系,缺省(EPSG:3857)
crs cad图的坐标系,为空的时候由元数据坐标系决定. 也可直接输入proj4字符串
mapbounds 地理真实范围,如有值时,srs将不起作用
width 瓦片像素宽
height 瓦片像素高
transparent 不透明时的背景颜色,默认为白色。格式必须为rgb(r,g,b)或rgba(r,g,b,a),a不透明应该是255.
backgroundColor 像素高
fourParameter 四参数(x偏移,y偏移,缩放,旋转弧度),可选,对坐标最后进行修正
isInverseFourParamter 是否用上面的四参数进行反算,默认false
mvt 是否是矢量瓦片
useImageRotate 是否考虑旋转,在不同坐标系中转换是需要考虑。默认自动考虑是否需要旋转
imageProcessAlg 旋转时图像处理算法. 1或2,默认自动选择(旋转时有用)
webMapType 当前互联网底图地图类型 WGS84(84坐标,如天地图,osm), GCJ02(火星坐标,如高德,腾讯地图), BD09LL(百度经纬度坐标,如百度地图), BD09MC(百度墨卡托米制坐标,如百度地图)*

js的源码如下


/**
 * wms服务url地址接口
 */
export interface IWmsTileUrl {
    /** 地图ID(为空时采用当前打开的mapid), 为数组时表时同时请求多个. */
    mapid?: string | string[];
    /** 地图版本(为空时采用当前打开的地图版本). */
    version?: string | string[];
    /** 图层名称(为空时采用当前打开的地图图层名称). */
    layers?: string | string[];
    /** 范围,缺省{bbox-epsg-3857}. (如果要获取地图cad一个范围的wms数据无需任何坐标转换,将此范围填cad范围,srs,crs,mapbounds填为空).*/
    bbox?: string;
    /** 当前坐标系,缺省(EPSG:3857). */
    srs?: string;
    /** cad图的坐标系,为空的时候由元数据坐标系决定. 也可直接输入proj4字符串*/
    crs?: string | string[];
    /** 地理真实范围,如有值时,srs将不起作用 */
    mapbounds?: string;
    /** 宽. */
    width?: number;
    /** 高. */
    height?: number;
    /** 是否透明. */
    transparent?: boolean;
    /** 不透明时的背景颜色,默认为白色。格式必须为rgb(r,g,b)或rgba(r,g,b,a),a不透明应该是255. */
    backgroundColor?: string;
    /** 四参数(x偏移,y偏移,缩放,旋转弧度),可选,对坐标最后进行修正*/
    fourParameter?: string | string[];
    /** 是否用上面的四参数进行反算,默认false*/
    isInverseFourParamter?:  boolean | boolean[];
    /** 是否是矢量瓦片. */
    mvt?: boolean;
    /** 是否考虑旋转,在不同坐标系中转换是需要考虑。默认自动考虑是否需要旋转. */
    useImageRotate?: boolean;
    /** 旋转时图像处理算法. 1或2,默认自动选择(旋转时有用)*/
    imageProcessAlg?: number;
    /** 当前互联网底图地图类型 WGS84(84坐标,如天地图,osm), GCJ02(火星坐标,如高德,腾讯地图), BD09LL(百度经纬度坐标,如百度地图), BD09MC(百度墨卡托米制坐标,如百度地图)*/
    webMapType?: "WGS84" | "GCJ02" | "BD09LL" | "BD09MC"
}
    wmsTileUrl(param: IWmsTileUrl): string {
        const mapid = param.mapid ?? this._cur_map_param?.mapid;
        const version = param.version ?? ((param.mapid == this._cur_map_param?.mapid) ? this._cur_map_param?.version : "_") ?? "_";
        const layers = param.layers ?? this._cur_map_param?.layer;
        const bbox = param.bbox ?? "{bbox-epsg-3857}";
        const srs = param.srs ?? "EPSG:3857";//底图坐标系
        let crs = param.crs ?? ""; //cad图坐标系
        if (crs.indexOf("+") >= 0) {
            // proj4字符串
            // @ts-ignore
            crs = encodeURIComponent(crs);
        }
        const mapbounds = param.mapbounds ?? "";
        const width = param.width ?? 256;
        const height = param.height ?? 256;
        const transparent = param.transparent ?? true;
        const fourParameter = param.fourParameter ?? "";
        const isInverseFourParamter = param.isInverseFourParamter === true ? `&isInverseFourParamter=true` : "";
        const mvt = param.mvt === true ? ".mvt" : ""
        const useImageRotate = param.useImageRotate === true ? `&useImageRotate=true` : "";
        const imageProcessAlg = isNumber(param.imageProcessAlg) ? `&imageProcessAlg=${param.imageProcessAlg}` : "";
        const webMapType = param.webMapType ? `&webMapType=${param.webMapType}` : "";
        const backgroundColor = (param.backgroundColor && !transparent) ? `&backgroundColor=${param.backgroundColor}` : "";
        if (!Array.isArray(mapid)) {
            // 如果不是数组,表示只请求一个地图的wms数据
            return  `${this._url("cmd")}/wms/${mapid}/${version}${mvt}` +
                `?mapbounds=${mapbounds}${bbox ? "&bbox=": ""}${bbox}&format=image/png&service=WMS&request=GetMap&srs=${srs}&transparent=${transparent}&width=${width}&height=${height}&layers=${layers}&crs=${crs}&fourParameter=${fourParameter}${isInverseFourParamter}${useImageRotate}${imageProcessAlg}${webMapType}${backgroundColor}&token=${this.accessToken}`
        } else {
            // 请求多个地图的wms数据
            //&layers=${layers}&crs=${crs}&fourParameter=${fourParameter}
            //${mapid}/${version}
            let mapidArr = mapid;
            let versionArr = Array.isArray(version) && version.length == mapidArr.length ?  version : mapidArr.map(m => version ?? "_")
            let layersArr = Array.isArray(layers) && layers.length == mapidArr.length ?  layers : mapidArr.map(m => layers ?? "")
            let crsArr = Array.isArray(crs) && crs.length == mapidArr.length ?  crs : mapidArr.map(m => crs ?? "")
            let fourParameterArr = Array.isArray(fourParameter) && fourParameter.length == mapidArr.length ?  fourParameter : mapidArr.map(m => fourParameter ?? "")
            let isInverseFourParamterArr = Array.isArray(isInverseFourParamter) && isInverseFourParamter.length == mapidArr.length ?  isInverseFourParamter : mapidArr.map(m => isInverseFourParamter ?? "")
            let param = `bbox=${bbox}&mapbounds=${mapbounds}&format=image/png&service=WMS&request=GetMap&srs=${srs}&transparent=${transparent}&width=${width}&height=${height}`
            let arrayParam = `mapid=${mapidArr.join("_,")}&version=${versionArr.join("_,")}&layers=${layersArr.join("_,")}&crs=${crsArr.join("_,")}&fourParameter=${fourParameterArr.join("_,")}&isInverseFourParamter=${isInverseFourParamterArr.join("_,")}`
            if (mapidArr.length == 1) {
               return `${this._url("cmd")}/wms/${mapidArr[0]}/${versionArr[0]}${mvt}` +
                    `?mapbounds=${mapbounds}${bbox ? "&bbox=": ""}${bbox}&format=image/png&service=WMS&request=GetMap&srs=${srs}&transparent=${transparent}&width=${width}&height=${height}&layers=${layersArr[0]}&crs=${crsArr[0]}&fourParameter=${fourParameterArr[0]}&isInverseFourParamter=${isInverseFourParamterArr[0]}${useImageRotate}${imageProcessAlg}${webMapType}${backgroundColor}&token=${this.accessToken}`
            } else {
                return `${this._svr_url_service}wms?${param}&${arrayParam}${useImageRotate}${imageProcessAlg}${webMapType}${backgroundColor}&token=${this.accessToken}`;
            }
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

# 删除地图

服务地址 api/v1/map/cmd/deletemap/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id;version版本号;如删除所有版本,输入"*"号
请求参数 参数说明 参数示例
retainVersionMaxCount 删除所有版本时,保留的最新的版本总数。如总共有10个版本,retainVersionMaxCount为3时,会保存最新的3个版本,其余的都会删除

# 地图重命名

服务地址 api/v1/map/cmd/deletemap/${mapid}/_
请求类型 Get 或 Post
服务说明 mapid地图id;
请求参数 参数说明 参数示例
newMapId 新的地图id

# 清空地图的几何和瓦片缓存数据

服务地址 api/v1/map/cmd/clearCacheTiles/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号;
请求参数 参数说明 参数示例

# 清空地图的瓦片缓存数据

服务地址 api/v1/map/cmd/clearCacheStyles/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号;
请求参数 参数说明 参数示例

# 删除地图样式

服务地址 api/v1/map/cmd/deletestyle/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号;
请求参数 参数说明 参数示例
styleid
onlycleardata 仅清空数据

# 删除地图缓存

服务地址 api/v1/map/cmd/deletecache/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号;
请求参数 参数说明 参数示例
key 缓存前缀

# 获取系统运行状态

服务地址 api/v1/map/cmd/runstatus/${mapid}/${version}
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号;
请求参数 参数说明 参数示例
detail 是否详细数据

# 组合成新地图

服务地址 api/v1/map/cmd/composeNewMap/_null/v1
请求类型 Get 或 Post
服务说明
请求参数 参数说明 参数示例
mapid 地图ID
version 地图版本
clipbounds 地图裁剪范围,范围如[x1,y1,x2,y2], 为空的话,表示不裁剪
selByCrossing 选择是包含还是相交(默认false表示包含,true相交)
fourParameter 四参数(x偏移,y偏移,缩放,旋转弧度),可选,对坐标最后进行修正
isInverseFourParamter 是否用上面的四参数进行反算,默认false
layers 要显示的图层名称,为空的时候,表示全部图层
layerPrefix 生新成图的图层名称前缀
layerSuffix 生新成图的图层名称后缀
savefilename 保存的文件名称,为空的时候,自根据参数自动生成
purge 生成后清理图形数据以减少dwg文件大小
cadVersion 导出的CAD版本号。如果为*表示为当前CAD图的版本

js的源码如下

/**
 * 组合新地图参数
 */
export interface IComposeNewMap {
    /** 地图ID. */
    mapid: string;
    /** 地图版本(为空时采用当前打开的地图版本). */
    version?: string;
    /** 地图裁剪范围,范围如[x1,y1,x2,y2], 为空的话,表示不裁剪 */
    clipbounds?: [number, number, number, number];
    /** 选择是包含还是相交(默认false表示包含,true相交) */
    selByCrossing?: boolean;
    /** 四参数(x偏移,y偏移,缩放,旋转弧度),可选,对坐标最后进行修正*/
    fourParameter?:  [number, number, number, number];
    /** 是否用上面的四参数进行反算,默认false*/
    isInverseFourParamter?:  boolean;
    /** 要显示的图层名称,为空的时候,表示全部图层 */
    layers?: string[];
    /** 生新成图的图层名称前缀 */
    layerPrefix?: string;
    /** 生新成图的图层名称后缀 */
    layerSuffix?: string;
    /** 保存的文件名称,为空的时候,自根据参数自动生成 */
    savefilename?: string;
    /** 生成后清理图形数据以减少dwg文件大小 */
    purge?: boolean
    /** 导出的CAD版本号。如果为*表示为当前CAD图的版本 */
    cadVersion?: string | "*" | "cad2000" | "cad2004" | "cad2007" | "cad2010" | "cad2013"| "cad2018"
}

    /**
     * 组合成新地图
     * @param param 组合参数
     * @return {Promise<any>}
     */
    async composeNewMap(param: IComposeNewMap | IComposeNewMap[]) {
        if (!Array.isArray(param)) {
            param = [param] // 变成数组,下面统一处理
        }
        let cmdParam: Record<string, any> = {};
        if (param.length > 1) {
            cmdParam['count'] = param.length;
        }

        for(let i = 0; i < param.length; i++) {
            let paramKey = i === 0 ? "" : ((i + 1) + "")
            cmdParam['mapid' + paramKey] = param[i].mapid;
            cmdParam['version' + paramKey] = param[i].version;
            cmdParam['clipBounds' + paramKey] = Array.isArray(param[i].clipbounds) ? JSON.stringify(param[i].clipbounds) : undefined;
            cmdParam['selByCrossing' + paramKey] = param[i].selByCrossing;
            cmdParam['fourParameter' + paramKey] = Array.isArray(param[i].fourParameter) ? JSON.stringify(param[i].fourParameter) : undefined;
            cmdParam['isInverseFourParamter' + paramKey] = param[i].isInverseFourParamter === true ? true : undefined;
            cmdParam['layers' + paramKey] = Array.isArray(param[i].layers) ? JSON.stringify(param[i].layers) : undefined;
            cmdParam['layerPrefix' + paramKey] = param[i].layerPrefix;
            cmdParam['layerSuffix' + paramKey] = param[i].layerSuffix;
            cmdParam['savefilename' + paramKey] = param[i].savefilename;
            cmdParam['purge' + paramKey] = param[i].purge;
            if (param[i].cadVersion) {
                cmdParam['cadVersion' + paramKey] = param[i].cadVersion;
            }
        }
        return await this.execCommand("composeNewMap", cmdParam, "_null", "v1", false);
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# 比较地图不同

服务地址 api/v1/map/cmd/mapDiff/_null/v1
请求类型 Get 或 Post
服务说明
请求参数 参数说明 参数示例
mapid1 地图一ID
version1 地图一版本(为空时采用当前打开的地图版本)
layer1 地图一样式图层
mapid2 地图二ID
version2 地图二版本(为空时采用当前打开的地图版本)
layer2 地图二样式图层
noCompareNew 不比较新增部分
noCompareDelete 不比较删除部分
size 比较大小
cellsize 比较单元大小
diffMinAlpha 不同的像素最小值
diffMinAlpha 不同的透明最小值
diffMinColor 不同的颜色最小值

# 投影prj文件WKT字符转proj4字符串

服务地址 api/v1/map/cmd/prjWktToPrj4Str//
请求类型 Post
服务说明 ;
请求参数 参数说明 参数示例
wkt 投影prj文件WKT字符

# 导出布局空间为dwg图

服务地址 api/v1/map/cmd/exportLayout/_null/v1
请求类型 Get 或 Post
服务说明 mapid地图id; version版本号;
请求参数 参数说明 参数示例
mapid 地图ID
version 地图版本(为空时采用当前打开的地图版本)
layoutIndex 布局索引,layoutIndex和layoutName只要输入一个就行,layoutIndex优先。如果都为空,则使用dwg当前的布局空间.
layoutName 布局名称. layoutIndex和layoutName只要输入一个就行,layoutIndex优先。如果都为空,则使用dwg当前的布局空间

# 目标匹配

服务地址 api/v1/map/cmd/objectMatch/_null/v1
请求类型 Get 或 Post
服务说明
请求参数 参数说明 参数示例
mapid 地图ID
version 地图版本(为空时采用当前打开的地图版本)
layer 图层样式名.为空时,将由选择的实体的图层来决定
mapBounds 目标匹配的地图范围,默认为全图的数据范围
objectIds 目标匹配的实体objectid数组,用
objectBounds 目标匹配的实体范围
layeron 目标匹配的地图打开的图层
size 匹配时的图像尺寸,默认10000
method "matchTemplate" "matchPattern"
maxCount 分数,小于此分类将不显示 (0 -1),默认 0.6
minReduceArea 金字塔大小 范围(64-2048).默认256, 方法为matchPattern有效
canOverlap 允许重叠 (默认false).
maxOverlap 重叠比例 范围(0-0.8),默认 0.3
toleranceAngle 角度范围(-180, 180)有旋转的时候需要。方法为matchPattern有效. 默认180
useToleranceRange 是否使用角度区间范围,默认false. 方法为matchPattern有效
tolerance1 角度区间1开始角度. 方法为matchPattern有效
tolerance2 角度区间1结束角度. 方法为matchPattern有效
tolerance3 角度区间2开始角度. 方法为matchPattern有效
tolerance4 角度区间2结束角度. 方法为matchPattern有效

# 获取创建实体的几何数据

服务地址 api/v1/map/cmd/createEntityGeoData/_null/v1
请求类型 Get 或 Post
服务说明
请求参数 参数说明 参数示例
filedoc 文件文档
mapBounds 图形范围.如果不填的话,则使用全图范围
renderAccuracy 渲染精度,默认1,有时候图形特别大导致圆或圆弧精度不够时,不够光滑,可以先清空之前的缓存数据,再重新上传时,改变渲染精度来使圆或圆弧光滑些。注:提高精度会导致空间数据文件增大,渲染性能下降
excludeAttribute 返回的数据中排除属性数据( 默认true)
useZip 返回的数据是否启用zip压缩( 默认true)

# 获取所有工作区

服务地址 api/v1/service/getWorkspace
请求类型 Get
服务说明

# 工作区切换

上面的请求接口都是默认工作区的接口地址。

如果要切换到不同的工作区中,需要请求头地址统一修改下。

/api/v1/map/ 统一修改为 /api/v1/workspace/工作区名称/

如上传的地址为 /api/v1/map/uploads 在工作区w1中上传需改为/api/v1/workspace/w1/uploads

切换工作区的前端代码实现

/**
* 切换至工作区
* @param workspaceName 工作区名称
* @return
*/
function  switchWorkspace(workspaceName) {
    workspaceName = workspaceName.trim()
    this._workspaceName = workspaceName;
    if (workspaceName != "") {
        // 指定工作区
        this._svr_url_map = this.serverUrl + "workspace/" + workspaceName + "/";
    } else {
        // 默认工作区
        this._svr_url_map = this.serverUrl + "map/";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16