		var Format_Common = 1;
		var Format_Common_Track = 2;
		var Format_Ozi_Point = 10;
		var Format_Mgn_Point = 20;
		var Format_Ozi_Track = 1001;
		var Format_Ozi_Track_Meter = 1002;
		var Format_Mgn_Track = 1101;
		

		function isPointFormat(format)
		{
			return format<1000;
		}
		function splitLineForName(line)
		{
			return line.split(/[\s,]/);
		}

		function containsChinese(string)
		{
			if(string==null)
				return false;
				
			for(var i=0;i<string.length;i++)
			{
				var code=string.charCodeAt(i);
				
				if(code>256)
					return true;
			}
			return false;
		}

		function containsAlpha(string)
		{
			if(string==null)
				return false;
			return string.match(/[a-zA-Z]/)!=null;
		}

		function containsNumber(string)
		{
			if(string==null)
				return false;
			return string.match(/[0-9]/)!=null;
		}
		
		function clearZeroPrefix(number)
		{
			if(g_isNull(number) || number=="")
				return "";
			for(var i=0;i<number.length;i++)
			{
				if(number.charAt(i)!=0)
					break;
			}
			if(i>0 && i<number.length)
				return number.substr(i,number.length-i);
			return number;
		}

		function extractChinese(segments)
		{
			var segment;
			
			for(var i=0;i<segments.length;i++)
			{
				segment=segments[i];
				if(containsChinese(segment))
					return segment;
			}
			
			return null;
		}

		function extractNonNumberPart(segments)
		{
			var segment;
			
			for(var i=0;i<segments.length;i++)
			{
				segment=segments[i];
				if(containsAlpha(segment))
				{
					if(segment.length>1)
						return segment;
				}
			}
			
			return null;
		}

		function extractFirstNumberPart(segments)
		{
			var segment;
			
			for(var i=0;i<segments.length;i++)
			{
				segment=segments[i];
				if(containsNumber(segment))
					return segment;
			}
			
			return null;
		}

		function extractName(line)
		{
			var segments=splitLineForName(line);
			
			var name=extractChinese(segments);
			if(name==null)
				name=extractNonNumberPart(segments);
				
			if(name==null)
				name=extractFirstNumberPart(segments);
			if(name!=null)
				name=g_trim(name);
			return name;
		}
		
		// throw away useless parts and return the number part of the coord
		function splictCoord(coordString)
		{
			return coordString.match(/[0-9]+/g);
		}

		function extractOziHeight(line)
		{
			var s;
			
			// first try three part
			s=line.match(/(?:,)[\s]*[-]*[0-9]{3,3}(?:.|,)/);
			if(s==null)
				s=line.match(/(?:,)[\s]*[-]*[0-9]{4,4}(?:.|,)/);
			if(s==null)
				s=line.match(/(?:,)[\s]*[-]*[0-9]{5,5}(?:.|,)/);

			// try two part
			if(s!=null)
			{
				var result=s[0];
				return result.replace(",","");
			}
			return null;
		}

		function extractOziCoordString(line)
		{
			var s;
			
			// first try three part
			s=line.match(/[0-9]{2,3}.[0-9]{5,8},/);
			// try two part
			if(s!=null)
				return s[0];
			return null;
		}
		
		function extractXCoordString(line)
		{
			var s;
			var type=0;
			
			line=line.toUpperCase();
			// first try three part
			s=line.match(/E[\s]*[0-9]{2,3}[^0-9][0-9]{1,2}[^0-9][0-9]{1,3}[^0-9]*/);
			if(s==null)
			{
				s=line.match(/E[\s]*[0-9]{2,3}[^0-9][0-9]{2,2}[^0-9][0-9]{2,2}.[0-9][^0-9]*/);
				type=1;
			}
			// try two part
			if(s!=null)
			{
				var result=s[0];
				if(result.charAt(0)=='E')
					result=result.substr(1,result.length-1);
				
				var coords=splictCoord(result);
				if(type==1)
				{
					// convert part xx.x second to normal xxx minute
					var val=(parseInt(clearZeroPrefix(coords[2]))+parseInt(clearZeroPrefix(coords[3]))/10.0)/60.0;
					coords[2]=parseInt(val*1000);
				}
				return coords;
			}
			return null;
		}

		function extractYCoordString(line)
		{
			var s;
			var type=0;
			
			line=line.toUpperCase();
			// first try three part
			s=line.match(/N[\s]*[0-9]{2,3}[^0-9][0-9]{1,2}[^0-9][0-9]{1,3}[^0-9]*/);
			if(s==null)
			{
				s=line.match(/N[\s]*[0-9]{2,3}[^0-9][0-9]{2,2}[^0-9][0-9]{2,2}.[0-9][^0-9]*/);
				type=1;
			}
			// try two part
			if(s!=null)
			{
				var result=s[0];
				if(result.charAt(0)=='N')
					result=result.substr(1,result.length-1);
				
				var coords=splictCoord(result);
				if(type==1)
				{
					// convert part xx.x second to normal xxx minute
					var val=(parseInt(clearZeroPrefix(coords[2]))+parseInt(clearZeroPrefix(coords[3]))/10.0)/60.0;
					coords[2]=parseInt(val*1000);
				}
				return coords;
			}
			return null;
		}
		
		function extractHeightString(line)
		{
			var s;
			var type=0;
			
			line=line.toUpperCase();
			// first try three part
			s=line.match(/[\s]*[0-9]{1,4}[\s]*M/);
		
			// try two part
			if(s!=null)
			{
				var result=s[0];
				var coords=splictCoord(result);
				if(coords!=null)
					return parseFloat(coords[0]);
			}
			return 0;
		}
		
		///////////////////////////////////////////////////////////
		// 	import methods
		function extractCommonPoint(line,routePoint)
		{
			var x, y , name;
			
			x = extractXCoordString(line);
			y = extractYCoordString(line);
			
			if(x==null || y==null )
				return false;
				
			name=extractName(line);		
		
			routePoint.annoText=name;
			
			routePoint.xDegree=parseInt(clearZeroPrefix(x[0]));
			routePoint.xMinute=parseInt(clearZeroPrefix(x[1]));
			routePoint.xSecond=parseInt(parseInt(clearZeroPrefix(x[2]))*0.06);
			routePoint.xMSecond=parseInt(parseInt(clearZeroPrefix(x[2]))*0.06-routePoint.xSecond);
			
			routePoint.yDegree=parseInt(clearZeroPrefix(y[0]));
			routePoint.yMinute=parseInt(clearZeroPrefix(y[1]));
			routePoint.ySecond=parseInt(parseInt(clearZeroPrefix(y[2]))*0.06);
			routePoint.yMSecond=parseInt(parseInt(clearZeroPrefix(y[2]))*0.06-routePoint.ySecond);
			
			routePoint.height=extractHeightString(line);
			
			return true;
		}		
		
		function extractOziPoint(line,routePoint)
		{
			var x, y , name;
			
			y = extractOziCoordString(line);
			if(y!=null)
			{
				line=line.replace(y,"");
				y=splictCoord(y);
			}
			
			x = extractOziCoordString(line);
			if(x!=null)
			{
				line=line.replace(x,"");
				x=splictCoord(x);
			}
			
			if(x==null || y==null )
				return false;
				
			name=extractName(line);	
			
			var height=extractOziHeight(line);	
		
			routePoint.annoText=name;
			routePoint.height=parseInt(height);
			
			routePoint.xDegree=parseInt(x[0]);
			routePoint.xMinute=parseInt(parseFloat(x[1])/1000000*60);
			routePoint.xSecond=secondFromDegree(parseFloat(x[1])/1000000);
			routePoint.xMSecond=msecondFromDegree(parseFloat(x[1])/1000000);
			
			routePoint.yDegree=parseInt(y[0]);
			routePoint.yMinute=parseInt(parseFloat(y[1])/1000000*60);
			routePoint.ySecond=secondFromDegree(parseFloat(y[1])/1000000);
			routePoint.yMSecond=msecondFromDegree(parseFloat(y[1])/1000000);
			
			return true;
		}		
		
		function extractOziTrackPoint(line,point)
		{
			var x, y , name;
			
			// use y to check format
			y = extractOziCoordString(line);
			
			if(y==null)
				return false;
			
			// simply split the coord
			var splits=line.split(',');
			
			if(splits==null || splits.length< 4)
				return false;
	
			y= splits[0];
			x =splits[1];
				
			var height=splits[3];;	
			

			point.x = parseFloat(x);
			point.y = parseFloat(y);
			point.height=parseInt(height);
			
			return true;
		}		
		
		function importRoutePoints(route, txtData, format)	
		{
			var lines=txtData.split(/\r|\n/);
			if(g_isNull(lines) || lines.length<=0)
				return;
			var subRoute=route.getSubRoute(0);
			if(subRoute==null)
				return;
			
			for(var i=0;i<lines.length; i++)
			{
				var line=lines[i];
				if(g_isNull(line))
					continue;
				if(line!="" )
				{
					// create the point from 
					var routePoint=new JRoutePoint();
					var success;
					
					if(format==Format_Common)
						success=extractCommonPoint(line, routePoint);
					else
					if(format==Format_Ozi_Point)
						success=extractOziPoint(line, routePoint);
					else
					if(format==Format_Mgn_Point)
						success=extractMgnPoint(line, routePoint);
					
					if( success )
					{
						if(routePoint.name==null)
							routePoint.name=i+1;
							
						subRoute.addRoutePoint(routePoint);
					}
				}
			}
		}
		
		
		function smoothPoints(points)
		{
			if(points.length<50)
				return points;
			
			var resultPoints=new Array();
			
			var count=points.length;
			var pt1,pt2,pt3;
			var minDis=0.0001;
			var largeDis=minDis*50;
			
			// first point
			resultPoints[0]=points[0];
			for(var i=1;i<count-1;i++)
			{
				pt1=resultPoints[resultPoints.length-1]; // last point of new
				pt2=points[i];
				pt3=points[i+1];
				// check whether new point can be accepet
				var angle1,angle2;
				angle1=pt1.angle(pt1.x,pt1.y,pt2.x,pt2.y);
				angle2=pt1.angle(pt2.x,pt2.y,pt3.x,pt3.y);
				
				// filter too close points
				if(Math.abs(pt1.x-pt2.x)<minDis && Math.abs(pt1.x-pt2.x)<minDis)
					continue;
				
				if(Math.abs(angle1-angle2)<Math.PI/4 || Math.abs(pt1.x-pt2.x)>largeDis || Math.abs(pt1.x-pt2.x)>largeDis)
				{
					resultPoints[resultPoints.length]=pt2;
				}
				
				// limit the total count of points
				if(resultPoints.length>8000)
					break;
			}
			// last point
			resultPoints[resultPoints.length]=points[points.length-1];
			return resultPoints;
		}
		
		function importCommonTrack(format, route, txtData,map)	
		{
			var lines=txtData.split(/\r|\n/);
			if(g_isNull(lines) || lines.length<=0)
				return;
				
			var msgPrefix="正在转入线路数据 ... "
			
			var subRoute;
			var points;
			var routeName="";
			var isNeedCreateLine=true;
			var hasPointData=false;
			
			for(var i=0;i<lines.length; i++)
			{
				if(i % 500 ==0 )
				{
					window.status=msgPrefix + 
						parseInt( 100* ( parseFloat(i)/lines.length) ) + "%";
				}
				
				if(isNeedCreateLine)
				{
					subRoute=new JSubRoute();
					subRoute.isLine=true;
					points=new Array();	
					isNeedCreateLine=false;			
				}
				
				
				var line=lines[i];
				line=g_trim(line);
				
				if(g_isNull(line))
					continue;
					
				var isEnd=(i>=lines.length-2);
				
				if(line!="" )
				{
					// create the point from 
					var routePoint=new JRoutePoint();
					var point=new JPoint();
					var success=extractCommonPoint(line, routePoint);
				
					if(success)
					{
						point.x=routePoint.getX();
						point.y=routePoint.getY();
						point.height=routePoint.height;
						if(point.height>=0 && point.height<9000)
						{
							points[points.length]=point;
							hasPointData=true;
						}
					}

					// a possible name or reach the end
					if(!success || isEnd)					
					{
						// try to add one sub route
						if(hasPointData)
						{
							// smooth points
							points=smoothPoints(points,0,0);
							
							subRoute.name=routeName;
							subRoute.linePoints=g_createPointArray(map);
							
							// convert to route
							for(var j=0;j<points.length;j++)
							{
								var point=points[j];
								subRoute.linePoints.AddPoint(point.x,point.height,point.y);
							}
							
							route.addSubRoute(subRoute);							
							
							// init variables
							isNeedCreateLine=true;			
							hasPointData=false;
							routeName="";
						}
						
						// used as name
						if(!hasPointData)
							routeName=line;
					}
				}
			}
			
			window.status="转入线路数据完毕";
			
		}
		
		
		// Ozi format
		function importOziTrack(format, route, txtData,map)	
		{
			var lines=txtData.split(/\r|\n/);
			if(g_isNull(lines) || lines.length<=0)
				return;
			var subRoute=new JSubRoute();
			if(subRoute==null)
				return;
				
			subRoute.isLine=true;
			
			var msgPrefix="正在转入线路数据 ... "
			
			var points=new Array();
			
			for(var i=0;i<lines.length; i++)
			{
				if(i % 500 ==0 )
				{
					window.status=msgPrefix + 
						parseInt( 100* ( parseFloat(i)/lines.length) ) + "%";
				}
				
				var line=lines[i];
				
				if(g_isNull(line))
					continue;
					
				if(line!="" )
				{
					// create the point from 
					var point=new JPoint();
				
					if(extractOziTrackPoint(line, point))
					{
						if(format==Format_Ozi_Track)
							point.height*=0.3048;
							
						if(point.height>0 && point.height<9000)
							points[points.length]=point;
					}
				}
			}
			
			// smooth points
			points=smoothPoints(points,0,0);
			
			subRoute.linePoints=g_createPointArray(map);
			
			// convert to route
			for(var i=0;i<points.length;i++)
			{
				var point=points[i];
				subRoute.linePoints.AddPoint(point.x,point.height,point.y);
			}
			
			route.addSubRoute(subRoute);
			
			window.status="转入线路数据完毕";
			
		}
		
		// $PMGNWPL format
		function extractMgnXCoordString(line)
		{
			var s;
			
			line=line.toUpperCase();
			// first try three part
			s=line.match(/[0-9]{5,5}.[0-9]{3,3},E/);
			if(s!=null)
				return s[0];
			return null;
		}
		
		function extractMgnYCoordString(line)
		{
			var s;
			
			line=line.toUpperCase();
			// first try three part
			s=line.match(/[0-9]{4,4}.[0-9]{3,3},N/);
			if(s!=null)
				return s[0];
			return null;
		}
		
		function extractMgnHeight(line)
		{
			var s;
			
			line=line.toUpperCase();
			// first try three part
			s=line.match(/[0-9]{5,8},M/);
			if(s!=null)
			{
				s=splictCoord(s[0]);
				return parseFloat(clearZeroPrefix(s[0]));
			}
			return 0;
		}
		
		function extractMgnPoint(line,routePoint)
		{
			var x, y , name;
			
			y = extractMgnYCoordString(line);
			if(y!=null)
			{
				line=line.replace(y,"");
				y=splictCoord(y);
			}
			
			x = extractMgnXCoordString(line);
			if(x!=null)
			{
				line=line.replace(x,"");
				x=splictCoord(x);
			}
			
			if(x==null || y==null )
				return false;
				
			name=extractName(line);	
			
			var height=extractMgnHeight(line);	
		
			routePoint.annoText=name;
			routePoint.height=parseFloat(height);
			
			routePoint.xDegree=parseInt(clearZeroPrefix(x[0].substr(0,3)));
			routePoint.xMinute=parseInt(clearZeroPrefix(x[0].substr(3,2)));
			routePoint.xSecond=parseInt(parseInt(clearZeroPrefix(x[1]))*0.06);
			routePoint.xMSecond=parseInt(parseInt(clearZeroPrefix(x[1]))*0.06-routePoint.xSecond);
			
			
			routePoint.yDegree=parseInt(clearZeroPrefix(y[0].substr(0,2)));
			routePoint.yMinute=parseInt(clearZeroPrefix(y[0].substr(2,2)));
			routePoint.ySecond=parseInt(parseInt(clearZeroPrefix(y[1]))*0.06);
			routePoint.yMSecond=parseInt(parseInt(clearZeroPrefix(y[1]))*0.06-routePoint.ySecond);
			
			return true;
		}		
		
		function extractMgnTrackPoint(line,point)
		{
			y = extractMgnYCoordString(line);
			if(y!=null)
			{
				line=line.replace(y,"");
				y=splictCoord(y);
			}
			
			x = extractMgnXCoordString(line);
			if(x!=null)
			{
				line=line.replace(x,"");
				x=splictCoord(x);
			}
			
			if(x==null || y==null )
				return false;
				
			name=extractName(line);	
			
			var height=extractMgnHeight(line);
				
			var degree,minute,second,msecond;
			
			degree=parseInt(clearZeroPrefix(x[0].substr(0,3)));
			minute=parseInt(clearZeroPrefix(x[0].substr(3,2)));
			second=parseInt(parseInt(clearZeroPrefix(x[1]))*0.06);
			msecond=parseInt(parseInt(clearZeroPrefix(x[1]))*0.06-second);
			
			point.x = degreeFromDMSHigh(degree,minute,second,msecond);
			
			
			degree=parseInt(clearZeroPrefix(y[0].substr(0,2)));
			minute=parseInt(clearZeroPrefix(y[0].substr(2,2)));
			second=parseInt(parseInt(clearZeroPrefix(y[1]))*0.06);
			msecond=parseInt(parseInt(clearZeroPrefix(y[1]))*0.06-second);
			
			point.y = degreeFromDMSHigh(degree,minute,second,msecond);
			
			point.height=parseFloat(height);
			
			return true;
		}		
		
		function importMgnTrack(format, route, txtData,map)	
		{
			var lines=txtData.split(/\r|\n/);
			if(g_isNull(lines) || lines.length<=0)
				return;
			var subRoute=new JSubRoute();
			if(subRoute==null)
				return;
				
			subRoute.isLine=true;
			
			var msgPrefix="正在转入线路数据 ... "
			
			var points=new Array();
			
			for(var i=0;i<lines.length; i++)
			{
				if(i % 500 ==0 )
				{
					window.status=msgPrefix + 
						parseInt( 100* ( parseFloat(i)/lines.length) ) + "%";
				}
				
				var line=lines[i];
				
				if(g_isNull(line))
					continue;
					
				if(line!="" )
				{
					// create the point from 
					var point=new JPoint();
				
					if(extractMgnTrackPoint(line, point))
					{
						if(point.height>0 && point.height<9000)
							points[points.length]=point;
					}
				}
			}
			
			// smooth points
			points=smoothPoints(points,0,0);
			
			subRoute.linePoints=g_createPointArray(map);
			
			// convert to route
			for(var i=0;i<points.length;i++)
			{
				var point=points[i];
				subRoute.linePoints.AddPoint(point.x,point.height,point.y);
			}
			
			window.status="转入线路数据完毕";
		}
		
		function importRoute(route, txtData, format,map)
		{
			if(route.subRoutes.length<=0)
			{
				//create the first default point subRoute
				var subRoute=new JSubRoute();
				subRoute.name="Points";
				subRoute.isLine=false;
				route.addSubRoute(subRoute);
			}
				
			if(format==Format_Ozi_Track || format==Format_Ozi_Track_Meter)	
				importOziTrack(format,route,txtData,map);
			else
			if(format==Format_Mgn_Track )	
				importMgnTrack(format,route,txtData,map);
			else
			if(format==Format_Common_Track )	
				importCommonTrack(format,route,txtData,map);
			else
				importRoutePoints(route,txtData,format);
		}
