<template>
  <div class="route-draw-control">
    <div class="draw-tools">
      <div class="tool-button" @click="startDrawLine" :class="{ active: isDrawing && drawType === 'LineString' }">
        <span>绘制路线</span>
      </div>
      <div class="tool-button" @click="startDrawPolygon" :class="{ active: isDrawing && drawType === 'Polygon' }">
        <span>绘制点线面</span>
      </div>
      <div class="tool-button" @click="clearDraw">
        <span>清除</span>
      </div>
      <div class="tool-button" @click="exportRouteData">
        <span>导出数据</span>
      </div>
      <div class="tool-button" @click="showImportDialog = true">
        <span>导入数据</span>
      </div>
    </div>
    
    <!-- 右侧点线面信息展示面板 -->
    <div class="polygon-panel" v-if="showPolygonPanel">
      <div class="panel-header">
        <span>点线面信息</span>
        <span class="close-btn" @click="closePolygonPanel">×</span>
      </div>
      <div class="panel-content">
        <div class="info-item" v-for="(polygon, index) in polygons" :key="index">
          <div class="info-header">点线面 {{ index + 1 }}</div>
          <div class="info-content">
            <p>面积: {{ polygon.area.toFixed(2) }} 平方米</p>
            <p>周长: {{ polygon.perimeter.toFixed(2) }} 米</p>
            <p>顶点数: {{ polygon.vertices }}</p>
            <button class="focus-btn" @click="focusOnPolygon(polygon)">定位</button>
          </div>
        </div>
        <div class="no-data" v-if="polygons.length === 0">
          暂无点线面数据，请先绘制点线面
        </div>
      </div>
    </div>

    <!-- 路线信息面板 -->
    <div class="route-lines-panel" v-if="showRouteLinesPanel">
      <div class="panel-header">
        <span>路线信息</span>
        <span class="close-btn" @click="closeRouteLinesPanel">×</span>
      </div>
      <div class="panel-content">
        <div class="info-item" v-for="(line, index) in routeLines" :key="index">
          <div class="info-header">路线 {{ index + 1 }}</div>
          <div class="info-content">
            <p>长度: {{ line.length.toFixed(2) }} 米</p>
            <p>顶点数: {{ line.vertices }}</p>
            <button class="focus-btn" @click="focusOnRoute(line)">定位</button>
          </div>
        </div>
        <div class="no-data" v-if="routeLines.length === 0">
          暂无路线数据，请先绘制路线
        </div>
      </div>
    </div>

    <!-- 导入JSON对话框 -->
    <div class="import-dialog" v-if="showImportDialog">
      <div class="dialog-content">
        <div class="dialog-header">
          <h3>导入数据</h3>
          <span class="close-btn" @click="showImportDialog = false">×</span>
        </div>
        <div class="dialog-body">
          <textarea v-model="importJsonText" placeholder="请粘贴JSON数据"></textarea>
          <div class="file-upload">
            <label for="jsonFileInput">或者上传JSON文件</label>
            <input type="file" id="jsonFileInput" accept=".json" @change="handleFileUpload">
          </div>
        </div>
        <div class="dialog-footer">
          <button @click="showImportDialog = false">取消</button>
          <button @click="importRouteData" class="primary-btn">导入</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import Draw from 'ol/interaction/Draw';
import { Vector as VectorSource } from 'ol/source';
import { Vector as VectorLayer } from 'ol/layer';
import { Style, Stroke, Fill, Circle } from 'ol/style';
import { getArea, getLength } from 'ol/sphere';
import { LineString, Polygon } from 'ol/geom';
import GeoJSON from 'ol/format/GeoJSON';
import Feature from 'ol/Feature';

// 定义props接收地图实例
const props = defineProps({
  map: Object
});

// 响应式状态
const isDrawing = ref(false);
const drawType = ref('');
const showPolygonPanel = ref(false);
const showRouteLinesPanel = ref(false);
const polygons = ref([]);
const routeLines = ref([]);
const showImportDialog = ref(false);
const importJsonText = ref('');

// 图层和交互
let drawInteraction = null;
let vectorSource = null;
let vectorLayer = null;

// 初始化绘图图层
function initDrawLayer() {
  if (!props.map) return;
  
  // 创建矢量数据源
  vectorSource = new VectorSource();
  
  // 创建矢量图层
  vectorLayer = new VectorLayer({
    source: vectorSource,
    style: new Style({
      fill: new Fill({
        color: 'rgba(0, 150, 255, 0.3)'
      }),
      stroke: new Stroke({
        color: '#0096ff',
        width: 3
      }),
      image: new Circle({
        radius: 7,
        fill: new Fill({
          color: '#0096ff'
        })
      })
    })
  });
  
  // 添加图层到地图
  props.map.addLayer(vectorLayer);
}

// 开始绘制线
function startDrawLine() {
  clearDraw();
  isDrawing.value = true;
  drawType.value = 'LineString';
  showRouteLinesPanel.value = true;
  
  drawInteraction = new Draw({
    source: vectorSource,
    type: 'LineString',
    style: new Style({
      stroke: new Stroke({
        color: '#ff0000',
        width: 3
      }),
      image: new Circle({
        radius: 5,
        fill: new Fill({
          color: '#ff0000'
        })
      })
    })
  });
  
  // 监听绘制结束事件
  drawInteraction.on('drawend', function(event) {
    const feature = event.feature;
    const geometry = feature.getGeometry();
    
    // 计算路线长度
    const length = getLength(geometry);
    const vertices = geometry.getCoordinates().length;
    
    // 设置特征属性
    feature.setProperties({
      type: 'route',
      length: length,
      vertices: vertices
    });
    
    // 添加到路线列表
    routeLines.value.push({
      id: Date.now(),
      feature: feature,
      length: length,
      vertices: vertices,
      extent: geometry.getExtent()
    });
    
    isDrawing.value = false;
  });
  
  props.map.addInteraction(drawInteraction);
}

// 开始绘制多边形（点线面）
function startDrawPolygon() {
  clearDraw();
  isDrawing.value = true;
  drawType.value = 'Polygon';
  showPolygonPanel.value = true;
  
  drawInteraction = new Draw({
    source: vectorSource,
    type: 'Polygon',
    style: new Style({
      fill: new Fill({
        color: 'rgba(255, 165, 0, 0.3)'
      }),
      stroke: new Stroke({
        color: '#ffa500',
        width: 3
      }),
      image: new Circle({
        radius: 5,
        fill: new Fill({
          color: '#ffa500'
        })
      })
    })
  });
  
  // 监听绘制结束事件
  drawInteraction.on('drawend', function(event) {
    const feature = event.feature;
    const geometry = feature.getGeometry();
    
    // 计算面积和周长
    const area = getArea(geometry);
    const perimeter = getLength(geometry.getLinearRing(0));
    const vertices = geometry.getLinearRing(0).getCoordinates().length - 1; // 减去重复的闭合点
    
    // 设置特征属性
    feature.setProperties({
      type: 'polygon',
      area: area,
      perimeter: perimeter,
      vertices: vertices
    });
    
    // 添加到点线面列表
    polygons.value.push({
      id: Date.now(),
      feature: feature,
      area: area,
      perimeter: perimeter,
      vertices: vertices,
      extent: geometry.getExtent()
    });
    
    isDrawing.value = false;
  });
  
  props.map.addInteraction(drawInteraction);
}

// 清除绘制
function clearDraw() {
  if (drawInteraction) {
    props.map.removeInteraction(drawInteraction);
    drawInteraction = null;
  }
  
  if (vectorSource) {
    vectorSource.clear();
  }
  
  isDrawing.value = false;
  polygons.value = [];
  routeLines.value = [];
}

// 关闭点线面面板
function closePolygonPanel() {
  showPolygonPanel.value = false;
}

// 关闭路线面板
function closeRouteLinesPanel() {
  showRouteLinesPanel.value = false;
}

// 定位到指定点线面
function focusOnPolygon(polygon) {
  if (props.map && polygon.extent) {
    props.map.getView().fit(polygon.extent, {
      padding: [50, 50, 50, 50],
      duration: 1000
    });
  }
}

// 定位到指定路线
function focusOnRoute(route) {
  if (props.map && route.extent) {
    props.map.getView().fit(route.extent, {
      padding: [50, 50, 50, 50],
      duration: 1000
    });
  }
}

// 导出路线数据为GeoJSON
function exportRouteData() {
  if (!vectorSource || vectorSource.getFeatures().length === 0) {
    alert('没有可导出的数据，请先绘制路线或点线面');
    return;
  }
  
  // 创建GeoJSON格式化器
  const format = new GeoJSON();
  
  // 获取所有特征
  const features = vectorSource.getFeatures();
  
  // 将特征转换为GeoJSON
  const geojsonObj = format.writeFeaturesObject(features, {
    dataProjection: 'EPSG:4326',  // 输出为WGS84坐标
    featureProjection: props.map.getView().getProjection()  // 从地图投影转换
  });
  
  // 转换为JSON字符串
  const geojsonStr = JSON.stringify(geojsonObj, null, 2);
  
  // 创建下载链接
  const blob = new Blob([geojsonStr], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = 'roadTest.json';  // 固定文件名为roadTest.json
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
  
  console.log('数据已导出为GeoJSON，文件名：roadTest.json');
  alert('文件已下载为roadTest.json，请将其复制到项目的public目录下');
}

// 处理文件上传
function handleFileUpload(event) {
  const file = event.target.files[0];
  if (!file) return;
  
  const reader = new FileReader();
  reader.onload = (e) => {
    importJsonText.value = e.target.result;
  };
  reader.readAsText(file);
}

// 从JSON数据导入路线
function importRouteData() {
  if (!importJsonText.value) {
    alert('请输入或上传JSON数据');
    return;
  }
  
  try {
    // 解析JSON
    const geojsonObj = JSON.parse(importJsonText.value);
    
    // 创建GeoJSON格式化器
    const format = new GeoJSON();
    
    // 清除现有图层
    clearDraw();
    
    // 从GeoJSON读取特征
    const features = format.readFeatures(geojsonObj, {
      dataProjection: 'EPSG:4326',  // 输入为WGS84坐标
      featureProjection: props.map.getView().getProjection()  // 转换到地图投影
    });
    
    // 添加特征到矢量源
    vectorSource.addFeatures(features);
    
    // 处理导入的特征，分类为路线和点线面
    features.forEach(feature => {
      const geometry = feature.getGeometry();
      const props = feature.getProperties();
      
      if (geometry instanceof LineString || props.type === 'route') {
        // 这是一条路线
        const length = getLength(geometry);
        const vertices = geometry.getCoordinates().length;
        
        routeLines.value.push({
          id: Date.now() + Math.random(),
          feature: feature,
          length: props.length || length,
          vertices: props.vertices || vertices,
          extent: geometry.getExtent()
        });
      } else if (geometry instanceof Polygon || props.type === 'polygon') {
        // 这是一个点线面
        const area = getArea(geometry);
        const perimeter = getLength(geometry.getLinearRing(0));
        const vertices = geometry.getLinearRing(0).getCoordinates().length - 1;
        
        polygons.value.push({
          id: Date.now() + Math.random(),
          feature: feature,
          area: props.area || area,
          perimeter: props.perimeter || perimeter,
          vertices: props.vertices || vertices,
          extent: geometry.getExtent()
        });
      }
    });
    
    // 更新面板显示
    if (routeLines.value.length > 0) {
      showRouteLinesPanel.value = true;
    }
    if (polygons.value.length > 0) {
      showPolygonPanel.value = true;
    }
    
    // 关闭导入对话框
    showImportDialog.value = false;
    importJsonText.value = '';
    
    // 缩放到所有特征的范围
    if (features.length > 0) {
      const extent = vectorSource.getExtent();
      props.map.getView().fit(extent, {
        padding: [50, 50, 50, 50],
        duration: 1000
      });
    }
    
    console.log('成功导入数据，共', features.length, '个特征');
  } catch (error) {
    console.error('导入数据失败:', error);
    alert('导入失败，请检查JSON格式是否正确');
  }
}

// 组件挂载时初始化
onMounted(() => {
  if (props.map) {
    initDrawLayer();
  }
});

// 监听地图实例变化
watch(() => props.map, (newMap) => {
  if (newMap) {
    initDrawLayer();
  }
});

// 组件卸载时清理
onUnmounted(() => {
  if (props.map) {
    if (drawInteraction) {
      props.map.removeInteraction(drawInteraction);
    }
    if (vectorLayer) {
      props.map.removeLayer(vectorLayer);
    }
  }
});

// 向外暴露方法
defineExpose({
  startDrawLine,
  startDrawPolygon,
  clearDraw,
  exportRouteData,
  importRouteData,
  showImportDialog
});
</script>

<style scoped>
.route-draw-control {
  position: relative;
}

.draw-tools {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 3000;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 120px;
  border: 2px solid #0096ff;
}

.tool-button {
  padding: 8px 12px;
  background-color: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  text-align: center;
  transition: all 0.2s;
  font-weight: bold;
  color: #333;
}

.tool-button:hover {
  background-color: #e0e0e0;
  transform: scale(1.05);
}

.tool-button.active {
  background-color: #0096ff;
  color: white;
  border-color: #0078cc;
}

.polygon-panel, .route-lines-panel {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 300px;
  max-height: 80vh;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  z-index: 3000;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.route-lines-panel {
  right: 340px;
}

.panel-header {
  padding: 12px 15px;
  background-color: #f5f5f5;
  border-bottom: 1px solid #ddd;
  font-weight: bold;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.close-btn {
  cursor: pointer;
  font-size: 20px;
  color: #666;
}

.close-btn:hover {
  color: #333;
}

.panel-content {
  padding: 15px;
  overflow-y: auto;
  max-height: calc(80vh - 50px);
}

.info-item {
  margin-bottom: 15px;
  border: 1px solid #eee;
  border-radius: 4px;
  overflow: hidden;
}

.info-header {
  padding: 8px 12px;
  background-color: #f9f9f9;
  border-bottom: 1px solid #eee;
  font-weight: bold;
}

.info-content {
  padding: 12px;
}

.info-content p {
  margin: 5px 0;
  font-size: 14px;
}

.focus-btn {
  margin-top: 8px;
  padding: 5px 10px;
  background-color: #0096ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.focus-btn:hover {
  background-color: #0078cc;
}

.no-data {
  text-align: center;
  color: #999;
  padding: 20px 0;
}

/* 导入对话框样式 */
.import-dialog {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 5000;
}

.dialog-content {
  width: 500px;
  background-color: white;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}

.dialog-header {
  padding: 15px;
  background-color: #f5f5f5;
  border-bottom: 1px solid #ddd;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.dialog-header h3 {
  margin: 0;
  font-size: 18px;
}

.dialog-body {
  padding: 20px;
}

.dialog-body textarea {
  width: 100%;
  height: 200px;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  resize: none;
  font-family: monospace;
  margin-bottom: 15px;
}

.file-upload {
  margin-top: 10px;
}

.file-upload label {
  display: inline-block;
  padding: 8px 12px;
  background-color: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
}

.file-upload input {
  display: none;
}

.dialog-footer {
  padding: 15px;
  background-color: #f5f5f5;
  border-top: 1px solid #ddd;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.dialog-footer button {
  padding: 8px 15px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: #f5f5f5;
  cursor: pointer;
}

.dialog-footer button.primary-btn {
  background-color: #0096ff;
  color: white;
  border-color: #0078cc;
}

.dialog-footer button.primary-btn:hover {
  background-color: #0078cc;
}
</style> 