MAPZONE GIS SDK接入Openlayers3之五——圖形編輯工具


圖形編輯工具提供對要素圖形進行增、刪、改的功能,具體包括以下幾種工具類型:

  • 瀏覽工具
  • 選擇工具
  • 創建要素工具
  • 刪除命令
  • 分割工具
  • 合並命令
  • 節點編輯工具
  • 修邊工具
  • 撤銷命令
  • 重做命令

工具的實現基本上是基於ol.interation來實現的,只不過做了組合、結果處理等實現。分割工具效果圖如下:

實現思路:

1.通過工具管理器進行工具間切換等統一調度

2.每個工具通過SetActive方法實現該工具的啟動、卸載邏輯

3.每個工具維護自己的光標狀態、輔助工具欄和交互處理邏輯

線分割示例代碼:

'use strict';
var mzToolType = require('./mzToolEnum');
var ToolManager = require('./mzToolManager.js');
var mzFormat = require('./../Format');
var mzSpatialanylize = require('./../../MAPZONE JavaScript SDK/mzGeometry/mzSpatialanylize.js');
var mzOperationGroup = require('./../mzUndoRedo/mzOperationGroup.js');
var mzSelectManager = require('./mzSelectManager.js');

module.exports = mzSplitTool;

function mzSplitTool(opt_options) {
    var options = opt_options || {};
    if (undefined == options.map)
        return;
    this.type = mzToolType.mzToolType.MZ_SPLIT_TOOL;
    this.name = options.name !== undefined ? options.name : '線分割';
    this.interaction = new ol.interaction.Draw({
        type: 'LineString'
    });

    options.map.addInteraction(this.interaction);
    this.interaction.setActive(false);

    //初始化輔助工具欄
    this.mainbar = new ol.control.Bar();
    this.initAssistantToolbar();
    this.active = false;
}

mzSplitTool.prototype.drawendfuntion = function (e) {
    var manager = ToolManager.getToolManager();
    var selectTool = manager.getTool('選擇');

    var lineString = e.feature.getGeometry();

    var SelectManager = mzSelectManager.getSelectManager();
    var fts = SelectManager.getSelectFs();
    if (fts.length < 1) {
        Materialize.toast("請至少選擇一個要素!", 2000);
        return;
    }
    var undoredoManager = selectTool.interaction.map_.undoredoManager;
    undoredoManager.beginTrans(new mzOperationGroup());

    for (var i = 0; i < fts.length; i++) {
        var source = fts[i].vector;
        var nSrid = source.getSrid();

        var polygon = mzFormat.olGeo2mzGeo(fts[i].feature.getGeometry());
        polygon.setSRID(nSrid);

        var path = mzFormat.olGeo2mzGeo(lineString);
        path.setSRID(nSrid);

        var tolarence = polygon.getTolerance();
        var geoSet = mzSpatialanylize.cut(polygon, path, tolarence);
        var nCount = geoSet.getGeometryCount();

        for (var j = 0; j < nCount; j++) {
            var geo = geoSet.getGeometry(j);
            if (0 == j) {
                source.updateGeometry(fts[i].feature, mzFormat.mzGeo2olGeo(geo), undoredoManager);
            }
            else {
                var feature = new ol.Feature();
                feature.setId(-1);
                feature.setProperties(fts[i].feature.getProperties());
                feature.setGeometry(mzFormat.mzGeo2olGeo(geo));
                source.addFeature(feature, undoredoManager);
            }
        }
    }
    undoredoManager.endTrans();

    selectTool.clear();

    selectTool.interaction.map_.customRefresh();
}

mzSplitTool.prototype.setActive = function (active) {

    if (active == this.active)
        return;
    if (undefined == this.interaction)
        return;
    var manager = ToolManager.getToolManager();
    var selectTool = manager.getTool('選擇');

    var SelectManager = mzSelectManager.getSelectManager();
    var fts = SelectManager.getSelectFs();

    if (fts.length < 1 && active) {
        Materialize.toast("請至少選擇一個要素!", 2000);
        active = false;
    }

    if (active) {
        manager.unLoadTool({
            tool: this
        });
        this.setCursor();
    }
    this.interaction.setActive(active);
    if (active) {
        this.interaction.on('drawend', this.drawendfuntion, this);

        //加載輔助工具欄
        this.interaction.map_.addControl(this.mainbar);
    }
    else {
        this.interaction.un('drawend', this.drawendfuntion, this);

        //卸載輔助工具欄
        this.interaction.map_.removeControl(this.mainbar);

    }

    this.active = active;
}

mzSplitTool.prototype.getActive = function () {
    return this.active;
}

mzSplitTool.prototype.setCursor = function (opt_options) {
    var options = opt_options || {};
    var cursor = options.cursor;
    document.getElementById("map").style.cursor = cursor == undefined ? "crosshair" : cursor;
}

mzSplitTool.prototype.initAssistantToolbar = function () {

    // Edit control bar
    var editbar = new ol.control.Bar(
        {
            toggleOne: true,    // one control active at the same time
            group: false            // group controls together
        });
    this.mainbar.addControl(editbar);

    //完成線分割
    var finishDrawing = new ol.control.TextButton(
        {
            html: '<i class="fa fa-check"></i>',
            title: "完成",
            handleClick: function () {
                var ToolManager = require('../../mapzone-ol3-plugin/mzTool/mzToolManager.js');
                var manager = ToolManager.getToolManager(this.map_);
                manager.getTool('線分割').interaction.finishDrawing();
            }
        });

    editbar.addControl(finishDrawing);

    //取消線分割
    var cancleDrawing = new ol.control.TextButton(
        {
            html: '<i class="fa fa-times"></i>',
            title: "取消",
            handleClick: function () {
                var ToolManager = require('../../mapzone-ol3-plugin/mzTool/mzToolManager.js');
                var manager = ToolManager.getToolManager(this.map_);
                manager.getTool('線分割').interaction.abortDrawing_();
            }
        });

    editbar.addControl(cancleDrawing);
}

撤銷重做實現邏輯:

1)將撤銷重做內容抽象成原子操作,可以執行do、undo、redo方法

2)實現撤銷重做管理器,根據需要將原子操作執行入棧、出棧等邏輯

3)為數據庫的增、刪、改實現撤銷重做原子操作,例如增的do和redo實現就是將Feature保存到數據庫中,undo是將該Feature從數據庫中刪除

4)實現撤銷重做原子操作組,像分割這樣執行多次數據庫增刪改的工具,可以一次撤銷、一次重做


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM