admin管理员组文章数量:1650776
概述:
在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('\n')}));
}
},
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/gisshixisheng
在线教程
http://edu.csdn/course/detail/799
Github
https://github/lzugis/
联系方式
q q:1004740957
e-mail:niujp08@qq
公众号:lzugis15
Q Q 群:452117357(webgis)
337469080(Android)
本文标签: VectorFeatureLayer
版权声明:本文标题:Openlayers2中vector扩展FeatureLayer 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1729532576a1204996.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论