diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2024-10-30 18:23:09 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-10-31 11:31:00 +0800 |
commit | 5465dc8ef4ecbb5b13510573d6f09f14d1e0f158 (patch) | |
tree | 6711d002af89fc90c65b3efccefe07a3a6a3783a | |
parent | 6a468847939c8983b7e2ad2a0604d66beebdb94f (diff) |
feat: add dms support when parsing coordinates
-rw-r--r-- | src/dumbyUtils.mjs | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/dumbyUtils.mjs b/src/dumbyUtils.mjs index c4f8d74..975833b 100644 --- a/src/dumbyUtils.mjs +++ b/src/dumbyUtils.mjs | |||
@@ -115,14 +115,34 @@ export const addMarkerByPoint = ({ point, map, title }) => { | |||
115 | export const addGeoSchemeByText = async (node) => { | 115 | export const addGeoSchemeByText = async (node) => { |
116 | const digit = '[\\d\\uFF10-\\uFF19]' | 116 | const digit = '[\\d\\uFF10-\\uFF19]' |
117 | const decimal = '[.\\uFF0E]' | 117 | const decimal = '[.\\uFF0E]' |
118 | const coordPatterns = `(-?${digit}+${decimal}?${digit}*)([,\x2F\uFF0C])(-?${digit}+${decimal}?${digit}*)` | 118 | const coordPattern = `(-?${digit}+${decimal}?${digit}*)` |
119 | const re = new RegExp(coordPatterns, 'g') | 119 | const DMSPattern = `([NEWS]${digit}+[dD°度]? ${digit}+[mM'分]? ${digit}+${decimal}?${digit}*[sS"秒]?)` |
120 | const re = new RegExp(`${coordPattern}[,\x2F\uFF0C]${coordPattern}|${DMSPattern}\\s${DMSPattern}`, 'g') | ||
120 | 121 | ||
121 | return replaceTextNodes(node, re, match => { | 122 | return replaceTextNodes(node, re, match => { |
122 | const [x, y] = [full2Half(match.at(1)), full2Half(match.at(3))] | 123 | const patterns = match.filter(p => p) |
124 | const [match1, match2] = [full2Half(patterns.at(1)), full2Half(patterns.at(2))] | ||
125 | let [x, y] = [undefined, undefined] | ||
126 | |||
127 | // Get x,y by DMS or coordinates pattern | ||
128 | if (match1.match('^[NEWS]')) { | ||
129 | const dms2degreeString = (pchar, nchar) => (dms) => { | ||
130 | const matches = dms.match(new RegExp(`([${pchar}${nchar}])(\\d+) (\\d+) (.*)$`)) | ||
131 | if (!matches) return null | ||
132 | |||
133 | return (matches[1] === pchar ? '' : '-') + (Number(matches[2]) + Number(matches[3]) / 60 + Number(matches[4]) / 3600) | ||
134 | } | ||
135 | x = [match1, match2].map(dms2degreeString('E', 'W')).find(x => x) | ||
136 | y = [match1, match2].map(dms2degreeString('N', 'S')).find(y => y) | ||
137 | } else { | ||
138 | [x, y] = [match1, match2] | ||
139 | } | ||
140 | |||
123 | // Don't process string which can be used as date | 141 | // Don't process string which can be used as date |
124 | if (Date.parse(match.at(0) + ' 1990')) return null | 142 | if (Date.parse(match.at(0) + ' 1990')) return null |
143 | if (!x || !y) return null | ||
125 | 144 | ||
145 | // Return anchor element with Geo Scheme | ||
126 | const a = document.createElement('a') | 146 | const a = document.createElement('a') |
127 | a.className = 'not-geolink from-text' | 147 | a.className = 'not-geolink from-text' |
128 | a.href = `geo:0,0?xy=${x},${y}` | 148 | a.href = `geo:0,0?xy=${x},${y}` |