经纬坐标(BLH)数据创建.kml文件小工具设计 Java版

技术背景

  KML,是标记语言(Keyhole Markup Language)的缩写,最初由Keyhole公司开发,是一种基于XML 语法与格式的、用于描述和保存地理信息(如点、线、图像、多边形和模型等)的编码规范,可以被 Google Earth 和 Google Maps 识别并显示。

  创建这个工具只是因为一次偶然的需求,因为要将一个2G的点云数据导到Google Earth上进行显示,手动编辑绝对是不可能的,所以临时创建了这个小工具,为了方便使用,添加了一些简易的操作界面,这样便可以批量写入经纬度三维坐标数据(含高程)至kml文件内,然后导入Google Earth进行显示。关于kml文件的内部格式这里就不再详细描述了,具体内容请查看参考博客1【KML地图文件解析】。下面具体讲述一下程序设计原理。

实现原理

  本程序核心原理是很简单的,首先将.csv(或.txt)文件(内部格式为B,L,H 一行一个点坐标)读取以后,创建kml文件的头,然后根据kml文件的固定格式,将数据写入,最后文件写入完成以后,添加上文件的尾部格式。文件选择采用的是JFileChooser,具体使用方法请查看参考博客2【swing中JFileChooser的用法】。

  最后是界面的简要制作,添加两个控件,一个是用来选择文件的,另一个为程序退出按钮。不再具体阐述了,原理比较简单,直接上代码吧。

具体实现

  项目结构


image

  核心部分

  1 package main;
  2 
  3 import java.io.BufferedWriter;
  4 import java.io.File;
  5 import java.io.FileNotFoundException;
  6 import java.io.FileOutputStream;
  7 import java.io.FileReader;
  8 import java.io.FileWriter;
  9 import java.io.IOException;
 10 import java.io.LineNumberReader;
 11 import java.io.PrintStream;
 12 import javax.swing.JFileChooser;
 13 import javax.swing.JLabel;
 14 
 15 public class BlhToKml {
 16 
 17 	/**
 18 	 * @param args
 19 	 */
 20 	public static String InputFilePath;
 21 	public static String OutputFilePath;
 22 	@SuppressWarnings("static-access")
 23 	public static void main() throws IOException{
 24 		JFileChooser jfc=new JFileChooser();
 25 		jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
 26 		jfc.showDialog(new JLabel(), "选择文件");
 27 		File file = jfc.getSelectedFile();
 28 		if(file == null){
 29 			return;
 30 		}
 31 		String FilePath = file.getAbsolutePath();
 32 		InputFilePath=FilePath;
 33 		OutputFilePath=InputFilePath;
 34 		if(OutputFilePath.indexOf(".")>=0)
 35 	     {
 36 			OutputFilePath = OutputFilePath.substring(0, OutputFilePath.lastIndexOf("."));
 37 	     }else{
 38 	    	return;
 39 	     }
 40 		OutputFilePath=OutputFilePath+".kml";
 41 		//System.out.println(OutputFilePath);
 42 		WriteHeadInformationToFile1();
 43 		WriteHeadInformationToFile2();
 44 		ReplacePointInformation();
 45 		WriteEndInformationToFile();
 46 		TipFrame TF = new TipFrame();
 47 		TF.tishifu("已经转换完成!");
 48 	}
 49 	//将标题写入到指定路径下的文本内
 50 	public static void WriteHeadInformationToFile1() {
 51 		String filePath = OutputFilePath;
 52 		try {
 53 			File file = new File(filePath);
 54             PrintStream ps = new PrintStream(new FileOutputStream(file));
 55             ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
 56             ps.append("<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\"\r\n");
 57         } catch (FileNotFoundException e){
 58             e.printStackTrace();
 59         }
 60     }
 61 	public static void WriteHeadInformationToFile2(){
 62 		String filePath = OutputFilePath;
 63 		try {
 64             FileWriter fw = new FileWriter(filePath, true);
 65             BufferedWriter bw = new BufferedWriter(fw);
 66             bw.write("xmlns:atom=\"http://www.w3.org/2005/Atom\">\r\n");
 67             bw.write("<Document>\r\n");
 68             bw.write("\t<name>Placemark.kml</name>\r\n");
 69             bw.write("\t<Style id=\"sh_placemark_circle_highlight\">\r\n");
 70             bw.write("\t\t<IconStyle>\r\n");
 71             bw.write("\t\t\t<color>ff0000ff</color>\r\n");
 72             bw.write("\t\t\t<scale>0.8</scale>\r\n");
 73             bw.write("\t\t\t<Icon>\r\n");
 74             bw.write("\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/open-diamond.png</href>\r\n");
 75             bw.write("\t\t\t</Icon>\r\n");
 76             bw.write("\t\t</IconStyle>\r\n");
 77             bw.write("\t\t<ListStyle>\r\n");
 78             bw.write("\t\t</ListStyle>\r\n");
 79             bw.write("\t</Style>\r\n");
 80             bw.write("\t<StyleMap id=\"msn_placemark_circle\">\r\n");
 81             bw.write("\t\t<Pair>\r\n");
 82             bw.write("\t\t\t<key>normal</key>\r\n");
 83             bw.write("\t\t\t<styleUrl>#sn_placemark_circle</styleUrl>\r\n");
 84             bw.write("\t\t</Pair>\r\n");
 85             bw.write("\t\t<Pair>\r\n");
 86             bw.write("\t\t\t<key>highlight</key>\r\n");
 87             bw.write("\t\t\t<styleUrl>#sh_placemark_circle_highlight</styleUrl>\r\n");
 88             bw.write("\t\t</Pair>\r\n");
 89             bw.write("\t</StyleMap>\r\n");
 90             bw.close();
 91             fw.close();
 92         } catch (Exception e) {
 93             e.printStackTrace();
 94         }
 95     }
 96 	public static void ReplacePointInformation() throws IOException {
 97 		String filePath = OutputFilePath;
 98 		File sourceFile = new File(InputFilePath);
 99 		int lineNum = getTotalLines(sourceFile);
100 		try {
101 			FileWriter fw = new FileWriter(filePath, true);
102 	        BufferedWriter bw = new BufferedWriter(fw);
103 	        for(int i = 0;i<lineNum;i++){
104 	        	bw.write("\t<Placemark>\r\n");
105 	        	bw.write("\t\t<styleUrl>#msn_placemark_circle</styleUrl>\r\n");
106 	        	bw.write("\t\t<Point>\r\n");
107 	        	String str1=readAppointedLineNumber(sourceFile, i+1);
108 	        	bw.write("\t\t\t<coordinates>"+str1+",</coordinates>\r\n");
109 	        	bw.write("\t\t</Point>\r\n");
110 	        	bw.write("\t</Placemark>\r\n");
111 	        }
112 	        bw.close();
113 	        fw.close();
114 		} catch (Exception e) {
115 	        e.printStackTrace();
116 	    }
117 	}
118 	public static void WriteEndInformationToFile() {
119 		String filePath = OutputFilePath;
120 		try {
121 			FileWriter fw = new FileWriter(filePath, true);
122 	        BufferedWriter bw = new BufferedWriter(fw);
123 	        bw.write("</Document>\r\n");
124 	        bw.write("</kml>");
125 	        bw.close();
126 	        fw.close();
127 		} catch (Exception e) {
128 	        e.printStackTrace();
129 	    }
130 	}
131 	// 读取文件指定行。
132     public static String readAppointedLineNumber(File sourceFile, int lineNumber)
133             throws IOException {
134         FileReader in = new FileReader(sourceFile);
135         LineNumberReader reader = new LineNumberReader(in);
136         String s = "";
137         if (lineNumber <= 0 || lineNumber > getTotalLines(sourceFile)) {
138             System.out.println("不在文件的行数范围(1至总行数)之内。");
139             System.exit(0);
140         }
141         int lines = 0;
142         while (s != null) {
143             lines++;
144             s = reader.readLine();
145             if((lines - lineNumber) == 0) {
146             	//System.out.println(s);
147             	return s;
148             }
149         }
150         reader.close();
151         in.close();
152 		return s;
153     }
154     // 文件内容的总行数。
155     public static int getTotalLines(File file) throws IOException {
156         FileReader in = new FileReader(file);
157         LineNumberReader reader = new LineNumberReader(in);
158         String s = reader.readLine();
159         int lines = 0;
160         while (s != null) {
161             lines++;
162             s = reader.readLine();
163             if(lines>=2){
164             	if(s!=null){
165             		//System.out.println(s+"$");
166             	}
167             }
168         }
169         reader.close();
170         in.close();
171         //System.out.println(lines);
172         return lines;
173     }
174 }

  窗体部分1-主界面

  1 package main;
  2 
  3 import java.awt.Color;
  4 import java.awt.FlowLayout;
  5 import java.awt.Font;
  6 import java.awt.Frame;
  7 import java.awt.Label;
  8 import java.awt.event.ActionEvent;
  9 import java.awt.event.ActionListener;
 10 import java.awt.event.WindowAdapter;
 11 import java.awt.event.WindowEvent;
 12 import java.io.IOException;
 13 import javax.swing.JButton;
 14 import javax.swing.JLabel;
 15 import javax.swing.JPanel;
 16 
 17 public class Frame1 {
 18 
 19 	/**
 20 	 * @param args
 21 	 */
 22 	public static void main(String[] args) {
 23 		// TODO Auto-generated method stub
 24 		major_Frame();
 25 	}
 26 	public static void major_Frame(){
 27 		final Frame major = new Frame("KML转换器");
 28 		major.setLayout(new FlowLayout(FlowLayout.CENTER));
 29 		major.setBounds(400, 300, 430, 250);
 30 		major.setBackground(new Color(255,255,255));
 31 		JPanel jPanel = new JPanel();//创建jPanel 
 32 		jPanel.setBackground(new Color(255,255,255) );
 33         jPanel.add(new JLabel("<html><br>\t每一行的数据属性为:精度,纬度,高程。每一个数据之间用英<br>" +
 34         		"文逗号隔开。<br><br><br></html>"));//为jPanel添加JLabel 
 35 		Label label1 = new Label("格式提示");
 36 		label1.setFont(new Font("",1,18));//字体大小
 37 		label1.setBounds(100,200,400,200);
 38 		major.add(label1);
 39 		major.add(jPanel);
 40 		JButton btn1 = new JButton("输入");
 41 		btn1.addActionListener(new ActionListener(){
 42 			@SuppressWarnings("unused")
 43 			public void actionPerformed(ActionEvent arg0) {
 44 				// TODO Auto-generated method stub
 45 				BlhToKml blhtokml = new BlhToKml();
 46 				try {
 47 					BlhToKml.main();
 48 				} catch (IOException e) {
 49 					// TODO Auto-generated catch block
 50 					e.printStackTrace();
 51 				}
 52 			}
 53 
 54 		});
 55 		JButton btn2 = new JButton("退出");
 56 		btn2.addActionListener(new ActionListener(){
 57 			public void actionPerformed(ActionEvent e) {
 58 				major.setVisible(false);
 59 				System.exit(0);
 60 			}
 61 		});
 62 		major.add(btn1);
 63 		major.add(btn2);
 64 		major.addWindowListener(new WindowAdapter(){
 65 		public void windowClosing(WindowEvent e){
 66 			//System.exit(0);
 67 			major.setVisible(false);
 68 			major.dispose();
 69 		   	}
 70 		});
 71 		major.setVisible(true);
 72 	}
 73 
 74 }

  窗体部分2-提示窗

  1 package main;
  2 
  3 import java.awt.FlowLayout;
  4 import java.awt.Font;
  5 import java.awt.Frame;
  6 import java.awt.GridLayout;
  7 import java.awt.Label;
  8 import java.awt.event.MouseEvent;
  9 import java.awt.event.MouseListener;
 10 import java.awt.event.WindowAdapter;
 11 import java.awt.event.WindowEvent;
 12 import javax.swing.JButton;
 13 import javax.swing.JPanel;
 14 
 15 public class TipFrame {
 16 	public static void tishifu(String str){
 17 		final Frame f1=new Frame("提示");
 18 		f1.setBounds(500, 300, 300, 160);
 19 		f1.setResizable(false);
 20 		f1.setLayout(new GridLayout(2,1));
 21 		JPanel jpanel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
 22 		Label label1 = new Label(str);
 23 		label1.setFont(new Font("",1,15));
 24 		jpanel1.add(label1);
 25 		f1.add(jpanel1);
 26 		JPanel jpanel2 = new JPanel(new FlowLayout(FlowLayout.CENTER));
 27 		JButton Yes =new JButton("确定");
 28 		jpanel2.add(Yes);
 29 		f1.add(jpanel2);
 30 		f1.addWindowListener(new WindowAdapter() {
 31 			public void windowClosing(WindowEvent e) {
 32 				//System.exit(0);
 33 				f1.setVisible(false);
 34 				f1.dispose();
 35 			}
 36 		});
 37 		Yes.addMouseListener(new MouseListener(){
 38 			@Override
 39 			public void mouseClicked(MouseEvent arg0) {
 40 				// TODO 自动生成的方法存根
 41 			}
 42 			@Override
 43 			public void mouseEntered(MouseEvent arg0) {
 44 				// TODO 自动生成的方法存根
 45 			}
 46 			@Override
 47 			public void mouseExited(MouseEvent arg0) {
 48 				// TODO 自动生成的方法存根
 49 			}
 50 			public void mousePressed(MouseEvent arg0) {
 51 				// TODO 自动生成的方法存根
 52 				f1.setVisible(false);
 53 				f1.dispose();
 54 			}
 55 			@Override
 56 			public void mouseReleased(MouseEvent arg0) {
 57 				// TODO 自动生成的方法存根
 58 			}
 59 		});
 60 		f1.setVisible(true);
 61 	}
 62 }

运行效果

  主窗体

image

  选择窗体

image

  提示窗

image

运行结果

  测试数据(部分)

image

  成果数据(部分)


image

  接下来导入到Google Earth就可以了

  至此,小工具设计完成了!

  源码我已经上传至博客园了,下载地址:https://files.cnblogs.com/files/thyou/BLH_to_KML.zip,希望能对使用kml文件这方面的同学有一丝帮助。

致谢

  感谢以下参考博客博主对于相关技术的分享交流,衷心感谢!

参考博客

1、KML地图文件解析【https://blog.csdn.net/onlymydreams_mfc/article/details/81840232】

2、swing中JFileChooser的用法【https://www.cnblogs.com/happyPawpaw/archive/2013/04/27/3046414.html】

posted @ 2018-11-18 20:20  thyou  阅读(2271)  评论(0编辑  收藏  举报