Files
DataStructureProject/parkinglot.cpp
T
2017-12-13 20:18:14 +08:00

272 lines
8.2 KiB
C++

#include "parkinglot.h"
#include <QDomDocument>
#include <QFile>
#include <QMessageBox>
#include <QPainter>
#include <QWidget>
#include <QDebug>
#include <algorithm>
ParkingLot::ParkingLot(const QString &fname, QWidget* parent)
{
map = new QPixmap(1000, 1000);
this->parent = parent;
QFile file(fname);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::critical(parent, QObject::tr("Error"),
QObject::tr("Cannot read file %1").arg(fname));
}
QString errorStr;
int errorLine;
int errorColumn;
doc = new QDomDocument;
if (!doc -> setContent(&file, false, &errorStr, &errorLine, &errorColumn)) {
QMessageBox::critical(parent, QObject::tr("Error"),
QObject::tr("Parse error at line %1, column %2: %3")
.arg(errorLine).arg(errorColumn).arg(errorStr));
}
// map->resize(1000, 1000);
// painter = new QPainter(map);
}
void ParkingLot::creatMap()
{/*
// painter = new QPainter(map);
QDomElement root =doc -> documentElement();
if (root.tagName() != "parkinglot") {
QMessageBox::critical(parent, QObject::tr("Error"),
QObject::tr("Not a parkinglot file"));
}
if (root.attribute("layout") == "vertical")
vertical = true;
else if (root.attribute("layout") == "horizontal")
vertical = false;
else
qDebug() << "XML文件错误:" << root.attribute("layout");
int currentX = 0, X = 0;
int currentY = 0, Y = 0;
int maxWidthOfColumn = 0;
int maxHeightOfLine = 0;
QPixmap roadPix(":/road/line");
QPixmap roomPix(":/road/room");
QPixmap *toDraw;
QMatrix rotate;
QDomNode line = root.firstChild();
while (!line.isNull()) { // <column>节点
QDomElement space = line.firstChild().toElement();
while(!space.isNull()) {
if (space.tagName() == "road") {
toDraw = &roadPix;
} else if (space.tagName() == "room") {
toDraw = &roomPix;
} else {
qDebug() << "文件错误" << space.tagName();
}
int n = space.attribute("number", "1").toInt();
painter->save();
switch(space.attribute("direction").at(0).unicode()) {
case 'E':
rotate.rotate(180);
break;
case 'S':
rotate =rotate.rotate(90);
break;
case 'W':
rotate =rotate.rotate(0);
break;
case 'N':
rotate =rotate.rotate(270);
break;
default:
qDebug() << "错误的方向" << space.attribute("direction").at(0).unicode();
}
for (int i = 0; i < n; i++) {
painter->drawPixmap(currentX, currentY, toDraw -> width(), toDraw -> height(),
toDraw->transformed(rotate));
if (vertical) {
currentY += toDraw -> height();
maxWidthOfColumn = std::max(maxWidthOfColumn, toDraw -> width());
} else {
currentX += toDraw -> width();
maxHeightOfLine = std::max(maxHeightOfLine, toDraw -> height());
}
}
painter->restore();
space = space.nextSibling().toElement();
}
if (vertical) {
Y = std::max(Y, currentY);
currentY = 0;
currentX += maxWidthOfColumn;
X = currentX;
maxWidthOfColumn = 0;
} else {
X = std::max(X, currentX);
currentX = 0;
currentY += maxHeightOfLine;
Y = currentY;
maxHeightOfLine = 0;
}
line = line.nextSibling();
}*/
}
QPixmap ParkingLot::creatMap2()
{
QDomElement root =doc -> documentElement();
if (root.tagName() != "parkinglot") {
QMessageBox::critical(parent, QObject::tr("Error"),
QObject::tr("Not a parkinglot file"));
}
qDebug() << "!!!!";
return parseLayout(root.firstChild().toElement());
}
QPixmap *ParkingLot::getPixmap()
{
return map;
}
ParkingLot::~ParkingLot()
{
// delete painter;
delete doc;
delete map;
}
QPixmap drawRoad(const QDomElement& roadXML) {
QPixmap result(800, 600);
if (roadXML.tagName() != "road") {
qDebug() << "XML is not a road";
return result.copy(0, 0, 0, 0);
}
int x = 0, y = 0;
QPainter painter(&result);
painter.setBrush(Qt::white);
painter.setPen(Qt::white);
enum {vertical, horizontal} direction;
const int length = roadXML.attribute("length").toInt();
qDebug() << "length:" << length;
if (roadXML.attribute("direction") == "horizontal")
direction = horizontal;
else
direction = vertical;
if (direction == horizontal) {
while (x < length) {
painter.drawRect(x + 5, 20, 40, 10);
x += 50;
}
} else {
while (y < length) {
painter.drawRect(20, y + 5, 10, 40);
y += 50;
}
}
if (direction == horizontal)
return result.copy(0, 0, length, 50);
else
return result.copy(0, 0, 50, length);
}
QPixmap drawRoom(const QDomElement& roomXML) {
QPixmap result(800, 600);
if (roomXML.tagName() != "room") {
qDebug() << "XML节点不是车位";
return result.copy(0, 0, 0, 0);
}
QPixmap temp(60, 40);
QPainter painter(&result), tPainter(&temp);
painter.setPen(Qt::white);
painter.setBrush(Qt::white);
tPainter.setPen(Qt::white);
tPainter.setBrush(Qt::white);
ushort direction = roomXML.attribute("direction").at(0).unicode();
int n = roomXML.attribute("number").toInt();
int x = 0, y = 0;
enum {down, right} expendDirection;
if (roomXML.attribute("expendDirection") == "down")
expendDirection = down;
else
expendDirection = right;
tPainter.drawRect(0, 0, 60, 5);
tPainter.drawRect(0, 5, 10, 35);
tPainter.drawRect(10, 35, 50, 5);
tPainter.end();
switch(direction) {
case 'E':
// temp = temp;
break;
case 'S':
temp = temp.transformed(QMatrix().rotate(270));
break;
case 'W':
temp = temp.transformed(QMatrix().rotate(180));
break;
case 'N':
temp = temp.transformed(QMatrix().rotate(90));
break;
default:
qDebug() << "未知方向" << direction;
break;
}
// tPainter.begin(&temp);
for (int i = 0; i < n; i++) {
painter.drawPixmap(x, y, temp.width(), temp.height(), temp);
if (expendDirection == down)
y += temp.height();
else
x += temp.width();
}
if (expendDirection == down)
return result.copy(0, 0, temp.width(), y);
else
return result.copy(0, 0, temp.height(), x);
}
QPixmap ParkingLot::parseLayout(const QDomElement& layout)
{
QPixmap result(2000, 2000), temp;
QPainter painter(&result);
painter.setPen(Qt::black);
int x = 0, y = 0, maxX = 0, maxY = 0;
enum {vertical, horizontal} direction;
if (layout.tagName() == "vLayout")
direction = vertical;
else if (layout.tagName() == "hLayout")
direction = horizontal;
else {
qDebug() << "错误的布局名称" << layout.tagName();
return result;
}
QDomElement child = layout.firstChild().toElement();
while(!child.isNull()) {
QString name = child.tagName();
if (name == "road") {
temp = drawRoad(child);
} else if (name == "room") {
temp = drawRoom(child);
} else if (name == "vLayout" || name == "hLayout")
temp = parseLayout(child);
painter.drawPixmap(x, y, temp.width(), temp.height(), temp);
if (direction == horizontal) {
x += temp.width();
maxY = std::max(maxY, temp.height());
} else {
y += temp.height();
maxX = std::max(maxX, temp.width());
}
child = child.nextSibling().toElement();
}
if (direction == horizontal) {
return result.copy(0, 0, x, maxY);
} else {
return result.copy(0, 0, maxX, y);
}
}