|
|
@@ -1,176 +1,292 @@
|
|
|
-<template>
|
|
|
- <div class="map-page">
|
|
|
- <div id="tdt-map-container" ref="mapContainer"></div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { ref, onMounted, onBeforeUnmount } from "vue";
|
|
|
-
|
|
|
-const mapContainer = ref(null);
|
|
|
-let map = null;
|
|
|
-const markers = [];
|
|
|
-
|
|
|
-// 珠海市中心坐标
|
|
|
-const ZHUHAI_CENTER = { lng: 113.57668, lat: 22.271 };
|
|
|
-// Demo 标签坐标(珠海市政府附近)
|
|
|
-const DEMO_POINT = { lng: 113.55267584, lat: 22.22234309 };
|
|
|
-
|
|
|
-const PAD_X = 10;
|
|
|
-const PAD_Y = 6;
|
|
|
-const FONT_SIZE = 16;
|
|
|
-const BORDER_TOP = 4;
|
|
|
-const TRI_H = 18;
|
|
|
-const TRI_W = 12;
|
|
|
-
|
|
|
-function getMarkerSize(text) {
|
|
|
- const textWidth = Math.max(text.length * FONT_SIZE, 80);
|
|
|
- const boxW = textWidth + PAD_X * 2;
|
|
|
- const boxH = FONT_SIZE + PAD_Y * 2;
|
|
|
- const totalH = boxH + TRI_H;
|
|
|
- return { boxW, totalH };
|
|
|
-}
|
|
|
-
|
|
|
-/** 生成 marker 的 SVG 内容(气泡样式:渐变背景 + 顶边 + 底部三角) */
|
|
|
-function createMarkerSvg(text, hover = false) {
|
|
|
- const { boxW, totalH } = getMarkerSize(text);
|
|
|
- const boxH = FONT_SIZE + PAD_Y * 2;
|
|
|
-
|
|
|
- const fill = hover ? "url(#bgHover)" : "url(#bg)";
|
|
|
- const strokeColor = hover ? "#e5b735" : "#98382e";
|
|
|
- const textColor = hover ? "#e4ca77" : "#98382e";
|
|
|
-
|
|
|
- return `<svg xmlns="http://www.w3.org/2000/svg" width="${boxW}" height="${totalH}" viewBox="0 0 ${boxW} ${totalH}">
|
|
|
- <defs>
|
|
|
- <linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
|
|
- <stop offset="0%" stop-color="#fffccd"/>
|
|
|
- <stop offset="50%" stop-color="#fffef0"/>
|
|
|
- <stop offset="100%" stop-color="#fffccd"/>
|
|
|
- </linearGradient>
|
|
|
- <linearGradient id="bgHover" x1="0" y1="0" x2="1" y2="0">
|
|
|
- <stop offset="0%" stop-color="#99372d"/>
|
|
|
- <stop offset="50%" stop-color="#b84033"/>
|
|
|
- <stop offset="100%" stop-color="#99372d"/>
|
|
|
- </linearGradient>
|
|
|
- </defs>
|
|
|
- <!-- 气泡主体 + 底部三角 -->
|
|
|
- <path d="M 0 ${BORDER_TOP} L 0 ${boxH} L ${boxW / 2 - TRI_W / 2} ${boxH} L ${boxW / 2} ${totalH} L ${boxW / 2 + TRI_W / 2} ${boxH} L ${boxW} ${boxH} L ${boxW} ${BORDER_TOP} L 0 ${BORDER_TOP} Z" fill="${fill}" stroke="none"/>
|
|
|
- <!-- 顶边 -->
|
|
|
- <rect x="0" y="0" width="${boxW}" height="${BORDER_TOP}" fill="${strokeColor}"/>
|
|
|
- <!-- 文本 -->
|
|
|
- <text x="${boxW / 2}" y="${BORDER_TOP + PAD_Y + FONT_SIZE - 4}" text-anchor="middle" font-size="${FONT_SIZE}" fill="${textColor}" font-family="sans-serif">${escapeXml(text)}</text>
|
|
|
-</svg>`;
|
|
|
-}
|
|
|
-
|
|
|
-function escapeXml(s) {
|
|
|
- return s
|
|
|
- .replace(/&/g, "&")
|
|
|
- .replace(/</g, "<")
|
|
|
- .replace(/>/g, ">")
|
|
|
- .replace(/"/g, """)
|
|
|
- .replace(/'/g, "'");
|
|
|
-}
|
|
|
-
|
|
|
-/** 将 SVG 转为 data URL,供 T.Icon 使用 */
|
|
|
-function svgToDataUrl(svg) {
|
|
|
- return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- if (typeof T === "undefined") {
|
|
|
- console.error("天地图 API 未加载,请检查 index.html 中的 tk 密钥配置");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const script = document.querySelector('script[src*="tianditu"]');
|
|
|
- const tk = script?.src.match(/tk=([^&]+)/)?.[1] || "";
|
|
|
-
|
|
|
- // 珠海市边界(纬度 21°48′~22°27′,经度 113°03′~114°19′)
|
|
|
- const zhuhaiBounds = new T.LngLatBounds(
|
|
|
- new T.LngLat(113.05, 21.8), // 西南角
|
|
|
- new T.LngLat(114.32, 22.45), // 东北角
|
|
|
- );
|
|
|
-
|
|
|
- // 矢量底图 + 矢量注记(EPSG:4326 使用 vec_c / cva_c)
|
|
|
- const vecUrl = `https://t0.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tk}`;
|
|
|
- const cvaUrl = `https://t0.tianditu.gov.cn/cva_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tk}`;
|
|
|
-
|
|
|
- const vecLayer = new T.TileLayer(vecUrl, { minZoom: 6, maxZoom: 18 });
|
|
|
- const cvaLayer = new T.TileLayer(cvaUrl, { minZoom: 6, maxZoom: 18 });
|
|
|
-
|
|
|
- map = new T.Map(mapContainer.value, {
|
|
|
- projection: "EPSG:4326",
|
|
|
- minZoom: 12,
|
|
|
- maxZoom: 18,
|
|
|
- maxBounds: zhuhaiBounds,
|
|
|
- layers: [vecLayer, cvaLayer],
|
|
|
- });
|
|
|
-
|
|
|
- map.centerAndZoom(new T.LngLat(ZHUHAI_CENTER.lng, ZHUHAI_CENTER.lat), 13);
|
|
|
-
|
|
|
- ["南屏村卓斋街一巷8号民居"].forEach((item) => {
|
|
|
- const { boxW, totalH } = getMarkerSize(item);
|
|
|
- const svg = createMarkerSvg(item);
|
|
|
- const iconUrl = svgToDataUrl(svg);
|
|
|
-
|
|
|
- const icon = new T.Icon({
|
|
|
- iconUrl,
|
|
|
- iconSize: new T.Point(boxW, totalH),
|
|
|
- iconAnchor: new T.Point(boxW / 2, totalH),
|
|
|
- });
|
|
|
-
|
|
|
- const marker = new T.Marker(new T.LngLat(DEMO_POINT.lng, DEMO_POINT.lat), {
|
|
|
- icon,
|
|
|
- });
|
|
|
-
|
|
|
- marker.on("click", () => console.log(item));
|
|
|
- marker.on("mouseover", () => {
|
|
|
- const hoverSvg = createMarkerSvg(item, true);
|
|
|
- marker.setIcon(
|
|
|
- new T.Icon({
|
|
|
- iconUrl: svgToDataUrl(hoverSvg),
|
|
|
- iconSize: new T.Point(boxW, totalH),
|
|
|
- iconAnchor: new T.Point(boxW / 2, totalH),
|
|
|
- }),
|
|
|
- );
|
|
|
- });
|
|
|
- marker.on("mouseout", () => {
|
|
|
- marker.setIcon(
|
|
|
- new T.Icon({
|
|
|
- iconUrl,
|
|
|
- iconSize: new T.Point(boxW, totalH),
|
|
|
- iconAnchor: new T.Point(boxW / 2, totalH),
|
|
|
- }),
|
|
|
- );
|
|
|
- });
|
|
|
-
|
|
|
- map.addOverLay(marker);
|
|
|
- markers.push(marker);
|
|
|
- });
|
|
|
-});
|
|
|
-
|
|
|
-onBeforeUnmount(() => {
|
|
|
- markers.forEach((m) => map?.removeOverLay(m));
|
|
|
- markers.length = 0;
|
|
|
- map = null;
|
|
|
-});
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
-.map-page {
|
|
|
- position: fixed;
|
|
|
- inset: 0;
|
|
|
- width: 100vw;
|
|
|
- height: 100vh;
|
|
|
- z-index: 0;
|
|
|
-}
|
|
|
-
|
|
|
-#tdt-map-container {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.tdt-marker) {
|
|
|
- cursor: pointer;
|
|
|
-}
|
|
|
-</style>
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ class="map-page"
|
|
|
+ :class="{ 'map-page--sidebar-visible': sidebarVisible }"
|
|
|
+ >
|
|
|
+ <div id="tdt-map-container" ref="mapContainer"></div>
|
|
|
+
|
|
|
+ <img
|
|
|
+ class="map-page-back"
|
|
|
+ src="@/assets/images/icon-fanhui.png"
|
|
|
+ @click="$router.push({ name: 'Home' })"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted, onBeforeUnmount, watch } from "vue";
|
|
|
+import { useRoute, useRouter } from "vue-router";
|
|
|
+import { storeToRefs } from "pinia";
|
|
|
+import { useSidebarStore } from "@/stores/sidebar";
|
|
|
+
|
|
|
+const route = useRoute();
|
|
|
+const { visible: sidebarVisible } = storeToRefs(useSidebarStore());
|
|
|
+const router = useRouter();
|
|
|
+const mapContainer = ref(null);
|
|
|
+let map = null;
|
|
|
+/** @type {Array<{ marker: T.Marker, item: object, name: string, boxW: number, totalH: number }>} */
|
|
|
+const markerRecords = [];
|
|
|
+const mapData = ref([]); // 有经纬度的数据项
|
|
|
+
|
|
|
+// 珠海市中心坐标
|
|
|
+const ZHUHAI_CENTER = { lng: 113.57668, lat: 22.271 };
|
|
|
+/** 默认视野;侧边栏选中某建筑时放大 */
|
|
|
+const ZOOM_DEFAULT = 14;
|
|
|
+const ZOOM_SIDEBAR_SELECT = 17;
|
|
|
+
|
|
|
+const PAD_X = 10;
|
|
|
+const PAD_Y = 6;
|
|
|
+const FONT_SIZE = 16;
|
|
|
+const BORDER_TOP = 4;
|
|
|
+const TRI_H = 18;
|
|
|
+const TRI_W = 12;
|
|
|
+
|
|
|
+function getMarkerSize(text) {
|
|
|
+ const textWidth = Math.max(text.length * FONT_SIZE, 80);
|
|
|
+ const boxW = textWidth + PAD_X * 2;
|
|
|
+ const boxH = FONT_SIZE + PAD_Y * 2;
|
|
|
+ const totalH = boxH + TRI_H;
|
|
|
+ return { boxW, totalH };
|
|
|
+}
|
|
|
+
|
|
|
+/** 生成 marker 的 SVG 内容(气泡样式:渐变背景 + 顶边 + 底部三角) */
|
|
|
+function createMarkerSvg(text, hover = false) {
|
|
|
+ const { boxW, totalH } = getMarkerSize(text);
|
|
|
+ const boxH = FONT_SIZE + PAD_Y * 2;
|
|
|
+
|
|
|
+ const fill = hover ? "url(#bgHover)" : "url(#bg)";
|
|
|
+ const strokeColor = hover ? "#e5b735" : "#98382e";
|
|
|
+ const textColor = hover ? "#e4ca77" : "#98382e";
|
|
|
+
|
|
|
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${boxW}" height="${totalH}" viewBox="0 0 ${boxW} ${totalH}">
|
|
|
+ <defs>
|
|
|
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="0">
|
|
|
+ <stop offset="0%" stop-color="#fffccd"/>
|
|
|
+ <stop offset="50%" stop-color="#fffef0"/>
|
|
|
+ <stop offset="100%" stop-color="#fffccd"/>
|
|
|
+ </linearGradient>
|
|
|
+ <linearGradient id="bgHover" x1="0" y1="0" x2="1" y2="0">
|
|
|
+ <stop offset="0%" stop-color="#99372d"/>
|
|
|
+ <stop offset="50%" stop-color="#b84033"/>
|
|
|
+ <stop offset="100%" stop-color="#99372d"/>
|
|
|
+ </linearGradient>
|
|
|
+ </defs>
|
|
|
+ <!-- 气泡主体 + 底部三角 -->
|
|
|
+ <path d="M 0 ${BORDER_TOP} L 0 ${boxH} L ${boxW / 2 - TRI_W / 2} ${boxH} L ${boxW / 2} ${totalH} L ${boxW / 2 + TRI_W / 2} ${boxH} L ${boxW} ${boxH} L ${boxW} ${BORDER_TOP} L 0 ${BORDER_TOP} Z" fill="${fill}" stroke="none"/>
|
|
|
+ <!-- 顶边 -->
|
|
|
+ <rect x="0" y="0" width="${boxW}" height="${BORDER_TOP}" fill="${strokeColor}"/>
|
|
|
+ <!-- 文本 -->
|
|
|
+ <text x="${boxW / 2}" y="${BORDER_TOP + PAD_Y + FONT_SIZE - 4}" text-anchor="middle" font-size="${FONT_SIZE}" fill="${textColor}" font-family="sans-serif">${escapeXml(text)}</text>
|
|
|
+</svg>`;
|
|
|
+}
|
|
|
+
|
|
|
+function escapeXml(s) {
|
|
|
+ return s
|
|
|
+ .replace(/&/g, "&")
|
|
|
+ .replace(/</g, "<")
|
|
|
+ .replace(/>/g, ">")
|
|
|
+ .replace(/"/g, """)
|
|
|
+ .replace(/'/g, "'");
|
|
|
+}
|
|
|
+
|
|
|
+/** 将 SVG 转为 data URL,供 T.Icon 使用 */
|
|
|
+function svgToDataUrl(svg) {
|
|
|
+ return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
|
|
|
+}
|
|
|
+
|
|
|
+function getSelectedNameFromRoute() {
|
|
|
+ return route.query.name ? String(route.query.name).trim() : "";
|
|
|
+}
|
|
|
+
|
|
|
+function isNameSelected(name) {
|
|
|
+ const sel = getSelectedNameFromRoute();
|
|
|
+ return !!sel && String(name).trim() === sel;
|
|
|
+}
|
|
|
+
|
|
|
+/** 设置 marker 外观:高亮为 true 时使用选中/悬停配色 */
|
|
|
+function applyMarkerVisual(rec, useHighlight) {
|
|
|
+ const { marker, name, boxW, totalH } = rec;
|
|
|
+ const svg = createMarkerSvg(name, useHighlight);
|
|
|
+ marker.setIcon(
|
|
|
+ new T.Icon({
|
|
|
+ iconUrl: svgToDataUrl(svg),
|
|
|
+ iconSize: new T.Point(boxW, totalH),
|
|
|
+ iconAnchor: new T.Point(boxW / 2, totalH),
|
|
|
+ }),
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+/** 根据路由同步所有 marker 高亮,并将选中项置于覆盖物最上层 */
|
|
|
+function syncMarkerHighlight() {
|
|
|
+ if (!map || !markerRecords.length) return;
|
|
|
+ for (const rec of markerRecords) {
|
|
|
+ applyMarkerVisual(rec, isNameSelected(rec.name));
|
|
|
+ }
|
|
|
+ const sel = getSelectedNameFromRoute();
|
|
|
+ if (!sel) return;
|
|
|
+ const rec = markerRecords.find((r) => String(r.name).trim() === sel);
|
|
|
+ if (!rec) return;
|
|
|
+ map.removeOverLay(rec.marker);
|
|
|
+ map.addOverLay(rec.marker);
|
|
|
+}
|
|
|
+
|
|
|
+/** 地图 min/maxZoom 与实例一致,用于钳制 query.zoom */
|
|
|
+function clampZoom(z) {
|
|
|
+ return Math.min(18, Math.max(12, z));
|
|
|
+}
|
|
|
+
|
|
|
+function getZoomFromRoute() {
|
|
|
+ if (getSelectedNameFromRoute()) return ZOOM_SIDEBAR_SELECT;
|
|
|
+ const raw = route.query.zoom;
|
|
|
+ if (raw !== undefined && raw !== null && String(raw).trim() !== "") {
|
|
|
+ const z = Number(raw);
|
|
|
+ if (!isNaN(z)) return clampZoom(z);
|
|
|
+ }
|
|
|
+ return ZOOM_DEFAULT;
|
|
|
+}
|
|
|
+
|
|
|
+/** 根据 route query 定位地图中心;侧边栏选中 name、或首页传入 zoom 等 */
|
|
|
+function centerMapToQuery() {
|
|
|
+ if (!map) return;
|
|
|
+ const lng = Number(route.query.lng);
|
|
|
+ const lat = Number(route.query.lat);
|
|
|
+ const center = !isNaN(lng) && !isNaN(lat) ? { lng, lat } : ZHUHAI_CENTER;
|
|
|
+ map.centerAndZoom(new T.LngLat(center.lng, center.lat), getZoomFromRoute());
|
|
|
+}
|
|
|
+
|
|
|
+/** 添加所有有经纬度的数据为地图标记 */
|
|
|
+function addMarkers() {
|
|
|
+ if (!map || !mapData.value.length) return;
|
|
|
+ mapData.value.forEach((item) => {
|
|
|
+ const lng = Number(item.lng);
|
|
|
+ const lat = Number(item.lat);
|
|
|
+ if (isNaN(lng) || isNaN(lat)) return;
|
|
|
+
|
|
|
+ const name = item.name;
|
|
|
+ const { boxW, totalH } = getMarkerSize(name);
|
|
|
+ const svg = createMarkerSvg(name, isNameSelected(name));
|
|
|
+ const iconUrl = svgToDataUrl(svg);
|
|
|
+
|
|
|
+ const icon = new T.Icon({
|
|
|
+ iconUrl,
|
|
|
+ iconSize: new T.Point(boxW, totalH),
|
|
|
+ iconAnchor: new T.Point(boxW / 2, totalH),
|
|
|
+ });
|
|
|
+
|
|
|
+ const marker = new T.Marker(new T.LngLat(lng, lat), { icon });
|
|
|
+ const rec = { marker, item, name, boxW, totalH };
|
|
|
+
|
|
|
+ marker.on("click", () => {
|
|
|
+ if (item.scene) {
|
|
|
+ router.push({ name: "Scene", query: { url: item.scene.trim() } });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ marker.on("mouseover", () => {
|
|
|
+ applyMarkerVisual(rec, true);
|
|
|
+ });
|
|
|
+ marker.on("mouseout", () => {
|
|
|
+ applyMarkerVisual(rec, isNameSelected(name));
|
|
|
+ });
|
|
|
+
|
|
|
+ map.addOverLay(marker);
|
|
|
+ markerRecords.push(rec);
|
|
|
+ });
|
|
|
+ syncMarkerHighlight();
|
|
|
+}
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => ({
|
|
|
+ lng: route.query.lng,
|
|
|
+ lat: route.query.lat,
|
|
|
+ name: route.query.name,
|
|
|
+ zoom: route.query.zoom,
|
|
|
+ }),
|
|
|
+ () => {
|
|
|
+ centerMapToQuery();
|
|
|
+ syncMarkerHighlight();
|
|
|
+ },
|
|
|
+ { deep: true },
|
|
|
+);
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ if (typeof T === "undefined") {
|
|
|
+ console.error("天地图 API 未加载,请检查 index.html 中的 tk 密钥配置");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await fetch("./data.json");
|
|
|
+ const raw = await res.json();
|
|
|
+ mapData.value = (raw || []).filter(
|
|
|
+ (i) => i.lng && i.lat && !isNaN(Number(i.lng)) && !isNaN(Number(i.lat)),
|
|
|
+ );
|
|
|
+ } catch (e) {
|
|
|
+ console.error("加载 data.json 失败:", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ const tk = "85cd0cdb9cea33df08557f0af24063d1";
|
|
|
+
|
|
|
+ const zhuhaiBounds = new T.LngLatBounds(
|
|
|
+ new T.LngLat(113.05, 21.8),
|
|
|
+ new T.LngLat(114.32, 22.45),
|
|
|
+ );
|
|
|
+
|
|
|
+ const vecUrl = `https://t0.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tk}`;
|
|
|
+
|
|
|
+ const vecLayer = new T.TileLayer(vecUrl, { minZoom: 6, maxZoom: 18 });
|
|
|
+
|
|
|
+ map = new T.Map(mapContainer.value, {
|
|
|
+ projection: "EPSG:4326",
|
|
|
+ minZoom: 12,
|
|
|
+ maxZoom: 18,
|
|
|
+ maxBounds: zhuhaiBounds,
|
|
|
+ layers: [vecLayer],
|
|
|
+ });
|
|
|
+
|
|
|
+ centerMapToQuery();
|
|
|
+ addMarkers();
|
|
|
+});
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ markerRecords.forEach((r) => map?.removeOverLay(r.marker));
|
|
|
+ markerRecords.length = 0;
|
|
|
+ map = null;
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+@use "@/assets/utils.scss";
|
|
|
+
|
|
|
+.map-page {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ z-index: 0;
|
|
|
+
|
|
|
+ &-back {
|
|
|
+ position: absolute;
|
|
|
+ right: utils.vh-calc(20);
|
|
|
+ bottom: utils.vh-calc(30);
|
|
|
+ width: utils.vh-calc(50);
|
|
|
+ height: utils.vh-calc(50);
|
|
|
+ cursor: pointer;
|
|
|
+ z-index: 999;
|
|
|
+ transition: right 0.3s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ &--sidebar-visible &-back {
|
|
|
+ /* 与 Home 页 mini-map 一致:侧栏展开时右移约 300 设计单位 */
|
|
|
+ right: utils.vh-calc(320);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#tdt-map-container {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.tdt-marker) {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+</style>
|