package MapData;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class MapData {
/**
* 矩阵
*/
public int[][] mapData;
/**
* 纬度(图片大小)
*/
public int dimensionLevel = 1;
/**
* 列
*/
public int mapCol;
/**
* 行
*/
public int mapRow;
/**
* 行偏移
*/
public int rowOffset;
/**
* 列偏移
*/
public int colOffset;
public MapData(int dimensionLevel) {
this.dimensionLevel = dimensionLevel;
}
/**
* @param outlines
*/
public void createMap(List<Line> outlines) {
int keyValue = MapColorCode.WHITE.getCode();
double rowMax = outlines.get(0).first.x;
double colMax = outlines.get(0).first.y;
double rowMin = rowMax;
double colMin = colMax;
for (Line line : outlines) {
Point l = line.first;
rowMax = Math.max(l.x, rowMax);
colMax = Math.max(l.y, colMax);
rowMin = Math.min(l.x, rowMin);
colMin = Math.min(l.y, colMin);
}
this.rowOffset = dealValue(0 - rowMin) + 2;
this.colOffset = dealValue(0 - colMin) + 2;
this.mapRow = dealValue(rowMax) + rowOffset + 2;
this.mapCol = dealValue(colMax) + colOffset + 2;
createMapGrid(keyValue);
}
/**
* @param outlines
* @param key 背景色
*/
public void createMap(List<Line> outlines, MapColorCode key) {
int keyValue = key.getCode();
double rowMax = outlines.get(0).first.x;
double colMax = outlines.get(0).first.y;
double rowMin = rowMax;
double colMin = colMax;
for (Line line : outlines) {
Point l = line.first;
rowMax = Math.max(l.x, rowMax);
colMax = Math.max(l.y, colMax);
rowMin = Math.min(l.x, rowMin);
colMin = Math.min(l.y, colMin);
}
this.rowOffset = dealValue(0 - colMin) + 2;
this.colOffset = dealValue(0 - rowMin) + 2;
this.mapRow = dealValue(colMax) + rowOffset + 2;
this.mapCol = dealValue(rowMax) + colOffset + 2;
createMapGrid(keyValue);
}
/**
* 添加线
*
* @param line
* @param key
*/
public void addLine(Line line, int key) {
ArrayList<Line> lines = new ArrayList<Line>();
lines.add(line);
createMapGrid(lines, key);
}
/**
* 添加线
*
* @param lines
* @param key
*/
public void addLines(List<Line> lines, int key) {
createMapGrid(lines, key);
}
/**
* 添加点
*
* @param point
* @param key
*/
public void addPoint(Point point, int key) {
createMapGrid(point, key);
}
/**
* 添加点
*
* @param points
* @param key
*/
public void addPoints(List<Point> points, int key) {
points.forEach(x -> createMapGrid(x, key));
}
/**
* 添加多边形,内部会填满
*
* @param pg
* @param key
*/
public void addPgFull(List<Line> pg, int key) {
createMapGridFull(pg, key);
}
/**
* 数据升维
*
* @param value
* @return
*/
public double dealUpColValue(int value) {
return (value - colOffset) * dimensionLevel;
}
/**
* 数据升维
*
* @param value
* @return
*/
public double dealUpRowValue(int value) {
return (value - rowOffset) * dimensionLevel;
}
/**
* 获取最大外轮廓
*
* @param lines
* @return
*/
public List<Line> getMaxBound(List<Line> lines) {
List<Point> points = new ArrayList<>();
if (lines != null) {
for (Line l : lines) {
points.add(l.first);
points.add(l.last);
}
}
List<Line> res = new ArrayList<>();
double maxX = 0;
double maxY = 0;
double minX = Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
for (Point p : points) {
maxX = Math.max(p.x, maxX);
minX = Math.min(p.x, minX);
minY = Math.min(p.y, minY);
maxY = Math.max(p.y, maxY);
}
res.add(new Line(new Point(maxX, maxY), new Point(maxX, minY)));
res.add(new Line(new Point(maxX, minY), new Point(minX, minY)));
res.add(new Line(new Point(minX, minY), new Point(minX, maxY)));
res.add(new Line(new Point(minX, maxY), new Point(maxX, maxY)));
return res;
}
/**
* 生成图片
*
* @param filedir 保存图片路径
* @throws IOException
*/
public void image(String filedir) throws IOException {
int[][] matrix = dealMapData(this.mapData);
int mapRow = matrix.length;
int mapCol = matrix[0].length;
// 每个像素的大小
int cz = 5;
//生成图的宽度
int width = mapRow * cz;
//生成图的高度
int height = mapCol * cz;
OutputStream output = new FileOutputStream(new File(filedir));
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bufImg.createGraphics();
gs.setBackground(Color.WHITE);
gs.clearRect(0, 0, width, height);
for (int i = 0; i < mapRow; i++) {
for (int j = 0; j < mapCol; j++) {
gs.setColor(color(matrix[i][j]));
gs.drawRect(i * cz, j * cz, cz, cz);
gs.fillRect(i * cz, j * cz, cz, cz);
}
}
gs.dispose();
bufImg.flush();
ImageIO.write(bufImg, "jpeg", output);
}
private int[][] dealMapData(int[][] mapData) {
int mapRow = mapData[0].length;
int mapCol = mapData.length;
int[][] map = new int[mapRow][mapCol];
for (int i = 0; i < mapRow; i++) {
for (int j = 0; j < mapCol; j++) {
map[i][j] = mapData[j][i];
}
}
// 上下翻转
for (int x = 0; x < mapRow; x++) {
for (int y = 0; y < mapCol / 2; y++) {
int value = map[x][mapCol - y - 1];
map[x][mapCol - y - 1] = map[x][y];
map[x][y] = value;
}
}
return map;
}
/**
* 颜色类型转换
*
* @param color
* @return
*/
private Color color(int color) {
if (color == MapColorCode.RED.getCode()) {
return Color.RED;
} else if (color == MapColorCode.GREEN.getCode()) {
return Color.GREEN;
} else if (color == MapColorCode.ORANGE.getCode()) {
return Color.ORANGE;
} else if (color == MapColorCode.BLACK.getCode()) {
return Color.BLACK;
} else if (color == MapColorCode.BLUE.getCode()) {
return Color.BLUE;
}
return Color.WHITE;
}
/**
* @param key
*/
private void createMapGrid(int key) {
mapData = new int[mapCol][];
for (int i = 0; i < mapCol; i++) {
mapData[i] = new int[mapRow];
for (int j = 0; j < mapRow; j++) {
mapData[i][j] = key;
}
}
}
private void createMapGrid(Point point, int key) {
mapData[dealColValue(point.y)][dealRowValue(point.x)] = key;
}
/**
* 更新矩阵
*
* @param lines
* @param key
*/
private void createMapGrid(List<Line> lines, int key) {
for (Line line : lines) {
try {
Point p1 = line.first;
Point p2 = line.last;
int y1 = dealRowValue(p1.x);
int y2 = dealRowValue(p2.x);
int x1 = dealColValue(p1.y);
int x2 = dealColValue(p2.y);
if (y1 == y2 && x1 != x2) {
for (int i = Math.min(x1, x2); i <= Math.max(x1, x2); i++) {
mapData[i][y1] = key;
}
} else if (x1 == x2 && y1 != y2) {
for (int i = Math.min(y1, y2); i <= Math.max(y1, y2); i++) {
mapData[x1][i] = key;
}
} else if (x1 == x2 && y1 == y2) {
mapData[x1][y1] = key;
} else {
double k = (double) (y2 - y1) / (double) (x2 - x1);
double b = (double) y2 - k * (double) x2;
int lasty = Integer.MAX_VALUE;
for (int i = Math.min(x1, x2); i <= Math.max(x1, x2); i++) {
int y = (int) (k * (double) i + b);
if (lasty != Integer.MAX_VALUE) {
for (int j = Math.min(lasty, y); j <= Math.max(lasty, y); j++) {
mapData[i][j] = key;
}
} else {
mapData[i][y] = key;
}
lasty = y;
}
}
} catch (Exception e) {
e.getMessage();
}
}
}
/**
* 更新矩阵
*
* @param lines
* @param key
*/
private void createMapGridFull(List<Line> lines, int key) {
int maxX = 0;
int maxY = 0;
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
double[] vertx = new double[lines.size()];
double[] verty = new double[lines.size()];
int t = 0;
for (Line l : lines) {
int x = dealRowValue(l.first.x);
int y = dealColValue(l.first.y);
maxX = Math.max(x, maxX);
minX = Math.min(x, minX);
minY = Math.min(y, minY);
maxY = Math.max(y, maxY);
vertx[t] = x;
verty[t++] = y;
}
for (int i = minX; i < maxX; i++) {
for (int j = minY; j < maxY; j++) {
if (pointInPoly(lines.size(), vertx, verty, i, j)) {
mapData[j][i] = key;
}
}
}
createMapGrid(lines, key);
}
/**
* 判断点是否在多边形内
*
* @param n
* @param vertx
* @param verty
* @param testx
* @param testy
* @return
*/
private boolean pointInPoly(int n, double[] vertx, double[] verty, int testx, int testy) {
boolean res = true;
for (int i = 0, j = n - 1; i < n; j = i++) {
if (((verty[i] > testy) != (verty[j] > testy)) &&
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
res = !res;
}
}
return !res;
}
private int dealRowValue(double value) {
return (int) Math.round(value / dimensionLevel) + rowOffset;
}
private int dealColValue(double value) {
return (int) Math.round(value / dimensionLevel) + colOffset;
}
private int dealValue(double value) {
return (int) Math.round(value / dimensionLevel);
}
}