地图裁剪器,可以将图片裁剪成瓦片数据,主要用途是将高清卫星图像裁剪成瓦片图,可以做离线地图的开发,基于墨卡托坐标
地图裁剪
package com.wwp.utils.map;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import javax.imageio.ImageIO;
public class BMapCut {
private int minlevel;
private int maxlevel;
private int piclevel;
private double mercatorx;
private double mercatory;
private String pic;
private String savepath;
public BMapCut(String pic, double mercatorx, double mercatory,
String savepath) {
this.pic = pic;
this.mercatorx = mercatorx;
this.mercatory = mercatory;
this.savepath = savepath;
}
public BMapCut(String pic, int minlevel, int maxlevel, int piclevel, double mercatorx,
double mercatory, String savepath) {
this.pic = pic;
this.minlevel = minlevel;
this.maxlevel = maxlevel;
this.mercatorx = mercatorx;
this.mercatory = mercatory;
this.savepath = savepath;
this.piclevel = piclevel;
}
public void cutterall() throws Exception {
for (int i = minlevel; i <= maxlevel; i++) {
cutterone(i);
}
}
public void cutterone(int level) throws Exception {
//图片中心的像素坐标(pixelx,pixely),图片中心的平面坐标即魔卡托坐标(mercatorx, mercatory)
//像素坐标 = 平面坐标 * Math.pow(2, level - 18)
double pixelx = mercatorx * Math.pow(2, level - 18);
double pixely = mercatory * Math.pow(2, level - 18);
System.out.println("pixelx : " + pixelx);
System.out.println("pixely : " + pixely);
BufferedImage bi = ImageIO.read(new File(pic));
int width = bi.getWidth();
int height = bi.getHeight();
//图片遵循原则:当前图片所属级别piclevel不缩放即像素级别相等。
//按照公式缩放:当前级别图片长度 = 原图片长度 * Math.pow(2, level - piclevel)
//minx: 图片左下角x坐标
//miny: 图片左下角y坐标
//maxx: 图片右上角x坐标
//maxy: 图片右上角y坐标
double minx = pixelx - width * Math.pow(2, level - piclevel) / 2;
double miny = pixely - height * Math.pow(2, level - piclevel) / 2;
double maxx = pixelx + width * Math.pow(2, level - piclevel) / 2;
double maxy = pixely + height * Math.pow(2, level - piclevel) / 2;
System.out.println("(minx,miny) = (" + minx + ", " + miny + ")" );
System.out.println("(maxx,maxy) = (" + maxx + ", " + maxy + ")" );
int neatminx = (int) minx / 256;
int remminx = (int) minx % 256;
int neatminy = (int) miny / 256;
int remminy = (int) miny % 256 ;
int neatmaxx = (int) maxx / 256;
int remmaxx = 256 - (int) maxx % 256;
int neatmaxy = (int) maxy / 256;
int remmaxy = 256 - (int) maxy % 256;
//(neatminx,neatminy)为图片左下角最近的整数图块坐标,neatminx到neatmaxx即当前级别下切割图块的图块坐标x
//(neatmaxx,neatmaxy)为图片右上角最近的整数图块坐标,neatminy到neatmaxy即当前级别下切割图块的图块坐标y
System.out.println("neatminx: " + neatminx);
System.out.println("neatmaxx: " + neatmaxx);
System.out.println("neatminy: " + neatminy);
System.out.println("neatmaxy: " + neatmaxy);
System.out.println("remminx width remmaxx : " + remminx + " "+ width + " "+ remmaxx );
System.out.println("remminy height remmaxy : " + remminy + " " + height +" " + remmaxy );
// 扩充原图片为width * height --- > (remminx + width + remmaxx ) * (remminy +
// height +remmaxy)
int extendwidth = (neatmaxx - neatminx + 1 ) * 256;
int extendheight = (neatmaxy - neatminy + 1 ) * 256;
System.out.println("extendwidth: " + extendwidth);
System.out.println("extendheight: " + extendheight);
BufferedImage outputimage = null;
Graphics2D g = bi.createGraphics();
BufferedImage extend = g.getDeviceConfiguration().createCompatibleImage(extendwidth, extendheight, Transparency.TRANSLUCENT);
g.dispose();
g = extend.createGraphics();
g.drawImage(extend, 0, 0, extendwidth, extendheight, null);
g.drawImage(bi.getScaledInstance((int) (width * Math.pow(2, level - piclevel)), (int)(height * Math.pow(2, level - piclevel)), Image.SCALE_SMOOTH), remminx, remmaxy, null);
//切割图片,共( neatmaxx - neatminx + 1) * (neatmaxy - neatminy + 1)份 256*256图片
String dirname = savepath.substring(0, savepath.lastIndexOf("\")) + "\tiles\" + level;
System.out.println("dirname : " + dirname);
File dir = new File(dirname);
Image image = extend.getScaledInstance(extendwidth, extendheight, Image.SCALE_DEFAULT);
if(dir.exists()) {
System.out.println("创建目录失败!, 目录已存在!");
} else {
if(dir.mkdirs()) {
ImageIO.write(extend, "png", new File(dirname + savepath.substring(savepath.lastIndexOf("\")) + ".png"));
System.out.println("savepath : " + dirname + savepath.substring(savepath.lastIndexOf("\")));
System.out.println("extend success!");
int w = neatmaxx - neatminx + 1;
int h = neatmaxy - neatminy + 1;
for(int i = 0; i < w; i++) {
for(int j = 1; j <= h; j++) {
ImageFilter cropfilter = new CropImageFilter(256 * i, 256* (h - j), 256, 256);
Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(),cropfilter));
BufferedImage tag = new BufferedImage(256, 256 , BufferedImage.TYPE_INT_BGR);
Graphics2D gs = tag.createGraphics();
tag = gs.getDeviceConfiguration().createCompatibleImage(256, 256, Transparency.TRANSLUCENT);
gs.dispose();
gs = tag.createGraphics();
gs.drawImage(img, 0, 0, null);
g.dispose();
String croppicname = dirname + "\tile" + (neatminx + i) + "_" + (neatminy + j - 1) + ".png";
ImageIO.write(tag, "png", new File(croppicname));
}
}
System.out.println("切割图片成功!");
} else {
System.out.println("创建目录失败!");
}
}
}
public static void main(String[] args) throws Exception{
BMapCut a=new BMapCut("C:\Users\Administrator\Desktop\geo\123.png",16,18,18,12958175,4825923.77,"C:\输出目录");
a.cutterall();
}
}



