ITS信号控制系统渠化图自动生成

最近公司在做一套城市交通信号控制系统的产品,由于渠化图生成都是单独采用图片作为底图,实现方式不太直观。公司主要的理念就是可视化,将数据变成可视化的元素展现出来,并和地图结合展现信号灯的相位状态。

实现思路:

(1)采用技术为SVG (可缩放矢量图形),为什么采用svg,主要考虑了浏览器的支持方面

浏览器支持
Internet Explorer 9、Firefox、Opera、Chrome 以及 Safari 支持内联 SVG。Internet Explorer 8或更早版本,可通过安装Adobe SVG Viewer以支持SVG。

进一步的信息可参考百度百科SVG介绍

(2)采用dojo进行了封装,由于地图展现采用了arcgis js api , 依赖于dojo,索性就采用dojo对象封装

 关于dojo,可参考dojo官方文档

(3)地图坐标联动,通过地图的缩放,实现与地图的联动,并在不同的Zoom level下,渠化图相应的进行适当的缩放。 

map.on("extent-change" , function(p1 , p2 , p3 , p4 ){
			sigs.rePosition() ; 
});


dojo封装实现:

define(["dojo/_base/declare" ,"dojo/dom" , "esri/geometry/Point" , "dojox/timing/_base" ,"dojo/dom-construct","dojo/dom-style" ,"dojox/gfx","dojox/gfx/move","dojox/gfx/fx" ],
  function(declare ,dom, Point ,  timer , domConstruct , domStyle){


	var timer = new timer.Timer();

	var surface = null;
	var surface_size = null ;


	var circle1 , circle2 , circle3 , circle4 ; 
	var selected_circle = null ; 

	var global1 = null ;
	var global2  = null ;
	var global3 = null ;
	var global4 = null ;
	var global5 = null ;
	//var global6 = null ;
	//var global7 = null ;
	var global8 = null ;

	var maxTime = 20 ; 
	var maxStage = 4 ; 

	var _me ; 

	var _road1 ; 
	var _road2 ; 
	var _gismap = null ; 

	return declare(null, {

		constructor: function(gismap ,  divid , road1 , road2 , lng , lat  ) {

			this._divid  = divid ;
			this._lat = lat ; 
			this._lng = lng ; 
			_me = this ; 
			_road1 = road1 ; 
			_road2 = road2 ; 
			_gismap = gismap ; 


			var ptCenter = new Point({ "x": this._lng, "y": this._lat, "spatialReference": { "wkid": 4326} }) ;
			var screenPoint = _gismap.toScreen(ptCenter) ; 

			domConstruct.create(
				"div",
				{
					style:
					{
				        "background-color": "gray",
				        "width" :"0px" ,
						"height":"0px" , 
				        "position": "absolute",
						"filter":"alpha(Opacity=80)",
						"-moz-opacity":"0.8",
						"opacity": "0.8",
						"z-index":"100",
				        "left": ( screenPoint.x - 150) +"px",
				        "top": ( screenPoint.y - 150) + "px",
				        "z-index": "40",
						"pointer-events": "none"
					} , 
					"id" : this._divid
				},
				dojo.body()
			);
		},
		/*     500*500为基础范围    */
		makeRoads : function(p)
		{
			var pathstr1 = "M100 200 200 200 200 100";		
			var groad = p.createGroup();
			/*roads*/
			groad
			.createPath(pathstr1)
			.setStroke({color: "white"})
			
			groad.createPath(pathstr1)
			.setStroke({color: "white"}).
			applyTransform([dojox.gfx.matrix.translate(100,0) ,  dojox.gfx.matrix.rotategAt(90, 200 , 200)]); 	
			
			groad.createPath(pathstr1)
			.setStroke({color: "white"}).
			applyTransform([ dojox.gfx.matrix.rotategAt(180, 250 , 250)]); 	
			
			groad.createPath(pathstr1)
			.setStroke({color: "white"}).
			applyTransform([dojox.gfx.matrix.translate(0,100) ,  dojox.gfx.matrix.rotategAt(-90, 200 , 200)]); 	
			
			groad.createPath("M100 200 200 200 200 100 300 100 300 200 400 200 400 300 300 300 300 400 200 400 200 300 100 300z")
				.setFill("#8a9599") ; 
			
			groad.createText({ x: 250, y: 258, text: "20", align: "middle"  })
			.setFont({ family: "Arial", size: "16pt", weight: "thin" }) //set font
			.setFill("green");		
			
			return groad ;	
		},


		setTimedText : function(groad , txt)
		{
			groad.children[5].setShape({text:txt}) ; 
		},

		makeArrows : function(p)
		{
			var garrow = p.createGroup() ; 
			
			var g1 = garrow.createGroup() ; 	
			g1.createPath("M120 257 130 257 130.0 254.5 135 258 130 261.5 130 259 120 259z")
				.setFill("white")	
			g1.createPath("M120 273 130 273 130.0 271.5 135 274 130 277.5 130 275 120 275z")
				.setFill("white")	
			g1.createPath("M120 289 130 289 130.0 287.5 135 290 130 293.5 130 291 120 291z")
				.setFill("white")			
			
			
			
			var g2 = garrow.createGroup() ; 	
			g2.createPath("M120 257 130 257 130.0 254.5 135 258 130 261.5 130 259 120 259z")
				.setFill("white")	
			g2.createPath("M120 273 130 273 130.0 271.5 135 274 130 277.5 130 275 120 275z")
				.setFill("white")	
			g2.createPath("M120 289 130 289 130.0 287.5 135 290 130 293.5 130 291 120 291z")
				.setFill("white")			
			g2.applyTransform([dojox.gfx.matrix.rotategAt(90, 250 , 250)]);
			
			var g3 = garrow.createGroup() ; 	
			g3.createPath("M120 257 130 257 130.0 254.5 135 258 130 261.5 130 259 120 259z")
				.setFill("white")	
			g3.createPath("M120 273 130 273 130.0 271.5 135 274 130 277.5 130 275 120 275z")
				.setFill("white")	
			g3.createPath("M120 289 130 289 130.0 287.5 135 290 130 293.5 130 291 120 291z")
				.setFill("white")			
			g3.applyTransform([dojox.gfx.matrix.rotategAt(180, 250 , 250)]);
			
			var g4 = garrow.createGroup() ; 	
			g4.createPath("M120 257 130 257 130.0 254.5 135 258 130 261.5 130 259 120 259z")
				.setFill("white")	
			g4.createPath("M120 273 130 273 130.0 271.5 135 274 130 277.5 130 275 120 275z")
				.setFill("white")	
			g4.createPath("M120 289 130 289 130.0 287.5 135 290 130 293.5 130 291 120 291z")
				.setFill("white")			
			g4.applyTransform([dojox.gfx.matrix.rotategAt(270, 250 , 250)]);
			
			
			return garrow ; 
		},

		makeChannels : function(p) {
			
			/*make channel */
			/*
			 * {
				style: "Dash", width: 3, cap: "butt", color: "#00f"
			 * */
			
			var gchannel = p.createGroup() ; 
			
			gchannel
				.createLine({x1: 250, y1: 100, x2: 250, y2: 200})
				.setStroke({style: "Dash", width: 2, cap: "butt", color: "#fff"}) ; 
			
			gchannel
				.createLine({x1: 250, y1: 300, x2: 250, y2: 400})
				.setStroke({style: "Dash", width: 2, cap: "butt", color: "#fff"}) ; 
			
			
			gchannel
				.createLine({x1: 100, y1: 250, x2: 200, y2: 250})
				.setStroke({style: "Dash", width: 2, cap: "butt", color: "#fff"}) ; 
			
			gchannel
				.createLine({x1: 300, y1: 250, x2: 400, y2: 250})
				.setStroke({style: "Dash", width: 2, cap: "butt", color: "#fff"}) ; 	
			
			gchannel.createText({ x: 320, y: 180, text: _road1, align: "start" })
				.setFont({ family: "SimSun", size: "10pt", weight: "thin" }) //set font
				.setFill("red")
				.applyTransform([dojox.gfx.matrix.rotategAt(-90, 320 , 180)]);
			
			gchannel.createText({ x: 350, y: 320, text: _road2, align: "start" })
				.setFont({ family: "SimSun", size: "10pt", weight: "thin" }) //set font
				.setFill("red");
			
			
			
			
			gchannel.createImage({x:0 , y:0,width: 135, height: 66, src: "images/che2.png"})
				.applyTransform([dojox.gfx.matrix.translate(140 , 285) , dojox.gfx.matrix.scaleAt(0.2, 0 , 0)]);
			
			return gchannel ;
			
			
		},

		makeChedaos : function(p) {

			
			var gChedao = p.createGroup() ; 

			for( var i = 1 ; i < 3 ; i ++ )
			{
				gChedao
					.createLine({x1: 100, y1: 250+16.67*i, x2: 180, y2: 250+16.67*i})
					.setStroke({style: "Dash", width: 1, cap: "butt", color: "#fff"}) ; 
				
				
				gChedao
				.createLine({x1: 320, y1: 200+16.67*i, x2: 400, y2: 200+16.67*i})
				.setStroke({style: "Dash", width: 1, cap: "butt", color: "#fff"}) ; 
				
				
				gChedao
				.createLine({x1: 200+16.67*i, y1:100 , x2: 200+16.67*i, y2:180 })
				.setStroke({style: "Dash", width: 1, cap: "butt", color: "#fff"}) ; 
			
			
				gChedao
				.createLine({x1: 250+16.67*i, y1:320 , x2: 250+16.67*i, y2:400 })
				.setStroke({style: "Dash", width: 1, cap: "butt", color: "#fff"}) ; 
			}
			
			/*绘制人行道*/
			for(var i = 0 ; i < 20 ; i ++ )
			{
				gChedao.createRect({x:180  , y:200 + i*5 , width : 20 , height :2.5})
					.setFill("white"); 		
				
				gChedao.createRect({x:300  , y:200 + i*5 , width : 20 , height :2.5})
					.setFill("white"); 		
				
				gChedao.createRect({x:200+i*5  , y:180 , width : 2.5 , height :20})
					.setFill("white"); 		
				
				gChedao.createRect({x:200+i*5  , y:300 , width : 2.5 , height :20})
					.setFill("white"); 		
			}
			
			return gChedao ;
			/*draw 车道*/			
		},


	

		createCircleGroupV : function(p ,x1,y1,r , str)
		{
			var group = p.createGroup() ; 	
			group.createCircle({cx: x1, cy: y1, r: r}).setStroke("white").setFill("red");
			group.createCircle({cx: x1, cy: y1 + 2.5*r, r: r}).setStroke("white").setFill("transparent");
			group.createCircle({cx: x1, cy: y1 + 5*r, r: r}).setStroke("white").setFill("transparent");
			
			group.createText({ x: x1, y: y1-r, text: str, align:"middle"}).setFill("white")
				.setFont({ family: "SimSun", size: "6pt", weight: "thin" });
			return group ; 
		},

		createCircleGroupH :  function(p , x1,y1,r ,str)
		{
			var group = p.createGroup() ; 	
			group.createCircle({cx: x1, cy: y1, r: r}).setStroke("white").setFill("transparent");
			group.createCircle({cx: x1+ 2.5*r, cy: y1 , r: r}).setStroke("white").setFill("transparent");
			group.createCircle({cx: x1+ 5*r, cy: y1 , r: r}).setStroke("white").setFill("green");
			
			group.createText({ x: x1-2*r, y: y1, text: str, align:"middle"}).setFill("white")
				.setFont({ family: "SimSun", size: "3pt", weight: "thin" });
			
			return group ; 
		},


		createLightgroups : function(p)
		{
			var gg = p.createGroup() ; 	  	
			this.createCircleGroupV(gg,270 ,150 , 4 , "0") ; //1
			this.createCircleGroupV(gg,280 ,150 , 4 , "1") ; //2	
			this.createCircleGroupV(gg,220 ,330 , 4 , "2") ; //3
			this.createCircleGroupV(gg,230 ,330 , 4 , "3") ; //4	
			
			this.createCircleGroupH(gg,150 ,220 , 4 , "4") ; //5
			this.createCircleGroupH(gg,150 ,230 , 4 , "5") ; //6
			this.createCircleGroupH(gg,330 ,270 , 4 , "6");  //7
			this.createCircleGroupH(gg,330 ,280 , 4 , "7") ; //8
			return gg ; 
		},


		createNorthArrow  :  function(p , x1, y1 , rotated){
			var gg = p.createGroup() ; 	  	
			
			var npoints1 = [{x: x1, y:y1}, {x:x1, y: y1-50}, {x: x1-25, y: y1+50} , {x: x1, y:y1}];
			var npoints2 = [{x: x1, y:y1}, {x:x1, y: y1-50}, {x: x1+25, y: y1+50} , {x: x1, y:y1}];

			gg.createPolyline(npoints1)
				.setFill([255, 0, 0, 0.5]);
			
			gg.createPolyline(npoints2)
				.setFill([255, 255, 255, 0.5]);
			
			gg.applyTransform([dojox.gfx.matrix.rotategAt(rotated, x1 , y1)]); 	

			return gg ; 
		},



		createTestStage  : function(p ,  x1, y1 , r )
		{
			var group = p.createGroup() ; 	
			
			circle1 = group.createCircle({cx: x1, cy: y1, r: r}).setStroke("white").setFill("gray");
			group.createText({ x: x1, y: y1, text: "1", align:"middle"}).setFill("red")
				.setFont({ family: "SimSun", size: "16pt", weight: "thin" });
			
			circle2 =  group.createCircle({cx: x1+ 2.5*r, cy: y1 , r: r}).setStroke("white").setFill("gray");
			group.createText({ x: x1+ 2.5*r, y: y1, text: "2", align:"middle"}).setFill("red")
				.setFont({ family: "SimSun", size: "16pt", weight: "thin" });
			
			circle3 =  group.createCircle({cx: x1+ 5*r, cy: y1 , r: r}).setStroke("white").setFill("gray");
			group.createText({ x: x1+ 5*r, y: y1, text: "3", align:"middle"}).setFill("red")
				.setFont({ family: "SimSun", size: "16pt", weight: "thin" });
			
			circle4 =  group.createCircle({cx: x1+ 7.5*r, cy: y1 , r: r}).setStroke("white").setFill("green");
			group.createText({ x: x1+ 7.5*r, y: y1, text: "4" , align:"middle"}).setFill("red")
				.setFont({ family: "SimSun", size: "16pt", weight: "thin" });
			
			circle1.connect("onmousedown", this.onMouseDown);
			circle2.connect("onmousedown", this.onMouseDown);
			circle3.connect("onmousedown", this.onMouseDown);
			circle4.connect("onmousedown", this.onMouseDown);
			
			
			return group ; 
		},


		createDirArrow  : function(p , ew){ //ew 东西方向拐弯
			var group = p.createGroup() ; 	
			if( ew )
			{
				group.createPath("M220 250 C240 240 240 240 250 220")
				.setStroke("green"); 	
			
				group.createPath("M220 250 C240 240 240 240 250 220")
					.setStroke("green")
					.applyTransform([dojox.gfx.matrix.rotategAt(180, 250 , 250)]); 
			}
			else
			{
				group.createPath("M220 250 C240 240 240 240 250 220")
				.setStroke("green")
				.applyTransform([dojox.gfx.matrix.rotategAt(-90, 250 , 250)]); 	
			
				group.createPath("M220 250 C240 240 240 240 250 220")
					.setStroke("green")
					.applyTransform([dojox.gfx.matrix.rotategAt(90, 250 , 250)]); 	
			}
			return group ; 
		},


		resetAll : function()
		{
			for( var i = 0 ; i < 8 ; i++ )
			{
				global4.children[i].children[0].setFill("red") ;	
				global4.children[i].children[1].setFill("transparent") ;	
				global4.children[i].children[2].setFill("transparent") ;	
			}

		},

		setStage  :  function(stage)
		{
			this.resetAll();
			switch( stage )
			{
			case 1:     //南北直行
				global4.children[1].children[0].setFill("transparent") ;	
				global4.children[1].children[1].setFill("transparent") ;	
				global4.children[1].children[2].setFill("green") ;	
				
				global4.children[2].children[0].setFill("transparent") ;	
				global4.children[2].children[1].setFill("transparent") ;	
				global4.children[2].children[2].setFill("green") ;
				break;
			case 2:     //南北左拐
				global4.children[0].children[0].setFill("transparent") ;	
				global4.children[0].children[1].setFill("transparent") ;	
				global4.children[0].children[2].setFill("green") ;	
				
				global4.children[3].children[0].setFill("transparent") ;	
				global4.children[3].children[1].setFill("transparent") ;	
				global4.children[3].children[2].setFill("green") ;
				break;  
			case 3:     //东西直行
				global4.children[4].children[0].setFill("transparent") ;	
				global4.children[4].children[1].setFill("transparent") ;	
				global4.children[4].children[2].setFill("green") ;	
				
				global4.children[7].children[0].setFill("transparent") ;	
				global4.children[7].children[1].setFill("transparent") ;	
				global4.children[7].children[2].setFill("green") ;
				break;
			case 4:     //东西左拐
				global4.children[5].children[0].setFill("transparent") ;	
				global4.children[5].children[1].setFill("transparent") ;	
				global4.children[5].children[2].setFill("green") ;	
				
				global4.children[6].children[0].setFill("transparent") ;	
				global4.children[6].children[1].setFill("transparent") ;	
				global4.children[6].children[2].setFill("green") ;
				break;		
			}
		},



		onMouseDown  :  function(evt){
			

			if( evt.target == circle1.getEventSource() ){
				_me.setStage(1) ; 
			}
			if( evt.target == circle2.getEventSource() ){
				_me.setStage(2) ; 
			}

			if( evt.target == circle3.getEventSource() ){
				_me.setStage(3) ; 
			}
			if( evt.target == circle4.getEventSource() ){
				_me.setStage(4) ; 
			}
			
			dojo.stopEvent(evt);
		},

		advanceTime  :  function(){
			maxTime -- ; 
			_me.setTimedText(global1 , maxTime) ; 
			
			if( maxTime == 0  )
			{
				
				maxTime = 21 ; 
				_me.setStage( maxStage);
				maxStage--;
				if( maxStage== 0  )
				{
					maxStage = 4 ; 
				}
			}
		},

		rotate : function(angle)
		{
			global1.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
			global2.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250  )]);
			global3.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
			global4.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
			global5.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
			//global6.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
			//global7.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
			global8.applyTransform([dojox.gfx.matrix.rotategAt(angle , 250, 250 )]);
		},

		centerIt : function(zlevel){
			if( zlevel == 0 )
				return ; 
			var ptCenter = new Point({ "x": this._lng, "y": this._lat, "spatialReference": { "wkid": 4326} }) ;
			_gismap.centerAndZoom(ptCenter, zlevel);
		},

		rePosition : function() {
			var ptCenter = new Point({ "x": this._lng, "y": this._lat, "spatialReference": { "wkid": 4326} }) ;
			var screenPoint = _gismap.toScreen(ptCenter) ; 
			dojo.query("#"+this._divid).style( {left: ( screenPoint.x - 150) +"px"  , top:( screenPoint.y - 150) + "px"} ) ; 
		},

		zoom : function(zoomFactor)
		{
			global1.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
			global2.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
			global3.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
			global4.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
			global5.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
			//global6.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
			//global7.applyTransform([dojox.gfx.matrix.scaleAt(0.8, 250 , 250)]);
			global8.applyTransform([dojox.gfx.matrix.scaleAt(zoomFactor, 250 , 250)]);
		},

		init :function() {
			
			surface = dojox.gfx.createSurface(this._divid, 400, 400);
			surface_size = {width: 400, height: 400};			
			global1 = this.makeRoads(surface);
			global2 = this.makeChannels(surface);
			global3 = this.makeChedaos(surface);
			global4 = this.createLightgroups(surface);
			global5 = this.makeArrows(surface) ;
			
			//global6 = this.createTestStage(surface , 200, 450 , 20 ) ; 
			//global7 = this.createNorthArrow(surface , 300 , 180 , 20) ; 
			
			global8 = this.createDirArrow(surface,false) ;			

			global1.applyTransform([dojox.gfx.matrix.translate(-100 , -100 )]);
			global2.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);
			global3.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);
			global4.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);
			global5.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);
			//global6.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);
			//global7.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);
			global8.applyTransform([dojox.gfx.matrix.translate(-100 , -100)]);		
			
			timer.setInterval(1000);
			timer.onTick = this.advanceTime;
			timer.start();

			
		}
	}) ; 
});








html中使用demo:

sig = new SignalDraw(map , "div123" , "XX路" , "YY路" , 121.539 ,31.125 ) ; 
		sig.init();
		sig.zoom(0.8) ; 
		sig.rotate(-10) ; 


实现效果:








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值