zoukankan      html  css  js  c++  java
  • 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)实现撤销重做原子操作组,像分割这样执行多次数据库增删改的工具,可以一次撤销、一次重做

  • 相关阅读:
    Plahte
    Sound 静音问题
    【模板】线段树 2
    winform GDI基础(四)简单截屏
    winform GDI基础(二)画带圆角的矩形框
    winform GDI基础(三)实现画笔
    winform GDI基础(一)
    winform播放视频(windows media player)
    c# 锁的使用
    C#Task学习
  • 原文地址:https://www.cnblogs.com/conorpai/p/6497478.html
Copyright © 2011-2022 走看看