1/** 2 * ãããåæåãµã¼ãã¹ 3 * MapKitControllerãããããåæåãã¸ãã¯ãåé¢ 4 */ 5export default class MapInitializer { 6 static DEFAULT_CENTER = {lat: 35.6762, lng: 139.6503}; // æ±äº¬ 7 8 constructor(controller) { 9 this.controller = controller; 10 } 11 12 /** 13 * ããããåæå 14 * @param {Element} mapElement - ãããè¦ç´ 15 * @param {Object} options - åæåãªãã·ã§ã³ 16 * @returns {Promise<Object>} åæåãããããã 17 */ 18 async initializeMap(mapElement, options = {}) { 19 await this._ensureMapkitToken(); 20 21 const { 22 initialCenterLat, 23 initialCenterLng, 24 showsUserLocationControl = false, 25 } = options; 26 27 // åå²åã¨åããã¸ãã¯: undefined ã null ã®å ´åã¯DEFAULT_CENTERãä½¿ç¨ 28 const lat = initialCenterLat || MapInitializer.DEFAULT_CENTER.lat; 29 const lng = initialCenterLng || MapInitializer.DEFAULT_CENTER.lng; 30 31 console.log('MapInitializer: åæå座æ¨', { 32 initialCenterLat, 33 initialCenterLng, 34 lat, 35 lng, 36 DEFAULT_CENTER: MapInitializer.DEFAULT_CENTER, 37 }); 38 39 const center = new mapkit.Coordinate(lat, lng); 40 41 const map = new mapkit.Map(mapElement, { 42 center, 43 region: new mapkit.CoordinateRegion(center, new mapkit.CoordinateSpan(0.1, 0.1)), 44 showsMapTypeControl: true, 45 showsZoomControl: true, 46 showsCompass: mapkit.FeatureVisibility.Visible, 47 showsScale: mapkit.FeatureVisibility.Visible, 48 showsUserLocationControl, 49 }); 50 51 this._addCustomControls(map, options); 52 53 return map; 54 } 55 56 /** 57 * ã«ã¹ã¿ã ã³ã³ããã¼ã«ã追å 58 * @private 59 */ 60 _addCustomControls(map, options) { 61 const { 62 showsSearchAtCenterButton = false, 63 showsRefreshButton = false, 64 searchAtCenterUrl = '/nearby_map/', 65 } = options; 66 67 const controls = [ 68 {cond: showsSearchAtCenterButton, fn: () => this._addSearchAtCenterControl(map, searchAtCenterUrl)}, 69 {cond: showsRefreshButton, fn: () => this._addRefreshControl(map)}, 70 ]; 71 controls.forEach(({cond, fn}) => cond && fn()); 72 } 73 74 /** 75 * ä¸å¿æ¤ç´¢ã³ã³ããã¼ã«ã追å 76 * @private 77 */ 78 _addSearchAtCenterControl(map, searchAtCenterUrl) { 79 const btn = document.createElement('button'); 80 btn.className = 'absolute z-50 h-8 px-3 flex items-center bg-white/70 rounded-full shadow-md ' 81 + 'border-none cursor-pointer backdrop-blur-sm top-1 md:top-2 right-28 md:right-32'; 82 btn.title = 'ãã®ä¸å¿ã§æ¤ç´¢ããããéã'; 83 btn.innerHTML = ` 84 <span class="mr-2 text-xs font-medium">表示ä½ç½®ã§åæ¤ç´¢</span> 85 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16"> 86 <path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z"/> 87 <path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z"/> 88 </svg>`; 89 btn.addEventListener('click', () => { 90 const {latitude, longitude} = map.region.center; 91 window.open(`${searchAtCenterUrl}?lat=${latitude}&lng=${longitude}`, '_blank'); 92 }); 93 map.element.parentNode.appendChild(btn); 94 } 95 96 /** 97 * ãªãã¬ãã·ã¥ã³ã³ããã¼ã«ã追å 98 * @private 99 */ 100 _addRefreshControl(map) { 101 const btn = document.createElement('button'); 102 btn.className = 'absolute z-50 w-8 h-8 flex items-center justify-center bg-white/70 rounded-full shadow-md ' 103 + 'border-none cursor-pointer p-0 backdrop-blur-sm top-1 md:top-2 right-28 md:right-32'; 104 btn.title = '表示ç¯å²ã§åæ¤ç´¢'; 105 btn.innerHTML = ` 106 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 107 <path stroke-linecap="round" stroke-linejoin="round" 108 d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/> 109 </svg>`; 110 btn.addEventListener('click', () => { 111 if (this.controller.refreshSearch) { 112 this.controller.refreshSearch(); 113 } 114 }); 115 map.element.parentNode.appendChild(btn); 116 } 117 118 /** 119 * MapKitãã¼ã¯ã³ãç¢ºä¿ 120 * @private 121 */ 122 async _ensureMapkitToken() { 123 if (window.mapkitInitialized) { 124 return; 125 } 126 127 try { 128 const token = await fetch('/api/v1/mapkit/token/') 129 .then(res => { 130 if (!res.ok) { 131 throw new Error('ãã¼ã¯ã³ã®åå¾ã«å¤±æãã¾ãã'); 132 } 133 134 return res.text(); 135 }) 136 .then(text => { 137 if (!text) { 138 throw new Error('MapKitãã¼ã¯ã³ã空ã§ã'); 139 } 140 141 try { 142 return JSON.parse(text).token; 143 } catch (e) { 144 console.error('MapKitãã¼ã¯ã³ã®JSONãã¼ã¹ã«å¤±æãã¾ãã:', text); 145 throw new Error('ç¡å¹ãªMapKitãã¼ã¯ã³å½¢å¼ã§ã'); 146 } 147 }); 148 149 mapkit.init({authorizationCallback: done => done(token)}); 150 window.mapkitInitialized = true; 151 } catch (error) { 152 console.error('MapKitåæåã¨ã©ã¼:', error); 153 throw error; 154 } 155 } 156}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.