openlayers Draw 理解、特殊图形创建

616 阅读2分钟

效果展示

featrues.gif

Draw 的layer创建和Source创建

let source = new VectorSource({ wrapX: false }),
  vector = new VectorLayer({
    source,
    style: new Style({
      fill: new Fill({ color: "rgba(255,255,255,0.2)" }),
      stroke: new Stroke({ color: "#f00", width: 2 })
    }),
  });

地图初始化、添加interaction

    let map = new Map({
      // 设置地图图层
      layers: [gaodeMapLayer, vector],
      // 设置显示地图的视图
      view: new View({
        center: transform([104.065735, 30.659462], "EPSG:4326", "EPSG:3857"),
        zoom: 9,
        minZoom: 1,
        maxZoom: 21,
        //  projection: "EPSG:4326",
        rotation: 0,
      }),
      // 让id为map的div作为地图的容器
      target: "featrues",
    });
    addInteraction();

addInteraction 函数

addInteraction() {
      let { type, map } = this,
        value = type;
      if (value != "None") {
        if (source == null) {
          source = new VectorSource({ wrapX: false });
          vector.setSource(source);
        }
        let maxPoints, geometryFunction;
        switch (value) {
          case "Spuare":
            value = "Circle";
            geometryFunction = createRegularPolygon(4);
            break;
          case "Regular": //多边形
            value = "Circle";
            geometryFunction = createRegularPolygon(7, 10);
            break;
          case "fan":
              //扇形代码
            break;
          case "Star":
              //五角星
            break;
          case "Box": 
              //长方形
           
            break;
        }
   
        let draw = new Draw({
          source,
          type: value == "freehand" ? "Polygon" : value,
          geometryFunction: geometryFunction,
          maxPoints,
          freehand: value == "freehand" ? true : false,
        });
        this.draw = draw;
        map.addInteraction(draw);
      } else {
        source = null;
        vector.setSource(source);
      }
    },

扇形点位算法

30°0.5°获取一个点位

    value = "Circle";
    geometryFunction = function (coordinates, geometry) {
      const center = coordinates[0];
      const last = coordinates[coordinates.length - 1];
      const dx = last[0] - center[0];
      const dy = last[1] - center[1];
      const radius = Math.sqrt(dx * dx + dy * dy);
      const rotation = Math.atan2(dy, dx);
      const newCoordinates = [center];
      for (let i = 0; i < 60; ++i) {  //
        const angle = rotation - i * (Math.PI / 360);
        const offsetX = radius * Math.cos(angle);
        const offsetY = radius * Math.sin(angle);
        newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
      }
      newCoordinates.push(center);
      if (!geometry) {
        geometry = new Polygon([newCoordinates]);
      } else {
        geometry.setCoordinates([newCoordinates]);
      }
      return geometry;
    };

五角星点位算法

value = "Circle";
geometryFunction = function (coordinates, geometry) {
  const center = coordinates[0];
  const last = coordinates[coordinates.length - 1];
  const dx = center[0] - last[0];
  const dy = center[1] - last[1];
  const radius = Math.sqrt(dx * dx + dy * dy);
  const rotation = Math.atan2(dy, dx);
  const newCoordinates = [];
  const numPoints = 12;
  for (let i = 0; i < numPoints; ++i) {
    const angle = rotation + (i * 2 * Math.PI) / numPoints;
    const fraction = i % 2 === 0 ? 1 : 0.5;
    const offsetX = radius * fraction * Math.cos(angle);
    const offsetY = radius * fraction * Math.sin(angle);
    newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
  }
  newCoordinates.push(newCoordinates[0].slice());
  if (!geometry) {
    geometry = new Polygon([newCoordinates]);
  } else {
    geometry.setCoordinates([newCoordinates]);
  }
  return geometry;
};

长方形点位算法

    value = "LineString";
    maxPoints = 2;
    geometryFunction = function (coordinate, geometry) {
      let start = coordinate[0],
        end = coordinate[1];
      if (!geometry) {
        geometry = new Polygon([
          [start, [start[0], end[1]], end, [end[0], start[1]], start],
        ]);
      }
      geometry.setCoordinates([
        [start, [start[0], end[1]], end, [end[0], start[1]], start],
      ]);

      return geometry;
    };