<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Cesium 無人機巡檢三維效果實現

      uavInspection.js代碼

      /**
       * 無人機巡檢
       */
      
      import * as mars3d from "mars3d"
      import * as Cesium from 'mars3d-cesium'
      import * as turf from "@turf/turf"
      
      import { getMap } from '@/components/mars3dMap/js/index.js'
      import { getHeightByLngLat } from '@/components/mars3dMap/js/utils.js'
      import GlowLineMaterialProperty from '@/components/mars3dMap/js/material/GlowLineMaterialProperty.js'
      
      import iamge from "@/components/mars3dMap/images/路徑撒點.png";
      import iamge2 from "@/components/mars3dMap/images/路徑撒點2.png";
      
      let graphicLayer;
      
      let uavInspectionMap = new Map();
      
      let pointCallback; // 無人機經過點位回調
      
      let UavInspection = (function () {
      
          /**
           * 無人機巡檢
           */
          function UavInspection(id, positions) {
              this.id = id;
              this.positions = positions || [];
              this.graphicMap = new Map();
              this.step = 20;
              this.callbackPointSet = new Set(); // 回調點位集合
              if (positions && positions.length > 0) {
                  this.segmentPositions = this.divideLine(positions, this.step);
              }
      
              if (!graphicLayer) {
                  let map = getMap();
                  graphicLayer = new mars3d.layer.GraphicLayer()
                  map.addLayer(graphicLayer);
              }
          }
      
          UavInspection.prototype.finishLabels = function (index) {
              for (let i = 1; i <= index; i++) {
                  this.finishLabel(i);
              }
          }
      
          UavInspection.prototype.finishLabel = function (index) {
              let id = `label-${index}`;
              if (this.graphicMap.has(id)) {
                  let data = this.graphicMap.get(id);
                  data.graphic.setStyle({ image: iamge2 });
              }
          }
      
          UavInspection.prototype.addLabels = function () {
              for (let [i, pos] of this.positions.entries()) {
                  let samePos = false; // 第1個點和最后一個點位置是否相同
                  if (this.positions.length > 0) {
                      let lastPos1 = this.positions[0];
                      let lastPos2 = this.positions[this.positions.length - 1];
                      let distance = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(lastPos1[0], lastPos1[1], lastPos1[2]),
                          Cesium.Cartesian3.fromDegrees(lastPos2[0], lastPos2[1], lastPos2[2]));
                      if (distance < 5) {
                          samePos = true;
                      }
                  }
      
                  if (i < (samePos ? this.positions.length - 1 : this.positions.length)) {
                      this.addLabel(i + 1, pos[0], pos[1], pos[2]);
                  }
              }
          }
      
          UavInspection.prototype.addLabel = function (index, lng, lat, height) {
              let id = `label-${index}`;
              let data;
              if (this.graphicMap.has(id)) {
                  return;
              } else {
                  data = { id: id, type: 'label' };
                  this.graphicMap.set(id, data);
              }
      
              data.graphic = new mars3d.graphic.BillboardEntity({
                  id: id,
                  position: [lng, lat, height],
                  style: {
                      image: iamge,
                      scale: 0.5,
                      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                      clampToGround: false,
                      pixelOffsetY: 30,
                      label: {
                          text: `${index}`,
                          pixelOffsetY: -31,
                          visibleDepth: false
                      }
                  },
              })
              graphicLayer.addGraphic(data.graphic);
          }
      
          UavInspection.prototype.clear = function () {
              for (let id of this.graphicMap.keys()) {
                  let data = this.graphicMap.get(id);
                  this.graphicMap.delete(id);
                  graphicLayer.removeGraphic(data.graphic);
                  data.graphic = undefined;
                  if (data.type == 'drone') {
                      data.positionProperty = undefined;
                  }
              }
              this.callbackPointSet.clear();
          }
      
          UavInspection.prototype.createPath = function () {
              return { // 實時軌跡顯示
                  show: true,
                  leadTime: 0, // 飛機將要經過的路徑,路徑存在的時間
                  trailTime: 60, // 飛機已經經過的路徑,路徑存在的時間
                  width: 8, // 線寬度
                  resolution: 1,
                  // color: 'rgba(255, 193, 37, 1)',
                  /* material: new Cesium.PolylineGlowMaterialProperty({
                      glowPower: 0.25, // 軌跡線的發光強度
                      color: new Cesium.Color(255 / 255, 193 / 255, 37 / 255, 1) // 顏色
                  }) */
                  material: new GlowLineMaterialProperty({
                      color: new Cesium.Color(255 / 255, 255 / 255, 0 / 255, 1),
                      power: 0.2
                  })
              };
          }
      
          UavInspection.prototype.createModel = function () {
              return new mars3d.graphic.ModelEntity({
                  position: [0, 0, 0], // 默認值
                  style: {
                      url: 'gltf/四旋翼無人機1.glb',
                      scale: 6,
                      minimumPixelSize: 100,
                      heading: 0
                  },
                  path: this.createPath()
              });
          }
      
          UavInspection.prototype.createDrone = function () {
              let id = this.id;
              let data;
              if (this.graphicMap.has(id)) {
                  return;
              } else {
                  data = { id: id, type: 'drone' };
                  this.graphicMap.set(id, data);
                  data.positionProperty = new Cesium.SampledPositionProperty();
                  data.positionProperty.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD; // 后續時段保持末位置
              }
      
              if (!data.graphic) {
                  data.graphic = this.createModel();
                  graphicLayer.addGraphic(data.graphic);
                  data.graphic.position = data.positionProperty;
                  this.addDashLine();
              }
          }
      
          UavInspection.prototype.updateDronePosition = function (lng, lat, height) {
              let id = this.id;
              if (this.graphicMap.has(id)) {
                  let data = this.graphicMap.get(id);
                  if (data.graphic) {
                      this.lastTime = new Date().getTime();
                      data.position = [lng, lat, height];
                      let position = Cesium.Cartesian3.fromDegrees(lng, lat, height);
                      let delay = 2000; // 延遲(單位:毫秒)
                      let time = Cesium.JulianDate.fromDate(new Date(new Date().getTime() + delay));
                      data.positionProperty.addSample(time, position);
                      setTimeout(() => {
                          this.updateDashLine(lng, lat, height);
                          this.drawBlocks(lng, lat);
                      }, delay);
                  }
              }
              // 無人機經緯標簽時標簽變色
              for (let [i, pos] of this.positions.entries()) {
                  if (i < this.positions.length) {
                      let distance = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(lng, lat, 0), Cesium.Cartesian3.fromDegrees(pos[0], pos[1], 0));
                      if (distance < 10) {
                          this.finishLabels(i + 1);
                      }
                  }
              }
              // 指定點位回調
              for (let [i, pos] of this.positions.entries()) {
                  let distance = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(lng, lat, 0), Cesium.Cartesian3.fromDegrees(pos[0], pos[1], 0));
                  if (distance < 10) {
                      if (pointCallback && !this.callbackPointSet.has(i + 1)) {
                          let map = getMap();
                          const screenPoint = map.scene.cartesianToCanvasCoordinates(Cesium.Cartesian3.fromDegrees(lng, lat, height));
                          this.callbackPointSet.add(i + 1);
                          setTimeout(() => {
                              pointCallback(i + 1, screenPoint);
                          }, 100);
                      }
                  }
              }
          }
      
          UavInspection.prototype.addDashLine = function () {
              let id = `dashline-${this.id}`;
              let data;
              if (this.graphicMap.has(id)) {
                  return;
              } else {
                  data = { id: id, type: 'dashline' };
                  this.graphicMap.set(id, data);
              }
      
              if (!data.graphic) {
                  data.graphic = new mars3d.graphic.PolylineEntity({
                      positions: undefined,
                      style: {
                          width: 2,
                          clampToGround: false,
                          materialType: mars3d.MaterialType.PolylineDash,
                          materialOptions: {
                              color: '#ff0000',
                              dashLength: 16.0
                          }
                      }
                  })
                  graphicLayer.addGraphic(data.graphic)
              }
          }
      
          UavInspection.prototype.updateDashLine = function (lng, lat, height) {
              let id = `dashline-${this.id}`;
              if (this.graphicMap.has(id)) {
                  let data = this.graphicMap.get(id);
                  (async () => {
                      let h = await getHeightByLngLat(getMap(), lng, lat);
                      if (data.graphic) {
                          data.graphic.setCallbackPositions([[lng, lat, height], [lng, lat, h]]);
                      }
                  })();
      
              }
          }
      
          /**
           * 計算正方形在三維空間中的四個頂點坐標
           */
          UavInspection.prototype.calculateSquareVertices = function (lng, lat, angle, step) {
              let centerPoint = Cesium.Cartesian3.fromDegrees(lng, lat, 0);
      
              // 獲取中心點處的ENU坐標系基向量(東、北、天)
              const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(centerPoint);
              const east = new Cesium.Cartesian3();
              const north = new Cesium.Cartesian3();
              Cesium.Matrix4.getColumn(matrix, 0, east);  // 東方向單位向量
              Cesium.Matrix4.getColumn(matrix, 1, north); // 北方向單位向量
      
              const halfLen = step / 2;
              const angleRad = Cesium.Math.toRadians(angle);  // 轉為弧度
      
              // 1. 計算目標方向向量(θ方向)在ENU坐標系的投影分量
              const cosTheta = Math.cos(angleRad);
              const sinTheta = Math.sin(angleRad);
      
              // 計算主方向單位向量 (基于東和北分量)
              const dirX = cosTheta;
              const dirY = -sinTheta; // 負號用于處理順時針旋轉
      
              // 構造三維空間中的方向向量
              const directionVector = new Cesium.Cartesian3();
              Cesium.Cartesian3.multiplyByScalar(east, dirX, directionVector);
              Cesium.Cartesian3.add(
                  directionVector,
                  Cesium.Cartesian3.multiplyByScalar(north, dirY, new Cesium.Cartesian3()),
                  directionVector
              );
      
              // 2. 計算垂直方向向量 (θ+90°) 的分量
              const perpX = -sinTheta;
              const perpY = -cosTheta;
      
              // 構造三維空間中的垂直向量
              const perpendicularVector = new Cesium.Cartesian3();
              Cesium.Cartesian3.multiplyByScalar(east, perpX, perpendicularVector);
              Cesium.Cartesian3.add(
                  perpendicularVector,
                  Cesium.Cartesian3.multiplyByScalar(north, perpY, new Cesium.Cartesian3()),
                  perpendicularVector
              );
      
              // 3. 計算四個頂點
              const result = [];
              const scratch = new Cesium.Cartesian3();
      
              // 頂點計算函數 (避免重復代碼)
              const calculatePoint = (xFactor, yFactor) => {
                  const point = scratch;
                  // point = centerPoint + (directionVector * xFactor * halfLen) + (perpendicularVector * yFactor * halfLen)
                  Cesium.Cartesian3.multiplyByScalar(directionVector, xFactor * halfLen, point);
                  Cesium.Cartesian3.add(
                      point,
                      Cesium.Cartesian3.multiplyByScalar(perpendicularVector, yFactor * halfLen, new Cesium.Cartesian3()),
                      point
                  );
                  return Cesium.Cartesian3.add(centerPoint, point, new Cesium.Cartesian3());
              };
      
              // 生成4個頂點(順時針順序)
              result.push(calculatePoint(1, -1));  // 起點:右下
              result.push(calculatePoint(1, 1));  // 右上
              result.push(calculatePoint(-1, 1));  // 左上
              result.push(calculatePoint(-1, -1));  // 左下
      
              return result;
          }
      
          UavInspection.prototype.getSquareVertices = function (pos, pos1, pos2, step) {
              let angle = this.calculateBearingFromEast(pos1, pos2);
              let r = this.calculateSquareVertices(pos[0], pos[1], angle, step);
              let result = { center: pos, positions: [] };
              for (let i = 0; i < r.length; i++) {
                  const cartographic = Cesium.Cartographic.fromCartesian(r[i]);
                  let position = [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height];
                  result.positions.push(position);
              }
              return result;
          }
      
          UavInspection.prototype.getRectangleVertices = function (pos1, pos2, step) {
              let mid1 = Cesium.Cartesian3.fromDegrees(pos1[0], pos1[1], 0);
              let mid2 = Cesium.Cartesian3.fromDegrees(pos2[0], pos2[1], 0);
      
              const { Cartesian3, Ellipsoid, Cartographic } = Cesium;
              const ellipsoid = Ellipsoid.WGS84;
      
              // 計算中點連線方向向量
              const v1 = Cartesian3.subtract(mid2, mid1, new Cartesian3());
              const distance = Cartesian3.magnitude(v1);
              Cartesian3.normalize(v1, v1);
      
              // 計算垂直方向向量
              const center = Cartesian3.midpoint(mid1, mid2, new Cartesian3());
              const normal = ellipsoid.geodeticSurfaceNormal(center, new Cartesian3());
              const v2 = Cartesian3.cross(normal, v1, new Cartesian3());
              Cartesian3.normalize(v2, v2);
      
              // 縮放垂直向量到指定長度
              const halfWidth = Cartesian3.multiplyByScalar(v2, step / 2.0, new Cartesian3());
      
              // 計算四個頂點的笛卡爾坐標
              const cornersCartesian = [
                  Cartesian3.add(mid1, Cartesian3.negate(halfWidth, new Cartesian3()), new Cartesian3()), // SW
                  Cartesian3.add(mid1, halfWidth, new Cartesian3()),  // NW
                  Cartesian3.add(mid2, halfWidth, new Cartesian3()),   // NE
                  Cartesian3.add(mid2, Cartesian3.negate(halfWidth, new Cartesian3()), new Cartesian3())  // SE
              ];
      
              // 轉換為經緯度(弧度)坐標
              const cornersRadians = cornersCartesian.map(cartesian => {
                  return Cartographic.fromCartesian(cartesian);
              });
      
              // 轉換為度數
              return cornersRadians.map(rad => {
                  return [Cesium.Math.toDegrees(rad.longitude), Cesium.Math.toDegrees(rad.latitude), rad.height];
              });
          }
      
          UavInspection.prototype.divideSegment = function (pos1, pos2, step) {
              let p1 = Cesium.Cartesian3.fromDegrees(pos1[0], pos1[1], 0);
              let p2 = Cesium.Cartesian3.fromDegrees(pos2[0], pos2[1], 0);
      
              let result = [];
              let lastPos = pos1;
              let currentPos;
              let distance = Cesium.Cartesian3.distance(p1, p2);
              let d = step;
              while (d < distance - 0.1) {
                  let t = d / distance;
      
                  const interpolatedCartesian = new Cesium.Cartesian3();
                  Cesium.Cartesian3.lerp(p1, p2, t, interpolatedCartesian);
      
                  const cartographic = Cesium.Cartographic.fromCartesian(interpolatedCartesian);
                  currentPos = [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height];
                  result.push({
                      pos1: lastPos,
                      pos2: currentPos,
                      positions: this.getRectangleVertices(lastPos, currentPos, step)
                  });
                  lastPos = currentPos;
      
                  d += step;
              }
              result.push({
                  pos1: currentPos,
                  pos2: pos2,
                  positions: this.getRectangleVertices(currentPos, pos2, step)
              });
              return result;
          }
      
          UavInspection.prototype.divideLine = function (positions, step) {
              let result = [];
              for (let i = 0; i < positions.length - 1; i++) {
                  let pos1 = positions[i];
                  let pos2 = positions[i + 1];
                  let array = this.divideSegment(pos1, pos2, step);
                  result.push(...array);
              }
              return result.slice(0, -1);
          }
      
          UavInspection.prototype.drawBlocks = function (lng, lat) {
              if (this.segmentPositions && this.segmentPositions.length > 0) {
                  let index = -1;
                  for (let [i, pos] of this.segmentPositions.entries()) {
                      let distance1 = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(pos.pos1[0], pos.pos1[1], 0), Cesium.Cartesian3.fromDegrees(pos.pos2[0], pos.pos2[1], 0));
                      let distance2 = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(lng, lat, 0), Cesium.Cartesian3.fromDegrees(pos.pos1[0], pos.pos1[1], 0));
                      let distance3 = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(lng, lat, 0), Cesium.Cartesian3.fromDegrees(pos.pos2[0], pos.pos2[1], 0));
                      if (distance1 - (distance2 + distance3) > -0.1) {
                          index = i;
                      }
                  }
      
                  for (let i = 0; i <= index; i++) {
                      let pos = this.segmentPositions[i];
                      let pos2
                      if (i + 1 < this.segmentPositions.length) {
                          pos2 = this.segmentPositions[i + 1];
                      } else {
                          pos2 = this.segmentPositions[i - 1];
                      }
      
                      this.drawBlock(i, pos);
                  }
              } else {
                  if (!this.lastBlockPos) {
                      this.lastBlockPos = [lng, lat, 0];
                      this.blockIndex = 0;
                  } else {
                      let distance = Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(this.lastBlockPos[0], this.lastBlockPos[1], 0), Cesium.Cartesian3.fromDegrees(lng, lat, 0));
                      if (distance >= this.step) {
                          let pos2 = [lng, lat, 0];
                          let vertices = this.getRectangleVertices(this.lastBlockPos, pos2, this.step);
                          this.drawBlock(this.blockIndex++, { positions: vertices });
                          this.lastBlockPos = [lng, lat, 0];
                      }
                  }
              }
          }
      
          UavInspection.prototype.drawBlock = function (i, pos) {
              let id = `block-${i}`;
              let data;
              if (this.graphicMap.has(id)) {
                  return;
              } else {
                  data = { id: id, type: 'block' };
                  this.graphicMap.set(id, data);
              }
      
              if (!data.graphic) {
                  data.graphic = new mars3d.graphic.PolygonPrimitive({
                      positions: pos.positions,
                      style: {
                          color: "#ff0000",
                          opacity: 0.3,
                          clampToGround: true
                      }
                  })
                  graphicLayer.addGraphic(data.graphic)
              }
          }
      
          /**
           * 計算兩點間方向(正東為0°,順時針到360°)
           * @returns {number} 方向角度(0°到360°,正東方向為0°)
           */
          UavInspection.prototype.calculateBearingFromEast = function (pos1, pos2) {
              const point1 = Cesium.Cartographic.fromDegrees(pos1[0], pos1[1]);
              const point2 = Cesium.Cartographic.fromDegrees(pos2[0], pos2[1]);
      
              const lon1 = point1.longitude;
              const lat1 = point1.latitude;
              const lon2 = point2.longitude;
              const lat2 = point2.latitude;
      
              // 經度差(考慮跨日期變更線)
              const dLon = lon2 - lon1;
      
              // 計算Y分量(與正北相關)
              const y = Math.sin(dLon) * Math.cos(lat2);
      
              // 計算X分量(與正北相關)
              const x = Math.cos(lat1) * Math.sin(lat2) -
                  Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
      
              // 計算初始方位角(0°為正北,順時針)
              const bearingRad = Math.atan2(y, x);
              let bearingDeg = Cesium.Math.toDegrees(bearingRad);
      
              // 轉換為0°~360°范圍
              if (bearingDeg < 0) {
                  bearingDeg += 360;
              }
      
              // 坐標系轉換:正北0° → 正東0°
              // 轉換公式: (bearingDeg + 90) % 360
              return (bearingDeg + 90) % 360;
          }
      
          return UavInspection;
      })()
      
      function createUavInspection(id, positions) {
          if (!uavInspectionMap.has(id)) {
              let uavInspection = new UavInspection(id, positions);
              uavInspection.createDrone();
              uavInspection.addLabels();
              uavInspectionMap.set(id, uavInspection);
          }
      }
      
      function uavInspectionExists(id) {
          return uavInspectionMap.has(id);
      }
      
      function updateUavInspectionPosition(id, lng, lat, height) {
          if (uavInspectionMap.has(id)) {
              let uavInspection = uavInspectionMap.get(id);
              uavInspection.updateDronePosition(lng, lat, height);
          }
      }
      
      function clearUavInspections() {
          for (let id of uavInspectionMap.keys()) {
              let uavInspection = uavInspectionMap.get(id);
              uavInspectionMap.delete(id);
              uavInspection.clear();
          }
          graphicLayer = undefined;
      }
      
      // 定時清理
      setInterval(() => {
          for (let id of uavInspectionMap.keys()) {
              let uavInspection = uavInspectionMap.get(id);
              if (new Date().getTime() - uavInspection.lastTime > 20 * 1000) {
                  uavInspectionMap.delete(id);
                  uavInspection.clear();
              }
          }
      }, 1000);
      
      // 無人機經過點位回調
      function registerPointCallback(callback) {
          pointCallback = callback;
      }
      
      export { uavInspectionExists, createUavInspection, updateUavInspectionPosition, clearUavInspections, registerPointCallback }
      

      實時接收WebSocket數據,展示無人機、航線、地面色塊

      部分代碼如下

      import { uavInspectionExists, createUavInspection, updateUavInspectionPosition } from '@/components/mars3dMap/js/uavInspection.js'
      
      async function processWebSocketData(json) {
          if (json.method && json.method == "FLIGHT" && json.data) {
              let data = json.data;
              let id = data.droneSN;
              let model = data.model; // 飛機型號
              let lng = data.longitude;
              let lat = data.latitude;
              let alt = data.altitude; // 海拔高度
              let heading = data.heading; // 朝向(度)
              let pitch = data.pitch; // 俯仰角(度)
              let roll = data.roll; // 翻轉角(度)
              let groundSpeed = data.groundSpeed; // 地面速度,單位m/s
      
              if (!uavInspectionExists(id)) {
                  let positions;
                  if (id == config.droneSN) {
                      positions = config.passingPoints;
                  } else {
                      positions = [];
                  }
                  createUavInspection(id, positions)
              }
      
              updateUavInspectionPosition(id, lng, lat, alt);
          }
      }
      

      效果截圖

      截圖說明:由于測試筆記本比較卡,所以紅虛線、紅色塊和無人機的位置不同步
      image

      posted @ 2025-07-02 17:35  0611163  閱讀(196)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 99精品国产兔费观看久久99| 视频专区熟女人妻第二页| 亚洲免费人成网站在线观看| 国产91精品一区二区亚洲| 免费午夜无码视频在线观看| 熟女一区| 少妇被粗大的猛进69视频| 国产一区二区三区色成人| 久久亚洲精品情侣| 国厂精品114福利电影免费| 在线中文字幕国产一区| 国产女人喷潮视频免费| 国产亚洲精品久久77777| 无码专区一va亚洲v专区在线| 视频一区视频二区中文字幕| 久久亚洲人成网站| 久久av无码精品人妻出轨| 久久久久国产精品人妻| 日韩伦理片一区二区三区| 欧美激情一区二区三区成人 | 91中文字幕一区在线| 精品无套挺进少妇内谢| 欧美丰满熟妇xxxx性| 免费国产精品黄色一区二区| 国产一级av在线播放| 日韩精品中文字幕有码| 南阳市| 喀喇沁旗| 亚洲人成电影网站色mp4| 久久久久久亚洲精品成人| 老太脱裤让老头玩ⅹxxxx| 激情在线网| 男女性杂交内射女bbwxz| 成熟女人特级毛片www免费| 99国产欧美另类久久久精品| 国产无遮挡又黄又爽高潮| 熟女亚洲综合精品伊人久久| 精品九九人人做人人爱| 亚洲中文字幕日产无码成人片| 免费观看的av在线播放| 日韩欧美精品suv|