在国土三调工作中,土地利用现状数据库的标注是个让人头疼的问题。我参与过多个地区的三调项目,发现标注不规范会导致图面混乱,严重影响成果质量。最常见的需求是要同时显示地类编码(DLBM)、地类名称(DLMC)和权属单位名称(QSDWMC),这就涉及到多行文本的排版问题。
传统的手动标注方式效率极低,一个县区的数据可能包含上万个图斑,每个都手动调整位置根本不现实。这时候就需要借助ArcGIS的标注引擎和VBScript脚本来自动化处理。经过多次实践,我发现二分式(上下两行)和三分式(三行)是最实用的两种排版方式。
二分式适合显示核心属性,比如地类编码+地类名称,或者地类编码+权属单位。三分式则能完整展示所有关键信息。但直接使用ArcGIS的默认多行标注功能会出现对齐不整齐、间距不一致的问题,特别是中英文混排时更明显。
先来看二分式标注的核心代码,这是我优化过的版本:
vbscript复制FUNCTION myFind(DZM, NAME)
a = strlen(dzm)
b = strlen(NAME)
IF a > b THEN
myFind = "<und>" & DZM & "</und>" & vbcrlf & NAME
ELSE
str = space((b-a)/2)
myFind = "<und>" & str & DZM & str & "</und>" & vbcrlf & NAME
END if
END Function
FUNCTION strlen(str)
dim p_len
p_len=0
strlen=0
p_len=len(str)
FOR xx=1 to p_len
IF asc(mid(str,xx,1))<0 THEN
strlen=int(strlen) + 2
ELSE
strlen=int(strlen) + 1
END if
NEXT
END function
Function FindLabel ([DLBM],[TBBH])
FindLabel = myFind([DLBM],[TBBH])
End Function
这段代码的关键点在于strlen函数,它解决了中文字符长度计算的问题。ASC码小于0的字符(如中文)按2个字符宽度计算,英文和数字按1个字符计算。这样计算出的字符串显示宽度更准确。
myFind函数实现了智能居中功能:当上行的地类编码比下行的名称短时,会自动在编码两侧添加空格使其居中显示。<und>标签可以让上行的文字加粗显示,增强视觉层次感。
在实际项目中,我发现原始代码有几个可以改进的地方:
vbscript复制IF IsNull(DZM) OR IsNull(NAME) THEN
FindLabel = ""
Exit Function
END IF
vbscript复制myFind = "<und>" & DZM & "</und>" & "<br>" & NAME
然后在标注属性里设置HTML渲染,并调整行高参数。
vbscript复制myFind = "<CLR red='255'><und>" & DZM & "</und></CLR><br>" & _
"<FNT name='Arial'>" & NAME & "</FNT>"
三分式标注的复杂度明显提升,下面是经过实战检验的代码:
vbscript复制FUNCTION myFind(cunname,DJH,SHAPE_Area)
dim str
str = SHAPE_Area
dim d
d = strlen(str)
dim d1
dim d2
d1 = strlen(cunname)/2
if d1<1 then d1=1 end if
d2 = strlen(DJH)/2
if d2<1 then d2=1 end if
if d2>d1 then d1=d2 end if
myFind = cunname & space(d) & vbnewline & _
string(d1,"—") & str & vbnewline & _
DJH & space(d)
END Function
Function FindLabel ([DLMC],[DLBM],[QSDWMC])
FindLabel = myFind([DLMC],[DLBM],[QSDWMC])
End Function
这段代码实现了三行文本的智能排版:
动态分隔线:string(d1,"—")会根据文本宽度自动生成合适长度的分隔线,比固定长度更美观。
右对齐留白:space(d)在首行和末行右侧添加空白,使整体布局更平衡。
宽度自适应:通过比较三行文本的宽度,自动调整排版参数。
特殊字符处理:当字段值包含括号、百分号等特殊字符时,需要额外处理:
vbscript复制cunname = Replace(cunname, "%", "%%")
最常见的困扰是中英文字符宽度不一致导致的对齐偏差。除了使用我们自定义的strlen函数外,还可以:
当处理上万条记录时,脚本性能变得很重要。我总结了几点经验:
实际项目中会遇到各种特殊情况:
vbscript复制IF strlen(QSDWMC) > 20 THEN
QSDWMC = left(QSDWMC,10) & "..."
END IF
vbscript复制SELECT CASE DLBM
CASE "0101", "0102"
'耕地使用特殊样式
CASE ELSE
'默认样式
END SELECT
vbscript复制IF [Shape_Area] < 1000 THEN
'小图斑简化显示
END IF
通过Python脚本与VBScript配合,可以实现更智能的标注:
虽然VBScript是ArcGIS的传统方案,但也可以考虑:
在实际的三调项目中,我建议先用VBScript实现基础功能,再根据项目需求逐步引入这些高级技术。特别是在处理省级或国家级大型数据库时,前期的标注方案设计会直接影响后期制图效率。