Skip to content

Commit 0977bc0

Browse files
committed
Добавил поддержку отрисовки площадных объектов с заполнителем и продолжил отрисовку значков
1 parent 88cfb42 commit 0977bc0

10 files changed

+105
-68
lines changed

MyMap.pro.user

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE QtCreatorProject>
3-
<!-- Written by QtCreator 4.11.0, 2021-07-10T12:30:39. -->
3+
<!-- Written by QtCreator 4.11.0, 2021-07-15T11:58:15. -->
44
<qtcreator>
55
<data>
66
<variable>EnvironmentId</variable>

drawfunctions.hpp

+87-51
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ namespace nDraw {
2121
const double SIZE_ICON_Y = 5; // Данные константы нужны для относительного преобразования размеров иконок с учетом их изначальных размеров
2222
double REAL_SIZE_ICON_X; // Размер иконки (по которой выводилась линейная функция) с учетом разрешения изображения
2323
double REAL_SIZE_ICON_Y;
24+
void GetRealSizes(const short& width, const short& height, double& real_size_x, double& real_size_y) { // Функция, вычисляющая реальные размеры иконок
25+
real_size_x = qMax(width*1.0, 1.0*REAL_SIZE_ICON_X * width / SIZE_ICON_X);
26+
real_size_y = qMax(height*1.0, 1.0*REAL_SIZE_ICON_Y * height / SIZE_ICON_Y);
27+
}
28+
QPixmap ChangeTextureSizes(const QPixmap& icon, const double& real_size_x, const double& real_size_y) {
29+
/* Постоянные линейных функций зависимости размера текстуры от размера значка (для отрисовки площадных объектов заполненных значками) */
30+
static const double K_X = 10;
31+
static const double B_X = 0;
32+
static const double K_Y = 8.2;
33+
static const double B_Y = 0;
34+
int32_t texture_size_x = qRound(K_X*real_size_x+B_X);
35+
int32_t texture_size_y = qRound(K_Y*real_size_y+B_Y);
36+
QPixmap result = icon;
37+
result = result.scaled(texture_size_x, texture_size_y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
38+
return result;
39+
}
2440

2541
template<class T>
2642
QPointF FromMapPointToWindowPointF(const T& coords_input) {
@@ -63,6 +79,37 @@ namespace nDraw {
6379
return result;
6480
}
6581

82+
void DrawPointObject(const nSXFFile::rRecord& record, QPainter& painter) {
83+
double real_size_x, real_size_y;
84+
QPixmap image("images/" + QString::number(record.m_title.m_classification_code_l) + ".png");
85+
GetRealSizes(image.width(), image.height(), real_size_x, real_size_y);
86+
image = image.scaled(image.width(), image.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
87+
painter.setPen(QPen(Qt::black, 1, Qt::SolidLine));
88+
QVector<QPointF> points = GetMetricPoints(record);
89+
painter.drawPixmap(QRect(qRound(points[0].x() - real_size_x/2.0), qRound(points[0].y() - real_size_y/2),
90+
qRound(real_size_x), qRound(real_size_y)), image, QRect(0, 0, image.width(), image.height()));
91+
}
92+
void DrawSquareObjectWithIcons(const short& width, const short& height, const nSXFFile::rRecord& record, QPainter& painter) {
93+
double real_size_x, real_size_y;
94+
GetRealSizes(width, height, real_size_x, real_size_y);
95+
QPixmap icon("images/" + QString::number(record.m_title.m_classification_code_l) + ".png");
96+
//std::cout << "BEFORE: " << icon.width() << " " << icon.height() << std::endl;
97+
icon = ChangeTextureSizes(icon, real_size_x, real_size_y);
98+
//std::cout << "AFTER: " << icon.width() << " " << icon.height() << std::endl;
99+
painter.setPen(QPen(Qt::black, 1, Qt::NoPen));
100+
painter.setBrush(QBrush(icon));
101+
QVector<QPointF> points = GetMetricPoints(record);
102+
painter.drawPolygon(points.data(), points.count());
103+
}
104+
bool SearchInGroupCodes(const int32_t* array, const int32_t& array_size, const int32_t& code) {
105+
for (int32_t i = 0; i < array_size; ++i) {
106+
if (array[i] == code) {
107+
return true;
108+
}
109+
}
110+
return false;
111+
}
112+
66113
void DrawHydrography(QPainter& painter, const nSXFFile::rSXFFile &file) {
67114
static const int32_t CODES_COUNT = 9;
68115
static const int32_t HYDROGRAPHY_CODE[CODES_COUNT] = {31110000, 31120000, 31131000, 31132000, 31133000, 31134000,
@@ -91,45 +138,38 @@ namespace nDraw {
91138
else if (localiz_type == nSXFFile::eLocalType::POINT) {
92139
painter.drawPoint(points[0]);
93140
}
94-
else {
95-
// Других типов характеров локализации среди объектов гидрографии нет
96-
}
97141
}
98142
}
99143

100144
void DrawLandRelief(QPainter& painter, const nSXFFile::rSXFFile &file) {
101-
static const int32_t CODES_COUNT = 6;
102-
static const int32_t LAND_RELIEF_CODE_LINEAR[CODES_COUNT] = {21100000, 21200000, 21300000, 22212000, 22221000, 22630000};
103-
static const int32_t PIT_CODE = 22250000;
104-
static const int32_t BARROW_CODE = 22520000;
145+
/* Коды линейных объектов */
146+
static const int32_t LINEAR_CODES_COUNT = 6;
105147
static const int32_t HORIZONTALS_CODE = 21100000;
148+
static const int32_t LINEAR_OBJECTS_CODES[LINEAR_CODES_COUNT] = {HORIZONTALS_CODE, 21200000, 21300000, 22212000, 22221000, 22630000};
149+
/* Коды точечных объектов */
150+
static const int32_t POINT_CODES_COUNT = 2;
151+
static const int32_t POINT_OBJECTS_CODES[POINT_CODES_COUNT] = {22250000, 22520000};
152+
106153
for (int32_t i = 0; i < file.m_descriptor.m_number_records_l; ++i) {
107-
if (file.m_records[i].m_title.m_classification_code_l == PIT_CODE) {
108-
// Отрисовка значка
109-
}
110-
else if (file.m_records[i].m_title.m_classification_code_l == BARROW_CODE) {
111-
// Отрисовка значка
112-
}
113-
else {
114-
bool find = false;
115-
for (int32_t j = 0; j < CODES_COUNT; ++j) {
116-
if (file.m_records[i].m_title.m_classification_code_l == LAND_RELIEF_CODE_LINEAR[j]) {
117-
find = true;
118-
break;
119-
}
120-
}
121-
if (!find) {
154+
if (file.m_records[i].m_title.LocalizationType() == nSXFFile::LINEAR) {
155+
if (!SearchInGroupCodes(LINEAR_OBJECTS_CODES, LINEAR_CODES_COUNT, file.m_records[i].m_title.m_classification_code_l)) {
122156
continue;
123157
}
124158
if (file.m_records[i].m_title.m_classification_code_l == HORIZONTALS_CODE) {
125-
painter.setPen(QPen(Qt::darkYellow, 2, Qt::SolidLine));
159+
painter.setPen(QPen(Qt::darkYellow, 2, Qt::SolidLine)); // ПОМЕНЯТЬ ЦВЕТ (СМ. ЦВЕТ ЗНАЧКА)
126160
}
127161
else {
128-
painter.setPen(QPen(Qt::darkYellow, 1, Qt::SolidLine));
162+
painter.setPen(QPen(Qt::darkYellow, 1, Qt::SolidLine)); // ПОМЕНЯТЬ ЦВЕТ (СМ. ЦВЕТ ЗНАЧКА)
129163
}
130164
QVector<QPointF> points = GetMetricPoints(file.m_records[i]);
131165
painter.drawPolyline(points.data(), points.size());
132166
}
167+
else if (file.m_records[i].m_title.LocalizationType() == nSXFFile::POINT) {
168+
if (!SearchInGroupCodes(POINT_OBJECTS_CODES, POINT_CODES_COUNT, file.m_records[i].m_title.m_classification_code_l)) {
169+
continue;
170+
}
171+
DrawPointObject(file.m_records[i], painter);
172+
}
133173
}
134174
}
135175

@@ -197,41 +237,37 @@ namespace nDraw {
197237
}
198238

199239
void DrawVegitation(QPainter& painter, const nSXFFile::rSXFFile& file) {
200-
static const int32_t CODES_LINE_COUNT = 2;
201-
static const int32_t VEGITATION_LINE_CODES[CODES_LINE_COUNT] = {71111110, 71131000}; // Массив с кодами линейных объектов (отрисовываются одинаково)
202-
static const int32_t FOREST_DENSE_HIGH_CODE = 71111110;
203-
static const int32_t FOREST_RARE_LOWGROWTH_CODE = 71111220;
204-
/* Здесь также нужно отрисовать несколько точечных объектов-значков и 2 площадных с заполнением в виде значков - это пока не реализовано */
240+
/* Коды линейных объектов */
241+
static const int32_t LINEAR_CODES_COUNT = 2;
242+
static const int32_t LINEAR_OBJECTS_CODES[LINEAR_CODES_COUNT] = {71111110, 71131000};
243+
/* Коды точечных объектов */
244+
static const int32_t POINT_CODES_COUNT = 4;
245+
static const int32_t POINT_OBJECTS_CODES[POINT_CODES_COUNT] = {71111110, 71111220, 71132000, 71211200};
246+
/* Коды площадных объектов */
247+
static const int32_t MEADOW_VEGITATION_CODE = 71314000;
248+
static const int32_t RICE_FIELDS_CODE = 71322100;
205249
for (int32_t i = 0; i < file.m_descriptor.m_number_records_l; ++i) {
206250
if (file.m_records[i].m_title.LocalizationType() == nSXFFile::eLocalType::LINEAR) {
207-
bool find = false;
208-
for (int32_t j = 0; j < CODES_LINE_COUNT; ++j) {
209-
if (file.m_records[i].m_title.m_classification_code_l == VEGITATION_LINE_CODES[j]) {
210-
find = true;
211-
break;
212-
}
213-
}
214-
if (!find) {
251+
if (!SearchInGroupCodes(LINEAR_OBJECTS_CODES, LINEAR_CODES_COUNT, file.m_records[i].m_title.m_classification_code_l)) {
215252
continue;
216253
}
217254
painter.setPen(QPen(Qt::black, 2, Qt::DotLine));
218255
QVector<QPointF> points = GetMetricPoints(file.m_records[i]);
219256
painter.drawPolyline(points.data(), points.size());
220257
}
221-
if (file.m_records[i].m_title.LocalizationType() == nSXFFile::eLocalType::POINT) {
222-
if (file.m_records[i].m_title.m_classification_code_l == FOREST_DENSE_HIGH_CODE) {
223-
std::cout << "HERE" << std::endl;
224-
static const double SIZE[] = {9, 9};
225-
double REAL_SIZE_X = qMax(SIZE[0], REAL_SIZE_ICON_X * SIZE[0] / SIZE_ICON_X);
226-
double REAL_SIZE_Y = qMax(SIZE[1], REAL_SIZE_ICON_Y * SIZE[1] / SIZE_ICON_Y);
227-
std::cout << REAL_SIZE_X << " " << REAL_SIZE_Y << std::endl;
228-
QPixmap image("images/" + QString::number(FOREST_DENSE_HIGH_CODE) + ".png");
229-
painter.setPen(QPen(Qt::black, 1, Qt::SolidLine));
230-
QVector<QPointF> points = GetMetricPoints(file.m_records[i]);
231-
painter.drawPixmap(QRectF(points[0].x() - REAL_SIZE_X/2.0, points[0].y() - REAL_SIZE_Y/2,
232-
REAL_SIZE_X, REAL_SIZE_Y), image, QRectF(0, 0, image.width(), image.height()));
258+
else if (file.m_records[i].m_title.LocalizationType() == nSXFFile::eLocalType::POINT) {
259+
if (!SearchInGroupCodes(POINT_OBJECTS_CODES, POINT_CODES_COUNT, file.m_records[i].m_title.m_classification_code_l)) {
260+
continue;
261+
}
262+
DrawPointObject(file.m_records[i], painter);
263+
}
264+
else if (file.m_records[i].m_title.LocalizationType() == nSXFFile::eLocalType::AREAL) {
265+
if (file.m_records[i].m_title.m_classification_code_l == MEADOW_VEGITATION_CODE) {
266+
static const short WIDTH = 3;
267+
static const short HEIGHT = 4;
268+
DrawSquareObjectWithIcons(WIDTH, HEIGHT, file.m_records[i], painter);
233269
}
234-
else if (file.m_records[i].m_title.m_classification_code_l == FOREST_RARE_LOWGROWTH_CODE) {
270+
else if (file.m_records[i].m_title.m_classification_code_l == RICE_FIELDS_CODE) {
235271

236272
}
237273
}
@@ -323,7 +359,7 @@ namespace nDraw {
323359
image_size_y_disc *= METERS_DESCRETE_X_D;
324360

325361
/* Вычисление размера пикселя в метрах ( подробнее об этом тут https://help13.gisserver.ru/russian/panorama/index.html?vekbmp.html ) */
326-
int32_t precision_met = file.m_passport.m_instrument_resolution_l /*6000*/; // Внимание! От этого значения зависит размер изображения, его можно изменять (уменьшать - меньше разрешение изображения)
362+
int32_t precision_met = /*file.m_passport.m_instrument_resolution_l*/ 6000; // Внимание! От этого значения зависит размер изображения, его можно изменять (уменьшать - меньше разрешение изображения)
327363
PIXEL_METERS_D = 1.0f*(file.m_passport.m_scale_l / precision_met);
328364
IMAGE_SIZE_X_PIX = qRound(image_size_x_disc / PIXEL_METERS_D);
329365
IMAGE_SIZE_Y_PIX = qRound(image_size_y_disc / PIXEL_METERS_D);

images/22250000.png

156 Bytes
Loading

images/22520000.png

175 Bytes
Loading

images/71111110.png

-103 Bytes
Loading

images/71111220.png

-76 Bytes
Loading

images/71132000.png

82 Bytes
Loading

images/71211200.png

110 Bytes
Loading

images/71314000.png

178 Bytes
Loading

main.cpp

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
#include <QApplication>
2-
#include "rsxffile.h"
3-
#include "drawfunctions.hpp"
4-
#include <iostream>
5-
6-
int main(int argc, char* argv[]) {
7-
setlocale(LC_ALL, "Russian");
8-
const char* FNAME = "M3833.SXF";
9-
nSXFFile::rSXFFile file;
10-
file.Read(FNAME);
11-
file.Print();
12-
QApplication app(argc, argv);
13-
nDraw::Draw(file);
14-
std::cout << "Отрисовка карты завершилась." << std::endl;
15-
return app.exec();
16-
}
1+
#include <QApplication>
2+
#include <QPixmap>
3+
#include "rsxffile.h"
4+
#include "drawfunctions.hpp"
5+
#include <iostream>
6+
7+
int main(int argc, char* argv[]) {
8+
setlocale(LC_ALL, "Russian");
9+
const char* FNAME = "M3833.SXF";
10+
nSXFFile::rSXFFile file;
11+
file.Read(FNAME);
12+
file.Print();
13+
QApplication app(argc, argv);
14+
nDraw::Draw(file);
15+
std::cout << "Отрисовка карты завершилась." << std::endl;
16+
return app.exec();
17+
}

0 commit comments

Comments
 (0)