瓦片图是什么呢
指将一定范围内的地图按照一定的尺寸和格式,按缩放级别或者比例尺,
切成若干行和列的正方形栅格图片,对切片后的正方形栅格图片被形象的称为瓦片
一幅精确到街道级别的世界地图图片宽度为数以百万计的像素,
由于这些数据太大了,从而导致无法一次下载并且在内存里也无法一次都hold住。
实际上,Web地图由许多小的正方形的图片组成,这些小图片称作瓦片。
瓦片的大小一般为256*256像素,这些瓦片一个挨一个并列放置以组成一张很大的看似无缝的地图。
高德命名方式
链接: link.
上面链接能够充分的看出命名规则
切图
直接上代码(由于是瓦片图,所以原图较大,用java的BufferedImage我还没有找到怎么读取大图,所以用的是Iterator)
/**
* 图片裁切
* @param sourcePath 源图片路径
*/
public static String cut(String sourcePath) {
String descPath = "";
FileInputStream is = null;
ImageInputStream iis = null;
int x1 = 0;
int y1 = 0;
try {
is = new FileInputStream(sourcePath);
String fileSuffix = sourcePath.substring(sourcePath.lastIndexOf(".") + 1);
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(fileSuffix);
ImageReader reader = it.next();
iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
//原始图宽度
int w = reader.getWidth(0);
//原始图高度
int h = reader.getHeight(0);
//一行有多少个256
int l;
int b;
//切片的边长
int ll;
//层级 1234567
int n = 1;
if (w>h){
ll=h;
}else{
ll=w;
}
while (ll%256!=0){
ll--;
}
l=ll/256;
while (!((b=l/2) ==1)){
l=b;
n++;
}
//创建文件夹
create(n+2);
l = (int) Math.pow(2,n);
//切图初始x坐标
int left = w-l*256/2;
//切图初始y坐标
int top = h-l*256/2;
for (int i=0;i<l;i++){
for (int j=0;j<l;j++){
x1 = left+i*256;
y1 = top+j*256;
descPath = "图片上层文件夹的目录"+(n+2)+"/"+(l+i)+"_"+(l+j)+".jpg";
Rectangle rect = new Rectangle(x1, y1, 256, 256);
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
bi.getHeight();
bi.getWidth();
ImageIO.write(bi, fileSuffix, new File(descPath));
}
}
for(int i = n;i>1;i--){
pin((int) (Math.pow(2,(i-2))*3),(i+1),l);
}
return "目录";
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
is = null;
}
if (iis != null) {
try {
iis.close();
} catch (IOException e) {
e.printStackTrace();
}
iis = null;
}
}
return null;
}
代码只是切了原图那层,需要缩放
/**
* 缩放
* @param file
* @param z
* @param path1
* @param path
* @throws Exception
*/
public static void zoomImage(File file,double z,String path1, String path)throws Exception{
BufferedImage bufImg = ImageIO.read(file);
BufferedImage bi = ImageIO.read(new File(path1));
int w = (int) (bi.getWidth()*z);
int h = (int) (bi.getHeight()*z);
//新生成结果图片
BufferedImage zoomImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
//缩放 getScaledInstance(width,height,hints)
zoomImg.getGraphics().drawImage(bufImg.getScaledInstance(w, h, Image.SCALE_SMOOTH), 0, 0, null);
ImageIO.write(zoomImg,"jpg",new File(path));
}
/**
*
*
* @param
* @param
* @paramisHorizontal 为true时表示水平方向合并,为false时表示垂直方向合并
* @return返回合并后的BufferedImage对象
* @throwsIOException
*/
/**
*
* @param a 缩放之后的命名起始
* @param c 缩放之后的文件夹名称(3,4,5,6.....)
* @param l 被缩放的层级的边长是多少个256
* @throws Exception
*/
public static void pin(int a,int c,int l) throws Exception {
int b;
for (int i = (a*2);i<(a*2+l);i++){
b=a;
for (int j = (a*2);j<(a*2+l);j++){
pinjie(i,j,a,b,c);
j++;
b++;
}
i++;
a++;
}
}
public static String pinjie(int i,int j,int a,int b,int c) throws Exception {
BufferedImage img1;
BufferedImage img2;
boolean isHorizontal;
BufferedImage img3;
img1 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+i+"_"+j+".jpg"));
img2 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+i+"_"+(j+1)+".jpg"));
isHorizontal = false;
img3 = mergeImage(img1, img2, isHorizontal);
File outputfile1 = new File("/app/cut/000/ll.jpg");
ImageIO.write(img3, "jpg", outputfile1);
img1 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+(i+1)+"_"+j+".jpg"));
img2 = ImageIO.read(new File("/app/cut/tiles/"+(c+1)+"/"+(i+1)+"_"+(j+1)+".jpg"));
isHorizontal = false;
img3 = mergeImage(img1, img2, isHorizontal);
File outputfile2 = new File("/app/cut/000/rr.jpg");
ImageIO.write(img3, "jpg", outputfile2);
img1 = ImageIO.read(new File("/app/cut/000/ll.jpg"));
img2 = ImageIO.read(new File("/app/cut/000/rr.jpg"));
isHorizontal = true;
img3 = mergeImage(img1, img2, isHorizontal);
File outputfile = new File("/app/cut/000/he.jpg");
ImageIO.write(img3, "jpg", outputfile);
String path = "/app/cut/000/he.jpg";
File file = new File(path);
String path1 = "/app/cut/tiles/"+c+"/"+a+"_"+b+".jpg";
//缩放为原来的0.5倍
zoomImage(file,0.5,path,path1);
return path1;
}
public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2, boolean isHorizontal) throws IOException {
int w1 = img1.getWidth();
int h1 = img1.getHeight();
int w2 = img2.getWidth();
int h2 = img2.getHeight();
//从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);//逐行扫描图像中各个像素的RGB到数组中
int[] ImageArrayTwo = new int[w2 * h2];
ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);
//生成新图片
BufferedImage DestImage = null;
if (isHorizontal) {//水平方向合并
DestImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);//设置上半部分或左半部分的RGB
DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
} else {//垂直方向合并
DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);//设置上半部分或左半部分的RGB
DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2);//设置下半部分的RGB
}
return DestImage;
}
static int flag = 1;//用来判断文件是否删除成功
public static void remove() {
//删除一个文件夹下的所有文件(包括子目录内的文件)
File file = new File("删除的文件夹");//输入要删除文件目录的绝对路径
deleteFile(file);
if (flag == 1) {
System.out.println("文件删除成功!");
}
}
public static void deleteFile(File file) {
//判断文件不为null或文件目录存在
if (file == null || !file.exists()) {
flag = 0;
System.out.println("文件删除失败,请检查文件路径是否正确");
return;
}
//取得这个目录下的所有子文件对象
File[] files = file.listFiles();
//遍历该目录下的文件对象
for (File f : files) {
//打印文件名
String name = file.getName();
System.out.println(name);
//判断子目录是否存在子目录,如果是文件则删除
if (f.isDirectory()) {
deleteFile(f);
} else {
f.delete();
}
}
//删除空文件夹 for循环已经把上一层节点的目录清空。
file.delete();
}
public static void create(int num) {
// 在D盘创建一个文件夹
File file = new File("/app/cut/tiles/");
file.mkdirs();
for (int i = 3;i<(num+1);i++){
File file1 = new File("/app/cut/tiles/"+i);
file1.mkdirs();
}
}
做个记录,第一次搞这个