OpenLayers动画效果显示路线
该类继承自Vector,加入层时不是一下子加入的,而是慢慢变长,动态的轨迹效果。这里借助了别人写的一个算法Point.js(附件)。已知地理位置两点,求第三点,其在第一点到第二点之间且距离第一点X米。见代码中的这个方法getPointOnLineByDistance。
trms.DynamicEffectLineVector = OpenLayers.Class(OpenLayers.Feature.Vector, { internal : 50, // 50ms speed : 50, // 50m/50ms, 1000m/s setVectorLayer : function(vectorLayer) { var components = this.geometry.components; this.geometry = new OpenLayers.Geometry.LineString(components[0], components[0]); vectorLayer.addFeatures([this]); var startPointIndex = 0; var startPoint = components[startPointIndex]; var stopPoint = components[startPointIndex + 1]; var currentPoint = components[startPointIndex]; var nextPoint; var t = this; var fn = function() { nextPoint = t.getNextPoint(currentPoint, stopPoint); t.geometry.addPoint(nextPoint); vectorLayer.drawFeature(t); currentPoint = nextPoint; if(currentPoint.equals(stopPoint)) { // is end point if(stopPoint.equals(components[components.length - 1])) { return; } startPoint = stopPoint; startPointIndex++; stopPoint = components[startPointIndex + 1]; } setTimeout(fn, t.internal); }; fn(); }, getNextPoint : function(currentPoint, stopPoint) { var nextPoint = this.getPointOnLineByDistance(currentPoint, stopPoint, this.speed); var x_current_stop = Math.abs(stopPoint.x - currentPoint.x); var x_current_next = Math.abs(nextPoint.x - currentPoint.x); var y_current_stop = Math.abs(stopPoint.y - currentPoint.y); var y_current_next = Math.abs(nextPoint.y - currentPoint.y); if(x_current_next > x_current_stop || y_current_next > y_current_stop) { return stopPoint; } return nextPoint; }, getPointOnLineByDistance : function(p1, p2, distance) { var ppp1 = new Point(p1.x, p1.y); var ppp2 = new Point(p2.x, p2.y); var bearing = ppp1.geoBearingTo(ppp2); var ppp3 = ppp1.geoWaypoint(distance / 1000, bearing); return new OpenLayers.Geometry.Point(ppp3.x, ppp3.y); } });
这下面的代码是一个完整的封装版本,包括状态管理、事件通知和样式等。下面用到的方法getBindToFn
请见我的这篇文章http://xiaying4415139-163-com.iteye.com/blog/430675
/** * support geom: MultiLineString */ trms.DynamicEffectLineVector = OpenLayers.Class(OpenLayers.Feature.Vector, { internal : 50, // 50ms speed : 5, // 5m/50ms, 100m/s vectorLayer : null, components : null, currentPointIndex : null, currentLineIndex : null, startPoint : null, stopPoint : null, currentTempPoint : null, timer : null, // event, fire when new point added pointAdded : null, // 'start', 'run', 'stop', 'end' dynamicState : 'start', // here state management orders : { start : { guardFn : function() { return this.dynamicState != 'start'; }, changeState : function() { this.dynamicState = 'run'; // start ---> run } }, stop : { guardFn : function() { return this.dynamicState != 'run'; }, changeState : function() { this.dynamicState = 'stop'; // run ---> stop } }, continueFn : { guardFn : function() { return this.dynamicState != 'stop'; }, changeState : function() { this.dynamicState = 'run'; // stop ---> run } }, restart : { guardFn : function() { return this.dynamicState == 'start'; }, changeState : function() { this.dynamicState = 'run'; // * except start ---> run } } }, initialize : function(geom, attributes) { if(geom instanceof OpenLayers.Geometry.LineString) { geom = new OpenLayers.Geometry.MultiLineString([geom]); } var style = this.getStyle(); style.label = attributes.name; style.strokeColor = attributes.color; style.fontColor = attributes.color; OpenLayers.Feature.Vector.prototype.initialize.apply(this, [geom, attributes, style]); this.components = this.geometry.components; this.initVariable(); }, // public setVectorLayer : function(vectorLayer) { this.vectorLayer = vectorLayer; }, // public executeOrder : function(order) { // start, stop, continueFn, restart var guardFn = this.orders[order].guardFn.getBindToFn(this); var changeState = this.orders[order].changeState.getBindToFn(this); if(guardFn()) return; this[order](); changeState(); }, /*-- private methods -------------------------------------------------------------------------------*/ initVariable : function() { this.currentPointIndex = 0; this.currentLineIndex = 0; this.startPoint = this.components[0].components[0]; this.stopPoint = this.components[0].components[1]; this.currentTempPoint = this.startPoint; }, start : function() { var line1 = new OpenLayers.Geometry.LineString(this.startPoint, this.startPoint); this.geometry = new OpenLayers.Geometry.MultiLineString([line1]); this.vectorLayer.addFeatures([this]); this.timeFn(); }, stop : function() { clearTimeout(this.timer); }, continueFn : function() { this.timeFn(); }, restart : function() { this.stop(); this.vectorLayer.removeFeatures([this]); this.initVariable(); this.start(); }, timeFn : function() { this.currentTempPoint = this.getNextPoint(this.currentTempPoint, this.stopPoint); this.geometry.components[this.currentLineIndex].addPoint(this.currentTempPoint); this.vectorLayer.drawFeature(this); if(this.currentTempPoint.equals(this.stopPoint)) { var currentLine = this.components[this.currentLineIndex]; // last point on current line if(this.currentTempPoint.equals(currentLine.components[currentLine.components.length - 1])) { // last line, end if(this.currentLineIndex == this.components.length - 1) { this.dynamicState = 'end'; return; } this.currentLineIndex++; this.currentPointIndex = 0; this.startPoint = this.components[this.currentLineIndex].components[0]; this.stopPoint = this.components[this.currentLineIndex].components[1]; this.currentTempPoint = this.startPoint; var newLine = new OpenLayers.Geometry.LineString(this.startPoint, this.startPoint); this.geometry.addComponent(newLine); } else { this.startPoint = this.stopPoint; this.currentPointIndex++; this.stopPoint = this.components[this.currentLineIndex].components[this.currentPointIndex + 1]; } } this.timer = setTimeout(this.timeFn.getBindToFn(this), this.internal); if(this.pointAdded) { this.pointAdded(this.currentTempPoint); // fire event } }, getNextPoint : function(currentTempPoint, stopPoint) { var nextPoint = this.getPointOnLineByDistance(currentTempPoint, stopPoint, this.speed); var x_current_stop = Math.abs(stopPoint.x - currentTempPoint.x); var x_current_next = Math.abs(nextPoint.x - currentTempPoint.x); var y_current_stop = Math.abs(stopPoint.y - currentTempPoint.y); var y_current_next = Math.abs(nextPoint.y - currentTempPoint.y); // deviation 0.000001 lonlat, about 0.01m var deviation = 1e-7; if(x_current_next - x_current_stop > deviation || y_current_next - y_current_stop > deviation) { return stopPoint; } return nextPoint; }, getPointOnLineByDistance : function(p1, p2, distance) { var ppp1 = new Point(p1.x, p1.y); var ppp2 = new Point(p2.x, p2.y); var bearing = ppp1.geoBearingTo(ppp2); var ppp3 = ppp1.geoWaypoint(distance / 1000, bearing); return new OpenLayers.Geometry.Point(ppp3.x, ppp3.y); }, getStyle : function() { var style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']); style.strokeWidth = 3; style.fontSize = '15px'; style.fontFamily = '楷体_GB2312'; style.fontWeight = 'bold'; style.labelAlign = 'rm'; return style; } }); trms.DynamicEffectLineVectorToolbar = Ext.extend(Ext.Toolbar, { dynamicVector : null, initComponent : function() { trms.DynamicEffectLineVectorToolbar.superclass.initComponent.call(this); var t = this; var btnStart = new Ext.Button({ text : '开始', handler : function() { t.dynamicVector.executeOrder('start'); } }); var btnStop = new Ext.Button({ text : '停止', handler : function() { t.dynamicVector.executeOrder('stop'); } }); var btnContinue = new Ext.Button({ text : '继续', handler : function() { t.dynamicVector.executeOrder('continueFn'); } }); var btnRestart = new Ext.Button({ text : '重新开始', handler : function() { t.dynamicVector.executeOrder('restart'); } }); var btnDestroy = new Ext.Button({ text : '清除', handler : function() { t.dynamicVector.destroy(); } }); this.add(btnStart); this.add(btnStop); this.add(btnContinue); this.add(btnRestart); this.add(btnDestroy); } });
转载自:https://blog.csdn.net/lanshan_84/article/details/83432524