用OSM数据画地图(含代码)

自己画的地图:

 

 

osm地图

 

小伙伴们有没有感觉两幅图很像啊。因为当时只研究路网,所以没有做那么精细。

 

步骤:

1:这里没有使用osm数据库,而是将osm文本文件按路段id读取出相应的经纬度按id名存储起来(里面嵌套了一个循环查找,时间复杂度为N的二次方,所以osm文本数据不建议太大,否则需要等好久才能处理好数据,我用的数据大小为15M,2分钟读取完毕)。

代码:

package DataUtils;

import java.io.File;

public class Main {
 public static void main(String[] args){
     //读取文件,因为我把文件放在了src下,所以直接写文件名即可
     Utils.readFileByLines("map.dat");
     File dir = new File("DataSet\\");
     File file[] = dir.listFiles();
     //打印路网文件个数
     System.out.println(file.length);
 }
}
package DataUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class Search {
	public static String search(String ss) {
		File file = new File("map.dat");
		String ind = null;
		BufferedReader reader = null;
		InputStreamReader reade = null;
		try {

			System.out.println("一次读一行");
			reade = new InputStreamReader(new FileInputStream(file), "utf-8");

			reader = new BufferedReader(reade);

			String tempString = null;
			String s[] = new String[9];

			int line = 1;
			// reader.readLine();
			// System.out.println(reader.readLine());
			// 一次读一行,读入null时文件结束
			for (int i = 0; i < 6; i++) {
				reader.readLine();
				line++;
			}

			while ((tempString = reader.readLine()) != null) {
				if (tempString.contains(ss) && tempString.contains("<node id=")) {
					s = tempString.trim().split(" ");
					s[2] = s[2].trim().replace("lat=", "").replace("\"", "")
							.trim();
					s[3] = s[3].trim().replace("lon=", "").replace("\"", "")
							.trim();
					ind = s[2] + "," + s[3];
					break;
				}
			}

		} catch (Exception e) {

		}
		System.out.println(ind);
		return ind;

	}

}

  

package DataUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;


public class Utils {
    static WriteToTxt wt = null;


    // 指定位置覆盖数据
    public static void write(long skip, String str, String fileName)
    {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(fileName, "rw");

            byte[] b = str.getBytes();
            raf.setLength(raf.length());

            raf.seek(skip);
            raf.write(b);
            raf.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                raf.close();
            } catch (Exception e) {

            }
        }
    }

    public static void readFileByLines(String fileName) {
        //osm的数据文件
        File file = new File(fileName);
        //新建字符流,因为osm数据需要按行读取,这里用了BufferedReader类,它提供了readLine方法
        BufferedReader reader = null;
        InputStreamReader input = null;
        try {

            System.out.println("一次读一行");
            
            input = new InputStreamReader(new FileInputStream(file), "utf-8");

            reader = new BufferedReader(input);

            String tempString = null;
            //后面读取时需要对行进行分割,用字符串数组存储
            String s[] = new String[9];
            //计数
            int line = 1;
            //osm数据前几行没用,先过滤掉
            for (int i = 0; i < 6; i++) {
                reader.readLine();
                line++;
            }
            //下面循环中主要是按路id新建文件,把一个路上的点存入对应的id文件中
            //因为小路太多,这里把小路都过滤掉
            while ((tempString = reader.readLine()) != null) {
                
                if (tempString.contains("<way id=")) {
                    System.out.println("=============================================");
                    String[] sss = tempString.trim().split(" ");
                    sss[1] = sss[1].trim().replace("id=", "").replace("\"", "")
                            .trim();
                    wt = new WriteToTxt(sss[1].trim());
                    System.out.println(wt);
                }
                if (tempString.contains("<nd ref=")) {
                    System.out.println("====================");
                    String[] ssss = tempString.trim().split(" ");
                    ssss[1] = ssss[1].trim().replace("ref=", "")
                            .replace("/>", "").replace("\"", "").trim();
                    wt.insert(Search.search(ssss[1]));
                }
            }

            

        } catch (IOException e) {

            e.printStackTrace();

        } finally {
            //关闭流
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }

            if (reader != null) {

                try {

                    reader.close();

                } catch (IOException e1) {

                }

            }

        }

    }

}

 


package DataUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class WriteToTxt {
    String str;
    
    public WriteToTxt(String trim)
    {
        //将路网数据文件都放在DataSet文件下
        str = "DataSet\\" + trim + ".txt";
        File file = new File(str);
        try {
            if (!file.exists()) {
                System.out.println("file" + str + "   do not exists");
                try {
                    file.createNewFile();
                    System.out.println("txt has been created");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }

    }
    //向文件中些数据
    public void insert(String s) {

        try {
            FileWriter writer = new FileWriter(str, true);
            writer.write(s);
            writer.write("\r\n");
            writer.flush();
            writer.close();
        } catch (IOException e) {
            
            e.printStackTrace();
        }

    }

}

 

 

2:设置需要画的地图大小,这与osm数据的minlon,minlat,maxlon,maxlat要建立关系,因为osm地图数据是框一个矩形框,而我们画的也是个矩形地图,只要建立好比例关系就可以画图了。

package Paint;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import util.FloatUtil;

public class Demo {
    public static void main(String[] args) {

        List x;
        List y;
        FloatUtil fu = null;
        Map<Integer, Integer> map = null;
        BufferedImage bufImg = new BufferedImage(1000, 800,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D gs2 = bufImg.createGraphics();

        // 设置背景色为白色
        gs2.setBackground(Color.WHITE);

        gs2.clearRect(0, 0, 1000, 800);

        // 设置填充的颜色
        gs2.setColor(Color.BLACK);
        File dir = new File("DataSet\\");
        File file[] = dir.listFiles();
        for (int j = 0; j < file.length; j++) {
            fu = new FloatUtil("DataSet\\" + file[j].getName());
            System.out.println(file[j].getName());
            x = fu.getY();

            y = fu.getX();
            gs2.setColor(Color.blue);
            for (int i = 0; i < x.size() - 1; i++) {
                gs2.drawLine(Integer.parseInt(x.get(i).toString()),
                        Integer.parseInt(y.get(i).toString()),
                        Integer.parseInt(x.get(i + 1).toString()),
                        Integer.parseInt(y.get(i + 1).toString()));
            }
        }

        gs2.dispose();
        bufImg.flush();

        try {
            ImageIO.write(bufImg, "png", new File("E:\\地图.png"));
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

}
package Paint;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class FloatUtil {
    double X = 1000 / (118.9437000 - 118.8865000);
    double Y = 800 / (32.1140000 - 32.0828000);
    String str;

    public FloatUtil(String str) {
        this.str = str;
    }

    public List getX() {
        File file = new File(str);

        BufferedReader reader = null;
        InputStreamReader input = null;
        float[] a;
        ArrayList<Integer> list = new ArrayList<Integer>();
        try {

            System.out.println("以行为单位读取文件内容,一次读一行");
            input = new InputStreamReader(new FileInputStream(file), "utf-8");

            reader = new BufferedReader(input);
            String tempString;
            int i = 0;

            while ((tempString = reader.readLine()) != null) {
                if (tempString.split(",").length == 2) {
                    System.out.println(tempString.split(",")[0].trim());
                    list.add((int) (800 - (Double.parseDouble(tempString
                            .split(",")[0].trim()) - 32.0828000) * Y));
                    System.out
                            .println((int) (800 - (Double
                                    .parseDouble(tempString.split(",")[0]
                                            .trim()) - 32.0828000)
                                    * Y));
                    i++;
                }

            }
        } catch (Exception e) {

        }
        System.out.println(list.size());

        return list;

    }

    public List getY() {
        File file = new File(str);

        BufferedReader reader = null;
        InputStreamReader input = null;
        float[] a;
        ArrayList<Integer> list = new ArrayList<Integer>();
        try {

            System.out.println("以行为单位读取文件内容,一次读一行");
            input = new InputStreamReader(new FileInputStream(file), "utf-8");

            reader = new BufferedReader(input);
            String tempString;
            int i = 0;

            while ((tempString = reader.readLine()) != null) {
                if (tempString.split(",").length == 2) {
                    list.add((int) ((Double.parseDouble(tempString.split(",")[1]
                            .trim()) - 118.8865000) * X));
                    i++;
                }

            }
        } catch (Exception e) {

        }
        System.out.println(list.size());

        return list;
    }
}

 

posted @ 2018-01-17 13:43  王者峡谷的码农  阅读(32311)  评论(0编辑  收藏  举报