A package based on openlayers v4.6.5

Package introduction

If openlayers 3 or above is used in the project, it is inevitable to operate the layer and complete some interaction. Then extract some common encapsulation logic. The encapsulation is based on Map object and initialization.

1. Some global definitions

In order to find the layer easily, when defining the layer, we add the "name" attribute to the layer as the primary key of the layer. Subsequent operations such as finding layers and filtering are based on this definition.

	//Default style
	var defaultStyle = {
        'PointHidden': new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: '#00ff00'
                }),
                radius: 0,
                stroke: new ol.style.Stroke({
                    color: '#000',
                    width: 0
                })
            })
        }),
        'PointCurrent': new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: '#00ff00'
                }),
                radius: 5,
                stroke: new ol.style.Stroke({
                    color: '#000',
                    width: 1
                })
            }),
            zIndex: 10
        }),
        'LineString': new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: '#f00',
                width: 3
            })
        }),
        'DeviceStyle': new ol.style.Style({
            stroke: new ol.style.Stroke({
                width: 5,
                color: "#000099"
            })
        }),
        'TransStyleDefault': new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: '#ff0'
                }),
                radius: 10,
                stroke: new ol.style.Stroke({
                    color: '#fff',
                    width: 1
                })
            }),
            zIndex: 15
        }),
        'TransStyleActive': new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: '#f00'
                }),
                radius: 10,
                stroke: new ol.style.Stroke({
                    color: '#fff',
                    width: 1
                })
            }),
            zIndex: 15
        }),
        'AfterTransStyleDefault': new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: '#0ff'
                }),
                radius: 10,
                stroke: new ol.style.Stroke({
                    color: '#fff',
                    width: 1
                })
            }),
            zIndex: 15
        }),
        'AfterTransStyleActive': new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({
                    color: '#f00'
                }),
                radius: 10,
                stroke: new ol.style.Stroke({
                    color: '#fff',
                    width: 1
                })
            }),
            zIndex: 15
        }),
        'DefaultRoute': new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: '#999',
                lineCap: 'round',
                width: 10
            }),
            fill: new ol.style.Fill({
                color: '#fff'
            })
        }),
        'route': new ol.style.Style({
            stroke: new ol.style.Stroke({
                width: 1,
                color: '#A1601E'
            })
        }),
        'geoMarker': new ol.style.Style({
            image: new ol.style.Circle({
                radius: 1,
                snapToPixel: false,
                fill: new ol.style.Fill({
                    color: '#A1601E'
                }),
                stroke: new ol.style.Stroke({
                    color: '#A1601E',
                    width: 2
                })
            })
        })
    };
	/**
     *  Click event container
     */
    var ec = {}
    /**
     *
     * hover Event corresponding layer container
     */
    var slc = [],
        selectStyleFun = [];

    /**
     * Get the callback function of click coordinate
     */
    var coord_collback = void(0);
    //Is the mark taking coordinates
    var isCoord = false;
    var _selectStyleFun = function (fea) {
        return selectStyleFun[select.getLayer(fea).get("_name")](fea)
    }

2. Map initialization

It is a difficult problem to control the layer sequence of base map. Generally, the layer sequence is: base map, other slice layers, vector surface layer, vector line layer, vector point layer, highlight layer and temporary layer. In addition, we can also use occupied layer (empty layer) to ensure the correctness of layer order.

/**
     * Highlight layer
     * @type {ol.layer.Vector}
     */
    highLightLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
            wrapX: false
        })
    })
    /**
     * Temporary layer
     * @type {ol.layer.Vector}
     */
    tempLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
            wrapX: false
        })
    })

    map = new ol.Map({
        target: 'map',
        layers: [Base map, ... , highLightLayer, tempLayer],
        view: view
    });

3. Click private method definition

All the stand-alone logics go here and are managed in a unified way

/**
     * Private map click method
     *  Click on the element layer is preferred. Click on the slice layer when the element layer is not clicked
     * @param e
     * @private
     */
    var _mapClick = function (e) {
    	//If the time takes coordinate
        if (isCoord) {
            coord_collback(e);
            return true;
        } else {
            var param = this;
            //Get the elements and layers corresponding to the click position
            var hasFea = map.hasFeatureAtPixel(e.pixel, {
                layerFilter: function (layer) {
                    return !("RegionLayer" === layer.get("_name")); //Exclude vector slice layers from feature layers
                }
            });
            //Vector data first
            if (hasFea) { //First check if there is any
                map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
                    // When stopped, returns true
                    var _name = layer.get("_name");
                    var _res = Object.keys(ec).find(function (item) {
                        return item === _name;
                    })
                    if (_res) {
                        if (ec[_res].callback && typeof ec[_res].callback === 'function') {
                            //If there is a callback function, it must return true to stop;
                            return ec[_res].callback(feature)
                        }
                    }
                    return true;
                });
            } else {
                //Update current division
                
            }
        }
    }

4. Map event handling

/**
     *  Bind event to Map
     * @param layer Event corresponding layer
     * @param callback event callbacks 
     * @param thisObj Event parameter (this parameter can be passed to the event function as this)
     */
    map.bindClickEvent = function (layer, callback, thisObj) {
        if (thisObj) map.un("click", _mapClick, thisObj)
        ec[layer.get("_name")] = {
            callback: callback || void(0),
            thisObj: thisObj || {}
        }
    }

    /**
     * Dismiss an event
     * @param type
     * @param callback
     * @param thisObj
     */
    map.unBindEvent = function (type, callback, thisObj) {
        map.un(type, _mapClick, thisObj);
    }

5. Coordinate picking event

/**
     * Click event binding for getting coordinates
     * @param _callback
     */
    map.position = function (_callback) {
        if (_callback) {
            coord_collback = _callback || void(0)
            isCoord = true;
            map.on("click", _mapClick)
        } else {
            coord_collback = void(0)
            isCoord = false;
            map.un("click", _mapClick)
        }
    }

6. Vector data hover event

/**
     * Bind hover event
     */
    map.bindHoverEvent = function (lys, selStyles) {
        if (lys instanceof Array) {
            lys.forEach(function (item, index, array) {
                selectStyleFun[item.get("_name")] = selStyles[index]
                var isCnt = slc.some(function (a) {
                    return a.get("_name") === item.get("_name")
                })
                if (!isCnt) slc.push(item)
            })
        } else {
            selectStyleFun[lys.get("_name")] = selStyles
            var isCnt = slc.some(function (a) {
                return a.get("_name") === lys.get("_name")
            })
            if (!isCnt) slc.push(lys)
        }
        if (select) map.removeInteraction(select);
        select = new ol.interaction.Select({
            condition: ol.events.condition.pointerMove,
            layers: slc,
            style: _selectStyleFun,
            multi: false
        })
        map.addInteraction(select)
    }

7. Drawing interactive encapsulation

/**
     * Drawing encapsulation
     * @param geoType Draw object type ol.interaction.Draw.type
     * @param targetLayer Linkage layer, when the mouse is close to the elements of this layer, it will be absorbed
     * @param cb Callback function after drawing
     * @param pointUp Point object special callback
     * @param geometryFunction ol.interaction.Draw.geometryFunction
     */
    map.startDraw = function (geoType, targetLayer, cb, pointUp, geometryFunction) {
        if (draw) map.removeInteraction(draw);
        if (snap) map.removeInteraction(snap);
        if (targetLayer && (targetLayer.getType() === "VECTOR")) {
            snap = new ol.interaction.Snap({
                source: targetLayer.getSource()
            });
        }
        var darwParam = {
            source: tempLayer.getSource(),
            type: geoType,
        };
        if (geometryFunction) {
            darwParam.geometryFunction = geometryFunction;
        }
        draw = new ol.interaction.Draw(darwParam);

        //4.5.6 it can be used. Here, you can make more detailed drawing by pressing the mouse, popping up and other callbacks. You can't use compressed packages
        // draw.handleEvent = function (event) {
        //     this.freehand_ = this.mode_ !== ol.interaction.Draw.Mode_.POINT && this.freehandCondition_(event);
        //     var pass = true;
        //     if (this.freehand_ && event.type === ol.MapBrowserEventType.POINTERDRAG && this.sketchFeature_ !== null) {
        //         this.addToDrawing_(event);
        //         pass = false;
        //     } else if (this.freehand_ && event.type === ol.MapBrowserEventType.POINTERDOWN) {
        //         pass = false;
        //     } else if (event.type === ol.MapBrowserEventType.POINTERMOVE) {
        //         pass = this.handlePointerMove_(event);
        //     } else if (event.type === ol.MapBrowserEventType.DBLCLICK) {
        //         pass = false;
        //     } else if (event.type === ol.MapBrowserEventType.SINGLECLICK) {
        //         if ($.isFunction(pointUp)) pointUp(event);
        //     }
        //     return ol.interaction.Pointer.handleEvent.call(this, event) && pass;
        // };

        draw.on("drawend", function (evt) {
            if (geoType === "Point")
                if ($.isFunction(pointUp)) pointUp(evt)
            if ($.isFunction(cb)) cb(evt.feature)
        })

        if (draw) map.addInteraction(draw);
        if (snap) map.addInteraction(snap);
    }

    /**
     * End drawing
     * @param notClear If true, the features on the temporary layer are retained after the drawing is finished
     */
    map.endDraw = function (notClear) {
        if (draw) map.removeInteraction(draw);
        if (snap) map.removeInteraction(snap);
        if (tempLayer && !notClear) {
            tempLayer.getSource().clear();
        }
        ;
    }

8. Find layers

/**
     * Find layers
     * @param _name
     * @returns {VRLayer | undefined}
     */
    map.findLayer = function (_name) {
        return map.getLayers().getArray().find(function (lyr) {
            return _name === lyr.get("_name");
        })
    };

9. Clear temporary layer

/**
     * Clear features on temporary layers
     */
    map.cleanTempLayer = function () {
        tempLayer.getSource().clear();
    }

10. Highlight feature set

/**
     * Highlight feature set
     * @param features
     */
    map.flashFeatures = function (features) {
        highLightLayer.getSource().clear();
        features.forEach(function (fea) {
            if (fea.getGeometry()) {
                fea.setStyle((fea.getGeometry().getType() === "Point") ? defaultStyle.PointCurrent : defaultStyle.LineString);
                highLightLayer.getSource().addFeature(fea);
            }
        })

        var tmout = setTimeout(function () {
            highLightLayer.getSource().clear();
            tmout = null;
        }, 2000);
    }

11. Zoom to feature set

/**
     *  Zoom to
     * @param features Essential factor
     * @param zoom Zoom level
     * @param isFlash Zoom in
     */
    map.panToFeatures = function (features, zoom, isFlash) {
        if (!features) return;
        var geoms = [];
        features.forEach(function (fea) {
            if (fea && fea.getGeometry()) geoms.push(fea.getGeometry());
        })

        if (geoms.length == 1) {
            var center, extent, geom = geoms[0];
            if (geom.getType() === "Point")
                center = geom.getCoordinates().slice(0, 2);
            else if (geom.getType() === "LineString" || geom.getType() === "MultiLineString" ||
                geom.getType() === "Polygon" || geom.getType() === "MultiPolygon")
                extent = geom.getExtent();
            if (center) view.animate({
                zoom: zoom || view.getZoom()
            }, {
                center: center
            })
            if (extent) view.fit(extent, {
                padding: [20, 20, 20, 20]
            })
        } else if (geoms.length > 1) {
            view.fit(new ol.geom.GeometryCollection(geoms).getExtent(), {
                padding: [20, 20, 20, 20]
            })
        }

        if (isFlash) map.flashFeatures(features);
    }

12. Pop up in map

	map.popup = function (loc, html) {
        map.clearPopup();
        var popup = $('<div style="z-index:999999;" class="ol-popup"><a href="#" class="ol-popup-closer"></a><div class="popup-content">' + html + '</div></div>');
        overla = new ol.Overlay({
            position: loc,
            element: popup[0],
            offset: [0, -39],
            autoPan: false,
            autoPanAnimation: {
                duration: 250
            }
        })
        popup.find('.ol-popup-closer').on("click", function () {
            tempLayer.getSource().clear();
            popup.blur();
            overla.setPosition(null);
        })
        map.addOverlay(overla);
        return overla;
    }

    map.andPOIMarker = function (geom) {
        if (tempLayer) tempLayer.getSource().clear();
        var fea = new ol.Feature({
            geometry: geom
        });
        fea.setStyle(new ol.style.Style({
            image: new ol.style.Icon({
                anchor: [0.5, 1],
                src: '/dgp-graph/static/lib/images/marker.png'
            })
        }));
        tempLayer.getSource().addFeature(fea);
    }

13. Zoom to range

/**
     * Zoom to range
     *
     * @param extent
     */
    map.zoomToExtent = function (extent) {
        map.getView().setResolution(map.getView().getResolutionForExtent(extent));
        map.getView().fit(extent, {
            padding: [30, 20, 30, 20]
        });
    };

14. Unified management of map click events

/**
     * Last click event
     */
    map.on("click", _mapClick);
Published 7 original articles, won praise 9, visited 100000+
Private letter follow

Tags: Attribute

Posted on Thu, 05 Mar 2020 01:54:41 -0800 by ('('