diff --git a/uniro_admin_frontend/src/page/buildingPage.tsx b/uniro_admin_frontend/src/page/buildingPage.tsx index a494c097..81fab7fe 100644 --- a/uniro_admin_frontend/src/page/buildingPage.tsx +++ b/uniro_admin_frontend/src/page/buildingPage.tsx @@ -56,6 +56,8 @@ const BuildingPage = () => { const { map, mapLoaded, mapRef, AdvancedMarker, Polyline } = useMap(); + const cachedRoute = useRef>(new Map()); + const [selectedBuildingId, setSelectedBuildingId] = useState(0); // mode = add or view일 때 선택한 빌딩 좌표 @@ -115,20 +117,87 @@ const BuildingPage = () => { if (!Polyline || !AdvancedMarker || !map) return; for (const coreRoutes of coreRouteList.coreRoutes) { - const { routes: subRoutes } = coreRoutes; + const { coreNode1Id, coreNode2Id, routes: subRoutes } = coreRoutes; + + const routeIds = subRoutes.map((el) => el.routeId); + + const key = coreNode1Id < coreNode2Id ? routeIds.join("_") : routeIds.reverse().join("_"); + + if (cachedRoute.current.has(key)) { + const cachedPolyline = cachedRoute.current.get(key); + if (!cachedPolyline) continue; + google.maps.event.clearListeners(cachedPolyline, "click"); + cachedPolyline.setMap(map); + cachedPolyline.setOptions({ + strokeColor: "#808080", + }); + google.maps.event.addListener(cachedPolyline, "click", (e: { latLng: google.maps.LatLng }) => { + if (mode === "view" || mode === "add") setSelectedBuildingId(0); + if (mode === "connect") { + const edges: CoreRoute[] = subRoutes.map(({ routeId, node1, node2 }) => { + return { routeId, node1, node2 }; + }); + + const { edge: nearestEdge } = findNearestSubEdge(edges, { + lat: e.latLng.lat(), + lng: e.latLng.lng(), + }); + const { node1, node2 } = nearestEdge; + + const polyline = new Polyline({ + map: map, + path: [ + { lat: node1.lat, lng: node1.lng }, + { lat: node2.lat, lng: node2.lng }, + ], + strokeColor: "#000000", + zIndex: 100, + }); + + const marker1 = new AdvancedMarker({ + map: map, + position: { lat: node1.lat, lng: node1.lng }, + content: waypointMarkerElement({ color: "red" }), + zIndex: 100, + }); + + const marker2 = new AdvancedMarker({ + map: map, + position: { lat: node2.lat, lng: node2.lng }, + content: waypointMarkerElement({ color: "blue" }), + zIndex: 100, + }); + setSelectedEdge({ + info: nearestEdge, + marker1, + marker2, + polyline, + }); + + setSelectedNode([node1, node2]); + } + }); + setPolylineList((prev) => [...prev, cachedPolyline]); + + continue; + } const subNodes = [subRoutes[0].node1, ...subRoutes.map((el) => el.node2)]; - const polyline = new Polyline({ + const routePolyLine = new Polyline({ map: map, path: subNodes.map((el) => { return { lat: el.lat, lng: el.lng }; }), strokeColor: "#808080", + geodesic: true, }); + cachedRoute.current.set(key, routePolyLine); + google.maps.event.clearListeners(routePolyLine, "click"); + //polyline을 선택 방지 - google.maps.event.addListener(polyline, "click", (e: { latLng: google.maps.LatLng }) => { + google.maps.event.addListener(routePolyLine, "click", (e: { latLng: google.maps.LatLng }) => { if (mode === "view" || mode === "add") setSelectedBuildingId(0); if (mode === "connect") { const edges: CoreRoute[] = subRoutes.map(({ routeId, node1, node2 }) => { @@ -174,15 +243,29 @@ const BuildingPage = () => { setSelectedNode([node1, node2]); } }); - setPolylineList((prev) => [...prev, polyline]); + setPolylineList((prev) => [...prev, routePolyLine]); } for (const coreRoutes of coreRouteList.buildingRoutes) { - const { routes: subRoutes } = coreRoutes; + const { coreNode1Id, coreNode2Id, routes: subRoutes } = coreRoutes; + + const routeIds = subRoutes.map((el) => el.routeId); + + const key = coreNode1Id < coreNode2Id ? routeIds.join("_") : routeIds.reverse().join("_"); + + if (cachedRoute.current.has(key)) { + const polyline = cachedRoute.current.get(key); + + if (!polyline) return; + + polyline.setMap(map); + + continue; + } const subNodes = [subRoutes[0].node1, ...subRoutes.map((el) => el.node2)]; - const polyline = new Polyline({ + const routePolyLine = new Polyline({ map: map, path: subNodes.map((el) => { return { lat: el.lat, lng: el.lng }; @@ -198,6 +281,8 @@ const BuildingPage = () => { ], geodesic: true, }); + + cachedRoute.current.set(key, routePolyLine); } }; @@ -274,13 +359,12 @@ const BuildingPage = () => { // 지도가 로드되면 클릭 이벤트를 추가 useEffect(() => { - if (!map || !mapLoaded || !university) return; + if (!map || !mapLoaded || !university || routes.isLoading || buildings.isLoading) return; if (routes.data) { - if (routes.data) { - drawRoute(routes.data, mode); - } + drawRoute(routes.data, mode); } + if (buildings.data) { addBuildings(); } @@ -312,7 +396,7 @@ const BuildingPage = () => { google.maps.event.clearListeners(map, "rightclick"); clearBuildingMarkers(); }; - }, [map, mapLoaded, routes.data, buildings.data]); + }, [map, mapLoaded, routes.data, buildings.data, routes.isLoading, buildings.isLoading]); useEffect(() => { if (!map || !mapLoaded) return;