注指南:分子分母排版技法詳解)
做國土調(diào)查、林業(yè)一張圖、管線普查這類項目時圖斑標(biāo)注經(jīng)常要排成“分?jǐn)?shù)”樣式地類名稱在上分類編碼在下中間一條橫線拉出來業(yè)內(nèi)叫它分子分母標(biāo)注。ArcGIS 的默認(rèn)標(biāo)注功能雖然也能拼字段但直接輸出[地類名稱] [地類編碼]這種單行文本出圖時既不專業(yè)也不規(guī)范。我自己剛接觸這塊時也繞了不少彎子后來摸清標(biāo)注表達式里的換行符和文本格式化標(biāo)簽以后幾百個圖斑的分式標(biāo)注幾分鐘就能批量搞定。這篇文章把我實際項目里驗證過的方法整理出來重點講 ArcMap 和 ArcGIS Pro 兩套環(huán)境下的寫法差異以及空值處理、數(shù)值格式化、標(biāo)注壓蓋這些容易踩坑的細節(jié)。不管你是常年用 ArcMap 的老用戶還是已經(jīng)切到 ArcGIS Pro 的新手照著操作基本都能復(fù)現(xiàn)。如果只是臨時出一張示意圖文末的斜杠替代方案也能救急。1. 先搞清楚分子分母標(biāo)注到底解決什么問題1.1 最常見的四類應(yīng)用場景分子分母標(biāo)注在制圖領(lǐng)域比想象中普遍。最典型的是土地利用現(xiàn)狀圖圖斑上要同時體現(xiàn)地類名稱和地類編碼比如分子寫“水田”分母寫“0101”一張圖上信息密度直接翻倍。林業(yè)調(diào)查的林地一張圖也類似省、縣、鄉(xiāng)、村各級林斑經(jīng)常要求標(biāo)注“林種/地類編碼”方便外業(yè)核查人員一眼看到兩個關(guān)鍵屬性。第二類是管線圖。給排水、燃氣、電力管道在做竣工圖時通常要在管線段上標(biāo)注“管徑/埋深”比如“DN300/1.2m”。如果把這些信息拆成兩行并加一條分?jǐn)?shù)線會比單純的斜杠分隔清楚得多也不容易看錯單位。第三類是測繪成果圖。像控制點成果圖里點號在上、高程在下或者點名在上、坐標(biāo)值在下用分式標(biāo)注比一行文字緊湊得多還能避免點號和坐標(biāo)串在一起難以辨認(rèn)。第四類是科研論文配圖或?qū)n}圖。分析土地利用變化時圖斑標(biāo)注“面積/占比”或者“原分類/現(xiàn)分類”都很常見。這種場景下標(biāo)注系統(tǒng)能不能快速按字段動態(tài)生成分式直接影響出圖效率。1.2 為什么不直接寫斜杠可能有人會說我直接標(biāo)注成“水田/0101”不就行了何必折騰成真正的分式分式標(biāo)注的核心價值有兩個。第一是視覺層次。分子和分母通過橫線分隔讀者先看分子再看分母信息層級天然區(qū)分。斜杠寫法在字號小、內(nèi)容多的時候容易把兩個字段粘連在一起比如“DN600/2.5m”和“DN600/25m”在快速瀏覽時容易看混。第二是制圖規(guī)范。很多行業(yè)制圖標(biāo)準(zhǔn)比如國土調(diào)查數(shù)據(jù)庫圖件規(guī)范、林業(yè)專題圖圖式明確要求圖斑標(biāo)注采用分式形式。如果提交的圖件不合規(guī)范后續(xù)質(zhì)檢和入庫都會很麻煩。與其在 CAD 里手動擺文字不如直接在 ArcGIS 標(biāo)注表達式里解決。1.3 核心思路一句話說清ArcGIS 的標(biāo)注表達式本質(zhì)上就是“根據(jù)要素屬性動態(tài)拼出要顯示的字符串”所以分式標(biāo)注的核心思路就是把分子寫在一行通過換行符切換到下一行再用文本格式化標(biāo)簽中的下劃線標(biāo)簽UND給分子加上一條橫線視覺效果上就變成了分?jǐn)?shù)線。實現(xiàn)下來,無非是分子文本字段或表達式拼接結(jié)果外面包一層UND和/UND。分隔VBScript 用vbCrLfPython 和 Arcade 用\n。分母普通字段或表達式直接換行輸出。掌握這一個基本公式后各種變體加前后綴、判斷空值、數(shù)字格式化都是在這個基礎(chǔ)上擴展的。2. ArcMap 里最實用的三種實現(xiàn)寫法2.1 方法一下劃線標(biāo)簽做出真分?jǐn)?shù)線這是我強烈推薦的主方案。ArcGIS 的標(biāo)注系統(tǒng)支持一組文本格式化標(biāo)簽其中UND表示給文本加下劃線。用UND [分子字段] /UND給分子加下劃線換行后再接分母出來的效果就是一條緊貼分子底部的水平線視覺上非常接近印刷體的分?jǐn)?shù)。在 ArcMap 中的操作路徑是圖層右鍵 → Properties → Labels 選項卡 → 在標(biāo)注字段下拉框右側(cè)點擊 Expression 按鈕 → 解析器選擇 VBScript → 在表達式框中輸入以下內(nèi)容UND [地類名稱] /UND vbCrLf [地類編碼]然后點擊 Verify 按鈕預(yù)覽效果確認(rèn)正常后一路點 OK。如果字段是數(shù)值型VBScript 在字符串拼接時會自動轉(zhuǎn)換通常不需要額外處理。但建議養(yǎng)成用CStr()包裹的習(xí)慣避免個別版本環(huán)境下出現(xiàn)類型不匹配的問題。UND CStr([地類名稱]) /UND vbCrLf CStr([地類編碼])這個方案的優(yōu)點是橫線長度自動匹配分子文本寬度分子改成“喬木林地”還是“水田”下劃線都會跟著變不需要手動調(diào)整。2.2 方法二固定橫線字符的三行式如果你不喜歡下劃線緊貼文本的效果想要一條空隙更大的分?jǐn)?shù)線可以改用橫線字符。原理很簡單分子一行橫線一行分母一行三行疊出分式。[地類名稱] vbCrLf ―――――― vbCrLf [地類編碼]這里的“――”是全角破折號也可以換成“-”或“—”選擇什么字符取決于字體。宋體、黑體等中文字體下全角破折號顯示比較整齊半角連字符則需要多寫幾個才能拉長。需要注意橫線長度是固定的如果分子字段長度差異很大短分子配長橫線會顯得很不協(xié)調(diào)。我的經(jīng)驗是橫線字符數(shù)量按“字段最長可能值的寬度 兩三個余量”來配置寧可稍長一點也不要出現(xiàn)分子寬度超出橫線的情況。如果字段特別長還可以用Left([字段], N)截斷分子配合提示符號使用。2.3 方法三斜杠分式的簡單替代對出圖精度要求不高、或者只需要在制圖過程中臨時看屬性的時候斜杠寫法就是效率最高的方案。直接在表達式框里寫[地類名稱] / [地類編碼]或者輸出成“地類名稱換行斜杠編碼”的變體[地類名稱] / [地類編碼]這不算真正的分式標(biāo)注但勝在快、簡單、不出錯。我一般是在數(shù)據(jù)檢查階段用這種臨時標(biāo)注等正式出圖前再切換成分式表達式。2.4 如何驗證表達式效果ArcMap 的標(biāo)注表達式對話框中有一個 Verify 按鈕點擊后會彈出預(yù)覽窗口顯示當(dāng)前圖層第一條要素的標(biāo)注結(jié)果。在初學(xué)階段我建議每寫完一段表達式都先點一下 Verify看看換行是否生效分子下劃線是否出現(xiàn)數(shù)字字段是否正常顯示空值字段是否顯示成空白而不是“ ”之類的字樣。預(yù)覽沒問題后再關(guān)閉對話框在內(nèi)容列表中勾選圖層的 Labels 復(fù)選框查看全圖效果。如果標(biāo)注壓蓋嚴(yán)重就應(yīng)該把“標(biāo)注優(yōu)先級”和“要素權(quán)重”調(diào)一下這在后面常見問題部分會展開說。3. 表達式別踩坑字段類型、空值和數(shù)值格式化3.1 字段類型轉(zhuǎn)換VBScript 和 Python 的差異分子分母標(biāo)注的字段并不總是文本型。面積、坡度、管徑等字段在屬性表里通常是雙精度數(shù)值拼接時要先轉(zhuǎn)成字符串。VBScript 里可以直接用連接它會隱式轉(zhuǎn)換數(shù)值到字符串而且轉(zhuǎn)換邏輯基本符合直覺但我在 ArcGIS Pro 里切換到 Python 解析器后直接拼接會報類型錯誤必須顯式用str()包裝def FindLabel([面積], [地類編碼]): area_str str([面積]) code_str str([地類編碼]) return UND area_str /UND\n code_strVBScript 里的寫法如果想顯式轉(zhuǎn)換可以用CStr()UND CStr([面積]) /UND vbCrLf CStr([地類編碼])3.2 空值與空字符串是兩個問題這是分式標(biāo)注里最容易翻車的地方。ArcGIS 的字段中Null 表示沒有值空字符串表示有一個空文本兩者性質(zhì)不同。Excel 導(dǎo)入的數(shù)據(jù)經(jīng)常出現(xiàn)空字符串CAD 轉(zhuǎn)過來的數(shù)據(jù)則可能出現(xiàn) Null。如果不處理分子或分母會直接空掉只顯示一條橫線或一個斜杠很不美觀。VBScript 中處理空值的標(biāo)準(zhǔn)寫法是用IIfIIf(IsNull([地類名稱]), -, CStr([地類名稱])) vbCrLf IIf(IsNull([地類編碼]), -, CStr([地類編碼]))不過IIf只判斷 Null空字符串會被當(dāng)成有效值顯示。為了更穩(wěn)妥建議在高級模式下寫一個完整的 FindLabel 函數(shù)把空值和空字符串一起處理Function FindLabel ([地類名稱], [地類編碼]) Dim sName Dim sCode If IsNull([地類名稱]) Or [地類名稱] Then sName - Else sName CStr([地類名稱]) End If If IsNull([地類編碼]) Or [地類編碼] Then sCode - Else sCode CStr([地類編碼]) End If FindLabel UND sName /UND vbCrLf sCode End Function在 ArcMap 中使用高級表達式需要勾選表達式對話框底部的“高級”復(fù)選框然后在表達式框中輸入整個函數(shù)。Python 解析器同樣適用高級模式寫法如下def FindLabel([地類名稱], [地類編碼]): name str([地類名稱]) if [地類名稱] is not None else - code str([地類編碼]) if [地類編碼] is not None else - if [地類名稱] : name - if [地類編碼] : code - return UND name /UND\n code3.3 數(shù)值格式化保留小數(shù)和千分位面積、長度這類數(shù)值直接轉(zhuǎn)字符串可能會出現(xiàn)一長串小數(shù)圖面上非常難看。控制小數(shù)位數(shù)有兩種常見需求保留兩位小數(shù)和千分位分隔。VBScript 里用FormatNumberUND FormatNumber([面積], 2) ha/UND vbCrLf CStr([地類編碼])Python 里用 format 語法def FindLabel([面積], [地類編碼]): area_str {:.2f}.format([面積]) return UND area_str /UND\n str([地類編碼])如果需要千分位分隔符Python 里可以用{:,.2f}.format([面積])比如 123456.78 顯示成 123,456.78。測繪圖件中面積過大時這種格式更容易讀。3.4 高級模式下做條件過濾有人問能不能只對部分要素做分式標(biāo)注當(dāng)然可以。比如面積大于 500 平方米的圖斑才顯示“面積/地類”面積太小的不標(biāo)注避免注記密集。高級模式下VBScript 的 FindLabel 函數(shù)可以直接用條件語句Function FindLabel ([面積], [地類編碼]) If [面積] 500 Then FindLabel UND FormatNumber([面積], 2) /UND vbCrLf CStr([地類編碼]) Else FindLabel End If End FunctionPython 版本同理def FindLabel([面積], [地類編碼]): if [面積] 500: return UND {:.2f}.format([面積]) /UND\n str([地類編碼]) else: return 這個技巧特別適合處理“圖斑多、面積小”的密集區(qū)域。配合比例尺范圍設(shè)置可以做到大比例尺下全標(biāo)注、小比例尺下只標(biāo)注大圖斑。3.5 在分子分母上加前后綴ArcGIS 標(biāo)注表達式支持任意字符串拼接所以給分子或分母加單位、前綴都不麻煩。比如分子顯示“面積150.25”再帶下劃線分母顯示“地類0301”。只需注意引號和字段的拼接順序UND面積 FormatNumber([面積], 2) /UND vbCrLf 地類 CStr([地類編碼])還有一種用法是給分子分母加單位比如“NDVI 0.75”作為分子“2023 年影像”作為分母適合做遙感分類專題圖的標(biāo)注。4. ArcGIS Pro 中的分式標(biāo)注別照搬舊腳本4.1 解析器差異Python 和 Arcade很多老 ArcMap 用戶切到 ArcGIS Pro 后發(fā)現(xiàn)標(biāo)注表達式對話框變樣了默認(rèn)解析器是 Python甚至沒有 VBScript 選項。ArcMap 里保存的 VBScript 標(biāo)注表達式在 Pro 中不一定能直接運行需要手動轉(zhuǎn)成 Python 或 Arcade 表達式。Pro 中的標(biāo)注表達式入口在內(nèi)容列表選中圖層 → 左上角 Labeling 選項卡 → Label Properties 下拉 → Expression。打開后可以選擇 Python 或 Arcade 解析器表達式框下方有 Verify 按鈕用法與 ArcMap 一致。4.2 Pro 中的推薦寫法在 ArcGIS Pro 中使用 Python 解析器推薦寫法就是定義一個 FindLabel 函數(shù)把所有字段作為參數(shù)傳進去邏輯寫清楚。以“分子為地類名稱、分母為地類編碼”為例def FindLabel([地類名稱], [地類編碼]): name str([地類名稱]) if [地類名稱] is not None else - code str([地類編碼]) if [地類編碼] is not None else - if name : name - if code : code - return UND name /UND\n code如果不想用函數(shù)單行表達式也可以UND str([地類名稱]) /UND\n str([地類編碼])但注意單行表達式遇到空值時容易報錯尤其是數(shù)值型字段為 None 時str(None)會輸出 None 而不是空值。所以只要字段可能為空我都建議用函數(shù)形式。Arcade 解析器的寫法則更接近 JavaScriptvar name $feature.地類名稱; var code $feature.地類編碼; if (name null) { name -; } if (code null) { code -; } return UND name /UND\n code;Arcade 的好處是字段名無需方括號表達式更清爽但如果你團隊里其他人都用 Python還是統(tǒng)一用 Python 更利于維護。4.3 行距和文本符號調(diào)整技巧分式標(biāo)注的兩行文本之間默認(rèn)行距可能太擠下劃線和分母會貼在一起。ArcMap 中可以通過標(biāo)注符號編輯器調(diào)整行距Labels 選項卡 → Symbol 按鈕 → 打開 Symbol Selector → 點擊 Properties / Advanced Text → 調(diào)整 Line SpacingLeading參數(shù)單位是磅值一般設(shè) 2~4 磅比較合適。ArcGIS Pro 中操作類似Labeling 選項卡 → Text Symbol 面板 → 打開 Format Text Symbol 面板 → 在 Spacing 區(qū)域調(diào)整 Leading行距。我一般把數(shù)值設(shè)為 2 到 5具體看分子文本的字體大小。還有一種取巧的辦法在表達式的分子和分母之間插入兩個換行符比如return UND name /UND\n\n code這樣會多空出一行但代價是標(biāo)注占用的圖面空間變大。如果只是偶然處理一張圖可以用如果是批量出圖還是調(diào)行距更專業(yè)。5. 常見問題排查速查表5.1 換行符不生效表現(xiàn)原因解決方案表達式輸出仍在同一行解析器選錯用 Python 卻寫vbCrLf確認(rèn)解析器后使用對應(yīng)的換行符換行了但中間有一條多余空白行使用了兩個換行符只保留一個\n或vbCrLf高級模式下函數(shù)沒有返回值FindLabel 未正確賦值檢查函數(shù)名和最后的賦值語句Python 中一定要注意\n寫在字符串內(nèi)部不能寫成/n。VBScript 中除了vbCrLf還可以用Chr(13) Chr(10)但沒必要vbCrLf足夠清晰。5.2 下劃線位置不對或跑偏UND標(biāo)簽包裹的范圍必須嚴(yán)格限定在分子文本外面不要包住換行符。正確寫法是UND 分子 /UND vbCrLf 分母如果誤把/UND放在換行符后面下劃線會延伸到換行符導(dǎo)致整條標(biāo)注都出現(xiàn)下劃線。某些字體或字形下下劃線距離文字底部太近看上去像文本自帶的下劃線而不是分?jǐn)?shù)線。這時改用 2.2 節(jié)的固定橫線字符方案或者調(diào)整行距把兩行間距拉大。還有一個少見問題如果分子字段包含換行符比如從 Excel 導(dǎo)入的字段內(nèi)部有回車UND的顯示會異常需要在表達式里先把字段內(nèi)部的換行符替換掉Replace([地類名稱], vbCrLf, )5.3 標(biāo)注重疊壓蓋分式標(biāo)注比單行標(biāo)注占用空間大更容易互相疊壓。別急著寫一堆代碼先確認(rèn)兩件事第一在圖層屬性中把“標(biāo)注優(yōu)先級”設(shè)為合適級別比如比道路注記低。第二在標(biāo)注符號的“放置屬性”中盡量勾選“移除沖突標(biāo)注”或者調(diào)整“權(quán)重”。ArcMap 中還有要素權(quán)重設(shè)置可以把需要優(yōu)先顯示的要素設(shè)為更高權(quán)重讓被壓蓋的標(biāo)注自動隱藏。如果圖斑太密集就按 3.4 節(jié)的條件過濾只標(biāo)注面積大于某個閾值的圖斑。5.4 從 ArcMap 遷到 Pro 的兼容問題ArcMap 的 mxd 圖層在 ArcGIS Pro 中打開時原來的 VBScript 標(biāo)注表達式可能會丟失或被轉(zhuǎn)成基礎(chǔ)字段標(biāo)注。建議遷移前先把關(guān)鍵標(biāo)注表達式截圖或復(fù)制保存到文檔里到 Pro 中再重寫 Python 版本。另一個兼容坑是UND等文本格式化標(biāo)簽在 Pro 中對不同字體支持不完全一致。我遇到過中文宋體下下劃線正常換到某些 CAD 導(dǎo)入字體后下劃線消失的情況。這種問題沒有通用解法只能換字體測試。6. 還想再省事把標(biāo)注轉(zhuǎn)成注記再微調(diào)6.1 什么時候需要轉(zhuǎn)注記標(biāo)注表達式的優(yōu)勢是動態(tài)更新屬性變了標(biāo)注自動變。但制圖出圖階段經(jīng)常需要人工挪動某些標(biāo)注的位置、修改個別文字內(nèi)容、刪除遮擋重要地物的注記。這時候就應(yīng)該把標(biāo)注轉(zhuǎn)為注記Annotation變成獨立存儲在數(shù)據(jù)庫或要素類中的對象可以逐個編輯。當(dāng)圖層轉(zhuǎn)為注記后就不再依賴標(biāo)注表達式可以自由調(diào)整字體、行數(shù)、位置。條件允許的話輸出“地理數(shù)據(jù)庫注記”比“地圖文檔注記”更靈活注記可以反復(fù)加載。6.2 轉(zhuǎn)換的兩種方式與邊界處理ArcMap 中圖層右鍵 → Convert Labels to Annotation??梢赃x擇“將標(biāo)注轉(zhuǎn)換為注記存儲于地理數(shù)據(jù)庫”還是“存儲于地圖文檔中”。ArcGIS Pro 中同樣是右鍵圖層 → Convert Labels to Annotation界面類似。需要注意的是轉(zhuǎn)注記前一定要把標(biāo)注表達式調(diào)到最終狀態(tài)因為轉(zhuǎn)完后表達式就不再“活著”了改字段值無法自動刷新注記。如果數(shù)據(jù)后續(xù)可能更新建議保留原始標(biāo)注圖層先在副本上轉(zhuǎn)注記做制圖整飾。轉(zhuǎn)注記時還有一個選項是關(guān)于未放置標(biāo)注Unplaced Annotation。密集區(qū)域的標(biāo)注可能被自動隱藏轉(zhuǎn)換后這些“未放置”的注記會存在注記組的表里??梢栽谥茍D整飾階段手動把這些未放置注記拖到合適位置增加圖面信息量。6.3 一個小技巧轉(zhuǎn)換前先檢查字段轉(zhuǎn)換注記后才發(fā)現(xiàn)面積字段格式不對或者地類編碼少了一位返工成本很高。我習(xí)慣在轉(zhuǎn)換前用“標(biāo)注表達式Verify”逐條檢查幾個關(guān)鍵圖斑再配合屬性表篩選看有沒有空值字段沒處理。檢查清單大致是分子分母是否都正常顯示是否有字段顯示為 “None” 或 “ ”數(shù)字是否按預(yù)期保留了小數(shù)位數(shù)有沒有字段內(nèi)容過長導(dǎo)致標(biāo)注超出圖斑范圍。確認(rèn)無誤后再轉(zhuǎn)注記Step by step穩(wěn)得很。我個人在實際項目里還會把標(biāo)注表達式存成文本文件按工程名分類放好下次遇到同類任務(wù)直接改字段名就能復(fù)用。ArcGIS 的標(biāo)注表達式并不復(fù)雜但寫一次容易寫一次好看又不出錯的往往就是多個細節(jié)疊加的結(jié)果。做分式標(biāo)注時先想清楚字段類型、空值、換行符、下劃線標(biāo)簽這四個環(huán)節(jié)再用上面的方法組合基本就能把大多數(shù)圖面標(biāo)注需求拿下來。