Как я могу изменить размер / масштабировать полигон геойсона - PullRequest
0 голосов
/ 19 апреля 2019

В настоящее время я строю различные взаимодействия полигонов геойсона.Мой блокировщик строит этот алгоритм, который позволяет масштабировать размер многоугольника с помощью метода onMouseDown.

Он был построен с помощью 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;

Я хочууметь увеличивать координаты многоугольника с помощью методов onMouseDown / onMouseUp / onDrag.

Демо: https://codesandbox.io/s/54qv8x244n

1 Ответ

1 голос
/ 19 апреля 2019

Вот клон 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;

Я упаковал его как пакет npm, и теперь вы можете использовать его точно так же, как и плагин rotate:

npm i mapbox-gl-scale-mode

Посмотри здесь работает .

...