• Openlayers2中vector扩展FeatureLayer


    概述:

    在Arcgis for js中,有一个图层FeatureLayer,能够很方便的实现点、线、面的高亮。FeatureLayer是GraphicsLayer图层的一个扩展,本文讲述如何在Openlayers中通过Vector的扩展实现FeatureLayer。


    思路:

    1、地图服务

    本示例应用的是Geoserver作为地图服务;

    2、数据来源

    Vector的数据通过WFS服务获取得到GeoJSON的数据;


    完成后效果:



    线


    实现代码:

    1、FeatureLayer

    OpenLayers.Layer.FeatureLayer = OpenLayers.Class(OpenLayers.Layer, {
        isBaseLayer: false,
        isFixed: false,
        features: null,
        filter: null,
        selectedFeatures: null,
        unrenderedFeatures: null,
        reportError: true, 
        style: null,
        styleMap: null,
        strategies: null,
        protocol: null,
        renderers: ['SVG', 'VML', 'Canvas'],
        renderer: null,
        rendererOptions: null,
        geometryType: null,
        drawn: false, 
        ratio: 1,
        highlayer:null,
        url:"",
        initialize: function(name, options) {
            var scope = this;
            OpenLayers.Layer.prototype.initialize.apply(scope, arguments);
            if (!scope.renderer || !scope.renderer.supported()) {  
                scope.assignRenderer();
            }
    
            // if no valid renderer found, display error
            if (!scope.renderer || !scope.renderer.supported()) {
                scope.renderer = null;
                scope.displayError();
            } 
    
            if (!scope.styleMap) {
                scope.styleMap = new OpenLayers.StyleMap();
            }
    
            scope.features = [];
            scope.selectedFeatures = [];
            scope.unrenderedFeatures = {};
            
            // Allow for custom layer behavior
            if(scope.strategies){
                for(var i=0, len=scope.strategies.length; i<len; i++) {
                    scope.strategies[i].setLayer(scope);
                }
            }       
            scope.url = options.url;
            
            var _url = scope.url+"?service=WFS&version=1.0.0&request=GetFeature&maxFeatures=50&outputFormat=application/json&typeName="+name;
            console.log(_url);
            var dataurl = "http://localhost:8081/lzugis/webAgent";
            $.get(dataurl,{"url":_url},function(result){
            	console.log(result);
    //          result = eval("("+result+")");
                var geojson_format = new OpenLayers.Format.GeoJSON();
                scope.addFeatures(geojson_format.read(result));
                scope.addSelectControl(map);
            });
        },
        addSelectControl:function(olmap){
            var scope = this;
            var select =  new OpenLayers.Control.SelectFeature(
                scope,
                {
                    clickout: true,
                    toggle: false,
                    multiple: false,
                    hover: true,
                    toggleKey: "ctrlKey", // ctrl key removes from selection
                    multipleKey: "shiftKey", // shift key adds to selection
                    box: false
                }
            );
            olmap.addControl(select);
            select.activate();
        },
        destroy: function() {
            if (this.strategies) {
                var strategy, i, len;
                for(i=0, len=this.strategies.length; i<len; i++) {
                    strategy = this.strategies[i];
                    if(strategy.autoDestroy) {
                        strategy.destroy();
                    }
                }
                this.strategies = null;
            }
            if (this.protocol) {
                if(this.protocol.autoDestroy) {
                    this.protocol.destroy();
                }
                this.protocol = null;
            }
            this.destroyFeatures();
            this.features = null;
            this.selectedFeatures = null;
            this.unrenderedFeatures = null;
            if (this.renderer) {
                this.renderer.destroy();
            }
            this.renderer = null;
            this.geometryType = null;
            this.drawn = null;
            OpenLayers.Layer.prototype.destroy.apply(this, arguments);  
        },
        clone: function (obj) {
            
            if (obj == null) {
                obj = new OpenLayers.Layer.Vector(this.name, this.getOptions());
            }
    
            //get all additions from superclasses
            obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
    
            // copy/set any non-init, non-simple values here
            var features = this.features;
            var len = features.length;
            var clonedFeatures = new Array(len);
            for(var i=0; i<len; ++i) {
                clonedFeatures[i] = features[i].clone();
            }
            obj.features = clonedFeatures;
    
            return obj;
        },    
        refresh: function(obj) {
            if(this.calculateInRange() && this.visibility) {
                this.events.triggerEvent("refresh", obj);
            }
        },  
        assignRenderer: function()  {
            for (var i=0, len=this.renderers.length; i<len; i++) {
                var rendererClass = this.renderers[i];
                var renderer = (typeof rendererClass == "function") ?
                    rendererClass :
                    OpenLayers.Renderer[rendererClass];
                if (renderer && renderer.prototype.supported()) {
                    this.renderer = new renderer(this.div, this.rendererOptions);
                    break;
                }  
            }  
        },
        displayError: function() {
            if (this.reportError) {
                OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported", 
                                         {renderers: this. renderers.join('
    ')}));
            }    
        },
        setMap: function(map) {        
            OpenLayers.Layer.prototype.setMap.apply(this, arguments);
    
            if (!this.renderer) {
                this.map.removeLayer(this);
            } else {
                this.renderer.map = this.map;
    
                var newSize = this.map.getSize();
                newSize.w = newSize.w * this.ratio;
                newSize.h = newSize.h * this.ratio;
                this.renderer.setSize(newSize);
            }
        },
        afterAdd: function() {
            if(this.strategies) {
                var strategy, i, len;
                for(i=0, len=this.strategies.length; i<len; i++) {
                    strategy = this.strategies[i];
                    if(strategy.autoActivate) {
                        strategy.activate();
                    }
                }
            }
        },
        removeMap: function(map) {
            this.drawn = false;
            if(this.strategies) {
                var strategy, i, len;
                for(i=0, len=this.strategies.length; i<len; i++) {
                    strategy = this.strategies[i];
                    if(strategy.autoActivate) {
                        strategy.deactivate();
                    }
                }
            }
        },
        onMapResize: function() {
            OpenLayers.Layer.prototype.onMapResize.apply(this, arguments);
            
            var newSize = this.map.getSize();
            newSize.w = newSize.w * this.ratio;
            newSize.h = newSize.h * this.ratio;
            this.renderer.setSize(newSize);
        },
        moveTo: function(bounds, zoomChanged, dragging) {
            OpenLayers.Layer.prototype.moveTo.apply(this, arguments);
            
            var coordSysUnchanged = true;
            if (!dragging) {
                this.renderer.root.style.visibility = 'hidden';
    
                var viewSize = this.map.getSize(),
                    viewWidth = viewSize.w,
                    viewHeight = viewSize.h,
                    offsetLeft = (viewWidth / 2 * this.ratio) - viewWidth / 2,
                    offsetTop = (viewHeight / 2 * this.ratio) - viewHeight / 2;
                offsetLeft += this.map.layerContainerOriginPx.x;
                offsetLeft = -Math.round(offsetLeft);
                offsetTop += this.map.layerContainerOriginPx.y;
                offsetTop = -Math.round(offsetTop);
    
                this.div.style.left = offsetLeft + 'px';
                this.div.style.top = offsetTop + 'px';
    
                var extent = this.map.getExtent().scale(this.ratio);
                coordSysUnchanged = this.renderer.setExtent(extent, zoomChanged);
    
                this.renderer.root.style.visibility = 'visible';
    
                // Force a reflow on gecko based browsers to prevent jump/flicker.
                // This seems to happen on only certain configurations; it was originally
                // noticed in FF 2.0 and Linux.
                if (OpenLayers.IS_GECKO === true) {
                    this.div.scrollLeft = this.div.scrollLeft;
                }
                
                if (!zoomChanged && coordSysUnchanged) {
                    for (var i in this.unrenderedFeatures) {
                        var feature = this.unrenderedFeatures[i];
                        this.drawFeature(feature);
                    }
                }
            }
            if (!this.drawn || zoomChanged || !coordSysUnchanged) {
                this.drawn = true;
                var feature;
                for(var i=0, len=this.features.length; i<len; i++) {
                    this.renderer.locked = (i !== (len - 1));
                    feature = this.features[i];
                    this.drawFeature(feature);
                }
            }    
        },
        display: function(display) {
            OpenLayers.Layer.prototype.display.apply(this, arguments);
            // we need to set the display style of the root in case it is attached
            // to a foreign layer
            var currentDisplay = this.div.style.display;
            if(currentDisplay != this.renderer.root.style.display) {
                this.renderer.root.style.display = currentDisplay;
            }
        },
        addFeatures: function(features, options) {
            if (!(OpenLayers.Util.isArray(features))) {
                features = [features];
            }
            
            var notify = !options || !options.silent;
            if(notify) {
                var event = {features: features};
                var ret = this.events.triggerEvent("beforefeaturesadded", event);
                if(ret === false) {
                    return;
                }
                features = event.features;
            }
            var featuresAdded = [];
            for (var i=0, len=features.length; i<len; i++) {
                if (i != (features.length - 1)) {
                    this.renderer.locked = true;
                } else {
                    this.renderer.locked = false;
                }    
                var feature = features[i];
                
                if (this.geometryType &&
                  !(feature.geometry instanceof this.geometryType)) {
                    throw new TypeError('addFeatures: component should be an ' +
                                        this.geometryType.prototype.CLASS_NAME);
                  }
                feature.layer = this;
    
                if (!feature.style && this.style) {
                    feature.style = OpenLayers.Util.extend({}, this.style);
                }
    
                if (notify) {
                    if(this.events.triggerEvent("beforefeatureadded",
                                                {feature: feature}) === false) {
                        continue;
                    }
                    this.preFeatureInsert(feature);
                }
    
                featuresAdded.push(feature);
                this.features.push(feature);
                this.drawFeature(feature);
                
                if (notify) {
                    this.events.triggerEvent("featureadded", {
                        feature: feature
                    });
                    this.onFeatureInsert(feature);
                }
            }
            
            if(notify) {
                this.events.triggerEvent("featuresadded", {features: featuresAdded});
            }
        },
        removeFeatures: function(features, options) {
            if(!features || features.length === 0) {
                return;
            }
            if (features === this.features) {
                return this.removeAllFeatures(options);
            }
            if (!(OpenLayers.Util.isArray(features))) {
                features = [features];
            }
            if (features === this.selectedFeatures) {
                features = features.slice();
            }
    
            var notify = !options || !options.silent;
            
            if (notify) {
                this.events.triggerEvent(
                    "beforefeaturesremoved", {features: features}
                );
            }
    
            for (var i = features.length - 1; i >= 0; i--) {
                if (i != 0 && features[i-1].geometry) {
                    this.renderer.locked = true;
                } else {
                    this.renderer.locked = false;
                }
        
                var feature = features[i];
                delete this.unrenderedFeatures[feature.id];
    
                if (notify) {
                    this.events.triggerEvent("beforefeatureremoved", {
                        feature: feature
                    });
                }
    
                this.features = OpenLayers.Util.removeItem(this.features, feature);
                // feature has no layer at this point
                feature.layer = null;
    
                if (feature.geometry) {
                    this.renderer.eraseFeatures(feature);
                }
                        
                //in the case that this feature is one of the selected features, 
                // remove it from that array as well.
                if (OpenLayers.Util.indexOf(this.selectedFeatures, feature) != -1){
                    OpenLayers.Util.removeItem(this.selectedFeatures, feature);
                }
    
                if (notify) {
                    this.events.triggerEvent("featureremoved", {
                        feature: feature
                    });
                }
            }
    
            if (notify) {
                this.events.triggerEvent("featuresremoved", {features: features});
            }
        },
        removeAllFeatures: function(options) {
            var notify = !options || !options.silent;
            var features = this.features;
            if (notify) {
                this.events.triggerEvent(
                    "beforefeaturesremoved", {features: features}
                );
            }
            var feature;
            for (var i = features.length-1; i >= 0; i--) {
                feature = features[i];
                if (notify) {
                    this.events.triggerEvent("beforefeatureremoved", {
                        feature: feature
                    });
                }
                feature.layer = null;
                if (notify) {
                    this.events.triggerEvent("featureremoved", {
                        feature: feature
                    });
                }
            }
            this.renderer.clear();
            this.features = [];
            this.unrenderedFeatures = {};
            this.selectedFeatures = [];
            if (notify) {
                this.events.triggerEvent("featuresremoved", {features: features});
            }
        },
        destroyFeatures: function(features, options) {
            var all = (features == undefined); // evaluates to true if
                                               // features is null
            if(all) {
                features = this.features;
            }
            if(features) {
                this.removeFeatures(features, options);
                for(var i=features.length-1; i>=0; i--) {
                    features[i].destroy();
                }
            }
        },
        drawFeature: function(feature, style) {
            // don't try to draw the feature with the renderer if the layer is not 
            // drawn itself
            if (!this.drawn) {
                return;
            }
            if (typeof style != "object") {
                if(!style && feature.state === OpenLayers.State.DELETE) {
                    style = "delete";
                }
                var renderIntent = style || feature.renderIntent;
                style = feature.style || this.style;
                if (!style) {
                    style = this.styleMap.createSymbolizer(feature, renderIntent);
                }
            }
            
            var drawn = this.renderer.drawFeature(feature, style);
            //TODO remove the check for null when we get rid of Renderer.SVG
            if (drawn === false || drawn === null) {
                this.unrenderedFeatures[feature.id] = feature;
            } else {
                delete this.unrenderedFeatures[feature.id];
            }
        },
        eraseFeatures: function(features) {
            this.renderer.eraseFeatures(features);
        },
        getFeatureFromEvent: function(evt) {
            if (!this.renderer) {
                throw new Error('getFeatureFromEvent called on layer with no ' +
                                'renderer. This usually means you destroyed a ' +
                                'layer, but not some handler which is associated ' +
                                'with it.');
            }
            var feature = null;
            var featureId = this.renderer.getFeatureIdFromEvent(evt);
            if (featureId) {
                if (typeof featureId === "string") {
                    feature = this.getFeatureById(featureId);
                } else {
                    feature = featureId;
                }
            }
            return feature;
        },
        getFeatureBy: function(property, value) {
            //TBD - would it be more efficient to use a hash for this.features?
            var feature = null;
            for(var i=0, len=this.features.length; i<len; ++i) {
                if(this.features[i][property] == value) {
                    feature = this.features[i];
                    break;
                }
            }
            return feature;
        },
        getFeatureById: function(featureId) {
            return this.getFeatureBy('id', featureId);
        },
        getFeatureByFid: function(featureFid) {
            return this.getFeatureBy('fid', featureFid);
        },
        getFeaturesByAttribute: function(attrName, attrValue) {
            var i,
                feature,    
                len = this.features.length,
                foundFeatures = [];
            for(i = 0; i < len; i++) {            
                feature = this.features[i];
                if(feature && feature.attributes) {
                    if (feature.attributes[attrName] === attrValue) {
                        foundFeatures.push(feature);
                    }
                }
            }
            return foundFeatures;
        },
        onFeatureInsert: function(feature) {
        },
        preFeatureInsert: function(feature) {
        },
        getDataExtent: function () {
            var maxExtent = null;
            var features = this.features;
            if(features && (features.length > 0)) {
                var geometry = null;
                for(var i=0, len=features.length; i<len; i++) {
                    geometry = features[i].geometry;
                    if (geometry) {
                        if (maxExtent === null) {
                            maxExtent = new OpenLayers.Bounds();
                        }
                        maxExtent.extend(geometry.getBounds());
                    }
                }
            }
            return maxExtent;
        },
        CLASS_NAME: "OpenLayers.Layer.FeatureLayer"
    });
    2、前台调用

    vector_layer = new OpenLayers.Layer.FeatureLayer("province",{
                    	url:"http://localhost:8088/geoserver/lzugis/ows"
                    });
                    map.addLayer(vector_layer);


    传播GIS知识 | 交流GIS经验 | 分享GIS价值 | 专注GIS发展

    技术博客

    http://blog.csdn.net/gisshixisheng

    在线教程

    http://edu.csdn.net/course/detail/799
    Github

    https://github.com/lzugis/

    联系方式

    q       q:1004740957

    e-mail:niujp08@qq.com

    公众号:lzugis15

    Q Q 群:452117357(webgis)
                 337469080(Android)



  • 相关阅读:
    C,LINUX,数据结构部分
    LINUX应用开发工程师职位(含答案)
    INT32 System_UserKeyFilter(NVTEVT evt, UINT32 paramNum, UINT32 *paramArray)
    屏幕调试
    1.ARM嵌入式体系结构与接口技术(Cortex-A8版)
    NT9666X调试log
    DemoKit编译过程错误
    selenium 代理设置
    pandas 轮询dataframe
    Spring 定时任务
  • 原文地址:https://www.cnblogs.com/lzugis/p/6539770.html
Copyright © 2020-2023  润新知