---
title: 要素查询 / 几何
source: https://vjmap.com/guide/service/api/03-query.html
---

# 要素查询 / 几何

> 分类代号：C.3  本章共 **4 个接口**

本章汇集所有"拿到几何 / 属性 / 投影"的基础操作。其中 `queryFeatures` 是最常用的接口，根据 `querytype` 可覆盖点/矩形/表达式/条件 4 种查询场景，因此 SDK 只暴露一个 `query_features(querytype=...)` 统一入口。

---

## 快速索引

| 序号 | SDK 方法 | HTTP | URL |
|----:|---------|------|-----|
| 26 | `query_features` / `queryFeatures` | POST | `/api/v1/map/cmd/queryFeatures/{mapid}/{version}` |
| 27 | `create_entity_geo_data` / `createEntityGeoData` | POST | `/api/v1/map/cmd/createEntityGeoData/_null/v1` |
| 28 | `coord_transform` / `coordTransform` | POST | `/api/v1/map/cmd/coordtransform/_/_` |
| 29 | `prj_wkt_to_prj4_str` / `prjWktToPrj4Str` | POST | `/api/v1/map/cmd/prjWktToPrj4Str/_/_` |

---

## 26 · 要素查询 `queryFeatures`

**URL**：`POST /api/v1/map/cmd/queryFeatures/{mapid}/{version}`  
**SDK**：`svc.query_features(querytype, ...)` / `svc.queryFeatures({ querytype, ... })`  

### `querytype` 枚举

| 值 | 含义 | 必填参数 |
|----|------|---------|
| `point` | 点查询：在屏幕像素范围内找要素 | `x`, `y`, `pixelsize`, `zoom`, `pixelToGeoLength` |
| `rect` | 矩形查询：几何 bounds 内找要素 | `x1`, `y1`, `x2`, `y2` |
| `expresion` | 表达式查询：按 DWG 属性字段过滤 | `expr` |
| `condition` | 条件查询：按后端预定义条件 | `condition`（可空），可选 `bounds` |

> ⚠️ `expresion` 是后端拼写，**不是** `expression`。

### 可选参数（所有 querytype 通用）

| 字段 | 说明 |
|------|------|
| `limit` | 最大返回条数（同时会写入 `maxReturnCount` 和 `limit` 两个字段） |
| `fields` | 要返回的属性字段，逗号分隔，空串 = 全部 |
| `geom` | 是否返回几何（默认 true，false 则只返回 envelop/attrs） |
| `simplifyTolerance` | 几何简化容差 |
| `useCache` | 开启查询缓存（condition/expresion 常用） |
| `toMapCoordinate` | 是否把返回坐标转成地图坐标系 |
| `maxGeomBytesSize` | 单条几何字节大小上限（超过则降级为 envelop） |

### 响应结构

```json
{
  "recordCount": 5,
  "result": [
    {
      "id": 1,
      "objectid": "EA_ED__EE_#",
      "layerindex": 13,
      "name": "AcDbArc",
      "geojson": "...",
      "envelop": "POLYGON(...)",
      "bounds": "[minx,miny,maxx,maxy]",
      "isEnvelop": true,
      "color": -65281,
      "linetype": "BYLAYER",
      "xdata": "",
      "center": "x,y,z",
      "points": "x1,y1,z1;x2,y2,z2;...",
      "colorIndex": 6
    }
  ]
}
```

- `recordCount`：**后端实际扫到的全量数量**，不是本次返回条数。想分页时根据 `recordCount` + `beginpos` 自行控制。
- `geojson` 是字符串而非对象，调用方需要再 `JSON.parse()`。
- `isEnvelop=true` 说明 geojson 被替换成了 envelop（单条太大或命中 `maxGeomBytesSize`）。

### 实采（rect 查询 sys_zp/v1，limit=5）

```json
{
  "recordCount": 5,
  "result": [{
    "id": 1,
    "objectid": "EA_ED__EE_#",
    "layerindex": 13,
    "name": "AcDbArc",
    "geojson": "{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Polygon\",\"coordinates\":[[[2271440.45,-685837.25],[2271440.45,-679783.61],[2276451.33,-679783.61],[2276451.33,-685837.25],[2271440.45,-685837.25]]]}]}",
    "envelop": "POLYGON((2271440.45 -685837.25, ... ))",
    "bounds": "[587661158.58,3103885970.22,587661256.00,3103886087.91]",
    "isEnvelop": true,
    "color": -65281,
    "linetype": "BYLAYER"
  }]
}
```

### 实采（condition 查询，limit=1）

```json
{
  "recordCount": 6982,
  "result": [{
    "id": 1,
    "name": "AcDbArc",
    "geojson": "",
    "envelop": "POLYGON(...)",
    "bounds": "[...]",
    "isEnvelop": false,
    "color": -65281,
    "center": "587661197.39,3103886029.19,-152738.04",
    "points": "x1,y1,z1;x2,y2,z2;x3,y3,z3",
    "colorIndex": 6
  }]
}
```

`recordCount=6982` 表示该地图共 6982 个要素满足条件；`limit=1` 只取第一条。

### Python

```python
# 矩形查询：sys_zp/v1 全图前 5 条
meta = svc.open_map(mapid="sys_zp", version="v1", mapopenway=MapOpenWay.GeomRender)
x1, y1, x2, y2 = [float(x) for x in meta["bounds"][1:-1].split(",")][:4]
res = svc.query_features(
    querytype="rect",
    mapid="sys_zp", version="v1",
    x1=x1, y1=y1, x2=x2, y2=y2,
    limit=5,
)
for item in res["result"]:
    print(item["id"], item["name"])

# 点查询：屏幕 5 像素范围
res = svc.query_features(
    querytype="point",
    x=587661197.39, y=3103886029.19,
    zoom=10,
    pixelsize=5,
    pixel_to_geo_length=100.0,
    limit=3,
)
```

### Node.js

```javascript
const res = await svc.queryFeatures({
  querytype: 'rect',
  mapid: 'sys_zp', version: 'v1',
  x1, y1, x2, y2, limit: 5,
});

const byExpr = await svc.queryFeatures({
  querytype: 'expresion',
  expr: "layerindex=13",
  limit: 10,
});
```

### curl

```bash
curl -X POST "http://127.0.0.1:27660/api/v1/map/cmd/queryFeatures/sys_zp/v1?token=$TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"querytype":"condition","layername":"","zoom":1,"limit":1}'
```

---

## 27 · 构造实体几何 `createEntityGeoData`

**URL**：`POST /api/v1/map/cmd/createEntityGeoData/_null/v1`  
**SDK**：`svc.create_entity_geo_data(mapdata=..., map_extent=..., render_accuracy=..., exclude_attribute=..., use_zip=...)`

> `mapdata` 是前端 `@vj/draw` 构造的 DWG 结构体（JSON 字符串）。独立使用场景较少，通常和前端绘图配合。

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `mapdata` | string | 前端传入的 DWG JSON 字符串 |
| `mapExtent` | string | 地图范围 JSON：`[minx,miny,maxx,maxy]` |
| `renderAccuracy` | number | 渲染精度（像素） |
| `excludeAttribute` | bool | 是否排除属性（默认 true） |
| `useZip` | bool | 是否对 mapdata 做 gzip 压缩（默认 true） |

### 响应

- 合法输入：`{ "result": [...], "bounds": "...", ... }`（与 queryFeatures 类似）

---

## 28 · 坐标转换 `coordtransform`

**URL**：`POST /api/v1/map/cmd/coordtransform/_/_`  
**SDK**：`svc.coord_transform(srs=..., crs=..., points=..., four_parameter=..., is_inverse_four_parameter=...)`

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `srs` | string | 源坐标系，例如 `EPSG:4326` |
| `crs` | string | 目标坐标系，例如 `EPSG:3857` |
| `points` | string | 多点串：`x1,y1;x2,y2` |
| `fourParameter` | string | 可选四参数：`xOff,yOff,scale,rotRad` |
| `isInverseFourParamter` | bool | 是否反向应用四参数（注意后端拼写是 `Paramter`） |

SDK 的 `points` 接受：

- 单点 `(x,y)` 或 `{"x":1,"y":2}`
- 多点 `[(x1,y1),(x2,y2)]`
- `fourParameter` 支持 `"x,y,s,r"` 或 `[x,y,s,r]`

### 响应（实采：4326 → 3857 两点）

```json
{
  "points": [
    [12957254.769864663, 4852582.082864688],
    [13522423.824622115, 3662655.1833045874]
  ]
}
```

### Python

```python
res = svc.coord_transform(
    srs="EPSG:4326",
    crs="EPSG:3857",
    points=[(116.397, 39.908), (121.474, 31.23)],
)
print(res["points"])  # [[12957254.77, 4852582.08], [13522423.82, 3662655.18]]
```

### Node.js

```javascript
const res = await svc.coordTransform({
  srs: 'EPSG:4326',
  crs: 'EPSG:3857',
  points: [[116.397, 39.908], [121.474, 31.23]],
});
console.log(res.points);
```

---

## 29 · WKT → PROJ4 `prjWktToPrj4Str`

**URL**：`POST /api/v1/map/cmd/prjWktToPrj4Str/_/_`  
**SDK**：`svc.prj_wkt_to_prj4_str(wkt, from_="")`

### 请求参数

| 字段 | 类型 | 说明 |
|------|------|------|
| `wkt` | string | ESRI prj 文件内容或 WKT 字符串 |
| `from` | string | 数据来源。空串 = WKT；其他可选 `wmsauto / xml / urn / crsurl / url / micoordsys / pci` |

### 响应（实采：WGS84 WKT）

```json
{ "proj4": "+proj=longlat +datum=WGS84 +no_defs" }
```

### Python

```python
wkt = open("sample.prj", encoding="utf-8").read()
res = svc.prj_wkt_to_prj4_str(wkt)
print(res["proj4"])
```

### Node.js

```javascript
import { readFileSync } from 'node:fs';
const wkt = readFileSync('sample.prj', 'utf8');
const res = await svc.prjWktToPrj4Str(wkt);
console.log(res.proj4);
```

---
