简体   繁体   English

如何调整Geojson多边形的大小/缩放

[英]How could I resize/scale a geojson polygon

I'm currently building different geojson polygon interactions. 我目前正在建立不同的geojson多边形互动。 My blocker is building this algorithm that allows to scale the size of the polygon with onMouseDown method. 我的阻止程序正在构建此算法,该算法允许使用onMouseDown方法缩放多边形的大小。

It was built with vanilla.js and use npm for dependencies. 它是使用vanilla.js构建的,并使用npm进行依赖。

import distance from "@turf/distance";
import centroid from "@turf/centroid";
import transformScale from "@turf/transform-scale";
import EventEmitter from "events";
const emitter = new EventEmitter();

const ScaleMode = {
  scalestart(selectedFeature, originalCenter) {},
  scaling(selectedFeature, originalCenter, lastMouseDown) {},
  scaleend(selectedFeature) {},

  onSetup: function(opts) {
    var state = {};

    emitter.addListener(
      "scalestart",
      function() {
        this.scalestart(state.selectedFeature, state.originalCenter);
      }.bind(this)
    );
    emitter.addListener(
      "scaling",
      function() {
        this.scaling(
          state.selectedFeature,
          state.originalCenter,
          state.lastMouseDownLngLat
        );
      }.bind(this)
    );
    emitter.addListener(
      "scaleend",
      function() {
        this.scaleend(state.selectedFeature, state.lastMouseDownLngLat);
      }.bind(this)
    );

    state.selectedFeature = opts.selectedFeature || false;
    state.lastMouseDownLngLat = false;
    state.originalCenter = false;
    state.mode = "scale" || false;
    return state;
  },
  toDisplayFeatures(state, geojson, display) {
    display(geojson);
  },
  onMouseDown: (state, e) => {
    if (e.featureTarget) {
      // calculate the polygon center
      state.polyCenter = turf.centroid(e.featureTarget);
      const polyCoordinates = state.polyCenter.geometry.coordinates;
      const poly = turf.polygon(PolyData);
      console.log(poly);
      const scaledPoly = turf.transformScale(poly, 3);
      console.log(poly);

      // scaling
      state.scaledPoly = transformScale(poly, 3);

      // disable on drag map over the polygon
      e.target["dragPan"].disable();
    }
  }
};

export default ScaleMode;

I want to be able to increase the coordinates of the polygon using onMouseDown/onMouseUp/onDrag methods. 我希望能够使用onMouseDown / onMouseUp / onDrag方法增加多边形的坐标。

Demo: https://codesandbox.io/s/54qv8x244n 演示: https//codesandbox.io/s/54qv8x244n

Here's a clone of mapbox-gl-rotate-mode handling scaleTransform : 这是mapbox-gl-rotate-mode处理scaleTransform

const distance = require("@turf/distance").default;
const centroid = require("@turf/centroid").default;
const transformScale = require("@turf/transform-scale").default;
const EventEmitter = require("events");
const emitter = new EventEmitter();

var ScaleMode = {
  scalestart: function() {},
  scaling: function() {},
  scaleend: function() {},

  onSetup: function(opts) {
    var state = {};

    emitter.addListener(
      "scalestart",
      function() {
        this.scalestart(state.selectedFeature, state.originalCenter);
      }.bind(this)
    );
    emitter.addListener(
      "scaling",
      function() {
        this.scaling(
          state.selectedFeature,
          state.originalCenter,
          state.scaleFactor
        );
      }.bind(this)
    );
    emitter.addListener(
      "scaleend",
      function() {
        this.scaleend(state.selectedFeature, state.scaleFactor);
      }.bind(this)
    );

    state.selectedFeature = opts.selectedFeature || undefined;
    state.scaleFactor = 1;
    state.originalCenter = undefined;
    state.mode = "scale";
    return state;
  },

  onMouseDown: function(state, e) {
    if (e.featureTarget) {
      if (this._ctx.api.get(e.featureTarget.properties.id)) {
        e.target["dragPan"].disable();
        state.selectedFeature = this._ctx.api.get(
          e.featureTarget.properties.id
        );
        state.originalCenter = centroid(e.featureTarget);
        state.originalFeature = e.featureTarget;
        state.originalDistance = Math.max(
          distance(state.originalCenter, [e.lngLat.lng, e.lngLat.lat]),
          0.1
        );
        emitter.emit("scalestart");
      }
    }
    return state;
  },

  toDisplayFeatures: function(state, geojson, display) {
    display(geojson);
  },

  onDrag: function(state, e) {
    if (state.selectedFeature && state.mode) {
      if (state.mode === "scale") {
        switch (state.originalFeature.properties["meta:type"]) {
          case "Point":
            break;
          case "LineString":
          case "Polygon":
          case "MultiLineString":
          case "MultiPolygon":
            state.scaleFactor =
              distance(state.originalCenter, [e.lngLat.lng, e.lngLat.lat]) /
                state.originalDistance || 1;
            break;
          default:
            return;
        }
        emitter.emit("scaling");
        state.selectedFeature.geometry = transformScale(
          state.originalFeature,
          state.scaleFactor
        ).geometry;
        this._ctx.api.add(state.selectedFeature);
      }
    }
  },

  onMouseUp: function(state, e) {
    e.target["dragPan"].enable();
    emitter.emit("scaleend");
    state.selectedFeature = undefined;
    state.scaleFactor = undefined;
    state.originalCenter = undefined;
    state.originalDistance = undefined;
    return state;
  }
};

module.exports = ScaleMode;

I wrapped it up as a npm package and you can now use it exactly like the rotate plugin: 我将其包装为npm包,现在可以像旋转插件一样使用它了:

npm i mapbox-gl-scale-mode

See it working here . 看到它在这里工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM