aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHsieh Chin Fan <pham@topo.tw>2024-10-30 18:23:09 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-10-31 11:31:00 +0800
commit5465dc8ef4ecbb5b13510573d6f09f14d1e0f158 (patch)
tree6711d002af89fc90c65b3efccefe07a3a6a3783a
parent6a468847939c8983b7e2ad2a0604d66beebdb94f (diff)
feat: add dms support when parsing coordinates
-rw-r--r--src/dumbyUtils.mjs26
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 }) => {
115export const addGeoSchemeByText = async (node) => { 115export 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}`