⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapchange.java

📁 地图格式转换程序
💻 JAVA
字号:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;

public class mapChange extends Canvas implements ActionListener {
//声明参数变量
	//图形用户界面
	Frame f, f2;
	ScrollPane sro;
	Panel panel;
	MenuBar mb;
	Menu mf, me, mh, mc;
	CheckboxMenuItem cmi;
	//文件指针(矢量,栅格写,栅格读)
	RandomAccessFile rf, rfs, rfb;
	//文件地址
	String path;
	//矢量数据,arcnum为弧段数,k[i][j]为第i条弧段的第j个数据,x[i][j]为第i条弧段的第j个节点的x坐标,y类似
	int arcnum = 0;
	int[][] k;
	double[][] x, y;
	//是否显示栅格图像
	boolean sta = false;
	//栅格过度数据(二维数组记录栅格中每一像原的属性)
	int[][] at;
	//最终栅格数据(以宽度为一像素的线记录栅格图像,是对二维数组的压缩)
	//lnum为线的数目,stx、sty,endx、endy为始末节点坐标,ln为线的属性)
	int lnum = 0;
	int[] stx, sty, endx, endy, ln;
	//矢量图的显示大小,和栅格的大小(或者叫精度)
	double size=1, sgsize=1;
	//以颜色区分不同多边形
	Color[] col;
	boolean again;

//本类的默认构造,生成图形用户界面,并对事件进行监听
	public mapChange(){
		f = new Frame("地图格式转换");
		f.setSize(1000, 900<Toolkit.getDefaultToolkit().getScreenSize().height-30?900:Toolkit.getDefaultToolkit().getScreenSize().height-30);
		f.setBackground(Color.lightGray);
		f.addWindowListener(new WindowAdapter(){public void windowClosing (WindowEvent e) {
		System.exit(0);
	}});
		setBackground(Color.white);
		sro = new ScrollPane();
		sro.add(this);
		f.add(sro);
		mb = new MenuBar();
		mf = new Menu("文件");
		me = new Menu("编辑");
		mh = new Menu("帮助");
		f.setMenuBar(mb);
		mb.add(mf);
		mb.add(me);
		mb.add(mh);
		mf.add(new MenuItem("打开矢量文件"));
		mf.add(new MenuItem("保存栅格文件"));
		mf.add(new MenuItem("打开栅格文件"));
		mf.addSeparator();
		mf.add(new MenuItem("退出"));
		me.add(new MenuItem("刷新"));
		mc = new Menu("放缩");
		mc.add(new MenuItem("默认"));
		mc.add(new MenuItem("50%"));
		mc.add(new MenuItem("200%"));
		mc.addSeparator();
		mc.add(new MenuItem("自定义"));
		mc.addActionListener(this);
		me.add(mc);
		me.add(new MenuItem("矢量转栅格"));
		me.addSeparator();
		cmi = new CheckboxMenuItem("显示矢量图", true);
		me.add(cmi);
		mh.add(new MenuItem("关于"));
		mf.addActionListener(this);
		mh.addActionListener(this);
		me.addActionListener(this);
		f.setVisible(true);
		col = new Color[50];
		for (int i=1; i<50; i++) {
			col[i] =new Color ((i*i)%256, (i*100)%256, (i*20)%256);
		}
	}
	
//菜单事件监听
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand()=="打开矢量文件") {
			FileDialog fd = new FileDialog(f, "打开矢量文件");
			fd.setFile("*.e00");
			fd.setVisible(true);
			path = fd.getDirectory() + fd.getFile();
			sta = false;
			try {
				rf = new RandomAccessFile (path,"r");
				arcnum = readin();
				again = true;
				repaint();
			}
			catch (IOException ioe){
				System.out.println (ioe);
			}
			catch (Exception fe) {
				System.out.println (fe);
			}
		}
		else if (e.getActionCommand() == "保存栅格文件") {
			FileDialog fds = new FileDialog (f, "保存栅格文件", 1);
			fds.setFile("*.bin");
			fds.setVisible(true);
			String spath = fds.getDirectory() + fds.getFile() + ".bin";
			try {
				rfs = new RandomAccessFile (spath, "rw");
				rfs.seek(0);
				rfs.writeInt(lnum);
				rfs.writeInt((int)(1000*sgsize));
				rfs.writeInt((int)(830*sgsize));
				for (int i=0; i<lnum; i++) {
					rfs.writeInt(stx[i]);
					rfs.writeInt(sty[i]);
					rfs.writeInt(endx[i]);
					rfs.writeInt(endy[i]);
					rfs.writeInt(ln[i]);
				}
				rfs.close();
			}
			catch (IOException ioe){
				System.out.println (ioe);
			}
			catch (Exception fe) {
				System.out.println (fe);
			}
		}
		else if (e.getActionCommand()=="200%") {
			size = 2;
			again = true;
			repaint();
		}
		else if (e.getActionCommand()=="50%") {
			size = 0.5;
			again = true;
			repaint();
		}
		else if (e.getActionCommand()=="默认") {
			size = 1;
			again = true;
			repaint();
		}
		else if (e.getActionCommand()=="自定义") {
			ratio();
		}
		else if (e.getActionCommand()=="打开栅格文件") {
			FileDialog fdr = new FileDialog (f, "打开栅格文件");
			fdr.setFile("*.bin");
			fdr.setVisible(true);
			String rpath = fdr.getDirectory()+fdr.getFile();
			try {
				rfb = new RandomAccessFile (rpath, "r");
				rfb.seek(0);
				lnum = rfb.readInt();
				sgsize = size = rfb.readInt()/1000.0;
				rfb.readInt();
				stx = new int[lnum];
				sty = new int[lnum];
				endx = new int[lnum];
				endy = new int[lnum];
				ln = new int[lnum];
				for (int i=0; i<lnum; i++) {
					stx[i] = rfb.readInt();
					sty[i] = rfb.readInt();
					endx[i] = rfb.readInt();
					endy[i] = rfb.readInt();
					ln[i] = rfb.readInt();
				}
				rfb.close();
			}
			catch (IOException ioe){
				System.out.println (ioe);
			}
			catch (Exception fe) {
				System.out.println (fe);
			}
			sta = true;
			arcnum = 0;
			again = true;
			repaint();
		}
		
		else if (e.getActionCommand()=="矢量转栅格") {
			if (rf == null) {
				JOptionPane.showMessageDialog(f, "请先打开矢量文件!", "错误", 2);
			}
			else {
				try {
					rf.seek(0);
					sta = true;
					change();
					lnum = reduce();
					repaint();
				}
				catch (IOException ioe){
					System.out.println (ioe);
				}
				catch (Exception fe) {
					System.out.println (fe);
				}
			}
		}
		else if (e.getActionCommand() == "关于") 
			f.add(new about());
		else if (e.getActionCommand() == "刷新")
			repaint();
		else if (e.getActionCommand()=="退出") {
			if (rf != null) {
				try {
					rf.close();
				}
				catch (IOException ioe) {}
			}
			System.exit(0);
		}
	}
	
//读取e00文件数据
	public int readin() {
		try{rf.seek(0);}
		catch(Exception e){}
		String linestr = "";
		String[] parts;
		arcnum = 0;
		k = new int[100][7];
		x = new double[100][];
		y = new double[100][];
		int j, n=0;
		//寻找数据初始位置
		try {
			while (! linestr.equals("ARC  2")){
				linestr = rf.readLine();
			}
		}
		catch (IOException ioe) {}
		catch (Exception e)
		{return 0;}
		//将文件内容读入内存
		try {
			while (true) {
				j = 0;
				linestr = rf.readLine();
				parts = linestr.split(" ");
				for (int i=0; i<parts.length; i++) {
					if (parts[i].length() != 0 )
						k[n][j++] = Integer.parseInt(parts[i]);
				}
				//遇到结束符终止循环
				if (k[n][0] == -1)
					break;
				//为数组开辟内存空间,用到才开,节省内存
				x[n] = new double[k[n][6]];
				y[n] = new double[k[n][6]];
				//读入节点坐标
				for (int i=0; i<(int)(k[n][6]/2); i++) {
					linestr = rf.readLine();
					parts = linestr.split(" ");
					x[n][i*2] = Double.parseDouble(parts[1]);
					y[n][i*2] = Double.parseDouble(parts[2]);
					x[n][i*2+1] = Double.parseDouble(parts[3]);
					y[n][i*2+1] = Double.parseDouble(parts[4]);
				}
				if (k[n][6]%2 == 1) {
					linestr = rf.readLine();
					parts = linestr.split(" ");
					x[n][k[n][6]-1] = Double.parseDouble(parts[1]);
					y[n][k[n][6]-1] = Double.parseDouble(parts[2]);
				}
				n++;
			}
		}
		catch (IOException ioe) {
			System.out.println (ioe);
		}
		catch (Exception e) {
			System.out.println (e);
		}
		//返回弧段总数
		return n;
	}

//绘图程序,repaint()方法调用
	public void paint(Graphics g) {
		//设置画布大小
		this.setSize((int)(1000*size), (int)(830*size));
		//判断栅格文件是否存在,是否要求绘出
		if (sta & lnum!=0) {
			//1:1比例绘出栅格图像
			if (sgsize == size)
				for (int i=0; i<lnum; i++) {
					if (ln[i] == 0)
						g.setColor(Color.WHITE);
					else
						g.setColor(col[ln[i]]);
					g.drawLine(stx[i], sty[i], endx[i], endy[i]);
				}
			//栅格图像显示比例与原始比例不同时,画线改为以对应比例绘出矩形
			else
				for (int i=0; i<lnum; i++) {
					if (ln[i] == 0)
						g.setColor(Color.WHITE);
					else
						g.setColor(col[ln[i]]);
					g.fillRect((int)(stx[i]*size/sgsize), (int)(sty[i]*size/sgsize), (int)((endx[i]-stx[i]+1)*size/sgsize+0.99), (int)(size/sgsize+0.99));
				}
		}
		//判断是否要求绘出矢量图像,是否以读入矢量文件
		if (cmi.getState() & arcnum!=0) {
			g.setColor(Color.BLACK);
			//遍历所有弧段,根据组成弧段的点的坐标安规定比例两点连线
			for (int n=0; n<arcnum; n++) 
				for (int i=1; i<k[n][6]; i++) 
					g.drawLine((int)((x[n][i-1]/5000-100)*size),(int)((830-y[n][i-1]/5000)*size),(int)((x[n][i]/5000-100)*size),(int)((830-y[n][i]/5000)*size));
		}
		if (again) {
			sro.validate();
			again = false;
		}	
		return;
	}

//将矢量图像转换为当前比例下的栅格文件(每栅格对应一像素),将结果记入二维数组
//转换使用边界代数法,具体过程见说明文档
	public void change() {
		at = new int[(int)(1000*size)][(int)(830*size)];
		for (int m=0; m<1000*size; m++)
			for (int n=0; n<830*size; n++)
				at[m][n] = 0;
		int s, l;
		int[] ix, iy;
		double xMax;
		sgsize = size;
		for (int n=0; n<arcnum; n++) {
			ix = new int[k[n][6]];
			iy = new int[k[n][6]];
			for (int i=0; i<k[n][6]; i++) {
				ix[i] = (int)((x[n][i]/5000-100)*sgsize);
				iy[i] = (int)((830-y[n][i]/5000)*sgsize);
			}
			for (int i=1; i<k[n][6]; i++) {
				if (iy[i]>iy[i-1]) {
					for (s = iy[i-1]; s<iy[i]; s++) {
						if (iy[i]-iy[i-1] == 1)
							for (l=0; l<=(ix[i-1]+ix[i])/2; l++)
								at[l][s] += (k[n][5] - k[n][4]);
						else {
							xMax = ix[i-1] + 1.0*(ix[i]-ix[i-1])/(iy[i]-iy[i-1])*(s-iy[i-1]);
							for (l=0; l<=xMax; l++)
								at[l][s] += k[n][5] - k[n][4];
						}
					}
				}
				else if (iy[i]<iy[i-1]) {
					for (s=iy[i]; s<iy[i-1]; s++) {
						if (iy[i-1]-iy[i] == 1)
							for (l=0; l<=(ix[i-1]+ix[i])/2; l++)
								at[l][s] += (k[n][4] - k[n][5]);
						else {
							xMax = ix[i] + (ix[i]-ix[i-1])*1.0/(iy[i]-iy[i-1])*(s-iy[i]);
							for (l=0; l<=xMax; l++)
								at[l][s] += k[n][4] - k[n][5];
						}
					}
				}
			}
		}
	}
	
//对生成的二维数组的栅格数据进行压缩,以提高绘图和缩放的效率,并且大大减小数据量
//具体压缩方法见说明文档
	public int reduce() {
		stx = new int[(int)(10000*size)];
		sty = new int[(int)(10000*size)];
		endx = new int[(int)(10000*size)];
		endy = new int[(int)(10000*size)];
		ln = new int[(int)(10000*size)];
		int i;
		int num=0, point;
		stx[0] = 0;
		sty[0] = 0;
		point = 0;
		for (int j=0; j<830*size; j++) {
			for (i=0; i<1000*size; i++) {
				if (num != at[i][j]) {
					ln[point] = num;
					endx[point] = i-1;
					endy[point++] = j;
					stx[point] = i;
					sty[point] = j;
					num = at[i][j];
				}
			}
			endx[point] = i-1;
			endy[point] = j;
			ln[point++] = num;
			stx[point] = 0;
			sty[point] = (j+1);
		}
		return point-1;
	}
	
//自定义图像比例时,接受数据的窗口
	public void ratio() {
		//生成图形用户界面
		Label lab;
		JButton but;
		final TextField text;
		Panel pan;
		f2 = new Frame("图像比例");
		lab = new Label("%");
		text = new TextField("100");
		but = new JButton("确定");
		but.addActionListener(new ActionListener() {
			//按钮事件监听(关闭此窗口,且修改数据,重载paint方法)
			public void actionPerformed (ActionEvent evt) {
				size = Double.parseDouble(text.getText())/100;
				f2.setVisible(false);
				again = true;
				repaint();
				return;
			}
		});
		pan = new Panel();
		pan.setBackground(Color.LIGHT_GRAY);
		pan.add(text);
		pan.add(lab);
		pan.add(but);
		f2.add(pan);
		f2.setSize(200, 100);
		f2.setLocation(250, 200);
		f2.setVisible(true);
	}

//main主函数,程序从这里开始运行
	public static void main (String[] args) {
		new mapChange();
	}
}

//“关于”的窗口,介绍一些软件信息
class about extends JFrame{
	JPanel p1, p2;
	Label l1, l2, l3;
	JLabel l4;
	ImageIcon img;
	
	public about() {
		p1 = new JPanel();
		p2 = new JPanel();
		l1 = new Label("地图格式转换");
		l2 = new Label("mapChange      版本:v2.31");
		l3 = new Label("开发: 刘明超(00612068)");
		p1.setLayout(new GridLayout(3,1));
		p1.add(l1);
		p1.add(l2);
		p1.add(l3);
		img = new ImageIcon("1.jpg");
		l4 = new JLabel(img);
		p2 = new JPanel();
		p2.add(l4);
		p1.setBackground(Color.WHITE);
		p2.setBackground(Color.WHITE);
		this.setLayout(new GridLayout(1,2));
		this.add(p2);
		this.add(p1);
		this.setTitle("关于 mapChange");
		this.setSize(350,200);
		this.setLocation(270, 150);
		this.setVisible(true);
	}
	
	public static void main(String[] args) {
		new about();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -