---
title : 使用TGOS服務地址轉座標
tags: TGOS服務、地址轉座標
creat-date: 2022-02-16
update_date : 2022-02-16
---
---
# 使用TGOS服務地址轉座標
---
#### ==說明:透過TGOS服務,將輸入地址轉X、Y座標==
#### ==條件:需先申請TGOS服務,取得ID、Key==
#### ==注意:TGOS服務有筆數的限制,若處理筆數過多,此服務會被鎖住。==
---
## 一、步驟
地址範例:XX縣/市XX鄉/鎮/市/區XX村/里XX鄰XX路/街XX段XX巷XX弄XX之XX號XX樓
例 如:基隆市信義區東信里11鄰東信路282之45號
### step1.清除門牌地址內的相關符號及字體半全形轉換
移除符號,例如: 空白符號、斷行符號、大於(>)、小於(<)、之(-)、雙引號(“) 及單引號(‘)等
### step2.文數字轉換
(1)中文數字轉為阿拉伯數字(如:鄰、弄、號、樓) 、阿拉伯數字轉為中文數字(如:巷)
(2) 「 F、f 」轉換為「樓」
(3) 「B、b」轉換為「地下」 ,且數字候補填「樓」
### step3.自動補填鄰里
依鄉鎮市、路街、號至「TGOS的全國門牌清單查詢服務」,以自動補填鄰、里
### step4. 保留「號」以後的文字內容
<br/>
## 二、程式內容
```C#=1
public static void AddressCheck(ref DataSet_ColumnValue dscv, ref DataSet_ColumnValue dscvTown, ref DataSet_ColumnValue dscvX, ref DataSet_ColumnValue dscvY)
{
string[] sNum = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
string[] sSymbol = { "\n\r", "\n", ">", ">", "<", "<", "\"", "'" };
string sValue = dscv.Value.Trim().Replace(" ", "");
sValue = sValue.Replace("台中縣", "臺中市");
sValue = sValue.Replace("臺中縣", "臺中市");
// 字體全形轉換為半形、移除符
for (int k = 0; k <= 7; k++) {
if (sValue.Contains(sNum[k]))
sValue = sValue.Replace(sNum[k], k.ToString());
sValue = sValue.Replace(sSymbol[k], "");
}
// 「B、b、F、f」樓層轉換
sValue = sValue.Replace("f", "樓").Replace("F", "樓");
if (sValue.Contains("b") || sValue.Contains("B")) {
int nBIndex = (sValue.Contains("b")) ? sValue.IndexOf("b") : sValue.IndexOf("B");
if (sValue.Length != nBIndex + 1) {
if (sValue.Length == nBIndex + 2)
sValue += "樓";
else
sValue = sValue.Substring(0, nBIndex + 2) + "樓" + sValue.Substring(nBIndex + 2, sValue.Length - (nBIndex + 2));
sValue = (sValue.Contains("b")) ? sValue.Replace("b", "地下") : sValue.Replace("B", "地下");
}
}
// 地址範例:○○縣/市 ○○鄉/鎮/市/區 ○○村/里 ○○鄰 ○○路/街 ○○段 ○○巷 ○○弄 ○○之 ○○號 ○○樓
string[] sBNumber = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
string[] sAddrName = { "區", "村", "里", "鄰", "路", "街", "段", "巷", "弄", "號", "樓" };
string sZipCode = "", sFloor = "", sKeyName = "", sNewAddr = "", sTempValue = sValue, sOriTown = "", sOriVillage = "";
if (sTempValue.IndexOf("臺中市") > 0) {
sZipCode = sTempValue.Split('臺')[0];
sTempValue = sTempValue.Replace(sZipCode, "");
sNewAddr = "臺中市";
sTempValue = sTempValue.Replace(sNewAddr, "");
}
else if (sTempValue.IndexOf("臺中市") == 0) {
sNewAddr = "臺中市";
sTempValue = sTempValue.Replace(sNewAddr, "");
}
else {
sNewAddr = (sTempValue.Length > 0 && sTempValue.IndexOf("市") < 0 && sTempValue.IndexOf("縣") < 0) ? "臺中市" : sNewAddr;
}
for (int k = 0; k <= 10; k++) {
if (sTempValue.IndexOf(sAddrName[k]) > 0) {
sKeyName = sTempValue.Split(Convert.ToChar(sAddrName[k]))[0] + sAddrName[k];
sTempValue = sTempValue.Replace(sKeyName, "");
// 判斷「巷」是全阿拉伯數字(bLane = false),還是有包含其他的中文字(bLane = true)
bool bLane = false;
if (sAddrName[k] == "巷") {
int nTotNum = 0;
for (int n = 0; n < sKeyName.Length - 1; n++) {
string sName = sKeyName.Substring(n, 1);
for (int m = 0; m <= 9; m++) {
if (sName == sBNumber[m] || sName == m.ToString() || sName == "之")
nTotNum++;
}
}
if (nTotNum != sKeyName.Length - 1)
bLane = true;
}
// 中文數字(如: 鄰、巷、弄、號、樓)轉為阿拉伯數字
if (sAddrName[k] == "鄰" || (sAddrName[k] == "巷" && bLane == false) || sAddrName[k] == "弄" || sAddrName[k] == "號" || sAddrName[k] == "樓") {
for (int m = 0; m <= 9; m++) {
if (sKeyName.Contains(sBNumber[m]))
sKeyName = sKeyName.Replace(sBNumber[m], m.ToString());
}
sKeyName = sKeyName.Replace("○", "0");
if (sAddrName[k] == "號")
sKeyName = sKeyName.Replace("-", "之");
}
// 文字中有阿拉伯數字轉國字
if (sAddrName[k] == "街" || sAddrName[k] == "路" || (sAddrName[k] == "巷" && bLane == true)) {
bool bCheck = false;
int nFirstIndex = 0, nEndIndex = 0;
for (int m = 0; m <= 9; m++) {
if (sKeyName.Contains(m.ToString())) { // 取得數字的第一個和最後一個位置
nFirstIndex = (bCheck == false) ? sKeyName.IndexOf(m.ToString()) : sKeyName.LastIndexOf(m.ToString());
bCheck = true;
}
}
if (bCheck) {
nEndIndex = (nEndIndex == 0) ? nFirstIndex : nEndIndex;
if (nEndIndex < nFirstIndex) {
int nIndex = nFirstIndex;
nFirstIndex = nEndIndex;
nEndIndex = nIndex;
}
string sNumAddr = sKeyName.Substring(nFirstIndex, nEndIndex - nFirstIndex + 1);
string sReturnNum = returnResult(sNumAddr.toInt());
sKeyName = sKeyName.Replace(sNumAddr, sReturnNum);
}
}
sOriTown = (sAddrName[k] == "區") ? sKeyName : sOriTown;
sOriVillage = (sAddrName[k] == "里" || sAddrName[k] == "村") ? sKeyName : sOriVillage;
if (sAddrName[k] == "樓")
sFloor = sKeyName;
else
sNewAddr += sKeyName; // 樓不加入
}
}
try {
// TGOS的全國門牌清單查詢服務
DataSet dsAddrList = TGOS_Search(sNewAddr);
DataTable dtInfo = dsAddrList.Tables["Info"];
DataTable dtAddrList = dsAddrList.Tables["AddressList"];
if (dtAddrList.Rows.Count == 0) { // 地址有誤
// 拆解的地址有誤,直接用他原始的地址去查
dsAddrList = TGOS_Search(sValue);
dtInfo = dsAddrList.Tables["Info"];
dtAddrList = dsAddrList.Tables["AddressList"];
if (dtAddrList.Rows.Count == 0) {
dscv.CheckValue = 2;
}
else {
if (dtInfo.Rows[0]["OutMatchType"].ToString() == "模糊比對" && dtAddrList.Rows[0]["FULL_ADDR"].ToString() != sNewAddr) {
dscv.CheckValue = 2;
}
else {
if (dscvTown != null)
dscvTown.Value = dtAddrList.Rows[0]["TOWN"].ToString();
dscvX.Value = dtAddrList.Rows[0]["X"].ToString();
dscvY.Value = dtAddrList.Rows[0]["Y"].ToString();
sValue = sZipCode + dtAddrList.Rows[0]["FULL_ADDR"].ToString() + sFloor + sTempValue;
dscv.CheckValue = (dscv.OriValue != sValue) ? 1 : dscv.CheckValue; // 地址有修正過
}
}
}
else {
if (dtInfo.Rows[0]["OutMatchType"].ToString() == "模糊比對" && dtAddrList.Rows[0]["FULL_ADDR"].ToString() != sNewAddr) { // 地址有誤
// 拆解的地址有誤,直接用他原始的地址去查
dsAddrList = TGOS_Search(sValue);
dtInfo = dsAddrList.Tables["Info"];
dtAddrList = dsAddrList.Tables["AddressList"];
if (dtAddrList.Rows.Count == 0) {
dscv.CheckValue = 2;
}
else {
if (dtInfo.Rows[0]["OutMatchType"].ToString() == "模糊比對" && dtAddrList.Rows[0]["FULL_ADDR"].ToString() != sNewAddr) {
dscv.CheckValue = 2;
}
else {
if (dscvTown != null)
dscvTown.Value = dtAddrList.Rows[0]["TOWN"].ToString();
dscvX.Value = dtAddrList.Rows[0]["X"].ToString();
dscvY.Value = dtAddrList.Rows[0]["Y"].ToString();
sValue = sZipCode + dtAddrList.Rows[0]["FULL_ADDR"].ToString() + sFloor + sTempValue;
dscv.CheckValue = (dscv.OriValue != sValue) ? 1 : dscv.CheckValue; // 地址有修正過
}
}
}
else {
if (dscvTown != null)
dscvTown.Value = dtAddrList.Rows[0]["TOWN"].ToString();
dscvX.Value = dtAddrList.Rows[0]["X"].ToString();
dscvY.Value = dtAddrList.Rows[0]["Y"].ToString();
sValue = sZipCode + dtAddrList.Rows[0]["FULL_ADDR"].ToString() + sFloor + sTempValue;
dscv.CheckValue = (dscv.OriValue != sValue) ? 1 : dscv.CheckValue; // 地址有修正過
}
}
}
catch (Exception ex) {
dscv.CheckValue = 2;
sValue = sZipCode + sNewAddr + sTempValue;
}
// 若行政區、X、Y坐標為空值,則設為有誤
if (dscvTown != null) {
if (dscvTown.Value == "")
dscvTown.CheckValue = 2;
}
if (dscvX.Value == "")
dscvX.CheckValue = 2;
if (dscvY.Value == "")
dscvY.CheckValue = 2;
dscv.Value = sValue;
}
/// <summary>
/// TGOS的全國門牌清單查詢服務
/// </summary>
/// <param name="sAddress">地址</param>
/// <returns></returns>
public static DataSet TGOS_Search(string sAddress)
{
WSQueryAddr wsq1 = new WSQueryAddr();
string rtval = wsq1.QueryAddr(ConfigurationManager.AppSettings["togs.queryAddr.APPID"],
ConfigurationManager.AppSettings["togs.queryAddr.APIKey"],
sAddress,
"EPSG:3826",
2,
"JSON",
0,
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
10);
DataSet dsAddrList = JsonConvert.DeserializeObject<DataSet>(rtval);
return dsAddrList;
}
```
<br/>
## 三、TGOS查詢比對

<br/>
## 四、產出結果

<br/>
## 五、常用座標轉換
| 坐標系統 | 用途 | EPSG | X坐標 | Y坐標 |
| -------- | -------- | -------- | -------- | -------- |
| TWD97二度分帶-中央經線121度 | 台灣本島圖資 | EPSG:3826 | 179266 | 2502459 |
| TWD67二度分帶-中央經線121度 | 台灣本島圖資(早期) | EPSG:3828 | 178436 | 2502665 |
| WGS84經緯度(球體) | 全球圖資 如:Google Map, GPS| EPSG:4326 | 120.311914 | 22.620820 |
| Spherical Mercator (投影) | 圖磚, WMTS | EPSG:3857 | 13393061.01 | 2586227.26 |
#### 資料來源:https://gisdawh.kcg.gov.tw/md/mdread.cfm?qid=qa%5C%E5%B9%B3%E5%8F%B0%E5%9C%B0%E5%9C%96%E8%88%87%E5%9C%96%E8%B3%87%E5%9D%90%E6%A8%99%E7%B3%BB%E7%B5%B1%E8%AA%AA%E6%98%8E