| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- <template>
- <div class="map-wrapper">
- <div ref="mapContainer" class="map-container"></div>
- </div>
- </template>
- <script>
- import AMapLoader from '@amap/amap-jsapi-loader';
- export default {
- name: "EvaluationTrafficMap",
- props: {
- amapKey: { type: String, required: true },
- securityJsCode: { type: String, required: true },
- mode: {
- type: String,
- default: 'overview',
- validator: (val) => ['overview', 'singlePoint', 'trunkLine', 'area'].includes(val)
- }
- },
- data() {
- return {
- AMap: null,
- map: null,
- overlays: [], // 统一管理当前地图上的所有覆盖物
- };
- },
- watch: {
- // 监听模式变化,重新绘制地图元素
- mode(newMode) {
- this.updateMapDisplay();
- }
- },
- mounted() {
- this.initAMap();
- },
- beforeDestroy() {
- if (this.map) {
- this.map.destroy();
- this.map = null;
- }
- },
- methods: {
- async initAMap() {
- window._AMapSecurityConfig = { securityJsCode: this.securityJsCode };
- try {
- const AMap = await AMapLoader.load({
- key: this.amapKey,
- version: "2.0",
- });
- this.AMap = AMap;
- this.map = new AMap.Map(this.$refs.mapContainer, {
- zoom: 13,
- mapStyle: "amap://styles/darkblue",
- center: [116.66, 39.91], // 通州区
- });
- this.map.on('complete', () => {
- this.updateMapDisplay();
- });
- } catch (err) {
- console.error('地图加载失败:', err);
- }
- },
- clearOverlays() {
- if (this.map && this.overlays.length > 0) {
- this.map.remove(this.overlays);
- this.overlays = [];
- }
- },
- updateMapDisplay() {
- if (!this.map || !this.AMap) return;
- this.clearOverlays();
- switch (this.mode) {
- case 'overview':
- this.drawOverview();
- break;
- case 'singlePoint':
- this.drawSinglePoint();
- break;
- case 'trunkLine':
- this.drawTrunkLine();
- break;
- case 'area':
- this.drawArea();
- break;
- }
- },
- // 1. 绘制总览:简单的红黄绿圆点
- drawOverview() {
- const mockData = [
- { pos: [116.65, 39.90], color: '#00FF00' }, { pos: [116.66, 39.91], color: '#FF0000' },
- { pos: [116.67, 39.89], color: '#FFA500' }, { pos: [116.69, 39.92], color: '#00FF00' },
- { pos: [116.64, 39.93], color: '#FF0000' }, { pos: [116.70, 39.90], color: '#FFA500' },
- { pos: [116.68, 39.91], color: '#00FF00' }, { pos: [116.66, 39.93], color: '#FF0000' },
- ];
- mockData.forEach(item => {
- const marker = new this.AMap.Marker({
- position: item.pos,
- content: `<div style="width: 12px; height: 12px; background-color: ${item.color}; border-radius: 50%; box-shadow: 0 0 5px ${item.color}; border: 1px solid #fff;"></div>`,
- offset: new this.AMap.Pixel(-6, -6),
- });
- this.overlays.push(marker);
- });
- this.map.add(this.overlays);
- },
- // 2. 绘制评价监测-单点:带 A-F 字母和对应颜色的点
- drawSinglePoint() {
- const colors = { A: '#8fc31f', B: '#d7df23', C: '#fff200', D: '#f39c12', E: '#e74c3c', F: '#c0392b' };
- const mockData = [
- { pos: [116.63, 39.90], level: 'A' }, { pos: [116.65, 39.91], level: 'B' },
- { pos: [116.66, 39.89], level: 'C' }, { pos: [116.68, 39.88], level: 'D' },
- { pos: [116.70, 39.91], level: 'E' }, { pos: [116.71, 39.90], level: 'F' },
- { pos: [116.67, 39.90], level: 'B' }, { pos: [116.69, 39.89], level: 'C' },
- { pos: [116.65, 39.88], level: 'A' }, { pos: [116.69, 39.87], level: 'D' },
- ];
- mockData.forEach(item => {
- const marker = new this.AMap.Marker({
- position: item.pos,
- content: `
- <div style="width: 20px; height: 20px; background-color: ${colors[item.level]}; border-radius: 50%; display: flex; justify-content: center; align-items: center; color: #fff; font-weight: bold; font-size: 12px; border: 2px solid rgba(255,255,255,0.5);">
- ${item.level}
- </div>
- `,
- offset: new this.AMap.Pixel(-10, -10),
- });
- this.overlays.push(marker);
- });
- this.map.add(this.overlays);
- },
- // 3. 绘制评价监测-干线:绿色波段线段
- drawTrunkLine() {
- const lines = [
- [[116.65, 39.91], [116.69, 39.92]],
- [[116.64, 39.90], [116.70, 39.91]],
- [[116.65, 39.89], [116.70, 39.89]],
- [[116.66, 39.88], [116.68, 39.85]],
- ];
- lines.forEach(path => {
- // 画线
- const polyline = new this.AMap.Polyline({
- path: path,
- isOutline: true,
- outlineColor: '#fff',
- borderWeight: 1,
- strokeColor: "#a6ce39",
- strokeOpacity: 0.9,
- strokeWeight: 5,
- });
- this.overlays.push(polyline);
- // 在线段两端或中间画点作为路口标识
- path.forEach(pos => {
- const marker = new this.AMap.Marker({
- position: pos,
- content: `<div style="width: 10px; height: 10px; background-color: #fff; border-radius: 50%; border: 2px solid #a6ce39;"></div>`,
- offset: new this.AMap.Pixel(-5, -5),
- });
- this.overlays.push(marker);
- });
- });
- this.map.add(this.overlays);
- },
- // 4. 绘制评价监测-区域:半透明多边形 + 中心文字
- drawArea() {
- const areas = [
- {
- path: [[116.67, 39.94], [116.70, 39.94], [116.71, 39.92], [116.70, 39.91], [116.67, 39.91]],
- color: '#d35400', label: '6.2', center: [116.69, 39.925]
- },
- {
- path: [[116.68, 39.90], [116.72, 39.90], [116.72, 39.88], [116.68, 39.88]],
- color: '#c0392b', label: '4.5', center: [116.70, 39.89]
- },
- {
- path: [[116.67, 39.87], [116.71, 39.87], [116.71, 39.85], [116.67, 39.85]],
- color: '#c0392b', label: '4.8', center: [116.69, 39.86]
- }
- ];
- areas.forEach(area => {
- // 绘制多边形
- const polygon = new this.AMap.Polygon({
- path: area.path,
- fillColor: area.color,
- fillOpacity: 0.4,
- strokeColor: area.color,
- strokeWeight: 2,
- });
- this.overlays.push(polygon);
- // 绘制中心数字标识
- const textMarker = new this.AMap.Marker({
- position: area.center,
- content: `<div style="color: rgba(255,255,255,0.8); font-size: 24px; font-weight: bold; text-shadow: 1px 1px 2px #000;">${area.label}</div>`,
- offset: new this.AMap.Pixel(-15, -15),
- });
- this.overlays.push(textMarker);
- });
- // 画一个圆形的区域 (对应图中的绿色 9.1)
- const circle = new this.AMap.Circle({
- center: [116.64, 39.88],
- radius: 1800,
- fillColor: '#27ae60',
- fillOpacity: 0.4,
- strokeColor: '#27ae60',
- strokeWeight: 2,
- });
- this.overlays.push(circle);
- const circleText = new this.AMap.Marker({
- position: [116.64, 39.88],
- content: `<div style="color: rgba(255,255,255,0.8); font-size: 24px; font-weight: bold; text-shadow: 1px 1px 2px #000;">9.1</div>`,
- offset: new this.AMap.Pixel(-15, -15),
- });
- this.overlays.push(circleText);
- this.map.add(this.overlays);
- }
- }
- };
- </script>
- <style scoped>
- .map-wrapper {
- width: 100%;
- height: 100vh;
- position: relative;
- background: #010813;
- }
- .map-container {
- width: 100%;
- height: 100%;
- }
- /* 隐藏高德Logo等 */
- ::v-deep .amap-logo,
- ::v-deep .amap-copyright,
- ::v-deep .amap-copyright-logo {
- display: none !important;
- }
- </style>
|