diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2024-11-03 13:58:38 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-11-03 14:36:15 +0800 |
commit | f4910b66e74034db14619ee384dc261423dc19fc (patch) | |
tree | 78382b3bb600b61a43b48d417cfbe3873d8da623 /src/MenuItem.mjs | |
parent | 3086cc484857dea32a33f829ec173adaf0cf8fbe (diff) |
feat: use bbox to update camera for result of Geocoding
* show markers from all Geocoding Results
* update mapclay for latest updateCamera method
* 3 steps for camera animation:
1. zoom out to bbox which contains all Geocoding Result
2. pan to marker of hovered result
3. zoom in to bbox from nonimatim query
* remove markers except selected Geocoding Result
Diffstat (limited to 'src/MenuItem.mjs')
-rw-r--r-- | src/MenuItem.mjs | 65 |
1 files changed, 50 insertions, 15 deletions
diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 6c6e6cf..8bee5c1 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs | |||
@@ -1,7 +1,7 @@ | |||
1 | import { shiftByWindow } from './utils.mjs' | 1 | import { onRemove, shiftByWindow } from './utils.mjs' |
2 | import { addMarkerByPoint } from './dumbyUtils.mjs' | 2 | import { addMarkerByPoint } from './dumbyUtils.mjs' |
3 | /* eslint-disable-next-line no-unused-vars */ | 3 | /* eslint-disable-next-line no-unused-vars */ |
4 | import { GeoLink, getMarkersFromMaps, getMarkersByGeoLink, removeLeaderLines, updateMapCameraByMarker } from './Link.mjs' | 4 | import { GeoLink, getMarkersFromMaps, getMarkersByGeoLink, removeLeaderLines } from './Link.mjs' |
5 | import * as markers from './marker.mjs' | 5 | import * as markers from './marker.mjs' |
6 | import { parseConfigsFromYaml } from 'mapclay' | 6 | import { parseConfigsFromYaml } from 'mapclay' |
7 | 7 | ||
@@ -606,8 +606,8 @@ export const addLinkbyGeocoding = (range) => { | |||
606 | /** Add spinning circle for Network */ | 606 | /** Add spinning circle for Network */ |
607 | e.target.classList.add('with-spinning-circle') | 607 | e.target.classList.add('with-spinning-circle') |
608 | const menu = e.target.closest('.dumby-menu') | 608 | const menu = e.target.closest('.dumby-menu') |
609 | |||
610 | if (!menu) return | 609 | if (!menu) return |
610 | |||
611 | /** Geocoding by Nominatim */ | 611 | /** Geocoding by Nominatim */ |
612 | // TODO Add more params like limit: | 612 | // TODO Add more params like limit: |
613 | // https://nominatim.org/release-docs/latest/api/Search/ | 613 | // https://nominatim.org/release-docs/latest/api/Search/ |
@@ -623,36 +623,71 @@ export const addLinkbyGeocoding = (range) => { | |||
623 | } | 623 | } |
624 | 624 | ||
625 | // Add items for each results | 625 | // Add items for each results |
626 | const items = places.map(geocodingResult((a) => { | 626 | const bbox = places.map(p => p.boundingbox).reduce((acc, cur) => [ |
627 | Math.min(acc[0], cur[0]), | ||
628 | Math.max(acc[1], cur[1]), | ||
629 | Math.min(acc[2], cur[2]), | ||
630 | Math.max(acc[3], cur[3]), | ||
631 | ]) | ||
632 | const bounds = [[bbox[2], bbox[0]], [bbox[3], bbox[1]]] | ||
633 | const items = places.map(geocodingResult(bounds, (a) => { | ||
627 | a.className = 'not-geolink from-geocoding' | 634 | a.className = 'not-geolink from-geocoding' |
628 | a.textContent = query | 635 | a.textContent = query |
629 | range.deleteContents() | 636 | range.deleteContents() |
630 | range.insertNode(a) | 637 | range.insertNode(a) |
631 | })) | 638 | })) |
632 | menu.replaceChildren(...items) | 639 | menu.replaceChildren(...items) |
640 | shiftByWindow(menu) | ||
633 | }, | 641 | }, |
634 | }) | 642 | }) |
635 | } | 643 | } |
636 | 644 | ||
637 | export const geocodingResult = (callback) => (result) => { | 645 | /** |
646 | * geocodingResult. | ||
647 | * | ||
648 | * @param {Array<Number[]>} bounds - boundingbox in format: [minLon, minLat, maxLon, maxLat] | ||
649 | * @param {Function} callback | ||
650 | */ | ||
651 | export const geocodingResult = (bounds, callback) => (result) => { | ||
638 | const item = Item({ | 652 | const item = Item({ |
639 | text: result.display_name, | 653 | text: result.display_name, |
640 | onclick: () => { | 654 | onclick: (e) => { |
655 | e.target.classList.add('clicked') | ||
656 | |||
641 | const a = document.createElement('a') | 657 | const a = document.createElement('a') |
642 | a.href = `geo:${result.lat},${result.lon}?name=${result.name}&osm=${result.osm_type}/${result.osm_id}` | 658 | a.href = `geo:${result.lat},${result.lon}` + |
659 | `?name=${result.name}` + | ||
660 | `&osm=${result.osm_type}/${result.osm_id}` | ||
643 | a.title = result.display_name | 661 | a.title = result.display_name |
644 | callback(a) | 662 | callback(a) |
645 | }, | 663 | }, |
646 | }) | 664 | }) |
665 | |||
666 | const xy = [result.lon, result.lat] | ||
667 | |||
668 | const markers = getMarkersFromMaps(xy, { | ||
669 | type: 'circle', | ||
670 | title: result.display_name, | ||
671 | }) | ||
672 | const bbox = result.boundingbox | ||
673 | const resultBounds = [[bbox[2], bbox[0]], [bbox[3], bbox[1]]] | ||
674 | |||
647 | item.onmouseover = () => { | 675 | item.onmouseover = () => { |
648 | const markers = getMarkersFromMaps( | 676 | markers.forEach(async marker => { |
649 | [result.lon, result.lat], | 677 | const renderer = marker.closest('.mapclay')?.renderer |
650 | { type: 'circle', title: result.display_name }, | 678 | await renderer.updateCamera({ bounds, duration: 1000, animation: true, padding: 20 }) |
651 | ) | 679 | await renderer.updateCamera({ center: xy, duration: 600, animation: true }) |
652 | markers.forEach(updateMapCameraByMarker([result.lon, result.lat])) | 680 | await renderer.updateCamera({ bounds: resultBounds, duration: 1500, animation: true, padding: 20 }) |
653 | item.onmouseout = () => { | 681 | }) |
654 | markers.forEach(m => m.remove()) | ||
655 | } | ||
656 | } | 682 | } |
683 | |||
684 | setTimeout(() => { | ||
685 | onRemove(item.closest('.menu'), () => { | ||
686 | if (item.classList.contains('clicked')) return | ||
687 | markers.forEach(marker => marker.remove()) | ||
688 | }), | ||
689 | 100 | ||
690 | }) | ||
691 | |||
657 | return item | 692 | return item |
658 | } | 693 | } |