用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;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM