aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHsieh Chin Fan <pham@topo.tw>2024-10-31 11:27:20 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-10-31 12:01:51 +0800
commit7ee1ad61627f9a2af04f080cfa95a30f3c8e4525 (patch)
treecff733c310788f802fe00fbcdd8f4054a3ef4075
parent2bcad7ff9a42ad39a4b2f24c4af9b6a5578ba1fd (diff)
feat: add menu-item for Geocoding
* Use nominatim for API calls * Create multiple GeoLinks for each results in response * Also add menu-item DELETE to remove duplicated GeoLinks from one Geocoding
-rw-r--r--src/MenuItem.mjs23
-rw-r--r--src/dumbyUtils.mjs2
-rw-r--r--src/dumbymap.mjs33
-rw-r--r--src/utils.mjs2
4 files changed, 57 insertions, 3 deletions
diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs
index 103f43e..13dbc44 100644
--- a/src/MenuItem.mjs
+++ b/src/MenuItem.mjs
@@ -586,3 +586,26 @@ export const editMap = (map, dumbymap) => {
586 ], 586 ],
587 }) 587 })
588} 588}
589
590export const addLinkbyNominatim = (range) => {
591 return Item({
592 text: 'Add Link by Geocoding',
593 onclick: () => {
594 const place = range.toString()
595 fetch(`https://nominatim.openstreetmap.org/search?q=${place.toString()}&format=json`)
596 .then(res => res.json())
597 .then(places => {
598 if (places.length === 0) return
599 console.log('nomiatim', places)
600 range.deleteContents()
601 places.forEach(p => {
602 const a = document.createElement('a')
603 a.className = 'not-geolink from-geocoding'
604 a.href = `geo:${p.lat},${p.lon}?name=${p.name}&osm=${p.osm_type}/${p.osm_id}`
605 a.textContent = place
606 range.insertNode(a)
607 })
608 })
609 },
610 })
611}
diff --git a/src/dumbyUtils.mjs b/src/dumbyUtils.mjs
index 975833b..8110e82 100644
--- a/src/dumbyUtils.mjs
+++ b/src/dumbyUtils.mjs
@@ -144,7 +144,7 @@ export const addGeoSchemeByText = async (node) => {
144 144
145 // Return anchor element with Geo Scheme 145 // Return anchor element with Geo Scheme
146 const a = document.createElement('a') 146 const a = document.createElement('a')
147 a.className = 'not-geolink from-text' 147 a.className = 'not-geolink from-geocoding'
148 a.href = `geo:0,0?xy=${x},${y}` 148 a.href = `geo:0,0?xy=${x},${y}`
149 a.textContent = match.at(0) 149 a.textContent = match.at(0)
150 return a 150 return a
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs
index 4562612..9bc1da7 100644
--- a/src/dumbymap.mjs
+++ b/src/dumbymap.mjs
@@ -540,7 +540,8 @@ export const generateMaps = (container, {
540 const map = e.target.closest('.mapclay') 540 const map = e.target.closest('.mapclay')
541 const block = e.target.closest('.dumby-block') 541 const block = e.target.closest('.dumby-block')
542 const linkWithLine = e.target.closest('.with-leader-line') 542 const linkWithLine = e.target.closest('.with-leader-line')
543 if (!block && !map && !linkWithLine) return 543 const rangeSelected = document.getSelection().type === 'Range'
544 if (!block && !map && !linkWithLine && !rangeSelected) return
544 e.preventDefault() 545 e.preventDefault()
545 546
546 /** Add HTMLElement for menu */ 547 /** Add HTMLElement for menu */
@@ -560,6 +561,12 @@ export const generateMaps = (container, {
560 }).observe(menu, { childList: true }) 561 }).observe(menu, { childList: true })
561 menu.timer = setTimeout(() => menu.remove(), 100) 562 menu.timer = setTimeout(() => menu.remove(), 100)
562 563
564 /** Menu Item for Geocoding */
565 if (rangeSelected) {
566 // TODO check click is inside selection
567 const range = document.getSelection().getRangeAt(0)
568 menu.appendChild(menuItem.addLinkbyNominatim(range))
569 }
563 /** Menu Item for editing map */ 570 /** Menu Item for editing map */
564 const mapEditor = e.target.closest('.edit-map') 571 const mapEditor = e.target.closest('.edit-map')
565 if (mapEditor) { 572 if (mapEditor) {
@@ -584,6 +591,30 @@ export const generateMaps = (container, {
584 ) 591 )
585 }, 592 },
586 })) 593 }))
594 } else if (geoLink.classList.contains('from-geocoding')) {
595 menu.appendChild(menuItem.Item({
596 innerHTML: '<strong style="color: red;">DELETE</strong>',
597 onclick: () => {
598 getMarkersFromMaps(geoLink)
599 .forEach(m => m.remove())
600
601 const sibling = [
602 geoLink.previousElementSibling,
603 geoLink.nextElementSibling,
604 ]
605 .find(a =>
606 a.classList.contains('from-geocoding') && a.textContent === geoLink.textContent,
607 )
608
609 if (sibling) {
610 geoLink.remove()
611 } else {
612 geoLink.replaceWith(
613 document.createTextNode(geoLink.textContent),
614 )
615 }
616 },
617 }))
587 } 618 }
588 menu.appendChild(menuItem.setGeoLinkType(geoLink)) 619 menu.appendChild(menuItem.setGeoLinkType(geoLink))
589 } 620 }
diff --git a/src/utils.mjs b/src/utils.mjs
index d2c5d8f..c0da23a 100644
--- a/src/utils.mjs
+++ b/src/utils.mjs
@@ -173,7 +173,7 @@ export const replaceTextNodes = (
173 const nodeIterator = document.createNodeIterator( 173 const nodeIterator = document.createNodeIterator(
174 rootNode, 174 rootNode,
175 window.NodeFilter.SHOW_TEXT, 175 window.NodeFilter.SHOW_TEXT,
176 node => node.textContent.match(pattern) && !node.parentElement.closest('pre,code,a') 176 node => node.textContent.match(pattern) && node.parentElement && !node.parentElement.closest('pre,code,a')
177 ? window.NodeFilter.FILTER_ACCEPT 177 ? window.NodeFilter.FILTER_ACCEPT
178 : window.NodeFilter.FILTER_REJECT, 178 : window.NodeFilter.FILTER_REJECT,
179 ) 179 )